@chan.run/design 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/README.md +195 -0
  2. package/assets/favicons/chan/android-chrome-144x144.png +0 -0
  3. package/assets/favicons/chan/android-chrome-192x192.png +0 -0
  4. package/assets/favicons/chan/android-chrome-256x256.png +0 -0
  5. package/assets/favicons/chan/android-chrome-36x36.png +0 -0
  6. package/assets/favicons/chan/android-chrome-384x384.png +0 -0
  7. package/assets/favicons/chan/android-chrome-48x48.png +0 -0
  8. package/assets/favicons/chan/android-chrome-512x512.png +0 -0
  9. package/assets/favicons/chan/android-chrome-72x72.png +0 -0
  10. package/assets/favicons/chan/android-chrome-96x96.png +0 -0
  11. package/assets/favicons/chan/apple-touch-icon-1024x1024.png +0 -0
  12. package/assets/favicons/chan/apple-touch-icon-114x114.png +0 -0
  13. package/assets/favicons/chan/apple-touch-icon-120x120.png +0 -0
  14. package/assets/favicons/chan/apple-touch-icon-144x144.png +0 -0
  15. package/assets/favicons/chan/apple-touch-icon-152x152.png +0 -0
  16. package/assets/favicons/chan/apple-touch-icon-167x167.png +0 -0
  17. package/assets/favicons/chan/apple-touch-icon-180x180.png +0 -0
  18. package/assets/favicons/chan/apple-touch-icon-57x57.png +0 -0
  19. package/assets/favicons/chan/apple-touch-icon-60x60.png +0 -0
  20. package/assets/favicons/chan/apple-touch-icon-72x72.png +0 -0
  21. package/assets/favicons/chan/apple-touch-icon-76x76.png +0 -0
  22. package/assets/favicons/chan/apple-touch-icon-precomposed.png +0 -0
  23. package/assets/favicons/chan/apple-touch-icon.png +0 -0
  24. package/assets/favicons/chan/browserconfig.xml +12 -0
  25. package/assets/favicons/chan/favicon-16x16.png +0 -0
  26. package/assets/favicons/chan/favicon-32x32.png +0 -0
  27. package/assets/favicons/chan/favicon-48x48.png +0 -0
  28. package/assets/favicons/chan/favicon.ico +0 -0
  29. package/assets/favicons/chan/head-snippet.html +25 -0
  30. package/assets/favicons/chan/manifest.webmanifest +68 -0
  31. package/assets/favicons/chan/mstile-144x144.png +0 -0
  32. package/assets/favicons/chan/mstile-150x150.png +0 -0
  33. package/assets/favicons/chan/mstile-310x150.png +0 -0
  34. package/assets/favicons/chan/mstile-310x310.png +0 -0
  35. package/assets/favicons/chan/mstile-70x70.png +0 -0
  36. package/assets/favicons/ensure/android-chrome-144x144.png +0 -0
  37. package/assets/favicons/ensure/android-chrome-192x192.png +0 -0
  38. package/assets/favicons/ensure/android-chrome-256x256.png +0 -0
  39. package/assets/favicons/ensure/android-chrome-36x36.png +0 -0
  40. package/assets/favicons/ensure/android-chrome-384x384.png +0 -0
  41. package/assets/favicons/ensure/android-chrome-48x48.png +0 -0
  42. package/assets/favicons/ensure/android-chrome-512x512.png +0 -0
  43. package/assets/favicons/ensure/android-chrome-72x72.png +0 -0
  44. package/assets/favicons/ensure/android-chrome-96x96.png +0 -0
  45. package/assets/favicons/ensure/apple-touch-icon-1024x1024.png +0 -0
  46. package/assets/favicons/ensure/apple-touch-icon-114x114.png +0 -0
  47. package/assets/favicons/ensure/apple-touch-icon-120x120.png +0 -0
  48. package/assets/favicons/ensure/apple-touch-icon-144x144.png +0 -0
  49. package/assets/favicons/ensure/apple-touch-icon-152x152.png +0 -0
  50. package/assets/favicons/ensure/apple-touch-icon-167x167.png +0 -0
  51. package/assets/favicons/ensure/apple-touch-icon-180x180.png +0 -0
  52. package/assets/favicons/ensure/apple-touch-icon-57x57.png +0 -0
  53. package/assets/favicons/ensure/apple-touch-icon-60x60.png +0 -0
  54. package/assets/favicons/ensure/apple-touch-icon-72x72.png +0 -0
  55. package/assets/favicons/ensure/apple-touch-icon-76x76.png +0 -0
  56. package/assets/favicons/ensure/apple-touch-icon-precomposed.png +0 -0
  57. package/assets/favicons/ensure/apple-touch-icon.png +0 -0
  58. package/assets/favicons/ensure/browserconfig.xml +12 -0
  59. package/assets/favicons/ensure/favicon-16x16.png +0 -0
  60. package/assets/favicons/ensure/favicon-32x32.png +0 -0
  61. package/assets/favicons/ensure/favicon-48x48.png +0 -0
  62. package/assets/favicons/ensure/favicon.ico +0 -0
  63. package/assets/favicons/ensure/head-snippet.html +25 -0
  64. package/assets/favicons/ensure/manifest.webmanifest +68 -0
  65. package/assets/favicons/ensure/mstile-144x144.png +0 -0
  66. package/assets/favicons/ensure/mstile-150x150.png +0 -0
  67. package/assets/favicons/ensure/mstile-310x150.png +0 -0
  68. package/assets/favicons/ensure/mstile-310x310.png +0 -0
  69. package/assets/favicons/ensure/mstile-70x70.png +0 -0
  70. package/assets/favicons/entropy/android-chrome-144x144.png +0 -0
  71. package/assets/favicons/entropy/android-chrome-192x192.png +0 -0
  72. package/assets/favicons/entropy/android-chrome-256x256.png +0 -0
  73. package/assets/favicons/entropy/android-chrome-36x36.png +0 -0
  74. package/assets/favicons/entropy/android-chrome-384x384.png +0 -0
  75. package/assets/favicons/entropy/android-chrome-48x48.png +0 -0
  76. package/assets/favicons/entropy/android-chrome-512x512.png +0 -0
  77. package/assets/favicons/entropy/android-chrome-72x72.png +0 -0
  78. package/assets/favicons/entropy/android-chrome-96x96.png +0 -0
  79. package/assets/favicons/entropy/apple-touch-icon-1024x1024.png +0 -0
  80. package/assets/favicons/entropy/apple-touch-icon-114x114.png +0 -0
  81. package/assets/favicons/entropy/apple-touch-icon-120x120.png +0 -0
  82. package/assets/favicons/entropy/apple-touch-icon-144x144.png +0 -0
  83. package/assets/favicons/entropy/apple-touch-icon-152x152.png +0 -0
  84. package/assets/favicons/entropy/apple-touch-icon-167x167.png +0 -0
  85. package/assets/favicons/entropy/apple-touch-icon-180x180.png +0 -0
  86. package/assets/favicons/entropy/apple-touch-icon-57x57.png +0 -0
  87. package/assets/favicons/entropy/apple-touch-icon-60x60.png +0 -0
  88. package/assets/favicons/entropy/apple-touch-icon-72x72.png +0 -0
  89. package/assets/favicons/entropy/apple-touch-icon-76x76.png +0 -0
  90. package/assets/favicons/entropy/apple-touch-icon-precomposed.png +0 -0
  91. package/assets/favicons/entropy/apple-touch-icon.png +0 -0
  92. package/assets/favicons/entropy/browserconfig.xml +12 -0
  93. package/assets/favicons/entropy/favicon-16x16.png +0 -0
  94. package/assets/favicons/entropy/favicon-32x32.png +0 -0
  95. package/assets/favicons/entropy/favicon-48x48.png +0 -0
  96. package/assets/favicons/entropy/favicon.ico +0 -0
  97. package/assets/favicons/entropy/head-snippet.html +25 -0
  98. package/assets/favicons/entropy/manifest.webmanifest +68 -0
  99. package/assets/favicons/entropy/mstile-144x144.png +0 -0
  100. package/assets/favicons/entropy/mstile-150x150.png +0 -0
  101. package/assets/favicons/entropy/mstile-310x150.png +0 -0
  102. package/assets/favicons/entropy/mstile-310x310.png +0 -0
  103. package/assets/favicons/entropy/mstile-70x70.png +0 -0
  104. package/assets/favicons/restunnel/android-chrome-144x144.png +0 -0
  105. package/assets/favicons/restunnel/android-chrome-192x192.png +0 -0
  106. package/assets/favicons/restunnel/android-chrome-256x256.png +0 -0
  107. package/assets/favicons/restunnel/android-chrome-36x36.png +0 -0
  108. package/assets/favicons/restunnel/android-chrome-384x384.png +0 -0
  109. package/assets/favicons/restunnel/android-chrome-48x48.png +0 -0
  110. package/assets/favicons/restunnel/android-chrome-512x512.png +0 -0
  111. package/assets/favicons/restunnel/android-chrome-72x72.png +0 -0
  112. package/assets/favicons/restunnel/android-chrome-96x96.png +0 -0
  113. package/assets/favicons/restunnel/apple-touch-icon-1024x1024.png +0 -0
  114. package/assets/favicons/restunnel/apple-touch-icon-114x114.png +0 -0
  115. package/assets/favicons/restunnel/apple-touch-icon-120x120.png +0 -0
  116. package/assets/favicons/restunnel/apple-touch-icon-144x144.png +0 -0
  117. package/assets/favicons/restunnel/apple-touch-icon-152x152.png +0 -0
  118. package/assets/favicons/restunnel/apple-touch-icon-167x167.png +0 -0
  119. package/assets/favicons/restunnel/apple-touch-icon-180x180.png +0 -0
  120. package/assets/favicons/restunnel/apple-touch-icon-57x57.png +0 -0
  121. package/assets/favicons/restunnel/apple-touch-icon-60x60.png +0 -0
  122. package/assets/favicons/restunnel/apple-touch-icon-72x72.png +0 -0
  123. package/assets/favicons/restunnel/apple-touch-icon-76x76.png +0 -0
  124. package/assets/favicons/restunnel/apple-touch-icon-precomposed.png +0 -0
  125. package/assets/favicons/restunnel/apple-touch-icon.png +0 -0
  126. package/assets/favicons/restunnel/browserconfig.xml +12 -0
  127. package/assets/favicons/restunnel/favicon-16x16.png +0 -0
  128. package/assets/favicons/restunnel/favicon-32x32.png +0 -0
  129. package/assets/favicons/restunnel/favicon-48x48.png +0 -0
  130. package/assets/favicons/restunnel/favicon.ico +0 -0
  131. package/assets/favicons/restunnel/head-snippet.html +25 -0
  132. package/assets/favicons/restunnel/manifest.webmanifest +68 -0
  133. package/assets/favicons/restunnel/mstile-144x144.png +0 -0
  134. package/assets/favicons/restunnel/mstile-150x150.png +0 -0
  135. package/assets/favicons/restunnel/mstile-310x150.png +0 -0
  136. package/assets/favicons/restunnel/mstile-310x310.png +0 -0
  137. package/assets/favicons/restunnel/mstile-70x70.png +0 -0
  138. package/assets/favicons/seam/android-chrome-144x144.png +0 -0
  139. package/assets/favicons/seam/android-chrome-192x192.png +0 -0
  140. package/assets/favicons/seam/android-chrome-256x256.png +0 -0
  141. package/assets/favicons/seam/android-chrome-36x36.png +0 -0
  142. package/assets/favicons/seam/android-chrome-384x384.png +0 -0
  143. package/assets/favicons/seam/android-chrome-48x48.png +0 -0
  144. package/assets/favicons/seam/android-chrome-512x512.png +0 -0
  145. package/assets/favicons/seam/android-chrome-72x72.png +0 -0
  146. package/assets/favicons/seam/android-chrome-96x96.png +0 -0
  147. package/assets/favicons/seam/apple-touch-icon-1024x1024.png +0 -0
  148. package/assets/favicons/seam/apple-touch-icon-114x114.png +0 -0
  149. package/assets/favicons/seam/apple-touch-icon-120x120.png +0 -0
  150. package/assets/favicons/seam/apple-touch-icon-144x144.png +0 -0
  151. package/assets/favicons/seam/apple-touch-icon-152x152.png +0 -0
  152. package/assets/favicons/seam/apple-touch-icon-167x167.png +0 -0
  153. package/assets/favicons/seam/apple-touch-icon-180x180.png +0 -0
  154. package/assets/favicons/seam/apple-touch-icon-57x57.png +0 -0
  155. package/assets/favicons/seam/apple-touch-icon-60x60.png +0 -0
  156. package/assets/favicons/seam/apple-touch-icon-72x72.png +0 -0
  157. package/assets/favicons/seam/apple-touch-icon-76x76.png +0 -0
  158. package/assets/favicons/seam/apple-touch-icon-precomposed.png +0 -0
  159. package/assets/favicons/seam/apple-touch-icon.png +0 -0
  160. package/assets/favicons/seam/browserconfig.xml +12 -0
  161. package/assets/favicons/seam/favicon-16x16.png +0 -0
  162. package/assets/favicons/seam/favicon-32x32.png +0 -0
  163. package/assets/favicons/seam/favicon-48x48.png +0 -0
  164. package/assets/favicons/seam/favicon.ico +0 -0
  165. package/assets/favicons/seam/head-snippet.html +25 -0
  166. package/assets/favicons/seam/manifest.webmanifest +68 -0
  167. package/assets/favicons/seam/mstile-144x144.png +0 -0
  168. package/assets/favicons/seam/mstile-150x150.png +0 -0
  169. package/assets/favicons/seam/mstile-310x150.png +0 -0
  170. package/assets/favicons/seam/mstile-310x310.png +0 -0
  171. package/assets/favicons/seam/mstile-70x70.png +0 -0
  172. package/assets/favicons/slides/android-chrome-144x144.png +0 -0
  173. package/assets/favicons/slides/android-chrome-192x192.png +0 -0
  174. package/assets/favicons/slides/android-chrome-256x256.png +0 -0
  175. package/assets/favicons/slides/android-chrome-36x36.png +0 -0
  176. package/assets/favicons/slides/android-chrome-384x384.png +0 -0
  177. package/assets/favicons/slides/android-chrome-48x48.png +0 -0
  178. package/assets/favicons/slides/android-chrome-512x512.png +0 -0
  179. package/assets/favicons/slides/android-chrome-72x72.png +0 -0
  180. package/assets/favicons/slides/android-chrome-96x96.png +0 -0
  181. package/assets/favicons/slides/apple-touch-icon-1024x1024.png +0 -0
  182. package/assets/favicons/slides/apple-touch-icon-114x114.png +0 -0
  183. package/assets/favicons/slides/apple-touch-icon-120x120.png +0 -0
  184. package/assets/favicons/slides/apple-touch-icon-144x144.png +0 -0
  185. package/assets/favicons/slides/apple-touch-icon-152x152.png +0 -0
  186. package/assets/favicons/slides/apple-touch-icon-167x167.png +0 -0
  187. package/assets/favicons/slides/apple-touch-icon-180x180.png +0 -0
  188. package/assets/favicons/slides/apple-touch-icon-57x57.png +0 -0
  189. package/assets/favicons/slides/apple-touch-icon-60x60.png +0 -0
  190. package/assets/favicons/slides/apple-touch-icon-72x72.png +0 -0
  191. package/assets/favicons/slides/apple-touch-icon-76x76.png +0 -0
  192. package/assets/favicons/slides/apple-touch-icon-precomposed.png +0 -0
  193. package/assets/favicons/slides/apple-touch-icon.png +0 -0
  194. package/assets/favicons/slides/browserconfig.xml +12 -0
  195. package/assets/favicons/slides/favicon-16x16.png +0 -0
  196. package/assets/favicons/slides/favicon-32x32.png +0 -0
  197. package/assets/favicons/slides/favicon-48x48.png +0 -0
  198. package/assets/favicons/slides/favicon.ico +0 -0
  199. package/assets/favicons/slides/head-snippet.html +25 -0
  200. package/assets/favicons/slides/manifest.webmanifest +68 -0
  201. package/assets/favicons/slides/mstile-144x144.png +0 -0
  202. package/assets/favicons/slides/mstile-150x150.png +0 -0
  203. package/assets/favicons/slides/mstile-310x150.png +0 -0
  204. package/assets/favicons/slides/mstile-310x310.png +0 -0
  205. package/assets/favicons/slides/mstile-70x70.png +0 -0
  206. package/assets/svg/chan-favicon.svg +5 -0
  207. package/assets/svg/chan-wordmark-dark.svg +5 -0
  208. package/assets/svg/chan-wordmark-light.svg +5 -0
  209. package/assets/svg/ensure-favicon.svg +5 -0
  210. package/assets/svg/ensure-icon-dark.svg +5 -0
  211. package/assets/svg/ensure-icon-light.svg +5 -0
  212. package/assets/svg/ensure-wordmark-dark.svg +4 -0
  213. package/assets/svg/ensure-wordmark-light.svg +4 -0
  214. package/assets/svg/entropy-favicon.svg +5 -0
  215. package/assets/svg/entropy-icon-dark.svg +5 -0
  216. package/assets/svg/entropy-icon-light.svg +5 -0
  217. package/assets/svg/entropy-wordmark-dark.svg +4 -0
  218. package/assets/svg/entropy-wordmark-light.svg +4 -0
  219. package/assets/svg/restunnel-favicon.svg +5 -0
  220. package/assets/svg/restunnel-icon-dark.svg +5 -0
  221. package/assets/svg/restunnel-icon-light.svg +5 -0
  222. package/assets/svg/restunnel-wordmark-dark.svg +4 -0
  223. package/assets/svg/restunnel-wordmark-light.svg +4 -0
  224. package/assets/svg/seam-favicon.svg +5 -0
  225. package/assets/svg/seam-icon-dark.svg +5 -0
  226. package/assets/svg/seam-icon-light.svg +5 -0
  227. package/assets/svg/seam-wordmark-dark.svg +4 -0
  228. package/assets/svg/seam-wordmark-light.svg +4 -0
  229. package/assets/svg/slides-favicon.svg +5 -0
  230. package/assets/svg/slides-icon-dark.svg +5 -0
  231. package/assets/svg/slides-icon-light.svg +5 -0
  232. package/assets/svg/slides-wordmark-dark.svg +4 -0
  233. package/assets/svg/slides-wordmark-light.svg +4 -0
  234. package/dist/index.d.mts +88 -12
  235. package/dist/index.mjs +292 -27
  236. package/package.json +21 -11
