@moonarc/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/package.json +228 -0
  4. package/src/components/Accordion.astro +110 -0
  5. package/src/components/Accordion.meta.ts +33 -0
  6. package/src/components/AnimatedBeam.astro +217 -0
  7. package/src/components/AnimatedBeam.meta.ts +39 -0
  8. package/src/components/AnimatedIcons.astro +193 -0
  9. package/src/components/AnimatedIcons.meta.ts +34 -0
  10. package/src/components/AnimatedList.astro +305 -0
  11. package/src/components/AnimatedList.meta.ts +36 -0
  12. package/src/components/AnimatedSelect.astro +227 -0
  13. package/src/components/AnimatedSelect.meta.ts +38 -0
  14. package/src/components/ArrowButton.astro +133 -0
  15. package/src/components/ArrowButton.meta.ts +32 -0
  16. package/src/components/Aurora.astro +188 -0
  17. package/src/components/Aurora.meta.ts +36 -0
  18. package/src/components/AvatarStack.astro +205 -0
  19. package/src/components/AvatarStack.meta.ts +37 -0
  20. package/src/components/BarGrow.astro +123 -0
  21. package/src/components/BarGrow.meta.ts +42 -0
  22. package/src/components/BorderBeam.astro +75 -0
  23. package/src/components/BorderBeam.meta.ts +33 -0
  24. package/src/components/BrowserFrame.astro +172 -0
  25. package/src/components/BrowserFrame.meta.ts +36 -0
  26. package/src/components/BubbleText.astro +90 -0
  27. package/src/components/BubbleText.meta.ts +38 -0
  28. package/src/components/CardStack.astro +79 -0
  29. package/src/components/CardStack.meta.ts +33 -0
  30. package/src/components/Carousel.astro +147 -0
  31. package/src/components/Carousel.meta.ts +35 -0
  32. package/src/components/CheckDraw.astro +159 -0
  33. package/src/components/CheckDraw.meta.ts +37 -0
  34. package/src/components/CircularText.astro +103 -0
  35. package/src/components/CircularText.meta.ts +38 -0
  36. package/src/components/CodeTabs.astro +213 -0
  37. package/src/components/CodeTabs.meta.ts +36 -0
  38. package/src/components/CommandPalette.astro +363 -0
  39. package/src/components/CommandPalette.meta.ts +40 -0
  40. package/src/components/Confetti.astro +143 -0
  41. package/src/components/Confetti.meta.ts +40 -0
  42. package/src/components/CopyButton.astro +189 -0
  43. package/src/components/CopyButton.meta.ts +41 -0
  44. package/src/components/CountUp.astro +134 -0
  45. package/src/components/CountUp.meta.ts +40 -0
  46. package/src/components/CountdownFlip.astro +244 -0
  47. package/src/components/CountdownFlip.meta.ts +39 -0
  48. package/src/components/CounterPreloader.astro +122 -0
  49. package/src/components/CounterPreloader.meta.ts +34 -0
  50. package/src/components/Cursor.astro +177 -0
  51. package/src/components/Cursor.meta.ts +37 -0
  52. package/src/components/CursorGrid.astro +113 -0
  53. package/src/components/CursorGrid.meta.ts +37 -0
  54. package/src/components/Curtain.astro +305 -0
  55. package/src/components/Curtain.meta.ts +38 -0
  56. package/src/components/Dialog.astro +156 -0
  57. package/src/components/Dialog.meta.ts +37 -0
  58. package/src/components/Dock.astro +193 -0
  59. package/src/components/Dock.meta.ts +35 -0
  60. package/src/components/DotPattern.astro +58 -0
  61. package/src/components/DotPattern.meta.ts +32 -0
  62. package/src/components/DottedMap.astro +153 -0
  63. package/src/components/DottedMap.meta.ts +38 -0
  64. package/src/components/Drawer.astro +196 -0
  65. package/src/components/Drawer.meta.ts +35 -0
  66. package/src/components/DynamicIsland.astro +122 -0
  67. package/src/components/DynamicIsland.meta.ts +35 -0
  68. package/src/components/FileTree.astro +207 -0
  69. package/src/components/FileTree.meta.ts +34 -0
  70. package/src/components/FilterGrid.astro +170 -0
  71. package/src/components/FilterGrid.meta.ts +38 -0
  72. package/src/components/FooterReveal.astro +54 -0
  73. package/src/components/FooterReveal.meta.ts +31 -0
  74. package/src/components/GlitchText.astro +145 -0
  75. package/src/components/GlitchText.meta.ts +39 -0
  76. package/src/components/Globe.astro +304 -0
  77. package/src/components/Globe.meta.ts +41 -0
  78. package/src/components/GlyphField.astro +363 -0
  79. package/src/components/GlyphField.meta.ts +53 -0
  80. package/src/components/GradientText.astro +63 -0
  81. package/src/components/GradientText.meta.ts +35 -0
  82. package/src/components/GridPattern.astro +55 -0
  83. package/src/components/GridPattern.meta.ts +32 -0
  84. package/src/components/HighlightMarker.astro +68 -0
  85. package/src/components/HighlightMarker.meta.ts +37 -0
  86. package/src/components/HorizontalScroll.astro +112 -0
  87. package/src/components/HorizontalScroll.meta.ts +34 -0
  88. package/src/components/HoverImageLinks.astro +219 -0
  89. package/src/components/HoverImageLinks.meta.ts +34 -0
  90. package/src/components/HoverVideo.astro +179 -0
  91. package/src/components/HoverVideo.meta.ts +37 -0
  92. package/src/components/ImageCompare.astro +212 -0
  93. package/src/components/ImageCompare.meta.ts +39 -0
  94. package/src/components/ImageTrail.astro +169 -0
  95. package/src/components/ImageTrail.meta.ts +36 -0
  96. package/src/components/Lightbox.astro +236 -0
  97. package/src/components/Lightbox.meta.ts +40 -0
  98. package/src/components/LinkPreview.astro +234 -0
  99. package/src/components/LinkPreview.meta.ts +39 -0
  100. package/src/components/LiquidGlass.astro +148 -0
  101. package/src/components/LiquidGlass.meta.ts +37 -0
  102. package/src/components/Magnetic.astro +92 -0
  103. package/src/components/Magnetic.meta.ts +31 -0
  104. package/src/components/Marquee.astro +165 -0
  105. package/src/components/Marquee.meta.ts +38 -0
  106. package/src/components/Meteors.astro +156 -0
  107. package/src/components/Meteors.meta.ts +36 -0
  108. package/src/components/Noise.astro +61 -0
  109. package/src/components/Noise.meta.ts +33 -0
  110. package/src/components/NumberFlow.astro +143 -0
  111. package/src/components/NumberFlow.meta.ts +42 -0
  112. package/src/components/Orb.astro +130 -0
  113. package/src/components/Orb.meta.ts +39 -0
  114. package/src/components/OrbitingCircles.astro +119 -0
  115. package/src/components/OrbitingCircles.meta.ts +36 -0
  116. package/src/components/OtpInput.astro +215 -0
  117. package/src/components/OtpInput.meta.ts +42 -0
  118. package/src/components/PageTransition.astro +121 -0
  119. package/src/components/PageTransition.meta.ts +33 -0
  120. package/src/components/Parallax.astro +69 -0
  121. package/src/components/Parallax.meta.ts +32 -0
  122. package/src/components/Particles.astro +210 -0
  123. package/src/components/Particles.meta.ts +37 -0
  124. package/src/components/PersistPlayer.astro +126 -0
  125. package/src/components/PersistPlayer.meta.ts +35 -0
  126. package/src/components/PhoneFrame.astro +161 -0
  127. package/src/components/PhoneFrame.meta.ts +35 -0
  128. package/src/components/PillNav.astro +170 -0
  129. package/src/components/PillNav.meta.ts +37 -0
  130. package/src/components/Popover.astro +95 -0
  131. package/src/components/Popover.meta.ts +34 -0
  132. package/src/components/PriceSwitch.astro +251 -0
  133. package/src/components/PriceSwitch.meta.ts +41 -0
  134. package/src/components/Probe.astro +84 -0
  135. package/src/components/Progress.astro +165 -0
  136. package/src/components/Progress.meta.ts +40 -0
  137. package/src/components/ProgressiveBlur.astro +95 -0
  138. package/src/components/ProgressiveBlur.meta.ts +36 -0
  139. package/src/components/PromptInput.astro +273 -0
  140. package/src/components/PromptInput.meta.ts +46 -0
  141. package/src/components/ReadingToc.astro +153 -0
  142. package/src/components/ReadingToc.meta.ts +34 -0
  143. package/src/components/RetroGrid.astro +84 -0
  144. package/src/components/RetroGrid.meta.ts +36 -0
  145. package/src/components/Reveal.astro +292 -0
  146. package/src/components/Reveal.meta.ts +48 -0
  147. package/src/components/Ripple.astro +94 -0
  148. package/src/components/Ripple.meta.ts +34 -0
  149. package/src/components/RotatingText.astro +170 -0
  150. package/src/components/RotatingText.meta.ts +35 -0
  151. package/src/components/ScrollExpand.astro +90 -0
  152. package/src/components/ScrollExpand.meta.ts +35 -0
  153. package/src/components/ScrollProgress.astro +73 -0
  154. package/src/components/ScrollProgress.meta.ts +32 -0
  155. package/src/components/ScrollScrub.astro +96 -0
  156. package/src/components/ScrollScrub.meta.ts +37 -0
  157. package/src/components/ShimmerButton.astro +109 -0
  158. package/src/components/ShimmerButton.meta.ts +37 -0
  159. package/src/components/ShinyText.astro +72 -0
  160. package/src/components/ShinyText.meta.ts +35 -0
  161. package/src/components/Skeleton.astro +76 -0
  162. package/src/components/Skeleton.meta.ts +32 -0
  163. package/src/components/Sparkline.astro +168 -0
  164. package/src/components/Sparkline.meta.ts +43 -0
  165. package/src/components/Spinner.astro +79 -0
  166. package/src/components/Spinner.meta.ts +33 -0
  167. package/src/components/SplitFlap.astro +157 -0
  168. package/src/components/SplitFlap.meta.ts +39 -0
  169. package/src/components/SplitText.astro +208 -0
  170. package/src/components/SplitText.meta.ts +50 -0
  171. package/src/components/Spotlight.astro +92 -0
  172. package/src/components/Spotlight.meta.ts +34 -0
  173. package/src/components/StaggerMenu.astro +301 -0
  174. package/src/components/StaggerMenu.meta.ts +39 -0
  175. package/src/components/StatefulButton.astro +148 -0
  176. package/src/components/StatefulButton.meta.ts +35 -0
  177. package/src/components/StickyBanner.astro +168 -0
  178. package/src/components/StickyBanner.meta.ts +45 -0
  179. package/src/components/StickyReveal.astro +256 -0
  180. package/src/components/StickyReveal.meta.ts +33 -0
  181. package/src/components/StrokeDraw.astro +110 -0
  182. package/src/components/StrokeDraw.meta.ts +43 -0
  183. package/src/components/Switch.astro +165 -0
  184. package/src/components/Switch.meta.ts +37 -0
  185. package/src/components/Tabs.astro +194 -0
  186. package/src/components/Tabs.meta.ts +47 -0
  187. package/src/components/TextRoll.astro +78 -0
  188. package/src/components/TextRoll.meta.ts +36 -0
  189. package/src/components/TextScramble.astro +107 -0
  190. package/src/components/TextScramble.meta.ts +35 -0
  191. package/src/components/ThemeScript.astro +17 -0
  192. package/src/components/ThemeToggle.astro +182 -0
  193. package/src/components/ThemeToggle.meta.ts +34 -0
  194. package/src/components/Tilt.astro +97 -0
  195. package/src/components/Tilt.meta.ts +34 -0
  196. package/src/components/Toast.astro +184 -0
  197. package/src/components/Toast.meta.ts +33 -0
  198. package/src/components/TracingBeam.astro +113 -0
  199. package/src/components/TracingBeam.meta.ts +34 -0
  200. package/src/components/Typewriter.astro +124 -0
  201. package/src/components/Typewriter.meta.ts +39 -0
  202. package/src/components/UnderlineHover.astro +61 -0
  203. package/src/components/UnderlineHover.meta.ts +34 -0
  204. package/src/components/VanishInput.astro +240 -0
  205. package/src/components/VanishInput.meta.ts +41 -0
  206. package/src/components/VideoDialog.astro +230 -0
  207. package/src/components/VideoDialog.meta.ts +40 -0
  208. package/src/components/WeightWave.astro +70 -0
  209. package/src/components/WeightWave.meta.ts +36 -0
  210. package/src/components/internal/DialogMorph.astro +97 -0
  211. package/src/components/internal/PromptInputSubmitOnEnter.astro +32 -0
  212. package/src/index.d.ts +43 -0
  213. package/src/index.js +60 -0
  214. package/src/lib/canvas.ts +124 -0
  215. package/src/lib/confetti.ts +127 -0
  216. package/src/lib/contrast.ts +116 -0
  217. package/src/lib/form.ts +231 -0
  218. package/src/lib/geo.ts +77 -0
  219. package/src/lib/gsap.ts +58 -0
  220. package/src/lib/land.ts +11 -0
  221. package/src/lib/lenis.ts +112 -0
  222. package/src/lib/meta.ts +79 -0
  223. package/src/lib/morph.ts +74 -0
  224. package/src/lib/reduced-motion-plugin.js +299 -0
  225. package/src/lib/runtime.ts +215 -0
  226. package/src/lib/support.ts +102 -0
  227. package/src/lib/theme.ts +18 -0
  228. package/src/lib/toast.ts +17 -0
  229. package/src/styles/base.css +218 -0
  230. package/src/styles/motion.css +43 -0
  231. package/src/styles/theme.css +397 -0
  232. package/src/styles/theme.tailwind.css +75 -0
