@orangecheck/design 0.21.0 → 0.23.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 +29 -8
- package/dist/components.d.mts +1 -1
- package/dist/components.d.ts +1 -1
- package/dist/components.js +20 -6
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +20 -7
- package/dist/components.mjs.map +1 -1
- package/dist/composites.d.mts +11 -1
- package/dist/composites.d.ts +11 -1
- package/dist/composites.js +20 -6
- package/dist/composites.js.map +1 -1
- package/dist/composites.mjs +20 -7
- package/dist/composites.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -14
- package/dist/index.mjs.map +1 -1
- package/dist/styles/theme.css +8 -4
- package/dist/styles/themes/ember.css +93 -3
- package/dist/styles/themes/orangecheck.css +6 -6
- package/dist/styles/themes.css +4 -3
- package/dist/tokens.d.mts +1 -1
- package/dist/tokens.d.ts +1 -1
- package/dist/tokens.js +7 -7
- package/dist/tokens.js.map +1 -1
- package/dist/tokens.mjs +7 -7
- package/dist/tokens.mjs.map +1 -1
- package/package.json +1 -1
package/dist/styles/theme.css
CHANGED
|
@@ -344,7 +344,11 @@
|
|
|
344
344
|
margin-top: 1rem;
|
|
345
345
|
}
|
|
346
346
|
.docs-prose h1 {
|
|
347
|
-
|
|
347
|
+
/* Skin-adaptive: mono under the cypherpunk skins (--oc-font-display
|
|
348
|
+
undefined → falls back to --oc-font-mono), Hanken sans under ember
|
|
349
|
+
(which sets --oc-font-display). Body copy is already sans, so this
|
|
350
|
+
keeps headings consistent per skin instead of always-mono. */
|
|
351
|
+
font-family: var(--oc-font-display, var(--oc-font-mono)), ui-monospace, monospace;
|
|
348
352
|
font-size: 2rem;
|
|
349
353
|
line-height: 1.1;
|
|
350
354
|
letter-spacing: -0.02em;
|
|
@@ -353,7 +357,7 @@
|
|
|
353
357
|
margin-bottom: 0.5rem;
|
|
354
358
|
}
|
|
355
359
|
.docs-prose h2 {
|
|
356
|
-
font-family: var(--oc-font-mono), ui-monospace, monospace;
|
|
360
|
+
font-family: var(--oc-font-display, var(--oc-font-mono)), ui-monospace, monospace;
|
|
357
361
|
font-size: 1.35rem;
|
|
358
362
|
line-height: 1.2;
|
|
359
363
|
letter-spacing: -0.01em;
|
|
@@ -364,7 +368,7 @@
|
|
|
364
368
|
border-top: 1px solid var(--border);
|
|
365
369
|
}
|
|
366
370
|
.docs-prose h3 {
|
|
367
|
-
font-family: var(--oc-font-mono), ui-monospace, monospace;
|
|
371
|
+
font-family: var(--oc-font-display, var(--oc-font-mono)), ui-monospace, monospace;
|
|
368
372
|
font-size: 1.05rem;
|
|
369
373
|
line-height: 1.3;
|
|
370
374
|
font-weight: 700;
|
|
@@ -372,7 +376,7 @@
|
|
|
372
376
|
margin-bottom: 0.4rem;
|
|
373
377
|
}
|
|
374
378
|
.docs-prose h4 {
|
|
375
|
-
font-family: var(--oc-font-mono), ui-monospace, monospace;
|
|
379
|
+
font-family: var(--oc-font-display, var(--oc-font-mono)), ui-monospace, monospace;
|
|
376
380
|
font-size: 0.9rem;
|
|
377
381
|
font-weight: 700;
|
|
378
382
|
margin-top: 1.5rem;
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
* existing JetBrains Mono eyebrows. Derived from the orangecheck.io redesign
|
|
9
9
|
* mockups; tuned for WCAG AA.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* ember is the FAMILY DEFAULT, so it owns the bare `:root`/`.dark` base (the
|
|
12
|
+
* no-JS / pre-hydration / SSR fallback) AS WELL AS its `[data-oc-theme='ember']`
|
|
13
|
+
* arms. The other skins are attribute-only arms imported AFTER this file, so
|
|
14
|
+
* they override the base when their attribute is set (orangecheck at equal
|
|
15
|
+
* specificity via source order; phosphor/lightning/gold via `:root[data-oc-theme]`).
|
|
16
|
+
* A skin must declare the COMPLETE token set in both modes so it fully overrides.
|
|
14
17
|
*
|
|
15
18
|
* --primary vs --brand split is intentional: --brand (oklch 0.635) is the exact
|
|
16
19
|
* sampled band terracotta (decorative full-bleed sections); --primary is one
|
|
@@ -19,6 +22,7 @@
|
|
|
19
22
|
* the big hero/CTA bands, --primary for interactive surfaces + text accents.
|
|
20
23
|
*/
|
|
21
24
|
|
|
25
|
+
:root,
|
|
22
26
|
[data-oc-theme='ember'] {
|
|
23
27
|
/* Soft, friendly corners — 1rem drives the derived scale: sm 12 / md 14 /
|
|
24
28
|
lg 16 / xl 20px, matching the sampled badge (12), card (16), panel (20). */
|
|
@@ -100,6 +104,7 @@
|
|
|
100
104
|
--brand-foreground: oklch(0.99 0.005 75);
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
.dark,
|
|
103
108
|
.dark[data-oc-theme='ember'],
|
|
104
109
|
[data-oc-theme='ember'].dark {
|
|
105
110
|
/* Dark — warm near-black, elevated warm-charcoal cards (grounded in the
|
|
@@ -221,3 +226,88 @@
|
|
|
221
226
|
text-transform: none;
|
|
222
227
|
letter-spacing: normal;
|
|
223
228
|
}
|
|
229
|
+
|
|
230
|
+
/* Keep the ambient aurora WARM under ember. The .oc-aurora element self-defines
|
|
231
|
+
--au-green/--au-blue from the semantic --success/--info tokens (green/blue),
|
|
232
|
+
which clash with the all-terracotta palette. Re-point them to warm sunset
|
|
233
|
+
hues so the field stays amber→terracotta→deep-orange, never cool teal/blue.
|
|
234
|
+
--au-orange/--au-violet already track --brand/--primary (terracotta). */
|
|
235
|
+
[data-oc-theme='ember'] .oc-aurora {
|
|
236
|
+
--au-green: oklch(0.74 0.15 74); /* golden amber, not node-green */
|
|
237
|
+
--au-blue: oklch(0.6 0.16 38); /* deep red-orange, not L2 blue */
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ── Data-dense ember treatments ───────────────────────────────────────
|
|
241
|
+
The dashboard / data composites (StatGrid, StatCard, DataRow lists,
|
|
242
|
+
DefinitionList, DataSection panels, DataTable) ship a SHARP, FLAT,
|
|
243
|
+
1px-bordered terminal look for the cypherpunk skins. Under ember those
|
|
244
|
+
same components become soft, warm, rounded, separated cards/panels —
|
|
245
|
+
the consumer markup is identical; only the active skin changes. This is
|
|
246
|
+
how data-dense technical subpages read as ember instead of terminal.
|
|
247
|
+
Every rule is scoped to [data-oc-theme='ember'] so the cypherpunk skins
|
|
248
|
+
keep their flat terminal treatment byte-for-byte. */
|
|
249
|
+
|
|
250
|
+
/* StatGrid — sharp 1px-separated grid → gapped soft rounded cards. */
|
|
251
|
+
[data-oc-theme='ember'] .oc-stat-grid {
|
|
252
|
+
background: transparent;
|
|
253
|
+
border: 0;
|
|
254
|
+
gap: 0.75rem;
|
|
255
|
+
}
|
|
256
|
+
[data-oc-theme='ember'] .oc-stat-tile {
|
|
257
|
+
background: var(--card);
|
|
258
|
+
border: 1px solid var(--border);
|
|
259
|
+
border-radius: var(--radius-lg);
|
|
260
|
+
box-shadow: var(--oc-shadow-sm);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* StatCard — flat sharp frame → rounded soft card. */
|
|
264
|
+
[data-oc-theme='ember'] .oc-stat-card {
|
|
265
|
+
border-radius: var(--radius-lg);
|
|
266
|
+
box-shadow: var(--oc-shadow-sm);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* DataSection / Panel — a full-width `border-t` divider section under the
|
|
270
|
+
cypherpunk skins → a discrete soft padded card under ember. */
|
|
271
|
+
[data-oc-theme='ember'] .oc-panel {
|
|
272
|
+
background: var(--card);
|
|
273
|
+
border: 1px solid var(--border);
|
|
274
|
+
border-radius: var(--radius-lg);
|
|
275
|
+
box-shadow: var(--oc-shadow-sm);
|
|
276
|
+
padding: 1.25rem 1.5rem;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* Data lists (a `divide-y` stack of DataRows) → one rounded soft card,
|
|
280
|
+
rows separated by warm hairlines. */
|
|
281
|
+
[data-oc-theme='ember'] .oc-data-list {
|
|
282
|
+
background: var(--card);
|
|
283
|
+
border: 1px solid var(--border);
|
|
284
|
+
border-radius: var(--radius-lg);
|
|
285
|
+
box-shadow: var(--oc-shadow-sm);
|
|
286
|
+
overflow: hidden;
|
|
287
|
+
}
|
|
288
|
+
[data-oc-theme='ember'] .oc-data-list > * {
|
|
289
|
+
padding-left: 1rem;
|
|
290
|
+
padding-right: 1rem;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* Data tables → rounded container, warm recessed header, soft separators.
|
|
294
|
+
Genuine code/JSON stays in `.terminal` (handled above) — this is for
|
|
295
|
+
tabular DATA, which under ember should read as a clean warm table. */
|
|
296
|
+
[data-oc-theme='ember'] .oc-data-table {
|
|
297
|
+
border-radius: var(--radius-lg);
|
|
298
|
+
overflow: hidden;
|
|
299
|
+
box-shadow: var(--oc-shadow-sm);
|
|
300
|
+
}
|
|
301
|
+
[data-oc-theme='ember'] .oc-data-table thead {
|
|
302
|
+
background: var(--muted);
|
|
303
|
+
}
|
|
304
|
+
[data-oc-theme='ember'] .oc-data-table thead th {
|
|
305
|
+
font-family: var(--oc-font-sans);
|
|
306
|
+
letter-spacing: 0.04em;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* DefinitionList — keep the mono micro-label voice (consistent with ember
|
|
310
|
+
eyebrows), but let long values read in the warm sans, not mono. */
|
|
311
|
+
[data-oc-theme='ember'] .oc-deflist dd {
|
|
312
|
+
font-family: var(--oc-font-sans);
|
|
313
|
+
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Skin: orangecheck (default)
|
|
2
|
+
* Skin: orangecheck (the original look — now an opt-in alternate, not the default)
|
|
3
3
|
*
|
|
4
|
-
* The current OrangeCheck look, ported byte-for-byte.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The current OrangeCheck look, ported byte-for-byte. ember now owns the bare
|
|
5
|
+
* `:root` / `.dark` base, so this file is an attribute-only arm: it activates
|
|
6
|
+
* only when `OcThemeProvider` sets `data-oc-theme='orangecheck'`. It is imported
|
|
7
|
+
* AFTER ember.css, so at equal specificity to ember's `:root` base it wins via
|
|
8
|
+
* source order whenever its attribute is present.
|
|
7
9
|
*
|
|
8
10
|
* MODE axis (light/dark) = `.dark` class (next-themes). SKIN axis = the
|
|
9
11
|
* `data-oc-theme` attribute. A skin file must declare the COMPLETE token set in
|
|
10
12
|
* both modes so it fully overrides whatever the default populated.
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
|
-
:root,
|
|
14
15
|
[data-oc-theme='orangecheck'] {
|
|
15
16
|
/* Sharp corners — cypherpunk, not SaaS */
|
|
16
17
|
--radius: 0.25rem;
|
|
@@ -83,7 +84,6 @@
|
|
|
83
84
|
--brand-foreground: oklch(0.1 0 0);
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
.dark,
|
|
87
87
|
[data-oc-theme='orangecheck'].dark {
|
|
88
88
|
/* Dark mode — near-true-black. Terminal energy. */
|
|
89
89
|
--background: oklch(0.08 0 0);
|
package/dist/styles/themes.css
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* @orangecheck/design — themes.css
|
|
3
3
|
*
|
|
4
4
|
* Aggregates every skin's token values. Import order matters: the default skin
|
|
5
|
-
* (
|
|
6
|
-
* fallback; later skins override via their `[data-oc-theme]` arms when active
|
|
5
|
+
* (ember) comes first because it also populates the bare `:root`/`.dark`
|
|
6
|
+
* fallback; later skins override via their `[data-oc-theme]` arms when active
|
|
7
|
+
* (equal specificity to `:root`, so source order is what lets them win).
|
|
7
8
|
*/
|
|
9
|
+
@import './themes/ember.css';
|
|
8
10
|
@import './themes/orangecheck.css';
|
|
9
11
|
@import './themes/phosphor.css';
|
|
10
12
|
@import './themes/lightning.css';
|
|
11
13
|
@import './themes/gold.css';
|
|
12
|
-
@import './themes/ember.css';
|
package/dist/tokens.d.mts
CHANGED
|
@@ -13,7 +13,7 @@ interface OcTheme {
|
|
|
13
13
|
declare const OC_THEMES: readonly OcTheme[];
|
|
14
14
|
declare const OC_DEFAULT_ACCENT = "#f97316";
|
|
15
15
|
declare function accentFor(id: string | null | undefined): string;
|
|
16
|
-
declare const DEFAULT_OC_THEME = "
|
|
16
|
+
declare const DEFAULT_OC_THEME = "ember";
|
|
17
17
|
type OcThemeId = (typeof OC_THEMES)[number]['id'] | (string & {});
|
|
18
18
|
declare function isKnownTheme(id: string | null | undefined): id is OcThemeId;
|
|
19
19
|
declare function resolveTheme(id: string | null | undefined): string;
|
package/dist/tokens.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ interface OcTheme {
|
|
|
13
13
|
declare const OC_THEMES: readonly OcTheme[];
|
|
14
14
|
declare const OC_DEFAULT_ACCENT = "#f97316";
|
|
15
15
|
declare function accentFor(id: string | null | undefined): string;
|
|
16
|
-
declare const DEFAULT_OC_THEME = "
|
|
16
|
+
declare const DEFAULT_OC_THEME = "ember";
|
|
17
17
|
type OcThemeId = (typeof OC_THEMES)[number]['id'] | (string & {});
|
|
18
18
|
declare function isKnownTheme(id: string | null | undefined): id is OcThemeId;
|
|
19
19
|
declare function resolveTheme(id: string | null | undefined): string;
|
package/dist/tokens.js
CHANGED
|
@@ -14,6 +14,12 @@ function cn(...inputs) {
|
|
|
14
14
|
|
|
15
15
|
// src/tokens/themes.ts
|
|
16
16
|
var OC_THEMES = [
|
|
17
|
+
{
|
|
18
|
+
id: "ember",
|
|
19
|
+
label: "ember",
|
|
20
|
+
description: "the warmth \u2014 burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk \xB7 approachable, human",
|
|
21
|
+
accent: "#da6736"
|
|
22
|
+
},
|
|
17
23
|
{
|
|
18
24
|
id: "orangecheck",
|
|
19
25
|
label: "orangecheck",
|
|
@@ -37,19 +43,13 @@ var OC_THEMES = [
|
|
|
37
43
|
label: "gold",
|
|
38
44
|
description: "sound money \u2014 digital gold, hard 0.125rem milled edge, mono ledger \xB7 21M",
|
|
39
45
|
accent: "#e3b831"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
id: "ember",
|
|
43
|
-
label: "ember",
|
|
44
|
-
description: "the warmth \u2014 burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk \xB7 approachable, human",
|
|
45
|
-
accent: "#da6736"
|
|
46
46
|
}
|
|
47
47
|
];
|
|
48
48
|
var OC_DEFAULT_ACCENT = "#f97316";
|
|
49
49
|
function accentFor(id) {
|
|
50
50
|
return OC_THEMES.find((t) => t.id === id)?.accent ?? OC_DEFAULT_ACCENT;
|
|
51
51
|
}
|
|
52
|
-
var DEFAULT_OC_THEME = "
|
|
52
|
+
var DEFAULT_OC_THEME = "ember";
|
|
53
53
|
function isKnownTheme(id) {
|
|
54
54
|
return !!id && OC_THEMES.some((t) => t.id === id);
|
|
55
55
|
}
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tokens/cn.ts","../src/tokens/themes.ts","../src/tokens/aurora.tsx","../src/tokens/provider.tsx","../src/tokens/theme-bridge.tsx","../src/tokens/theme-picker.tsx","../src/tokens/appearance-menu.tsx"],"names":["twMerge","clsx","jsx","createContext","useState","useRef","useEffect","useCallback","useMemo","jsxs","useContext","ONE_YEAR","useTheme","Palette","Check","Sun","Moon","Monitor"],"mappings":"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","file":"tokens.js","sourcesContent":["import type { ClassValue } from 'clsx';\n\nimport { clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Canonical class-name merge for the OrangeCheck family.\n * `clsx` for conditional composition, `tailwind-merge` to resolve\n * conflicting Tailwind utilities (last-wins by property).\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * The OrangeCheck theme (skin) registry.\n *\n * A *skin* is the named-theme axis, orthogonal to the light/dark *mode* axis\n * (which stays owned by `next-themes` via the `.dark` class). A skin is applied\n * as `data-oc-theme=\"<id>\"` on `<html>` and persisted in the `oc_skin` cookie at\n * `Domain=.ochk.io` so a choice on one family site carries to every other.\n *\n * Adding a skin = add a `themes/<id>.css` token block in this package and a\n * row here. Every site picks it up on the next `@orangecheck/design` bump; no\n * per-site edits.\n */\nexport interface OcTheme {\n /** Stable id — also the `data-oc-theme` attribute value and the CSS file stem. */\n readonly id: string;\n /** Human label for the picker (lowercase, house voice). */\n readonly label: string;\n /** One-line description shown in the picker / Storybook. */\n readonly description: string;\n /**\n * Accent hex (sRGB of the skin's dark-mode `--brand`). Used to swap the\n * browser chrome — `<meta name=\"theme-color\">` and the favicon (recolored\n * from the family `#f97316`) — when the skin changes. Mirrors the\n * `SKINS` palette in `oc-media-kit/build/brands.py` (same source of truth).\n */\n readonly accent: string;\n}\n\n// Every skin is rooted in the Bitcoin ethos — sharp, flat, cypherpunk — and\n// carries a meaning, not just a colour: the chain, the node, the network, sound\n// money. No SaaS softness.\nexport const OC_THEMES: readonly OcTheme[] = [\n {\n id: 'orangecheck',\n label: 'orangecheck',\n description: 'the chain — Bitcoin orange, sharp 0.25rem corners, Inter + JetBrains Mono',\n accent: '#f97316',\n },\n {\n id: 'phosphor',\n label: 'phosphor',\n description: 'the node — CRT terminal green, hard 0.125rem, all-mono · sovereignty & verify',\n accent: '#55d671',\n },\n {\n id: 'lightning',\n label: 'lightning',\n description: 'the network — electric violet (L2), hardest 0rem edges, sans · instant',\n accent: '#c27dff',\n },\n {\n id: 'gold',\n label: 'gold',\n description: 'sound money — digital gold, hard 0.125rem milled edge, mono ledger · 21M',\n accent: '#e3b831',\n },\n {\n id: 'ember',\n label: 'ember',\n description:\n 'the warmth — burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk · approachable, human',\n accent: '#da6736',\n },\n] as const;\n\n/** The family default accent (orangecheck), and the hex every favicon ships\n * with — the swap recolors from this to the active skin's accent. */\nexport const OC_DEFAULT_ACCENT = '#f97316';\n\n/** Accent hex for a skin id, falling back to the default. */\nexport function accentFor(id: string | null | undefined): string {\n return OC_THEMES.find((t) => t.id === id)?.accent ?? OC_DEFAULT_ACCENT;\n}\n\nexport const DEFAULT_OC_THEME = 'orangecheck';\n\nexport type OcThemeId = (typeof OC_THEMES)[number]['id'] | (string & {});\n\nexport function isKnownTheme(id: string | null | undefined): id is OcThemeId {\n return !!id && OC_THEMES.some((t) => t.id === id);\n}\n\nexport function resolveTheme(id: string | null | undefined): string {\n return isKnownTheme(id) ? id : DEFAULT_OC_THEME;\n}\n\n/** Cookie name for the cross-subdomain skin choice. */\nexport const OC_SKIN_COOKIE = 'oc_skin';\n","import type { CSSProperties } from 'react';\n\nimport { cn } from './cn';\n\nexport interface OcAuroraProps {\n /**\n * Master intensity multiplier (default 1, from the theme CSS). Overrides\n * `--oc-aurora-intensity` for this mount — e.g. dial a reading-heavy site down.\n */\n intensity?: number;\n className?: string;\n}\n\nconst BLOBS = [1, 2, 3, 4, 5] as const;\n\n/**\n * The ambient \"bitcoin aurora\" background — soft, theme-reactive colour clouds\n * that slowly wander (styling in styles/aurora.css; recolours from --brand /\n * --success / --info / --primary across mode + skin). Pure markup, fixed behind\n * all content; `OcThemeProvider` mounts it by default. Mount manually only if a\n * site renders the aurora outside the provider.\n */\nexport function OcAurora({ intensity, className }: OcAuroraProps) {\n const style =\n intensity == null\n ? undefined\n : ({ '--oc-aurora-intensity': String(intensity) } as CSSProperties);\n return (\n <div className={cn('oc-aurora', className)} style={style} aria-hidden=\"true\">\n {BLOBS.map((n) => (\n <div key={n} className={`oc-aurora__blob oc-aurora__blob-${n}`} />\n ))}\n </div>\n );\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n accentFor,\n DEFAULT_OC_THEME,\n OC_DEFAULT_ACCENT,\n OC_SKIN_COOKIE,\n OC_THEMES,\n resolveTheme,\n type OcTheme,\n} from './themes';\nimport { OcAurora } from './aurora';\n\ndeclare global {\n interface Window {\n /** Defined by `getOcThemeInitScript()`; recolors favicon + theme-color. */\n __ocApplySkinChrome?: (skin: string) => void;\n }\n}\n\n/**\n * OcThemeProvider — the skin (named-theme) axis.\n *\n * Orthogonal to `next-themes`, which owns light/dark via the `.dark` class.\n * This provider owns the `data-oc-theme` attribute on `<html>` and persists the\n * choice in the `oc_skin` cookie at `Domain=.ochk.io`, so a skin chosen on one\n * `*.ochk.io` site is honored on every other. It re-reads the cookie on focus /\n * visibility change so a fresh choice picks up when the user returns to a tab\n * (same cross-site pickup trick `OcAccountMenu` uses for sign-in).\n *\n * Mount once, inside (or beside) the `next-themes` `<ThemeProvider>`:\n *\n * <ThemeProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n * <OcThemeProvider>\n * …app…\n * </OcThemeProvider>\n * </ThemeProvider>\n *\n * Pair with `getOcThemeInitScript()` in `_document` to avoid a flash before\n * hydration.\n */\n\nconst ONE_YEAR = 60 * 60 * 24 * 365;\nconst ATTR = 'data-oc-theme';\n\nfunction readSkinCookie(): string | null {\n if (typeof document === 'undefined') return null;\n const prefix = `${OC_SKIN_COOKIE}=`;\n for (const part of document.cookie.split(';')) {\n const trimmed = part.trim();\n if (trimmed.startsWith(prefix)) {\n const v = decodeURIComponent(trimmed.slice(prefix.length));\n return v.length > 0 ? v : null;\n }\n }\n return null;\n}\n\nfunction writeSkinCookie(value: string): void {\n if (typeof document === 'undefined') return;\n const isLocal =\n location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const parts = [\n `${OC_SKIN_COOKIE}=${encodeURIComponent(value)}`,\n 'Path=/',\n `Max-Age=${ONE_YEAR}`,\n 'SameSite=Lax',\n ];\n if (!isLocal) {\n parts.push('Domain=.ochk.io');\n parts.push('Secure');\n }\n document.cookie = parts.join('; ');\n}\n\nfunction applyAttr(skin: string): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(ATTR, skin);\n}\n\n/**\n * Swap the browser chrome (favicon + `<meta name=\"theme-color\">`) to the skin's\n * accent. The real work lives in the global installed by\n * `getOcThemeInitScript()` (so the favicon's original SVG is captured exactly\n * once, before the init script's own first recolor — avoids re-reading an\n * already-swapped data: URI). If the init script wasn't included, fall back to\n * the theme-color swap alone (favicon recolor needs the captured original).\n */\nfunction applySkinChrome(skin: string): void {\n if (typeof window === 'undefined') return;\n if (typeof window.__ocApplySkinChrome === 'function') {\n window.__ocApplySkinChrome(skin);\n return;\n }\n const meta = document.querySelector('meta[name=\"theme-color\"]');\n if (meta) meta.setAttribute('content', accentFor(skin));\n}\n\ninterface OcSkinContextValue {\n /** Current skin id (always resolved to a known theme). */\n skin: string;\n /** Set the skin: validates, applies the attribute, persists the cookie. */\n setSkin: (id: string) => void;\n /** The full registry, for rendering a picker. */\n themes: readonly OcTheme[];\n}\n\nconst OcSkinContext = createContext<OcSkinContextValue | null>(null);\n\nexport interface OcThemeProviderProps {\n children: ReactNode;\n /** Skin to assume before the cookie is read (defaults to `orangecheck`). */\n defaultSkin?: string;\n /**\n * The ambient bitcoin-aurora background. `true` (default) renders it behind\n * the app; `false` disables it; `{ intensity }` tunes its strength for this\n * site (e.g. `aurora={{ intensity: 0.5 }}` on a reading-heavy surface).\n */\n aurora?: boolean | { intensity?: number };\n}\n\nexport function OcThemeProvider({\n children,\n defaultSkin = DEFAULT_OC_THEME,\n aurora = true,\n}: OcThemeProviderProps) {\n const [skin, setSkinState] = useState<string>(() => resolveTheme(defaultSkin));\n const hydratedRef = useRef(false);\n\n // Hydrate from the cookie once on mount and align the attribute.\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const fromCookie = resolveTheme(readSkinCookie() ?? defaultSkin);\n applyAttr(fromCookie);\n applySkinChrome(fromCookie);\n setSkinState(fromCookie);\n }, [defaultSkin]);\n\n // Cross-site pickup: re-read the cookie when the tab regains focus.\n useEffect(() => {\n function sync() {\n const fromCookie = resolveTheme(readSkinCookie() ?? skin);\n if (fromCookie !== skin) {\n applyAttr(fromCookie);\n applySkinChrome(fromCookie);\n setSkinState(fromCookie);\n }\n }\n window.addEventListener('focus', sync);\n document.addEventListener('visibilitychange', sync);\n return () => {\n window.removeEventListener('focus', sync);\n document.removeEventListener('visibilitychange', sync);\n };\n }, [skin]);\n\n const setSkin = useCallback((id: string) => {\n const next = resolveTheme(id);\n applyAttr(next);\n applySkinChrome(next);\n writeSkinCookie(next);\n setSkinState(next);\n }, []);\n\n const value = useMemo<OcSkinContextValue>(\n () => ({ skin, setSkin, themes: OC_THEMES }),\n [skin, setSkin]\n );\n\n return (\n <OcSkinContext.Provider value={value}>\n {aurora !== false && (\n <OcAurora intensity={typeof aurora === 'object' ? aurora.intensity : undefined} />\n )}\n {children}\n </OcSkinContext.Provider>\n );\n}\n\n/** Read the current skin + setter. Throws if used outside `OcThemeProvider`. */\nexport function useOcSkin(): OcSkinContextValue {\n const ctx = useContext(OcSkinContext);\n if (!ctx) {\n throw new Error('useOcSkin must be used within <OcThemeProvider>');\n }\n return ctx;\n}\n\n/**\n * Blocking init script for `_document` (Pages Router) `<Head>`. Applies the\n * cookie's skin to `<html>` before first paint so there is no flash of the\n * default skin. Inject with:\n *\n * <script dangerouslySetInnerHTML={{ __html: getOcThemeInitScript() }} />\n */\nexport function getOcThemeInitScript(defaultSkin: string = DEFAULT_OC_THEME): string {\n // Self-contained IIFE — no imports available at parse time. Beyond applying\n // the skin attribute before first paint, it installs `window.__ocApplySkinChrome`\n // (the single owner of the favicon + theme-color swap) and runs it for the\n // saved skin. OcThemeProvider re-invokes the same global on later changes, so\n // the favicon's *original* SVG is captured exactly once (before any recolor)\n // and re-recolored from `#f97316` to the active skin's accent. The favicon\n // recolor is async (a fetch of the same-origin favicon.svg) — chrome updates\n // a beat after paint, which is fine; the skin attribute itself is synchronous.\n const accents = Object.fromEntries(OC_THEMES.map((t) => [t.id, t.accent]));\n return (\n `(function(){` +\n `var ACC=${JSON.stringify(accents)},DEF=${JSON.stringify(defaultSkin)},ORIG=${JSON.stringify(OC_DEFAULT_ACCENT)},fav=null;` +\n `function acc(s){return ACC[s]||ACC[DEF]||ORIG;}` +\n `window.__ocApplySkinChrome=function(s){try{` +\n `var a=acc(s);` +\n `var meta=document.querySelector('meta[name=\"theme-color\"]');if(meta){meta.setAttribute('content',a);}` +\n `var link=document.querySelector('link[rel~=\"icon\"][type=\"image/svg+xml\"]');if(!link){return;}` +\n `var paint=function(svg){link.setAttribute('href','data:image/svg+xml,'+encodeURIComponent(svg.split(ORIG).join(a)));};` +\n `if(fav!=null){paint(fav);return;}` +\n `var h=link.getAttribute('href');if(!h||h.indexOf('data:')===0){return;}` +\n `fetch(h).then(function(r){return r.text();}).then(function(svg){fav=svg;paint(svg);}).catch(function(){});` +\n `}catch(e){}};` +\n `try{var m=document.cookie.match(/(?:^|; )${OC_SKIN_COOKIE}=([^;]*)/);var s=m?decodeURIComponent(m[1]):DEF;if(!s){s=DEF;}` +\n `document.documentElement.setAttribute('${ATTR}',s);window.__ocApplySkinChrome(s);}` +\n `catch(e){document.documentElement.setAttribute('${ATTR}',DEF);}` +\n `})();`\n );\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useTheme } from 'next-themes';\n\n/**\n * OcThemeBridge — cross-subdomain persistence for the MODE axis (light/dark).\n *\n * `next-themes` defaults to origin-scoped `localStorage`, so a dark/light choice\n * on one `*.ochk.io` site won't carry to another. This layers an\n * `oc_theme` cookie at `Domain=.ochk.io` on top so the choice is visible\n * family-wide. (The SKIN axis has its own `oc_skin` bridge inside\n * `OcThemeProvider`; this is the mode counterpart, previously duplicated in\n * every consumer repo.)\n *\n * Mount once inside the next-themes `<ThemeProvider>`:\n *\n * <ThemeProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n * <OcThemeBridge />\n * <OcThemeProvider>…</OcThemeProvider>\n * </ThemeProvider>\n *\n * The cookie is intentionally non-HttpOnly (next-themes JS reads/writes it) and\n * carries no auth value — a leak only reveals a theme preference.\n */\nconst COOKIE = 'oc_theme';\nconst ALLOWED = new Set(['light', 'dark', 'system']);\nconst ONE_YEAR = 60 * 60 * 24 * 365;\n\nfunction readCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n const prefix = `${name}=`;\n for (const part of document.cookie.split(';')) {\n const trimmed = part.trim();\n if (trimmed.startsWith(prefix)) {\n const v = decodeURIComponent(trimmed.slice(prefix.length));\n return v.length > 0 ? v : null;\n }\n }\n return null;\n}\n\nfunction writeCookie(value: string): void {\n if (typeof document === 'undefined') return;\n if (!ALLOWED.has(value)) return;\n const isLocal = location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const parts = [\n `${COOKIE}=${encodeURIComponent(value)}`,\n 'Path=/',\n `Max-Age=${ONE_YEAR}`,\n 'SameSite=Lax',\n ];\n if (!isLocal) {\n parts.push('Domain=.ochk.io');\n parts.push('Secure');\n }\n document.cookie = parts.join('; ');\n}\n\nexport function OcThemeBridge() {\n const { theme, setTheme } = useTheme();\n const hydratedRef = useRef(false);\n\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const cookieValue = readCookie(COOKIE);\n if (cookieValue && ALLOWED.has(cookieValue) && cookieValue !== theme) {\n setTheme(cookieValue);\n }\n }, [theme, setTheme]);\n\n useEffect(() => {\n if (!hydratedRef.current) return;\n if (!theme) return;\n writeCookie(theme);\n }, [theme]);\n\n return null;\n}\n","'use client';\n\nimport { Check, Palette } from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { cn } from './cn';\nimport { useOcSkin } from './provider';\n\n/**\n * OcThemePicker — the skin selector. Sits beside `ThemeToggle` in the header.\n * Self-contained dropdown (no Radix): outside-click + Escape to close. Mirrors\n * the ghost-icon affordance of `ThemeToggle`. Gate its mount behind\n * `NEXT_PUBLIC_OC_THEME_PICKER` during staged rollout.\n */\nexport interface OcThemePickerProps {\n className?: string;\n triggerClassName?: string;\n popoverClassName?: string;\n}\n\nexport function OcThemePicker({ className, triggerClassName, popoverClassName }: OcThemePickerProps) {\n const { skin, setSkin, themes } = useOcSkin();\n const [open, setOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn('relative', className)}>\n <button\n type=\"button\"\n aria-label=\"choose theme\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title=\"choose theme\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n 'text-muted-foreground hover:text-foreground inline-flex size-9 items-center justify-center rounded-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',\n triggerClassName\n )}\n >\n <Palette className=\"size-4\" aria-hidden />\n </button>\n\n {open && (\n <div\n role=\"menu\"\n className={cn(\n 'bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-64 overflow-hidden rounded-md border shadow-md',\n popoverClassName\n )}\n >\n <div className=\"label-mono text-muted-foreground px-3 pt-3 pb-1\">theme</div>\n <ul className=\"pb-1\">\n {themes.map((t) => {\n const active = t.id === skin;\n return (\n <li key={t.id}>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => {\n setSkin(t.id);\n setOpen(false);\n }}\n className={cn(\n 'hover:bg-accent hover:text-accent-foreground flex w-full items-start gap-2 px-3 py-2 text-left transition-colors',\n active && 'text-foreground'\n )}\n >\n <span className=\"mt-0.5 size-4 shrink-0\">\n {active && <Check className=\"size-4 text-primary\" aria-hidden />}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium\">{t.label}</span>\n <span className=\"text-muted-foreground block text-xs leading-snug\">\n {t.description}\n </span>\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Check, Monitor, Moon, Palette, Sun } from 'lucide-react';\nimport { useTheme } from 'next-themes';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { cn } from './cn';\nimport { useOcSkin } from './provider';\n\n/**\n * OcAppearanceMenu — the single header control for ALL appearance settings.\n *\n * One icon button opens a dropdown with both axes:\n * • mode — light / dark / system (next-themes `.dark` class)\n * • theme — the registered skins (data-oc-theme, persisted .ochk.io)\n *\n * Replaces the separate `ThemeToggle` + `OcThemePicker` so every family site\n * carries exactly one appearance control. Self-contained dropdown (no Radix):\n * outside-click + Escape to close. Requires `<OcThemeProvider>` above it (skin\n * axis) and a next-themes `<ThemeProvider>` (mode axis) — both already mounted\n * on every family site.\n */\nexport interface OcAppearanceMenuProps {\n className?: string;\n triggerClassName?: string;\n popoverClassName?: string;\n}\n\nconst MODES = [\n { id: 'light', label: 'light', Icon: Sun },\n { id: 'dark', label: 'dark', Icon: Moon },\n { id: 'system', label: 'system', Icon: Monitor },\n] as const;\n\n/**\n * AppearanceControls — the mode segment + skin list, with no trigger/popover\n * chrome of its own. Embed it anywhere a surface wants to host appearance\n * settings inline (the standalone OcAppearanceMenu popover, the mobile account\n * menu, a site's Sheet drawer). Requires `<OcThemeProvider>` + next-themes\n * above it, like OcAppearanceMenu.\n */\nexport function AppearanceControls({ className }: { className?: string }) {\n const { skin, setSkin, themes } = useOcSkin();\n const { theme, setTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n const activeMode = mounted ? (theme ?? 'system') : null;\n\n return (\n <div className={className}>\n <div className=\"label-mono text-muted-foreground px-3 pt-3 pb-2\">mode</div>\n <div className=\"grid grid-cols-3 gap-1 px-2 pb-2\">\n {MODES.map(({ id, label, Icon }) => {\n const active = activeMode === id;\n return (\n <button\n key={id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => setTheme(id)}\n className={cn(\n 'flex flex-col items-center gap-1 rounded-md border py-2 text-[11px] transition-colors',\n active\n ? 'border-primary text-foreground bg-accent'\n : 'border-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground'\n )}\n >\n <Icon className=\"size-4\" aria-hidden />\n {label}\n </button>\n );\n })}\n </div>\n <div className=\"label-mono text-muted-foreground border-t px-3 pt-3 pb-1\">theme</div>\n <ul className=\"pb-1\">\n {themes.map((t) => {\n const active = t.id === skin;\n return (\n <li key={t.id}>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => setSkin(t.id)}\n className={cn(\n 'hover:bg-accent hover:text-accent-foreground flex w-full items-start gap-2 px-3 py-2 text-left transition-colors',\n active && 'text-foreground'\n )}\n >\n <span className=\"mt-0.5 size-4 shrink-0\">\n {active && <Check className=\"text-primary size-4\" aria-hidden />}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium\">{t.label}</span>\n <span className=\"text-muted-foreground block text-xs leading-snug\">\n {t.description}\n </span>\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\nexport function OcAppearanceMenu({\n className,\n triggerClassName,\n popoverClassName,\n}: OcAppearanceMenuProps) {\n const [open, setOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn('relative', className)}>\n <button\n type=\"button\"\n aria-label=\"appearance settings\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title=\"appearance · mode + theme\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n 'text-muted-foreground hover:text-foreground inline-flex size-9 items-center justify-center rounded-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',\n triggerClassName\n )}\n >\n <Palette className=\"size-4\" aria-hidden />\n </button>\n\n {open && (\n <div\n role=\"menu\"\n className={cn(\n 'bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-64 overflow-hidden rounded-md border shadow-md',\n popoverClassName\n )}\n >\n <AppearanceControls />\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tokens/cn.ts","../src/tokens/themes.ts","../src/tokens/aurora.tsx","../src/tokens/provider.tsx","../src/tokens/theme-bridge.tsx","../src/tokens/theme-picker.tsx","../src/tokens/appearance-menu.tsx"],"names":["twMerge","clsx","jsx","createContext","useState","useRef","useEffect","useCallback","useMemo","jsxs","useContext","ONE_YEAR","useTheme","Palette","Check","Sun","Moon","Monitor"],"mappings":"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","file":"tokens.js","sourcesContent":["import type { ClassValue } from 'clsx';\n\nimport { clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Canonical class-name merge for the OrangeCheck family.\n * `clsx` for conditional composition, `tailwind-merge` to resolve\n * conflicting Tailwind utilities (last-wins by property).\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * The OrangeCheck theme (skin) registry.\n *\n * A *skin* is the named-theme axis, orthogonal to the light/dark *mode* axis\n * (which stays owned by `next-themes` via the `.dark` class). A skin is applied\n * as `data-oc-theme=\"<id>\"` on `<html>` and persisted in the `oc_skin` cookie at\n * `Domain=.ochk.io` so a choice on one family site carries to every other.\n *\n * Adding a skin = add a `themes/<id>.css` token block in this package and a\n * row here. Every site picks it up on the next `@orangecheck/design` bump; no\n * per-site edits.\n */\nexport interface OcTheme {\n /** Stable id — also the `data-oc-theme` attribute value and the CSS file stem. */\n readonly id: string;\n /** Human label for the picker (lowercase, house voice). */\n readonly label: string;\n /** One-line description shown in the picker / Storybook. */\n readonly description: string;\n /**\n * Accent hex (sRGB of the skin's dark-mode `--brand`). Used to swap the\n * browser chrome — `<meta name=\"theme-color\">` and the favicon (recolored\n * from the family `#f97316`) — when the skin changes. Mirrors the\n * `SKINS` palette in `oc-media-kit/build/brands.py` (same source of truth).\n */\n readonly accent: string;\n}\n\n// ember leads — the warm, human default. The other four are the Bitcoin-ethos\n// alternates (sharp, flat, cypherpunk), each carrying a meaning, not just a\n// colour: the chain, the node, the network, sound money. Order here is the\n// order shown in the appearance menu / picker (ember first).\nexport const OC_THEMES: readonly OcTheme[] = [\n {\n id: 'ember',\n label: 'ember',\n description:\n 'the warmth — burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk · approachable, human',\n accent: '#da6736',\n },\n {\n id: 'orangecheck',\n label: 'orangecheck',\n description: 'the chain — Bitcoin orange, sharp 0.25rem corners, Inter + JetBrains Mono',\n accent: '#f97316',\n },\n {\n id: 'phosphor',\n label: 'phosphor',\n description: 'the node — CRT terminal green, hard 0.125rem, all-mono · sovereignty & verify',\n accent: '#55d671',\n },\n {\n id: 'lightning',\n label: 'lightning',\n description: 'the network — electric violet (L2), hardest 0rem edges, sans · instant',\n accent: '#c27dff',\n },\n {\n id: 'gold',\n label: 'gold',\n description: 'sound money — digital gold, hard 0.125rem milled edge, mono ledger · 21M',\n accent: '#e3b831',\n },\n] as const;\n\n/** The family default accent (orangecheck), and the hex every favicon ships\n * with — the swap recolors from this to the active skin's accent. */\nexport const OC_DEFAULT_ACCENT = '#f97316';\n\n/** Accent hex for a skin id, falling back to the default. */\nexport function accentFor(id: string | null | undefined): string {\n return OC_THEMES.find((t) => t.id === id)?.accent ?? OC_DEFAULT_ACCENT;\n}\n\n// ember is the family default — the skin a user with no `oc_skin` cookie gets.\n// (The favicon SVGs still ship baked with OC_DEFAULT_ACCENT below; the init\n// script recolors them from that to the active skin's accent on load.)\nexport const DEFAULT_OC_THEME = 'ember';\n\nexport type OcThemeId = (typeof OC_THEMES)[number]['id'] | (string & {});\n\nexport function isKnownTheme(id: string | null | undefined): id is OcThemeId {\n return !!id && OC_THEMES.some((t) => t.id === id);\n}\n\nexport function resolveTheme(id: string | null | undefined): string {\n return isKnownTheme(id) ? id : DEFAULT_OC_THEME;\n}\n\n/** Cookie name for the cross-subdomain skin choice. */\nexport const OC_SKIN_COOKIE = 'oc_skin';\n","import type { CSSProperties } from 'react';\n\nimport { cn } from './cn';\n\nexport interface OcAuroraProps {\n /**\n * Master intensity multiplier (default 1, from the theme CSS). Overrides\n * `--oc-aurora-intensity` for this mount — e.g. dial a reading-heavy site down.\n */\n intensity?: number;\n className?: string;\n}\n\nconst BLOBS = [1, 2, 3, 4, 5] as const;\n\n/**\n * The ambient \"bitcoin aurora\" background — soft, theme-reactive colour clouds\n * that slowly wander (styling in styles/aurora.css; recolours from --brand /\n * --success / --info / --primary across mode + skin). Pure markup, fixed behind\n * all content; `OcThemeProvider` mounts it by default. Mount manually only if a\n * site renders the aurora outside the provider.\n */\nexport function OcAurora({ intensity, className }: OcAuroraProps) {\n const style =\n intensity == null\n ? undefined\n : ({ '--oc-aurora-intensity': String(intensity) } as CSSProperties);\n return (\n <div className={cn('oc-aurora', className)} style={style} aria-hidden=\"true\">\n {BLOBS.map((n) => (\n <div key={n} className={`oc-aurora__blob oc-aurora__blob-${n}`} />\n ))}\n </div>\n );\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n accentFor,\n DEFAULT_OC_THEME,\n OC_DEFAULT_ACCENT,\n OC_SKIN_COOKIE,\n OC_THEMES,\n resolveTheme,\n type OcTheme,\n} from './themes';\nimport { OcAurora } from './aurora';\n\ndeclare global {\n interface Window {\n /** Defined by `getOcThemeInitScript()`; recolors favicon + theme-color. */\n __ocApplySkinChrome?: (skin: string) => void;\n }\n}\n\n/**\n * OcThemeProvider — the skin (named-theme) axis.\n *\n * Orthogonal to `next-themes`, which owns light/dark via the `.dark` class.\n * This provider owns the `data-oc-theme` attribute on `<html>` and persists the\n * choice in the `oc_skin` cookie at `Domain=.ochk.io`, so a skin chosen on one\n * `*.ochk.io` site is honored on every other. It re-reads the cookie on focus /\n * visibility change so a fresh choice picks up when the user returns to a tab\n * (same cross-site pickup trick `OcAccountMenu` uses for sign-in).\n *\n * Mount once, inside (or beside) the `next-themes` `<ThemeProvider>`:\n *\n * <ThemeProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n * <OcThemeProvider>\n * …app…\n * </OcThemeProvider>\n * </ThemeProvider>\n *\n * Pair with `getOcThemeInitScript()` in `_document` to avoid a flash before\n * hydration.\n */\n\nconst ONE_YEAR = 60 * 60 * 24 * 365;\nconst ATTR = 'data-oc-theme';\n\nfunction readSkinCookie(): string | null {\n if (typeof document === 'undefined') return null;\n const prefix = `${OC_SKIN_COOKIE}=`;\n for (const part of document.cookie.split(';')) {\n const trimmed = part.trim();\n if (trimmed.startsWith(prefix)) {\n const v = decodeURIComponent(trimmed.slice(prefix.length));\n return v.length > 0 ? v : null;\n }\n }\n return null;\n}\n\nfunction writeSkinCookie(value: string): void {\n if (typeof document === 'undefined') return;\n const isLocal =\n location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const parts = [\n `${OC_SKIN_COOKIE}=${encodeURIComponent(value)}`,\n 'Path=/',\n `Max-Age=${ONE_YEAR}`,\n 'SameSite=Lax',\n ];\n if (!isLocal) {\n parts.push('Domain=.ochk.io');\n parts.push('Secure');\n }\n document.cookie = parts.join('; ');\n}\n\nfunction applyAttr(skin: string): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute(ATTR, skin);\n}\n\n/**\n * Swap the browser chrome (favicon + `<meta name=\"theme-color\">`) to the skin's\n * accent. The real work lives in the global installed by\n * `getOcThemeInitScript()` (so the favicon's original SVG is captured exactly\n * once, before the init script's own first recolor — avoids re-reading an\n * already-swapped data: URI). If the init script wasn't included, fall back to\n * the theme-color swap alone (favicon recolor needs the captured original).\n */\nfunction applySkinChrome(skin: string): void {\n if (typeof window === 'undefined') return;\n if (typeof window.__ocApplySkinChrome === 'function') {\n window.__ocApplySkinChrome(skin);\n return;\n }\n const meta = document.querySelector('meta[name=\"theme-color\"]');\n if (meta) meta.setAttribute('content', accentFor(skin));\n}\n\ninterface OcSkinContextValue {\n /** Current skin id (always resolved to a known theme). */\n skin: string;\n /** Set the skin: validates, applies the attribute, persists the cookie. */\n setSkin: (id: string) => void;\n /** The full registry, for rendering a picker. */\n themes: readonly OcTheme[];\n}\n\nconst OcSkinContext = createContext<OcSkinContextValue | null>(null);\n\nexport interface OcThemeProviderProps {\n children: ReactNode;\n /** Skin to assume before the cookie is read (defaults to `orangecheck`). */\n defaultSkin?: string;\n /**\n * The ambient bitcoin-aurora background. `true` (default) renders it behind\n * the app; `false` disables it; `{ intensity }` tunes its strength for this\n * site (e.g. `aurora={{ intensity: 0.5 }}` on a reading-heavy surface).\n */\n aurora?: boolean | { intensity?: number };\n}\n\nexport function OcThemeProvider({\n children,\n defaultSkin = DEFAULT_OC_THEME,\n aurora = true,\n}: OcThemeProviderProps) {\n const [skin, setSkinState] = useState<string>(() => resolveTheme(defaultSkin));\n const hydratedRef = useRef(false);\n\n // Hydrate from the cookie once on mount and align the attribute.\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const fromCookie = resolveTheme(readSkinCookie() ?? defaultSkin);\n applyAttr(fromCookie);\n applySkinChrome(fromCookie);\n setSkinState(fromCookie);\n }, [defaultSkin]);\n\n // Cross-site pickup: re-read the cookie when the tab regains focus.\n useEffect(() => {\n function sync() {\n const fromCookie = resolveTheme(readSkinCookie() ?? skin);\n if (fromCookie !== skin) {\n applyAttr(fromCookie);\n applySkinChrome(fromCookie);\n setSkinState(fromCookie);\n }\n }\n window.addEventListener('focus', sync);\n document.addEventListener('visibilitychange', sync);\n return () => {\n window.removeEventListener('focus', sync);\n document.removeEventListener('visibilitychange', sync);\n };\n }, [skin]);\n\n const setSkin = useCallback((id: string) => {\n const next = resolveTheme(id);\n applyAttr(next);\n applySkinChrome(next);\n writeSkinCookie(next);\n setSkinState(next);\n }, []);\n\n const value = useMemo<OcSkinContextValue>(\n () => ({ skin, setSkin, themes: OC_THEMES }),\n [skin, setSkin]\n );\n\n return (\n <OcSkinContext.Provider value={value}>\n {aurora !== false && (\n <OcAurora intensity={typeof aurora === 'object' ? aurora.intensity : undefined} />\n )}\n {children}\n </OcSkinContext.Provider>\n );\n}\n\n/** Read the current skin + setter. Throws if used outside `OcThemeProvider`. */\nexport function useOcSkin(): OcSkinContextValue {\n const ctx = useContext(OcSkinContext);\n if (!ctx) {\n throw new Error('useOcSkin must be used within <OcThemeProvider>');\n }\n return ctx;\n}\n\n/**\n * Blocking init script for `_document` (Pages Router) `<Head>`. Applies the\n * cookie's skin to `<html>` before first paint so there is no flash of the\n * default skin. Inject with:\n *\n * <script dangerouslySetInnerHTML={{ __html: getOcThemeInitScript() }} />\n */\nexport function getOcThemeInitScript(defaultSkin: string = DEFAULT_OC_THEME): string {\n // Self-contained IIFE — no imports available at parse time. Beyond applying\n // the skin attribute before first paint, it installs `window.__ocApplySkinChrome`\n // (the single owner of the favicon + theme-color swap) and runs it for the\n // saved skin. OcThemeProvider re-invokes the same global on later changes, so\n // the favicon's *original* SVG is captured exactly once (before any recolor)\n // and re-recolored from `#f97316` to the active skin's accent. The favicon\n // recolor is async (a fetch of the same-origin favicon.svg) — chrome updates\n // a beat after paint, which is fine; the skin attribute itself is synchronous.\n const accents = Object.fromEntries(OC_THEMES.map((t) => [t.id, t.accent]));\n return (\n `(function(){` +\n `var ACC=${JSON.stringify(accents)},DEF=${JSON.stringify(defaultSkin)},ORIG=${JSON.stringify(OC_DEFAULT_ACCENT)},fav=null;` +\n `function acc(s){return ACC[s]||ACC[DEF]||ORIG;}` +\n `window.__ocApplySkinChrome=function(s){try{` +\n `var a=acc(s);` +\n `var meta=document.querySelector('meta[name=\"theme-color\"]');if(meta){meta.setAttribute('content',a);}` +\n `var link=document.querySelector('link[rel~=\"icon\"][type=\"image/svg+xml\"]');if(!link){return;}` +\n `var paint=function(svg){link.setAttribute('href','data:image/svg+xml,'+encodeURIComponent(svg.split(ORIG).join(a)));};` +\n `if(fav!=null){paint(fav);return;}` +\n `var h=link.getAttribute('href');if(!h||h.indexOf('data:')===0){return;}` +\n `fetch(h).then(function(r){return r.text();}).then(function(svg){fav=svg;paint(svg);}).catch(function(){});` +\n `}catch(e){}};` +\n `try{var m=document.cookie.match(/(?:^|; )${OC_SKIN_COOKIE}=([^;]*)/);var s=m?decodeURIComponent(m[1]):DEF;if(!s){s=DEF;}` +\n `document.documentElement.setAttribute('${ATTR}',s);window.__ocApplySkinChrome(s);}` +\n `catch(e){document.documentElement.setAttribute('${ATTR}',DEF);}` +\n `})();`\n );\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useTheme } from 'next-themes';\n\n/**\n * OcThemeBridge — cross-subdomain persistence for the MODE axis (light/dark).\n *\n * `next-themes` defaults to origin-scoped `localStorage`, so a dark/light choice\n * on one `*.ochk.io` site won't carry to another. This layers an\n * `oc_theme` cookie at `Domain=.ochk.io` on top so the choice is visible\n * family-wide. (The SKIN axis has its own `oc_skin` bridge inside\n * `OcThemeProvider`; this is the mode counterpart, previously duplicated in\n * every consumer repo.)\n *\n * Mount once inside the next-themes `<ThemeProvider>`:\n *\n * <ThemeProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n * <OcThemeBridge />\n * <OcThemeProvider>…</OcThemeProvider>\n * </ThemeProvider>\n *\n * The cookie is intentionally non-HttpOnly (next-themes JS reads/writes it) and\n * carries no auth value — a leak only reveals a theme preference.\n */\nconst COOKIE = 'oc_theme';\nconst ALLOWED = new Set(['light', 'dark', 'system']);\nconst ONE_YEAR = 60 * 60 * 24 * 365;\n\nfunction readCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n const prefix = `${name}=`;\n for (const part of document.cookie.split(';')) {\n const trimmed = part.trim();\n if (trimmed.startsWith(prefix)) {\n const v = decodeURIComponent(trimmed.slice(prefix.length));\n return v.length > 0 ? v : null;\n }\n }\n return null;\n}\n\nfunction writeCookie(value: string): void {\n if (typeof document === 'undefined') return;\n if (!ALLOWED.has(value)) return;\n const isLocal = location.hostname === 'localhost' || location.hostname === '127.0.0.1';\n const parts = [\n `${COOKIE}=${encodeURIComponent(value)}`,\n 'Path=/',\n `Max-Age=${ONE_YEAR}`,\n 'SameSite=Lax',\n ];\n if (!isLocal) {\n parts.push('Domain=.ochk.io');\n parts.push('Secure');\n }\n document.cookie = parts.join('; ');\n}\n\nexport function OcThemeBridge() {\n const { theme, setTheme } = useTheme();\n const hydratedRef = useRef(false);\n\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const cookieValue = readCookie(COOKIE);\n if (cookieValue && ALLOWED.has(cookieValue) && cookieValue !== theme) {\n setTheme(cookieValue);\n }\n }, [theme, setTheme]);\n\n useEffect(() => {\n if (!hydratedRef.current) return;\n if (!theme) return;\n writeCookie(theme);\n }, [theme]);\n\n return null;\n}\n","'use client';\n\nimport { Check, Palette } from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { cn } from './cn';\nimport { useOcSkin } from './provider';\n\n/**\n * OcThemePicker — the skin selector. Sits beside `ThemeToggle` in the header.\n * Self-contained dropdown (no Radix): outside-click + Escape to close. Mirrors\n * the ghost-icon affordance of `ThemeToggle`. Gate its mount behind\n * `NEXT_PUBLIC_OC_THEME_PICKER` during staged rollout.\n */\nexport interface OcThemePickerProps {\n className?: string;\n triggerClassName?: string;\n popoverClassName?: string;\n}\n\nexport function OcThemePicker({ className, triggerClassName, popoverClassName }: OcThemePickerProps) {\n const { skin, setSkin, themes } = useOcSkin();\n const [open, setOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn('relative', className)}>\n <button\n type=\"button\"\n aria-label=\"choose theme\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title=\"choose theme\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n 'text-muted-foreground hover:text-foreground inline-flex size-9 items-center justify-center rounded-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',\n triggerClassName\n )}\n >\n <Palette className=\"size-4\" aria-hidden />\n </button>\n\n {open && (\n <div\n role=\"menu\"\n className={cn(\n 'bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-64 overflow-hidden rounded-md border shadow-md',\n popoverClassName\n )}\n >\n <div className=\"label-mono text-muted-foreground px-3 pt-3 pb-1\">theme</div>\n <ul className=\"pb-1\">\n {themes.map((t) => {\n const active = t.id === skin;\n return (\n <li key={t.id}>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => {\n setSkin(t.id);\n setOpen(false);\n }}\n className={cn(\n 'hover:bg-accent hover:text-accent-foreground flex w-full items-start gap-2 px-3 py-2 text-left transition-colors',\n active && 'text-foreground'\n )}\n >\n <span className=\"mt-0.5 size-4 shrink-0\">\n {active && <Check className=\"size-4 text-primary\" aria-hidden />}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium\">{t.label}</span>\n <span className=\"text-muted-foreground block text-xs leading-snug\">\n {t.description}\n </span>\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Check, Monitor, Moon, Palette, Sun } from 'lucide-react';\nimport { useTheme } from 'next-themes';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { cn } from './cn';\nimport { useOcSkin } from './provider';\n\n/**\n * OcAppearanceMenu — the single header control for ALL appearance settings.\n *\n * One icon button opens a dropdown with both axes:\n * • mode — light / dark / system (next-themes `.dark` class)\n * • theme — the registered skins (data-oc-theme, persisted .ochk.io)\n *\n * Replaces the separate `ThemeToggle` + `OcThemePicker` so every family site\n * carries exactly one appearance control. Self-contained dropdown (no Radix):\n * outside-click + Escape to close. Requires `<OcThemeProvider>` above it (skin\n * axis) and a next-themes `<ThemeProvider>` (mode axis) — both already mounted\n * on every family site.\n */\nexport interface OcAppearanceMenuProps {\n className?: string;\n triggerClassName?: string;\n popoverClassName?: string;\n}\n\nconst MODES = [\n { id: 'light', label: 'light', Icon: Sun },\n { id: 'dark', label: 'dark', Icon: Moon },\n { id: 'system', label: 'system', Icon: Monitor },\n] as const;\n\n/**\n * AppearanceControls — the mode segment + skin list, with no trigger/popover\n * chrome of its own. Embed it anywhere a surface wants to host appearance\n * settings inline (the standalone OcAppearanceMenu popover, the mobile account\n * menu, a site's Sheet drawer). Requires `<OcThemeProvider>` + next-themes\n * above it, like OcAppearanceMenu.\n */\nexport function AppearanceControls({ className }: { className?: string }) {\n const { skin, setSkin, themes } = useOcSkin();\n const { theme, setTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n const activeMode = mounted ? (theme ?? 'system') : null;\n\n return (\n <div className={className}>\n <div className=\"label-mono text-muted-foreground px-3 pt-3 pb-2\">mode</div>\n <div className=\"grid grid-cols-3 gap-1 px-2 pb-2\">\n {MODES.map(({ id, label, Icon }) => {\n const active = activeMode === id;\n return (\n <button\n key={id}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => setTheme(id)}\n className={cn(\n 'flex flex-col items-center gap-1 rounded-md border py-2 text-[11px] transition-colors',\n active\n ? 'border-primary text-foreground bg-accent'\n : 'border-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground'\n )}\n >\n <Icon className=\"size-4\" aria-hidden />\n {label}\n </button>\n );\n })}\n </div>\n <div className=\"label-mono text-muted-foreground border-t px-3 pt-3 pb-1\">theme</div>\n <ul className=\"pb-1\">\n {themes.map((t) => {\n const active = t.id === skin;\n return (\n <li key={t.id}>\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n onClick={() => setSkin(t.id)}\n className={cn(\n 'hover:bg-accent hover:text-accent-foreground flex w-full items-start gap-2 px-3 py-2 text-left transition-colors',\n active && 'text-foreground'\n )}\n >\n <span className=\"mt-0.5 size-4 shrink-0\">\n {active && <Check className=\"text-primary size-4\" aria-hidden />}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium\">{t.label}</span>\n <span className=\"text-muted-foreground block text-xs leading-snug\">\n {t.description}\n </span>\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\nexport function OcAppearanceMenu({\n className,\n triggerClassName,\n popoverClassName,\n}: OcAppearanceMenuProps) {\n const [open, setOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn('relative', className)}>\n <button\n type=\"button\"\n aria-label=\"appearance settings\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title=\"appearance · mode + theme\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n 'text-muted-foreground hover:text-foreground inline-flex size-9 items-center justify-center rounded-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',\n triggerClassName\n )}\n >\n <Palette className=\"size-4\" aria-hidden />\n </button>\n\n {open && (\n <div\n role=\"menu\"\n className={cn(\n 'bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-64 overflow-hidden rounded-md border shadow-md',\n popoverClassName\n )}\n >\n <AppearanceControls />\n </div>\n )}\n </div>\n );\n}\n"]}
|
package/dist/tokens.mjs
CHANGED
|
@@ -12,6 +12,12 @@ function cn(...inputs) {
|
|
|
12
12
|
|
|
13
13
|
// src/tokens/themes.ts
|
|
14
14
|
var OC_THEMES = [
|
|
15
|
+
{
|
|
16
|
+
id: "ember",
|
|
17
|
+
label: "ember",
|
|
18
|
+
description: "the warmth \u2014 burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk \xB7 approachable, human",
|
|
19
|
+
accent: "#da6736"
|
|
20
|
+
},
|
|
15
21
|
{
|
|
16
22
|
id: "orangecheck",
|
|
17
23
|
label: "orangecheck",
|
|
@@ -35,19 +41,13 @@ var OC_THEMES = [
|
|
|
35
41
|
label: "gold",
|
|
36
42
|
description: "sound money \u2014 digital gold, hard 0.125rem milled edge, mono ledger \xB7 21M",
|
|
37
43
|
accent: "#e3b831"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
id: "ember",
|
|
41
|
-
label: "ember",
|
|
42
|
-
description: "the warmth \u2014 burnt-sienna terracotta, soft 1rem corners, pill buttons, Hanken Grotesk \xB7 approachable, human",
|
|
43
|
-
accent: "#da6736"
|
|
44
44
|
}
|
|
45
45
|
];
|
|
46
46
|
var OC_DEFAULT_ACCENT = "#f97316";
|
|
47
47
|
function accentFor(id) {
|
|
48
48
|
return OC_THEMES.find((t) => t.id === id)?.accent ?? OC_DEFAULT_ACCENT;
|
|
49
49
|
}
|
|
50
|
-
var DEFAULT_OC_THEME = "
|
|
50
|
+
var DEFAULT_OC_THEME = "ember";
|
|
51
51
|
function isKnownTheme(id) {
|
|
52
52
|
return !!id && OC_THEMES.some((t) => t.id === id);
|
|
53
53
|
}
|