package/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # @chan.run/design
2
+
3
+ Shared Chakra UI v3 theme and brand-asset library for the chan.run ecosystem. **Single source of truth** for tokens, components, product icons, wordmarks, and favicons. Every site, app, and product UI imports from this package — never inline an SVG, never copy a PNG.
4
+
5
+ ## Install
6
+
7
+ The package is published to npm and pinned by every workspace consumer:
8
+
9
+ ```jsonc
10
+ // package.json
11
+ {
12
+ "dependencies": {
13
+ "@chakra-ui/react": "3.35.0",
14
+ "@chan.run/design": "^0.2.0",
15
+ "next-themes": "*",
16
+ "react": "19.2.4"
17
+ }
18
+ }
19
+ ```
20
+
21
+ `@chakra-ui/react`, `next-themes`, and `react` are peer deps — keep them aligned to the versions in this package's `peerDependencies` to avoid duplicate Chakra installs (which produce structural type errors when passing `system` between packages).
22
+
23
+ ## Theme + provider
24
+
25
+ ```tsx
26
+ import { ChakraProvider } from "@chakra-ui/react";
27
+ import { system } from "@chan.run/design";
28
+ import { ThemeProvider } from "next-themes";
29
+
30
+ <ChakraProvider value={system}>
31
+ <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
32
+ {children}
33
+ </ThemeProvider>
34
+ </ChakraProvider>
35
+ ```
36
+
37
+ Tokens live in the `chan.*` namespace (`chan.bg`, `chan.text`, `chan.orange`, …) — see [`src/theme.ts`](./src/theme.ts) and `lat.md/design-system.md` for the full taxonomy.
38
+
39
+ ## Brand marks
40
+
41
+ Two flavors: the **chan.run umbrella brand** (`CHAN[•]RUN`, dot accent) and **per-product marks** (`SEA[M]`, `ENTROP[Y]`, …, last-letter accent). Rules locked per `lat.md/brand-marks.md`.
42
+
43
+ ### React components
44
+
45
+ ```tsx
46
+ import {
47
+ Wordmark, // CHAN[•]RUN — umbrella brand
48
+ SeamIcon, SeamWordmark,
49
+ EntropyIcon, EntropyWordmark,
50
+ RestunnelIcon, RestunnelWordmark,
51
+ EnsureIcon, EnsureWordmark,
52
+ SlidesIcon, SlidesWordmark,
53
+ PRODUCT_ICONS, // Record<name, ComponentType>
54
+ PRODUCT_WORDMARKS,
55
+ } from "@chan.run/design";
56
+
57
+ // Themed React component — switches with light/dark mode automatically
58
+ <HStack gap="3">
59
+ <SeamIcon />
60
+ <SeamWordmark fontSize="22px" />
61
+ </HStack>
62
+
63
+ // Loop products from the registry
64
+ {Object.entries(PRODUCT_ICONS).map(([name, Icon]) => <Icon key={name} />)}
65
+ ```
66
+
67
+ `<Wordmark pulseDot />` opacity-cycles the dot via the `chan-pulse` keyframe — used by `Splash` for loading states.
68
+
69
+ ### Raw SVG assets
70
+
71
+ When you need the SVG as an image (e.g. inside Chakra's `<Image>`):
72
+
73
+ ```tsx
74
+ import seamIconUrl from "@chan.run/design/svg/seam-icon-dark.svg?url";
75
+ import { Image } from "@chakra-ui/react";
76
+
77
+ <Image src={seamIconUrl} alt="" boxSize="44px" />
78
+ ```
79
+
80
+ Variants under `@chan.run/design/svg/`:
81
+
82
+ | Pattern | What |
83
+ | ------------------------------------------- | -------------------------------------------- |
84
+ | `chan-wordmark-{dark,light}.svg` | CHAN[•]RUN, dark or light text |
85
+ | `<name>-wordmark-{dark,light}.svg` | Product wordmark (text-as-paths) |
86
+ | `<name>-icon-{dark,light}.svg` | 176×176 squircle monogram |
87
+ | `<name>-favicon.svg` | 32×32 single-letter favicon source |
88
+
89
+ Where `<name>` ∈ `chan` (wordmark only) | `ensure` | `entropy` | `restunnel` | `seam` | `slides`. SVGs use **path-converted text** (no font dependency) and survive `pnpm build` (live in `assets/`, not `dist/`).
90
+
91
+ For theme-aware rendering, prefer the React component. The static `-dark`/`-light` SVGs are for surfaces where you can't use Chakra (Rust dashboards, native apps, README screenshots, etc.).
92
+
93
+ ## Favicons
94
+
95
+ Each product ships a full favicon bundle (16/32/48 PNG, ICO, Apple touch, Android Chrome, Windows mstile, manifest, head snippet). Three ways to consume:
96
+
97
+ ### 1. Head component (drop-in)
98
+
99
+ ```tsx
100
+ import { SeamFaviconHead } from "@chan.run/design";
101
+
102
+ <head>
103
+ <SeamFaviconHead />
104
+ {/* opt into PWA: <SeamFaviconHead manifest /> */}
105
+ </head>
106
+ ```
107
+
108
+ Per-product components: `ChanFaviconHead`, `EnsureFaviconHead`, `EntropyFaviconHead`, `RestunnelFaviconHead`, `SeamFaviconHead`, `SlidesFaviconHead`. Each emits the full set of `<link>`/`<meta>` tags with hashed asset URLs the bundler emits at build time.
109
+
110
+ ### 2. Asset URL imports (raw URLs for custom wiring)
111
+
112
+ ```tsx
113
+ import faviconIco from "@chan.run/design/favicons/seam/favicon.ico?url";
114
+ import appleTouchIcon from "@chan.run/design/favicons/seam/apple-touch-icon.png?url";
115
+ import manifestUrl from "@chan.run/design/favicons/seam/manifest.webmanifest?url";
116
+
117
+ <link rel="icon" href={faviconIco} />
118
+ ```
119
+
120
+ ### 3. Asset-URL maps (programmatic)
121
+
122
+ ```tsx
123
+ import { seamFaviconAssets } from "@chan.run/design";
124
+ seamFaviconAssets.ico; // bundler-emitted hashed URL
125
+ seamFaviconAssets.png16;
126
+ seamFaviconAssets.apple;
127
+ seamFaviconAssets.android192;
128
+ seamFaviconAssets.manifest;
129
+ ```
130
+
131
+ ### Browser extensions
132
+
133
+ Vite-style `?url` imports don't work inside `wxt.config.ts` (it's loaded by Node, not Vite). Use `createRequire` to get a filesystem path, then let `@wxt-dev/auto-icons` downscale to the manifest sizes:
134
+
135
+ ```ts
136
+ // wxt.config.ts
137
+ import { createRequire } from 'node:module';
138
+ import { defineConfig } from 'wxt';
139
+
140
+ const require = createRequire(import.meta.url);
141
+ const seamIconPath = require.resolve(
142
+ '@chan.run/design/favicons/seam/android-chrome-512x512.png',
143
+ );
144
+
145
+ export default defineConfig({
146
+ modules: ['@wxt-dev/module-react', '@wxt-dev/auto-icons'],
147
+ autoIcons: { baseIconPath: seamIconPath },
148
+ });
149
+ ```
150
+
151
+ See `products/seam/seam-extension/wxt.config.ts` for the working example.
152
+
153
+ ## Adding a new product mark
154
+
155
+ 1. Add to `src/products/<name>/<Name>Icon.tsx` and `<Name>Wordmark.tsx`. Use `ProductIcon` / `ProductWordmark` from `src/products/_internal.tsx` — they encode the locked visual rules so you only specify the letter splits.
156
+ 2. Register in `src/products/index.ts` (`PRODUCT_ICONS`, `PRODUCT_WORDMARKS`).
157
+ 3. Add an entry to `scripts/export-svg.ts` (`PRODUCTS` array) and `scripts/gen-favicons.ts` (`MARKS` array) so SVG/favicon variants are generated.
158
+ 4. Run `pnpm gen-brand` to produce the `assets/` outputs.
159
+ 5. Run `pnpm typecheck && pnpm exec biome check .` to confirm.
160
+
161
+ See `lat.md/brand-marks.md` for the full hard-rules reference.
162
+
163
+ ## Repo layout
164
+
165
+ ```
166
+ packages/design/
167
+ ├── src/
168
+ │ ├── brand/ # CHAN[•]RUN umbrella wordmark
169
+ │ ├── components/ # Splash, Topbar, slides, ColorModeButton, …
170
+ │ ├── favicons/ # Per-product head components + asset URL maps
171
+ │ ├── products/ # Per-product Icon + Wordmark components
172
+ │ │ ├── _internal.tsx # Locked visual primitives (do not export)
173
+ │ │ ├── <name>/ # ensure | entropy | restunnel | seam | slides
174
+ │ │ └── index.ts # Exports + PRODUCT_ICONS / PRODUCT_WORDMARKS
175
+ │ ├── styled-system/ # Chakra typegen output (do not edit by hand)
176
+ │ ├── theme.ts # `system` — Chakra v3 theme config
177
+ │ ├── TokenShowcase.tsx # Visual reference for all tokens
178
+ │ └── index.ts
179
+ ├── scripts/
180
+ │ ├── export-svg.ts # Wordmarks/icons/favicon-source SVGs → assets/svg/
181
+ │ └── gen-favicons.ts # Per-product favicon bundles → assets/favicons/
182
+ └── assets/ # Committed build outputs (subpath-exported)
183
+ ├── svg/
184
+ └── favicons/<name>/
185
+ ```
186
+
187
+ ## Scripts
188
+
189
+ | Command | What |
190
+ | ------------------------- | --------------------------------------------------------------- |
191
+ | `pnpm build` | Build TS bundle into `dist/` (consumed by published package) |
192
+ | `pnpm typecheck` | `tsc --noEmit` for `src/` and `scripts/` |
193
+ | `pnpm gen-brand` | Regenerate all SVG and favicon assets into `assets/` |
194
+ | `pnpm export-svg` | Just the SVGs |
195
+ | `pnpm gen-favicons` | Just the favicon bundles (depends on SVGs being generated) |
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <browserconfig>
3
+ <msapplication>
4
+ <tile>
5
+ <square70x70logo src="/mstile-70x70.png"/>
6
+ <square150x150logo src="/mstile-150x150.png"/>
7
+ <wide310x150logo src="/mstile-310x150.png"/>
8
+ <square310x310logo src="/mstile-310x310.png"/>
9
+ <TileColor>#0a0a08</TileColor>
10
+ </tile>
11
+ </msapplication>
12
+ </browserconfig>
Binary file
@@ -0,0 +1,25 @@
1
+ <link rel="icon" type="image/x-icon" href="/favicon.ico">
2
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
3
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
4
+ <link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png">
5
+ <link rel="manifest" href="/manifest.webmanifest">
6
+ <meta name="mobile-web-app-capable" content="yes">
7
+ <meta name="theme-color" content="#ff4d00">
8
+ <meta name="application-name" content="chan.run">
9
+ <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
10
+ <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
11
+ <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
12
+ <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
13
+ <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
14
+ <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
15
+ <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
16
+ <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
17
+ <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167x167.png">
18
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
19
+ <link rel="apple-touch-icon" sizes="1024x1024" href="/apple-touch-icon-1024x1024.png">
20
+ <meta name="apple-mobile-web-app-capable" content="yes">
21
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
22
+ <meta name="apple-mobile-web-app-title" content="chan">
23
+ <meta name="msapplication-TileColor" content="#0a0a08">
24
+ <meta name="msapplication-TileImage" content="/mstile-144x144.png">
25
+ <meta name="msapplication-config" content="/browserconfig.xml">
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "chan.run",
3
+ "short_name": "chan",
4
+ "description": null,
5
+ "dir": "auto",
6
+ "lang": "en-US",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "start_url": "/?homescreen=1",
10
+ "background_color": "#0a0a08",
11
+ "theme_color": "#ff4d00",
12
+ "icons": [
13
+ {
14
+ "src": "/android-chrome-36x36.png",
15
+ "sizes": "36x36",
16
+ "type": "image/png",
17
+ "purpose": "any"
18
+ },
19
+ {
20
+ "src": "/android-chrome-48x48.png",
21
+ "sizes": "48x48",
22
+ "type": "image/png",
23
+ "purpose": "any"
24
+ },
25
+ {
26
+ "src": "/android-chrome-72x72.png",
27
+ "sizes": "72x72",
28
+ "type": "image/png",
29
+ "purpose": "any"
30
+ },
31
+ {
32
+ "src": "/android-chrome-96x96.png",
33
+ "sizes": "96x96",
34
+ "type": "image/png",
35
+ "purpose": "any"
36
+ },
37
+ {
38
+ "src": "/android-chrome-144x144.png",
39
+ "sizes": "144x144",
40
+ "type": "image/png",
41
+ "purpose": "any"
42
+ },
43
+ {
44
+ "src": "/android-chrome-192x192.png",
45
+ "sizes": "192x192",
46
+ "type": "image/png",
47
+ "purpose": "any"
48
+ },
49
+ {
50
+ "src": "/android-chrome-256x256.png",
51
+ "sizes": "256x256",
52
+ "type": "image/png",
53
+ "purpose": "any"
54
+ },
55
+ {
56
+ "src": "/android-chrome-384x384.png",
57
+ "sizes": "384x384",
58
+ "type": "image/png",
59
+ "purpose": "any"
60
+ },
61
+ {
62
+ "src": "/android-chrome-512x512.png",
63
+ "sizes": "512x512",
64
+ "type": "image/png",
65
+ "purpose": "any"
66
+ }
67
+ ]
68
+ }
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <browserconfig>
3
+ <msapplication>
4
+ <tile>
5
+ <square70x70logo src="/mstile-70x70.png"/>
6
+ <square150x150logo src="/mstile-150x150.png"/>
7
+ <wide310x150logo src="/mstile-310x150.png"/>
8
+ <square310x310logo src="/mstile-310x310.png"/>
9
+ <TileColor>#0a0a08</TileColor>
10
+ </tile>
11
+ </msapplication>
12
+ </browserconfig>
@@ -0,0 +1,25 @@
1
+ <link rel="icon" type="image/x-icon" href="/favicon.ico">
2
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
3
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
4
+ <link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png">
5
+ <link rel="manifest" href="/manifest.webmanifest">
6
+ <meta name="mobile-web-app-capable" content="yes">
7
+ <meta name="theme-color" content="#ff4d00">
8
+ <meta name="application-name" content="ensure">
9
+ <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
10
+ <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
11
+ <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
12
+ <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
13
+ <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
14
+ <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
15
+ <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
16
+ <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
17
+ <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167x167.png">
18
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
19
+ <link rel="apple-touch-icon" sizes="1024x1024" href="/apple-touch-icon-1024x1024.png">
20
+ <meta name="apple-mobile-web-app-capable" content="yes">
21
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
22
+ <meta name="apple-mobile-web-app-title" content="ensure">
23
+ <meta name="msapplication-TileColor" content="#0a0a08">
24
+ <meta name="msapplication-TileImage" content="/mstile-144x144.png">
25
+ <meta name="msapplication-config" content="/browserconfig.xml">
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "ensure",
3
+ "short_name": "ensure",
4
+ "description": null,
5
+ "dir": "auto",
6
+ "lang": "en-US",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "start_url": "/?homescreen=1",
10
+ "background_color": "#0a0a08",
11
+ "theme_color": "#ff4d00",
12
+ "icons": [
13
+ {
14
+ "src": "/android-chrome-36x36.png",
15
+ "sizes": "36x36",
16
+ "type": "image/png",
17
+ "purpose": "any"
18
+ },
19
+ {
20
+ "src": "/android-chrome-48x48.png",
21
+ "sizes": "48x48",
22
+ "type": "image/png",
23
+ "purpose": "any"
24
+ },
25
+ {
26
+ "src": "/android-chrome-72x72.png",
27
+ "sizes": "72x72",
28
+ "type": "image/png",
29
+ "purpose": "any"
30
+ },
31
+ {
32
+ "src": "/android-chrome-96x96.png",
33
+ "sizes": "96x96",
34
+ "type": "image/png",
35
+ "purpose": "any"
36
+ },
37
+ {
38
+ "src": "/android-chrome-144x144.png",
39
+ "sizes": "144x144",
40
+ "type": "image/png",
41
+ "purpose": "any"
42
+ },
43
+ {
44
+ "src": "/android-chrome-192x192.png",
45
+ "sizes": "192x192",
46
+ "type": "image/png",
47
+ "purpose": "any"
48
+ },
49
+ {
50
+ "src": "/android-chrome-256x256.png",
51
+ "sizes": "256x256",
52
+ "type": "image/png",
53
+ "purpose": "any"
54
+ },
55
+ {
56
+ "src": "/android-chrome-384x384.png",
57
+ "sizes": "384x384",
58
+ "type": "image/png",
59
+ "purpose": "any"
60
+ },
61
+ {
62
+ "src": "/android-chrome-512x512.png",
63
+ "sizes": "512x512",
64
+ "type": "image/png",
65
+ "purpose": "any"
66
+ }
67
+ ]
68
+ }