@@ -0,0 +1,397 @@
1
+ /*
2
+ * @moonarc/core/theme.css — the theme contract (phase 7F, palette and tone scopes 7F.3). Opt-in.
3
+ *
4
+ * The Pro sections read the shadcn variable names — --background, --card,
5
+ * --primary, --border, --radius … — with the base tokens as fallback
6
+ * (`var(--card, var(--ma-panel))`), so a page that imports nothing but
7
+ * base.css still renders, and a page that pastes a shadcn or tweakcn theme
8
+ * recolours every section without editing one. This file is the default
9
+ * theme for pages that have no theme of their own, plus the pieces shadcn
10
+ * does not have:
11
+ *
12
+ * --ma-brand one colour; --primary (step 600 light, 400 dark), --ring and the charts derive from it
13
+ * --ma-brand-50 … 950 its scale — a static ramp first, then re-derived from --ma-brand
14
+ * where oklch(from …) exists (Chrome 122 · Firefox 128 · Safari 18)
15
+ * --ma-neutral the tinted neutral (the primary's hue −31.8°, low chroma), derived unless you set it
16
+ * --ma-neutral-50 … 950 its scale; --background, --foreground, --muted, --border, --input … point at its steps
17
+ * --ma-accent the second colour (the primary's hue −143.5°), derived unless you set it; it fills, and
18
+ * --ma-accent-text is the accent darkened (light) or kept light (dark) enough to read as text on the page
19
+ * --ma-success, --ma-warning, --ma-info (+ -foreground), and shadcn's --destructive: the status colours. A tinted
20
+ * background is mixed where it is used: color-mix(in oklab, var(--ma-success) 14%, transparent)
21
+ * --ma-tone-muted, -ink, -brand the grounds of tone="muted" · "ink" · "brand" (shadcn's --muted is too close to
22
+ * --background to read as a band); -ink-foreground and -brand-foreground are their text
23
+ * --ma-tone-glow-1 … 3 the colours a decorated section's aurora takes, at the brand ground's lightness
24
+ * --ma-card-shadow a card's elevation: two soft shadows in light, a top-edge highlight in dark
25
+ * --ma-radius-sm … 4xl derived from --radius by shadcn's multipliers; not Tailwind's
26
+ * --radius-* names, which Tailwind emits on :root of every project
27
+ * --ma-density 1; the section padding multiplier
28
+ * --ma-shadow-1 … 3 elevation
29
+ * --ma-dim, --ma-sec-floor the faintest secondary text may be drawn (0.75; 0.9 on tone="brand")
30
+ *
31
+ * A painted tone is a theme scope: a section with data-ma-tone="muted" · "ink" · "brand" re-declares --card, --border,
32
+ * --input, --ring and --ma-card-shadow (and on ink and brand --card-foreground and --accent; on muted and brand the
33
+ * text floor) for everything inside it, so cards, hairlines, fields and focus rings follow the tone without the
34
+ * section writing them.
35
+ *
36
+ * Every rule is :where() — zero specificity — so a consumer's `:root { --primary: … }`
37
+ * or a pasted `.dark { … }` block wins, whatever the import order. Light is the base,
38
+ * system dark applies unless the page chose light, explicit dark wins (base.css's rule).
39
+ * A subtree can carry a theme of its own: `<section data-ma-theme style="--ma-brand: …">`
40
+ * re-derives every token inside it (the /theme preview is one), and
41
+ * data-ma-theme="light" / "dark" pins its scheme.
42
+ * --primary takes a colour or a --ma-brand-* step. The neutral, the accent and the tones are derived from it, so
43
+ * `--primary: var(--foreground)`, `var(--ma-neutral-900)` or `var(--ma-tone-ink)` is a cycle, and a cycle leaves every
44
+ * custom property in it invalid: the page loses its whole palette (measured, 2026-09-27). Setting --ma-neutral as well
45
+ * ends the cycle through the neutrals and --foreground; one through the accent or a tone has no such exit (dark reads
46
+ * --ma-tone-ink from --primary).
47
+ * Everything between the >>> <<< markers is written by scripts/build-brand-scale.mjs from
48
+ * scripts/theme-tables.mjs; do not edit it by hand.
49
+ */
50
+
51
+ @layer theme {
52
+ :where(:root, [data-ma-theme]) {
53
+ color-scheme: light;
54
+
55
+ /* the one colour a buyer sets; everything blue below follows it */
56
+ --ma-brand: oklch(0.5433 0.0974 235);
57
+ /* >>> brand-scale:static */
58
+ --ma-brand-50: #eef9ff;
59
+ --ma-brand-100: #d6efff;
60
+ --ma-brand-200: #b6def6;
61
+ --ma-brand-300: #8fc6e6;
62
+ --ma-brand-400: #67abd2;
63
+ --ma-brand-500: #438fb8;
64
+ --ma-brand-600: #24749c;
65
+ --ma-brand-700: #025a7e;
66
+ --ma-brand-800: #00435f;
67
+ --ma-brand-900: #003045;
68
+ --ma-brand-950: #001e2d;
69
+ /* <<< brand-scale:static */
70
+ /* the neutral and the accent follow the primary unless set; the neutral scale follows the neutral */
71
+ /* >>> neutral:static */
72
+ --ma-neutral: #253031;
73
+ --ma-accent: #bcab79;
74
+ --ma-neutral-50: #fafcfd;
75
+ --ma-neutral-100: #f1f6f7;
76
+ --ma-neutral-200: #d5e0e1;
77
+ --ma-neutral-300: #b3c1c2;
78
+ --ma-neutral-400: #97a4a6;
79
+ --ma-neutral-500: #7c898a;
80
+ --ma-neutral-600: #5f6c6d;
81
+ --ma-neutral-700: #3f4a4b;
82
+ --ma-neutral-800: #1e292a;
83
+ --ma-neutral-900: #121d1e;
84
+ --ma-neutral-950: #080f0f;
85
+ /* <<< neutral:static */
86
+
87
+ /* >>> roles:light */
88
+ --background: var(--ma-neutral-50);
89
+ --foreground: var(--ma-neutral-900);
90
+ --card: oklch(1 0 0);
91
+ --card-foreground: var(--ma-neutral-900);
92
+ --popover: oklch(1 0 0);
93
+ --popover-foreground: var(--ma-neutral-900);
94
+ --primary: var(--ma-brand-600);
95
+ --primary-foreground: var(--ma-neutral-50);
96
+ --secondary: var(--ma-neutral-100);
97
+ --secondary-foreground: var(--ma-neutral-900);
98
+ --muted: var(--ma-neutral-100);
99
+ --muted-foreground: var(--ma-neutral-600);
100
+ --accent: var(--ma-neutral-100);
101
+ --accent-foreground: var(--ma-neutral-900);
102
+ --destructive: oklch(0.55 0.19 25);
103
+ --destructive-foreground: var(--ma-neutral-50);
104
+ --border: var(--ma-neutral-200);
105
+ --input: var(--ma-neutral-500);
106
+ --ring: var(--ma-brand-600);
107
+ --ma-card-shadow: var(--ma-shadow-1), var(--ma-shadow-2);
108
+ /* <<< roles:light */
109
+ /* >>> semantic:light */
110
+ --ma-success: oklch(0.5 0.13 150);
111
+ --ma-success-foreground: var(--ma-neutral-50);
112
+ --ma-warning: #ac5700;
113
+ --ma-warning-foreground: var(--ma-neutral-50);
114
+ --ma-info: var(--primary);
115
+ --ma-info-foreground: var(--primary-foreground);
116
+ --ma-accent-foreground: var(--ma-neutral-900);
117
+ --ma-accent-text: #726232;
118
+ /* <<< semantic:light */
119
+ /* >>> chart:static-light */
120
+ --chart-1: #3d89b2;
121
+ --chart-2: #593868;
122
+ --chart-3: #985d4d;
123
+ --chart-4: #323700;
124
+ --chart-5: #006c6c;
125
+ /* <<< chart:static-light */
126
+
127
+ /* the painted tones: muted a tinted band, ink a deep panel, brand the brand's own deep colour — apart by ≥ 0.1 ΔEok
128
+ (build-brand-scale.mjs); the glows are what a decorated section's aurora paints */
129
+ /* >>> tone:static-light */
130
+ --ma-tone-muted: #b6def7;
131
+ --ma-tone-ink: #253031;
132
+ --ma-tone-brand: #0d5f84;
133
+ --ma-tone-glow-1: #006566;
134
+ --ma-tone-glow-2: #44548c;
135
+ --ma-tone-glow-3: #6a4978;
136
+ --ma-tone-ink-foreground: var(--ma-neutral-100);
137
+ --ma-tone-brand-foreground: var(--ma-neutral-50);
138
+ --ma-tone-muted-card: oklch(1 0 0 / 60%);
139
+ --ma-tone-muted-border: #a6cae0;
140
+ --ma-tone-muted-shadow: var(--ma-shadow-1);
141
+ /* <<< tone:static-light */
142
+
143
+ /* secondary text: the faintest it is drawn (a section takes max(its own opacity, the floor)) */
144
+ /* >>> faint */
145
+ --ma-dim: 0.75;
146
+ --ma-sec-floor: 0.75;
147
+ --ma-sec-floor-brand: 0.9;
148
+ /* <<< faint */
149
+
150
+ /* shape and space */
151
+ --radius: 0.625rem;
152
+ --ma-radius-sm: calc(var(--radius) * 0.6);
153
+ --ma-radius-md: calc(var(--radius) * 0.8);
154
+ --ma-radius-lg: var(--radius);
155
+ --ma-radius-xl: calc(var(--radius) * 1.4);
156
+ --ma-radius-2xl: calc(var(--radius) * 1.8);
157
+ --ma-radius-3xl: calc(var(--radius) * 2.2);
158
+ --ma-radius-4xl: calc(var(--radius) * 2.6);
159
+ --ma-density: 1;
160
+ --ma-shadow-1: 0 1px 2px rgb(0 0 0 / 0.06);
161
+ --ma-shadow-2: 0 8px 24px -12px rgb(0 0 0 / 0.25);
162
+ --ma-shadow-3: 0 32px 64px -32px rgb(0 0 0 / 0.5);
163
+ }
164
+
165
+ /* the same values, from the buyer's colours: lightness fixed per step, chroma tapered at the ends (it clips near L 0 and 1) */
166
+ @supports (color: oklch(from red l c h)) {
167
+ :where(:root, [data-ma-theme]) {
168
+ /* >>> brand-scale:derived */
169
+ --ma-brand-50: oklch(from var(--ma-brand) 0.975 calc(c * 0.2) h);
170
+ --ma-brand-100: oklch(from var(--ma-brand) 0.94 calc(c * 0.35) h);
171
+ --ma-brand-200: oklch(from var(--ma-brand) 0.88 calc(c * 0.55) h);
172
+ --ma-brand-300: oklch(from var(--ma-brand) 0.8 calc(c * 0.75) h);
173
+ --ma-brand-400: oklch(from var(--ma-brand) 0.71 calc(c * 0.92) h);
174
+ --ma-brand-500: oklch(from var(--ma-brand) 0.62 c h);
175
+ --ma-brand-600: oklch(from var(--ma-brand) 0.53 c h);
176
+ --ma-brand-700: oklch(from var(--ma-brand) 0.44 calc(c * 0.95) h);
177
+ --ma-brand-800: oklch(from var(--ma-brand) 0.36 calc(c * 0.85) h);
178
+ --ma-brand-900: oklch(from var(--ma-brand) 0.29 calc(c * 0.7) h);
179
+ --ma-brand-950: oklch(from var(--ma-brand) 0.22 calc(c * 0.55) h);
180
+ /* <<< brand-scale:derived */
181
+ /* >>> neutral:derived */
182
+ --ma-neutral: oklch(from var(--primary) 0.2994 min(calc(c * 0.2), 0.0151) calc(h - 31.8));
183
+ --ma-accent: oklch(from var(--primary) 0.7437 min(calc(c * 0.8), 0.0697) calc(h - 143.5));
184
+ --ma-neutral-50: oklch(from var(--ma-neutral) 0.99 min(calc(c * 0.2), 0.02) h);
185
+ --ma-neutral-100: oklch(from var(--ma-neutral) 0.97 min(calc(c * 0.4), 0.02) h);
186
+ --ma-neutral-200: oklch(from var(--ma-neutral) 0.9 min(calc(c * 0.8), 0.02) h);
187
+ --ma-neutral-300: oklch(from var(--ma-neutral) 0.8 min(c, 0.02) h);
188
+ --ma-neutral-400: oklch(from var(--ma-neutral) 0.71 min(c, 0.02) h);
189
+ --ma-neutral-500: oklch(from var(--ma-neutral) 0.62 min(c, 0.02) h);
190
+ --ma-neutral-600: oklch(from var(--ma-neutral) 0.52 min(c, 0.02) h);
191
+ --ma-neutral-700: oklch(from var(--ma-neutral) 0.4 min(c, 0.02) h);
192
+ --ma-neutral-800: oklch(from var(--ma-neutral) 0.27 min(c, 0.02) h);
193
+ --ma-neutral-900: oklch(from var(--ma-neutral) 0.22 min(c, 0.02) h);
194
+ --ma-neutral-950: oklch(from var(--ma-neutral) 0.16 min(calc(c * 0.66), 0.02) h);
195
+ /* <<< neutral:derived */
196
+ /* >>> semantic:derived-light */
197
+ --ma-accent-text: oklch(from var(--ma-accent) min(l, 0.5) c h);
198
+ /* <<< semantic:derived-light */
199
+ /* >>> chart:derived-light */
200
+ --chart-1: oklch(from var(--ma-brand) 0.6 c h);
201
+ --chart-2: oklch(from var(--ma-brand) 0.4 calc(c * 0.9) calc(h + 80));
202
+ --chart-3: oklch(from var(--ma-brand) 0.54 calc(c * 0.85) calc(h + 160));
203
+ --chart-4: oklch(from var(--ma-brand) 0.32 calc(c * 0.8) calc(h + 240));
204
+ --chart-5: oklch(from var(--ma-brand) 0.48 calc(c * 0.9) calc(h + 320));
205
+ /* <<< chart:derived-light */
206
+ /* >>> tone:derived-light */
207
+ --ma-tone-muted: oklch(from var(--primary) 0.88 calc(c * 0.56) h);
208
+ --ma-tone-ink: oklch(from var(--ma-neutral) 0.2994 min(c, 0.02) h);
209
+ --ma-tone-brand: oklch(from var(--primary) calc(l + (0.46 - l) * clamp(0, (l - 0.3) * 20, 1)) calc(c * 0.953) h);
210
+ --ma-tone-glow-1: oklch(from var(--ma-tone-brand) l calc(c * 1.15) calc(h - 40));
211
+ --ma-tone-glow-2: oklch(from var(--ma-tone-brand) l c calc(h + 35));
212
+ --ma-tone-glow-3: oklch(from var(--ma-tone-brand) l calc(c * 0.9) calc(h + 80));
213
+ --ma-tone-muted-border: oklch(from var(--ma-tone-muted) 0.82 calc(c * 0.9) h);
214
+ /* <<< tone:derived-light */
215
+ }
216
+ }
217
+
218
+ /* dark: its own values, not the light ramp inverted (a naive inversion goes muddy); the scales are shared, the roles pick other steps */
219
+ @media (prefers-color-scheme: dark) {
220
+ :where(:root:not([data-theme='light']):not(.light), :root:not([data-theme='light']):not(.light) [data-ma-theme]:not([data-ma-theme='light'])) {
221
+ color-scheme: dark;
222
+ /* >>> roles:dark */
223
+ --background: var(--ma-neutral-950);
224
+ --foreground: var(--ma-neutral-100);
225
+ --card: var(--ma-neutral-900);
226
+ --card-foreground: var(--ma-neutral-100);
227
+ --popover: var(--ma-neutral-900);
228
+ --popover-foreground: var(--ma-neutral-100);
229
+ --primary: var(--ma-brand-400);
230
+ --primary-foreground: var(--ma-neutral-950);
231
+ --secondary: var(--ma-neutral-800);
232
+ --secondary-foreground: var(--ma-neutral-100);
233
+ --muted: var(--ma-neutral-800);
234
+ --muted-foreground: var(--ma-neutral-400);
235
+ --accent: var(--ma-neutral-800);
236
+ --accent-foreground: var(--ma-neutral-100);
237
+ --destructive: oklch(0.7 0.17 25);
238
+ --destructive-foreground: var(--ma-neutral-950);
239
+ --border: oklch(1 0 0 / 10%);
240
+ --input: var(--ma-neutral-600);
241
+ --ring: var(--ma-brand-400);
242
+ --ma-card-shadow: inset 0 1px 0 oklch(1 0 0 / 5%);
243
+ /* <<< roles:dark */
244
+ /* >>> semantic:dark */
245
+ --ma-success: oklch(0.78 0.14 150);
246
+ --ma-success-foreground: var(--ma-neutral-950);
247
+ --ma-warning: oklch(0.8 0.14 65);
248
+ --ma-warning-foreground: var(--ma-neutral-950);
249
+ --ma-info: var(--primary);
250
+ --ma-info-foreground: var(--primary-foreground);
251
+ --ma-accent-foreground: var(--ma-neutral-900);
252
+ --ma-accent-text: #bcab79;
253
+ /* <<< semantic:dark */
254
+ /* >>> chart:static-dark */
255
+ --chart-1: #6aaed5;
256
+ --chart-2: #7c598c;
257
+ --chart-3: #f7c3b5;
258
+ --chart-4: #7e864b;
259
+ --chart-5: #7dc6c6;
260
+ /* <<< chart:static-dark */
261
+ /* >>> tone:static-dark */
262
+ --ma-tone-muted: #284548;
263
+ --ma-tone-ink: #00283b;
264
+ --ma-tone-brand: #0d5f84;
265
+ --ma-tone-glow-1: #006566;
266
+ --ma-tone-glow-2: #44548c;
267
+ --ma-tone-glow-3: #6a4978;
268
+ --ma-tone-ink-foreground: var(--ma-neutral-100);
269
+ --ma-tone-brand-foreground: var(--ma-neutral-50);
270
+ --ma-tone-muted-card: color-mix(in oklab, var(--foreground) 6%, transparent);
271
+ --ma-tone-muted-border: color-mix(in oklab, var(--foreground) 10%, transparent);
272
+ --ma-tone-muted-shadow: inset 0 1px 0 color-mix(in oklab, var(--foreground) 5%, transparent);
273
+ /* <<< tone:static-dark */
274
+ }
275
+ @supports (color: oklch(from red l c h)) {
276
+ :where(:root:not([data-theme='light']):not(.light), :root:not([data-theme='light']):not(.light) [data-ma-theme]:not([data-ma-theme='light'])) {
277
+ /* >>> semantic:derived-dark */
278
+ --ma-accent-text: oklch(from var(--ma-accent) max(l, 0.72) c h);
279
+ /* <<< semantic:derived-dark */
280
+ /* >>> chart:derived-dark */
281
+ --chart-1: oklch(from var(--ma-brand) 0.72 calc(c * 0.92) h);
282
+ --chart-2: oklch(from var(--ma-brand) 0.52 calc(c * 0.9) calc(h + 80));
283
+ --chart-3: oklch(from var(--ma-brand) 0.86 calc(c * 0.65) calc(h + 160));
284
+ --chart-4: oklch(from var(--ma-brand) 0.6 calc(c * 0.85) calc(h + 240));
285
+ --chart-5: oklch(from var(--ma-brand) 0.78 calc(c * 0.75) calc(h + 320));
286
+ /* <<< chart:derived-dark */
287
+ /* >>> tone:derived-dark */
288
+ --ma-tone-muted: oklch(from var(--ma-neutral) 0.37 min(calc(c * 2.318), 0.0464) h);
289
+ --ma-tone-ink: oklch(from var(--primary) 0.26 calc(c * 0.67) h);
290
+ --ma-tone-brand: oklch(from var(--primary) calc(l + (0.46 - l) * clamp(0, (l - 0.3) * 20, 1)) calc(c * 1.036) h);
291
+ --ma-tone-glow-1: oklch(from var(--ma-tone-brand) l calc(c * 1.15) calc(h - 40));
292
+ --ma-tone-glow-2: oklch(from var(--ma-tone-brand) l c calc(h + 35));
293
+ --ma-tone-glow-3: oklch(from var(--ma-tone-brand) l calc(c * 0.9) calc(h + 80));
294
+ /* <<< tone:derived-dark */
295
+ }
296
+ }
297
+ }
298
+ :where(:root[data-theme='dark'], :root.dark, :is(:root[data-theme='dark'], :root.dark) [data-ma-theme]:not([data-ma-theme='light']), [data-ma-theme='dark']) {
299
+ color-scheme: dark;
300
+ /* >>> roles:dark */
301
+ --background: var(--ma-neutral-950);
302
+ --foreground: var(--ma-neutral-100);
303
+ --card: var(--ma-neutral-900);
304
+ --card-foreground: var(--ma-neutral-100);
305
+ --popover: var(--ma-neutral-900);
306
+ --popover-foreground: var(--ma-neutral-100);
307
+ --primary: var(--ma-brand-400);
308
+ --primary-foreground: var(--ma-neutral-950);
309
+ --secondary: var(--ma-neutral-800);
310
+ --secondary-foreground: var(--ma-neutral-100);
311
+ --muted: var(--ma-neutral-800);
312
+ --muted-foreground: var(--ma-neutral-400);
313
+ --accent: var(--ma-neutral-800);
314
+ --accent-foreground: var(--ma-neutral-100);
315
+ --destructive: oklch(0.7 0.17 25);
316
+ --destructive-foreground: var(--ma-neutral-950);
317
+ --border: oklch(1 0 0 / 10%);
318
+ --input: var(--ma-neutral-600);
319
+ --ring: var(--ma-brand-400);
320
+ --ma-card-shadow: inset 0 1px 0 oklch(1 0 0 / 5%);
321
+ /* <<< roles:dark */
322
+ /* >>> semantic:dark */
323
+ --ma-success: oklch(0.78 0.14 150);
324
+ --ma-success-foreground: var(--ma-neutral-950);
325
+ --ma-warning: oklch(0.8 0.14 65);
326
+ --ma-warning-foreground: var(--ma-neutral-950);
327
+ --ma-info: var(--primary);
328
+ --ma-info-foreground: var(--primary-foreground);
329
+ --ma-accent-foreground: var(--ma-neutral-900);
330
+ --ma-accent-text: #bcab79;
331
+ /* <<< semantic:dark */
332
+ /* >>> chart:static-dark */
333
+ --chart-1: #6aaed5;
334
+ --chart-2: #7c598c;
335
+ --chart-3: #f7c3b5;
336
+ --chart-4: #7e864b;
337
+ --chart-5: #7dc6c6;
338
+ /* <<< chart:static-dark */
339
+ /* >>> tone:static-dark */
340
+ --ma-tone-muted: #284548;
341
+ --ma-tone-ink: #00283b;
342
+ --ma-tone-brand: #0d5f84;
343
+ --ma-tone-glow-1: #006566;
344
+ --ma-tone-glow-2: #44548c;
345
+ --ma-tone-glow-3: #6a4978;
346
+ --ma-tone-ink-foreground: var(--ma-neutral-100);
347
+ --ma-tone-brand-foreground: var(--ma-neutral-50);
348
+ --ma-tone-muted-card: color-mix(in oklab, var(--foreground) 6%, transparent);
349
+ --ma-tone-muted-border: color-mix(in oklab, var(--foreground) 10%, transparent);
350
+ --ma-tone-muted-shadow: inset 0 1px 0 color-mix(in oklab, var(--foreground) 5%, transparent);
351
+ /* <<< tone:static-dark */
352
+ }
353
+ @supports (color: oklch(from red l c h)) {
354
+ :where(:root[data-theme='dark'], :root.dark, :is(:root[data-theme='dark'], :root.dark) [data-ma-theme]:not([data-ma-theme='light']), [data-ma-theme='dark']) {
355
+ /* >>> semantic:derived-dark */
356
+ --ma-accent-text: oklch(from var(--ma-accent) max(l, 0.72) c h);
357
+ /* <<< semantic:derived-dark */
358
+ /* >>> chart:derived-dark */
359
+ --chart-1: oklch(from var(--ma-brand) 0.72 calc(c * 0.92) h);
360
+ --chart-2: oklch(from var(--ma-brand) 0.52 calc(c * 0.9) calc(h + 80));
361
+ --chart-3: oklch(from var(--ma-brand) 0.86 calc(c * 0.65) calc(h + 160));
362
+ --chart-4: oklch(from var(--ma-brand) 0.6 calc(c * 0.85) calc(h + 240));
363
+ --chart-5: oklch(from var(--ma-brand) 0.78 calc(c * 0.75) calc(h + 320));
364
+ /* <<< chart:derived-dark */
365
+ /* >>> tone:derived-dark */
366
+ --ma-tone-muted: oklch(from var(--ma-neutral) 0.37 min(calc(c * 2.318), 0.0464) h);
367
+ --ma-tone-ink: oklch(from var(--primary) 0.26 calc(c * 0.67) h);
368
+ --ma-tone-brand: oklch(from var(--primary) calc(l + (0.46 - l) * clamp(0, (l - 0.3) * 20, 1)) calc(c * 1.036) h);
369
+ --ma-tone-glow-1: oklch(from var(--ma-tone-brand) l calc(c * 1.15) calc(h - 40));
370
+ --ma-tone-glow-2: oklch(from var(--ma-tone-brand) l c calc(h + 35));
371
+ --ma-tone-glow-3: oklch(from var(--ma-tone-brand) l calc(c * 0.9) calc(h + 80));
372
+ /* <<< tone:derived-dark */
373
+ }
374
+ }
375
+
376
+ /* a painted tone is a theme scope (7F.3): what it re-declares for everything inside it. A section paints its own
377
+ ground (with fallbacks, so a page without this file keeps its tones); these follow it */
378
+ /* >>> tone:scope */
379
+ :where([data-ma-tone='muted']) { --card: var(--ma-tone-muted-card); --border: var(--ma-tone-muted-border); --input: color-mix(in oklab, var(--foreground) 65%, transparent); --ring: var(--foreground); --ma-card-shadow: var(--ma-tone-muted-shadow); --ma-dim: 0.8; --ma-sec-floor: 0.8; }
380
+ :where([data-ma-tone='ink']) { --card: color-mix(in oklab, var(--ma-tone-ink-foreground) 6%, transparent); --card-foreground: var(--ma-tone-ink-foreground); --border: color-mix(in oklab, var(--ma-tone-ink-foreground) 10%, transparent); --input: color-mix(in oklab, var(--ma-tone-ink-foreground) 65%, transparent); --ring: var(--ma-tone-ink-foreground); --accent: color-mix(in oklab, var(--ma-tone-ink-foreground) 14%, transparent); --ma-card-shadow: inset 0 1px 0 color-mix(in oklab, var(--ma-tone-ink-foreground) 6%, transparent); }
381
+ :where([data-ma-tone='brand']) { --card: color-mix(in oklab, var(--ma-tone-brand-foreground) 10%, transparent); --card-foreground: var(--ma-tone-brand-foreground); --border: color-mix(in oklab, var(--ma-tone-brand-foreground) 18%, transparent); --input: color-mix(in oklab, var(--ma-tone-brand-foreground) 65%, transparent); --ring: var(--ma-tone-brand-foreground); --accent: color-mix(in oklab, var(--ma-tone-brand-foreground) 14%, transparent); --ma-card-shadow: inset 0 1px 0 color-mix(in oklab, var(--ma-tone-brand-foreground) 12%, transparent); --ma-dim: 0.9; --ma-sec-floor: 0.9; }
382
+ /* <<< tone:scope */
383
+
384
+ /* text on the filled colours: black or white, whichever contrasts more, where the engine can decide
385
+ (Chrome 147 · Firefox 146 · Safari 26); the static values above are the tested fallback. Last on purpose: it
386
+ applies in both themes and still loses to a consumer's own :root / .dark declaration. */
387
+ @supports (color: contrast-color(red)) {
388
+ :where(:root, [data-ma-theme]) {
389
+ --primary-foreground: contrast-color(var(--primary));
390
+ --destructive-foreground: contrast-color(var(--destructive));
391
+ --ma-success-foreground: contrast-color(var(--ma-success));
392
+ --ma-warning-foreground: contrast-color(var(--ma-warning));
393
+ --ma-accent-foreground: contrast-color(var(--ma-accent));
394
+ --ma-tone-brand-foreground: contrast-color(var(--ma-tone-brand));
395
+ }
396
+ }
397
+ }
@@ -0,0 +1,75 @@
1
+ /*
2
+ * @moonarc/core/styles/theme.tailwind.css — the Tailwind v4 bridge for
3
+ * the theme contract. Optional, Tailwind only; theme.css itself needs nothing.
4
+ *
5
+ * `@theme inline` (not `@theme`): the utility carries `var(--background)`
6
+ * itself, so `bg-background` in your markup and a Pro section read the same
7
+ * variable and both change when a theme swaps it at runtime — a plain
8
+ * `@theme` would freeze the value at build (checked on this site's own
9
+ * global.css, three engines). The radius keys replace Tailwind's fixed
10
+ * `--radius-*` with the contract's scale, as shadcn's globals.css does, so
11
+ * `rounded-lg` is `--radius`. The status colours (7F.3) are `bg-success`,
12
+ * `text-warning`, `bg-info` … with their -foreground. The accent and the
13
+ * neutral scale have no utility name of their own, because shadcn's `accent`
14
+ * is a neutral hover surface and Tailwind already ships a `neutral` palette:
15
+ * reach them as `bg-(--ma-accent)`, `text-(--ma-accent-text)`,
16
+ * `bg-(--ma-neutral-100)`.
17
+ *
18
+ * Usage: @import "tailwindcss";
19
+ * @import "@moonarc/core/theme.css";
20
+ * @import "@moonarc/core/styles/theme.tailwind.css";
21
+ */
22
+
23
+ @theme inline {
24
+ --color-background: var(--background);
25
+ --color-foreground: var(--foreground);
26
+ --color-card: var(--card);
27
+ --color-card-foreground: var(--card-foreground);
28
+ --color-popover: var(--popover);
29
+ --color-popover-foreground: var(--popover-foreground);
30
+ --color-primary: var(--primary);
31
+ --color-primary-foreground: var(--primary-foreground);
32
+ --color-secondary: var(--secondary);
33
+ --color-secondary-foreground: var(--secondary-foreground);
34
+ --color-muted: var(--muted);
35
+ --color-muted-foreground: var(--muted-foreground);
36
+ --color-accent: var(--accent);
37
+ --color-accent-foreground: var(--accent-foreground);
38
+ --color-destructive: var(--destructive);
39
+ --color-destructive-foreground: var(--destructive-foreground);
40
+ --color-border: var(--border);
41
+ --color-input: var(--input);
42
+ --color-ring: var(--ring);
43
+ --color-chart-1: var(--chart-1);
44
+ --color-chart-2: var(--chart-2);
45
+ --color-chart-3: var(--chart-3);
46
+ --color-chart-4: var(--chart-4);
47
+ --color-chart-5: var(--chart-5);
48
+ --color-brand: var(--ma-brand);
49
+ --color-brand-50: var(--ma-brand-50);
50
+ --color-brand-100: var(--ma-brand-100);
51
+ --color-brand-200: var(--ma-brand-200);
52
+ --color-brand-300: var(--ma-brand-300);
53
+ --color-brand-400: var(--ma-brand-400);
54
+ --color-brand-500: var(--ma-brand-500);
55
+ --color-brand-600: var(--ma-brand-600);
56
+ --color-brand-700: var(--ma-brand-700);
57
+ --color-brand-800: var(--ma-brand-800);
58
+ --color-brand-900: var(--ma-brand-900);
59
+ --color-brand-950: var(--ma-brand-950);
60
+ --color-ink: var(--ma-tone-ink);
61
+ --color-ink-foreground: var(--ma-tone-ink-foreground);
62
+ --color-success: var(--ma-success);
63
+ --color-success-foreground: var(--ma-success-foreground);
64
+ --color-warning: var(--ma-warning);
65
+ --color-warning-foreground: var(--ma-warning-foreground);
66
+ --color-info: var(--ma-info);
67
+ --color-info-foreground: var(--ma-info-foreground);
68
+ --radius-sm: var(--ma-radius-sm);
69
+ --radius-md: var(--ma-radius-md);
70
+ --radius-lg: var(--ma-radius-lg);
71
+ --radius-xl: var(--ma-radius-xl);
72
+ --radius-2xl: var(--ma-radius-2xl);
73
+ --radius-3xl: var(--ma-radius-3xl);
74
+ --radius-4xl: var(--ma-radius-4xl);
75
+ }