@sableui/react 0.0.0-stage → 0.1.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 (247) hide show
  1. package/AGENTS.md +157 -0
  2. package/CHANGELOG.md +55 -0
  3. package/CONTRIBUTING.md +221 -0
  4. package/DESIGN.md +548 -0
  5. package/LICENSE +21 -0
  6. package/README.md +194 -2
  7. package/THIRD_PARTY_NOTICES.md +44 -0
  8. package/bin/sable-lint.mjs +0 -0
  9. package/bin/sable.mjs +1223 -0
  10. package/dist/_contract-CYScOdf5.d.ts +150 -0
  11. package/dist/chunk-3IWZYBGH.js +398 -0
  12. package/dist/chunk-5Z5KLOAU.js +167 -0
  13. package/dist/chunk-7MG4SHYX.js +15 -0
  14. package/dist/chunk-ADLLDWLW.js +15 -0
  15. package/dist/chunk-EP55KSYA.js +14 -0
  16. package/dist/chunk-J23ELQQZ.js +9396 -0
  17. package/dist/chunk-JI7WJP2L.js +286 -0
  18. package/dist/chunk-K7RUHUGC.js +14 -0
  19. package/dist/chunk-KO3NAEBF.js +15 -0
  20. package/dist/chunk-L4IEIQQA.js +14 -0
  21. package/dist/chunk-L6Y46C62.js +270 -0
  22. package/dist/chunk-NEQNXI2G.js +25 -0
  23. package/dist/chunk-PAOZBZME.js +40 -0
  24. package/dist/chunk-RWP4XBSK.js +139 -0
  25. package/dist/chunk-SRQWQUTW.js +63 -0
  26. package/dist/chunk-YXBOYWBN.js +15 -0
  27. package/dist/foundations/index.d.ts +88 -0
  28. package/dist/foundations/index.js +792 -0
  29. package/dist/icon/index.d.ts +60 -0
  30. package/dist/icon/index.js +2 -0
  31. package/dist/icon-sets/brands.d.ts +44 -0
  32. package/dist/icon-sets/brands.js +147 -0
  33. package/dist/icon-sets/reicon.d.ts +8 -0
  34. package/dist/icon-sets/reicon.js +1 -0
  35. package/dist/index.d.ts +7013 -0
  36. package/dist/index.js +15462 -0
  37. package/dist/ios/chrome.css +83 -0
  38. package/dist/ios/frame.css +5 -0
  39. package/dist/ios/index.d.ts +70 -0
  40. package/dist/ios/index.js +313 -0
  41. package/dist/ios/preview.d.ts +64 -0
  42. package/dist/ios/preview.js +133 -0
  43. package/dist/ios/styles.css +77 -0
  44. package/dist/layout/index.d.ts +280 -0
  45. package/dist/layout/index.js +2 -0
  46. package/dist/meta-6dUzgC6M.d.ts +205 -0
  47. package/dist/patterns/index.d.ts +36 -0
  48. package/dist/patterns/index.js +934 -0
  49. package/dist/presets/index.d.ts +37 -0
  50. package/dist/presets/index.js +117 -0
  51. package/dist/registry-CyL28OzJ.d.ts +28 -0
  52. package/dist/styles.css +1893 -0
  53. package/dist/theme-provider-BWcizhAt.d.ts +105 -0
  54. package/dist/themes/atelier/atelier.css +213 -0
  55. package/dist/themes/atelier/index.d.ts +9 -0
  56. package/dist/themes/atelier/index.js +1 -0
  57. package/dist/themes/base/base.css +443 -0
  58. package/dist/themes/base/index.d.ts +9 -0
  59. package/dist/themes/base/index.js +1 -0
  60. package/dist/themes/ember/ember.css +270 -0
  61. package/dist/themes/ember/index.d.ts +9 -0
  62. package/dist/themes/ember/index.js +1 -0
  63. package/dist/themes/index.d.ts +10 -0
  64. package/dist/themes/index.js +8 -0
  65. package/dist/themes/meridian/index.d.ts +9 -0
  66. package/dist/themes/meridian/index.js +1 -0
  67. package/dist/themes/meridian/meridian.css +255 -0
  68. package/dist/themes/poppy/index.d.ts +6 -0
  69. package/dist/themes/poppy/index.js +1 -0
  70. package/dist/themes/poppy/poppy.css +174 -0
  71. package/dist/themes/prism/index.d.ts +6 -0
  72. package/dist/themes/prism/index.js +1 -0
  73. package/dist/themes/prism/prism.css +183 -0
  74. package/dist/themes/verdant/index.d.ts +9 -0
  75. package/dist/themes/verdant/index.js +1 -0
  76. package/dist/themes/verdant/verdant.css +210 -0
  77. package/dist/themes.css +30 -0
  78. package/llms/components/accordion.md +93 -0
  79. package/llms/components/app-header.md +70 -0
  80. package/llms/components/app-shell.md +117 -0
  81. package/llms/components/attachment.md +105 -0
  82. package/llms/components/avatar.md +141 -0
  83. package/llms/components/badge.md +117 -0
  84. package/llms/components/banner.md +119 -0
  85. package/llms/components/bottom-nav.md +80 -0
  86. package/llms/components/breadcrumbs.md +75 -0
  87. package/llms/components/browser.md +67 -0
  88. package/llms/components/bubble.md +119 -0
  89. package/llms/components/button.md +199 -0
  90. package/llms/components/calendar.md +75 -0
  91. package/llms/components/card.md +135 -0
  92. package/llms/components/carousel.md +87 -0
  93. package/llms/components/chat-composer.md +126 -0
  94. package/llms/components/checkbox-card.md +98 -0
  95. package/llms/components/checkbox.md +90 -0
  96. package/llms/components/code-block.md +81 -0
  97. package/llms/components/code.md +62 -0
  98. package/llms/components/collapsible.md +83 -0
  99. package/llms/components/color-field.md +100 -0
  100. package/llms/components/combobox.md +119 -0
  101. package/llms/components/command-menu.md +158 -0
  102. package/llms/components/context-card.md +73 -0
  103. package/llms/components/context-menu.md +79 -0
  104. package/llms/components/data-table.md +99 -0
  105. package/llms/components/date-picker.md +97 -0
  106. package/llms/components/description.md +96 -0
  107. package/llms/components/destructive-action-modal.md +76 -0
  108. package/llms/components/dialog.md +127 -0
  109. package/llms/components/dots-menu.md +64 -0
  110. package/llms/components/empty-state.md +113 -0
  111. package/llms/components/entity.md +67 -0
  112. package/llms/components/feedback.md +63 -0
  113. package/llms/components/fieldset.md +106 -0
  114. package/llms/components/file-dropzone.md +103 -0
  115. package/llms/components/form.md +111 -0
  116. package/llms/components/gliding-highlight.md +84 -0
  117. package/llms/components/inline-status.md +62 -0
  118. package/llms/components/input.md +127 -0
  119. package/llms/components/kbd.md +57 -0
  120. package/llms/components/label.md +73 -0
  121. package/llms/components/marker.md +99 -0
  122. package/llms/components/marquee.md +66 -0
  123. package/llms/components/menu.md +122 -0
  124. package/llms/components/message-scroller.md +110 -0
  125. package/llms/components/message.md +114 -0
  126. package/llms/components/meter.md +124 -0
  127. package/llms/components/middle-truncate.md +62 -0
  128. package/llms/components/note.md +81 -0
  129. package/llms/components/notification-badge.md +67 -0
  130. package/llms/components/number-field.md +70 -0
  131. package/llms/components/otp-field.md +101 -0
  132. package/llms/components/page-header.md +76 -0
  133. package/llms/components/page-loader.md +67 -0
  134. package/llms/components/pagination.md +92 -0
  135. package/llms/components/panel-group.md +120 -0
  136. package/llms/components/panel-section.md +122 -0
  137. package/llms/components/phone.md +70 -0
  138. package/llms/components/pill.md +73 -0
  139. package/llms/components/popover.md +79 -0
  140. package/llms/components/progress.md +98 -0
  141. package/llms/components/radio-card.md +90 -0
  142. package/llms/components/radio.md +86 -0
  143. package/llms/components/relative-time.md +60 -0
  144. package/llms/components/scroller.md +88 -0
  145. package/llms/components/scrub-field.md +97 -0
  146. package/llms/components/search-input.md +84 -0
  147. package/llms/components/select.md +106 -0
  148. package/llms/components/separator.md +70 -0
  149. package/llms/components/settings-menu.md +139 -0
  150. package/llms/components/sheet.md +97 -0
  151. package/llms/components/show-more.md +59 -0
  152. package/llms/components/side-nav.md +106 -0
  153. package/llms/components/sidebar.md +87 -0
  154. package/llms/components/skeleton.md +62 -0
  155. package/llms/components/slider.md +114 -0
  156. package/llms/components/spinner.md +87 -0
  157. package/llms/components/status-bar.md +91 -0
  158. package/llms/components/status-dot.md +70 -0
  159. package/llms/components/stepper.md +125 -0
  160. package/llms/components/streaming-text.md +86 -0
  161. package/llms/components/switch.md +87 -0
  162. package/llms/components/table.md +112 -0
  163. package/llms/components/tabs.md +84 -0
  164. package/llms/components/textarea.md +88 -0
  165. package/llms/components/theme-selector.md +95 -0
  166. package/llms/components/theme-switcher.md +71 -0
  167. package/llms/components/thinking-orb.md +91 -0
  168. package/llms/components/toast.md +130 -0
  169. package/llms/components/toggle.md +95 -0
  170. package/llms/components/toolbar.md +168 -0
  171. package/llms/components/tooltip.md +93 -0
  172. package/llms/components/tree.md +227 -0
  173. package/llms/components/video.md +66 -0
  174. package/llms/components/workspace.md +138 -0
  175. package/llms/foundations/accessibility.md +60 -0
  176. package/llms/foundations/motion.md +96 -0
  177. package/llms/foundations/scrolling.md +41 -0
  178. package/llms/foundations/shape.md +73 -0
  179. package/llms/foundations/spacing.md +82 -0
  180. package/llms/foundations/surfaces.md +69 -0
  181. package/llms/foundations/typography.md +120 -0
  182. package/llms/layout/aspect-box.md +37 -0
  183. package/llms/layout/bleed.md +31 -0
  184. package/llms/layout/center.md +37 -0
  185. package/llms/layout/columns.md +51 -0
  186. package/llms/layout/grid-overlay.md +40 -0
  187. package/llms/layout/grid.md +47 -0
  188. package/llms/layout/page.md +39 -0
  189. package/llms/layout/region.md +49 -0
  190. package/llms/layout/row.md +40 -0
  191. package/llms/layout/safe-area.md +37 -0
  192. package/llms/layout/spacer.md +39 -0
  193. package/llms/layout/split-pane.md +41 -0
  194. package/llms/layout/stack.md +39 -0
  195. package/llms/patterns/auth-page.md +68 -0
  196. package/llms/patterns/brand-landing-page.md +423 -0
  197. package/llms/patterns/chat-panel.md +210 -0
  198. package/llms/patterns/dashboard-page.md +170 -0
  199. package/llms/patterns/feed-page.md +103 -0
  200. package/llms/patterns/landing-page.md +122 -0
  201. package/llms/patterns/list-detail-page.md +100 -0
  202. package/llms/patterns/settings-page.md +121 -0
  203. package/llms/reference/token-intent.md +324 -0
  204. package/llms/reference/utilities.md +129 -0
  205. package/llms/tasks/adding-a-component.md +113 -0
  206. package/llms/tasks/auditing-an-app.md +216 -0
  207. package/llms/tasks/building-a-page.md +109 -0
  208. package/llms/tasks/building-a-tool.md +141 -0
  209. package/llms/tasks/building-an-ios-prototype.md +105 -0
  210. package/llms/tasks/building-with-sable.md +73 -0
  211. package/llms/tasks/choosing-a-component.md +109 -0
  212. package/llms/tasks/converting-an-app.md +139 -0
  213. package/llms/tasks/creating-a-preset.md +43 -0
  214. package/llms/tasks/creating-design-assets.md +96 -0
  215. package/llms/tasks/designing-a-surface.md +115 -0
  216. package/llms/tasks/developing-taste.md +157 -0
  217. package/llms/tasks/getting-started.md +63 -0
  218. package/llms/tasks/learning-from-builds.md +74 -0
  219. package/llms/tasks/reviewing-a-design.md +114 -0
  220. package/llms/tasks/reviewing-a-journey.md +84 -0
  221. package/llms/tasks/reviewing-motion.md +92 -0
  222. package/llms/tasks/using-presets.md +87 -0
  223. package/llms/taste/asset-plan.template.json +53 -0
  224. package/llms/taste/composition-follows-content.md +20 -0
  225. package/llms/taste/hierarchy-is-a-relationship.md +22 -0
  226. package/llms/taste/lessons.json +57 -0
  227. package/llms/taste/motion-needs-a-reason.md +21 -0
  228. package/llms/taste/surface-states-travel-together.md +20 -0
  229. package/llms-full.txt +14906 -0
  230. package/llms.txt +405 -0
  231. package/package.json +185 -3
  232. package/registry.json +18812 -0
  233. package/scripts/agent-setup.mjs +54 -0
  234. package/scripts/design-atlas.mjs +221 -0
  235. package/scripts/design-directions.mjs +123 -0
  236. package/scripts/design-memory.mjs +166 -0
  237. package/scripts/design-preferences.mjs +227 -0
  238. package/scripts/design-presets.mjs +48 -0
  239. package/scripts/grade.mjs +509 -0
  240. package/scripts/lint-rules.mjs +1065 -0
  241. package/scripts/review-evidence.mjs +120 -0
  242. package/scripts/skeleton.mjs +248 -0
  243. package/skills/entry/SKILL.md +34 -0
  244. package/skills/sable/SKILL.md +187 -0
  245. package/skills/sable/agents/openai.yaml +6 -0
  246. package/targets/ios.json +982 -0
  247. package/third-party/reicon-LICENSE.txt +20 -0
@@ -0,0 +1,270 @@
1
+ /* ==========================================================================
2
+ Ember — a Sable theme, developed from reference analysis.
3
+
4
+ Components must reference the SEMANTIC tokens (--background, --primary,
5
+ --tone-edition, …), never any palette ramp directly. See themes/_contract.ts.
6
+ ========================================================================== */
7
+
8
+ /* Scoped only — never a bare `:root`. Base alone owns `:root` as the
9
+ package default; a second theme claiming it leaks its tokens into every other
10
+ theme, and `themes.test.ts` fails the build on it. */
11
+ [data-sable-theme="ember"] {
12
+ /* Font stacks (theme-internal; host app provides the actual font files).
13
+
14
+ The reference's observed face is Helvetica Neue — a Linotype commercial
15
+ font, NOT available on Google Fonts. (The resolver claims otherwise:
16
+ Google's API answers for it via the restricted `/l/font?kit=` endpoint,
17
+ which is not an open licence.)
18
+
19
+ Rather than substitute a neutral lookalike, this theme takes a DELIBERATE
20
+ DIVERGENCE: Work Sans, chosen for a little warmth without commentary. It
21
+ keeps the reference's grotesque bones and its wide, even rhythm at display
22
+ size, while its slightly humanist details stop the page reading as
23
+ anonymous the way a pure neutral does. It carries a genuine 300 weight,
24
+ which the whole theme depends on.
25
+
26
+ Space Grotesk was tried first and pulled back from: its technical, quirky
27
+ letterforms competed with the registration chrome rather than supporting
28
+ it — two things talking at once on a page that is already maximal in
29
+ colour.
30
+
31
+ Helvetica Neue is deliberately NOT first in the stack: leading with it
32
+ would mean anyone who licenses it silently gets a different design than
33
+ the one that was chosen. */
34
+ --font-sans: "Work Sans", sans-serif;
35
+ --font-mono: "DM Mono", ui-monospace, monospace;
36
+
37
+ /* Layout foundation — px, never rem. These MUST be declared here even where
38
+ a value equals Sable's default: `styles.css` unconditionally imports
39
+ the original default theme's CSS, which declared these on a bare `:root`, so a theme that
40
+ omits them silently inherits that theme's caps regardless of which
41
+ `data-sable-theme` is active. Values from the reference's own measured
42
+ container widths — 1280px grid inside an 80px page inset at 1440.
43
+
44
+ rem here would be a bug, not a style choice: the responsive root is 14px
45
+ on desktop, so `80rem` renders 1120px, not the 1280px it reads as. */
46
+ --page-inset: clamp(20px, 5.5vw, 80px);
47
+ --region-form: 480px;
48
+ --region-feed: 640px;
49
+ --region-content: 960px;
50
+ --region-wide: 1280px;
51
+ --region-full: 1536px;
52
+ --region-ultrawide: 1800px;
53
+
54
+ /* Theme foundation vars consumed by styles.css. */
55
+ --theme-radius-none: 0px;
56
+ --theme-radius-xs: 6px;
57
+ --theme-radius-sm: 10px;
58
+ --theme-radius-md: 12px;
59
+ --theme-radius-lg: 20px;
60
+ --theme-radius-xl: 28px;
61
+ --theme-radius-full: 9999px;
62
+
63
+ /* Type-scale foundation vars consumed by styles.css's paired text-* utilities. */
64
+ --type-display-4xl-weight: 300;
65
+ --type-display-4xl-leading: 0.92;
66
+ --type-display-4xl-tracking: -0.02em;
67
+ --type-display-3xl-size: 5.4286rem;
68
+ --type-display-3xl-weight: 300;
69
+ --type-display-3xl-leading: 0.95;
70
+ --type-display-3xl-tracking: -0.015em;
71
+ --type-display-2xl-size: 4.8571rem;
72
+ --type-display-2xl-weight: 300;
73
+ --type-display-2xl-leading: 1;
74
+ --type-display-2xl-tracking: -0.01em;
75
+ --type-display-xl-size: 3.7143rem;
76
+ --type-display-xl-weight: 300;
77
+ --type-display-xl-leading: 1.2;
78
+ --type-display-xl-tracking: -0.01em;
79
+ --type-display-lg-size: 2.8571rem;
80
+ --type-display-lg-weight: 300;
81
+ --type-display-lg-leading: 1.1;
82
+ --type-display-lg-tracking: -0.005em;
83
+ --type-heading-weight: 300;
84
+ --type-heading-1-size: 2.2857rem;
85
+ --type-heading-1-leading: 1.1;
86
+ --type-heading-1-tracking: -0.005em;
87
+ --type-heading-2-size: 1.7143rem;
88
+ --type-heading-2-leading: 1.1;
89
+ --type-heading-2-tracking: 0em;
90
+ --type-heading-3-size: 1.4286rem;
91
+ --type-heading-3-leading: 1.4;
92
+ --type-heading-3-tracking: 0em;
93
+ --type-heading-4-size: 1.2857rem;
94
+ --type-heading-4-leading: 1.4;
95
+ --type-heading-4-tracking: 0em;
96
+ --type-title-weight: 500;
97
+ --type-title-leading: 1.25;
98
+ --type-title-tracking: 0em;
99
+ --type-title-sm-tracking: 0em;
100
+
101
+ /* Overline/eyebrow foundation vars consumed by styles.css's text-overline utility. */
102
+ --type-overline-size: 0.7143rem;
103
+ --type-overline-weight: 500;
104
+ --type-overline-leading: 1;
105
+ --type-overline-tracking: 0.1em;
106
+ --type-overline-transform: uppercase;
107
+
108
+ /* ----------------------------------------------------------------------
109
+ Palette ramps. Theme-internal — never used directly by components.
110
+ ---------------------------------------------------------------------- */
111
+ /* ember */
112
+ --ember-50: oklch(97% 0.02 32.9);
113
+ --ember-100: oklch(94% 0.045 32.9);
114
+ --ember-200: oklch(88% 0.08 32.9);
115
+ --ember-300: oklch(80% 0.13 32.9);
116
+ --ember-400: oklch(72% 0.19 32.9);
117
+ --ember-500: oklch(65.2% 0.235 32.9);
118
+ --ember-600: oklch(58% 0.245 32.9);
119
+ --ember-700: oklch(50% 0.21 32.9);
120
+ --ember-800: oklch(42% 0.17 32.9);
121
+ --ember-900: oklch(34% 0.13 32.9);
122
+ --ember-950: oklch(24% 0.09 32.9);
123
+
124
+ /* soot — one continuous warm neutral. Steps 50-500 were chroma 0 while
125
+ 600-950 were warm, so the ramp changed temperature halfway and light mode
126
+ read as a different theme from dark mode. */
127
+ --soot-50: oklch(97% 0.005 80);
128
+ --soot-100: oklch(93.1% 0.007 78);
129
+ --soot-200: oklch(85.8% 0.008 76);
130
+ --soot-300: oklch(79.2% 0.010 74);
131
+ --soot-400: oklch(61% 0.010 72);
132
+ --soot-500: oklch(46.8% 0.010 70);
133
+ --soot-600: oklch(32.9% 0.010 61.1);
134
+ --soot-700: oklch(25.2% 0.012 67.2);
135
+ --soot-800: oklch(18.8% 0.013 55.5);
136
+ /* Warm, like every step around it. This was `oklch(15.9% 0 90)` — chroma 0,
137
+ a neutral grey punched into an otherwise warm ramp — and because it feeds
138
+ `--sidebar` and `--secondary` in dark mode, the docs rail read as a cold
139
+ panel floating on a warm ground. The chroma/hue here are interpolated
140
+ between its neighbours (950 at 0.018/70.5, 800 at 0.013/55.5); the
141
+ lightness is untouched, so only the temperature changed. */
142
+ --soot-900: oklch(15.9% 0.016 65);
143
+ --soot-950: oklch(14.1% 0.018 70.5);
144
+
145
+ /* ----------------------------------------------------------------------
146
+ Semantic tokens — light mode
147
+ ---------------------------------------------------------------------- */
148
+ --background: oklch(96.5% 0.008 78);
149
+ --foreground: oklch(23.1% 0.014 70);
150
+ --card: oklch(99% 0.004 80);
151
+ --card-foreground: oklch(23.1% 0.014 70);
152
+ --popover: oklch(99% 0.004 80);
153
+ --popover-foreground: oklch(23.1% 0.014 70);
154
+ --muted: oklch(93% 0.007 76);
155
+ --muted-foreground: oklch(46.8% 0.010 70);
156
+ --border: oklch(88% 0.008 74);
157
+ --border-strong: oklch(82% 0.010 73);
158
+ --input: oklch(85% 0.009 74);
159
+ --ring: oklch(58% 0.245 32.9);
160
+ --primary: oklch(58% 0.245 32.9);
161
+ --primary-foreground: oklch(100% 0 0);
162
+ --secondary: oklch(91% 0.010 75);
163
+ --secondary-foreground: oklch(23.1% 0.014 70);
164
+ --accent: oklch(92% 0.011 74);
165
+ --accent-foreground: oklch(23.1% 0.014 70);
166
+ --destructive: oklch(50% 0.17 25);
167
+ --destructive-foreground: oklch(100% 0 0);
168
+ --success: oklch(43% 0.10 165);
169
+ --success-foreground: oklch(100% 0 0);
170
+ --tone-standard: oklch(40% 0.07 130);
171
+ --tone-collectible: oklch(46% 0.14 285);
172
+ --tone-edition: oklch(45% 0.15 309);
173
+ --tone-info: oklch(48% 0.13 250);
174
+ --tone-warning: oklch(50% 0.12 52);
175
+ --highlight: oklch(58% 0.245 32.9);
176
+ --tone-standard-foreground: oklch(100% 0 0);
177
+ --tone-collectible-foreground: oklch(100% 0 0);
178
+ --tone-edition-foreground: oklch(100% 0 0);
179
+ --tone-info-foreground: oklch(100% 0 0);
180
+ --tone-warning-foreground: oklch(100% 0 0);
181
+ --highlight-foreground: oklch(100% 0 0);
182
+ --overlay: oklch(14.1% 0.018 70.5);
183
+ --overlay-foreground: oklch(100% 0 0);
184
+ --sidebar: oklch(96.5% 0.008 78);
185
+ --sidebar-foreground: oklch(23.1% 0.014 70);
186
+ --sidebar-primary: oklch(58% 0.245 32.9);
187
+ --sidebar-primary-foreground: oklch(100% 0 0);
188
+ --sidebar-accent: oklch(93% 0.007 76);
189
+ --sidebar-accent-foreground: oklch(23.1% 0.014 70);
190
+ --sidebar-border: oklch(88% 0.008 74);
191
+ --sidebar-ring: oklch(58% 0.245 32.9);
192
+
193
+ /* ----------------------------------------------------------------------
194
+ Motion tokens (mode-independent)
195
+ ---------------------------------------------------------------------- */
196
+ --motion-scale: 1;
197
+ --motion-duration-instant: calc(100ms * var(--motion-scale));
198
+ --motion-duration-fast: calc(200ms * var(--motion-scale));
199
+ --motion-duration-base: calc(300ms * var(--motion-scale));
200
+ --motion-duration-slow: calc(400ms * var(--motion-scale));
201
+ --motion-duration-slower: calc(650ms * var(--motion-scale));
202
+ --motion-duration-enter: calc(400ms * var(--motion-scale));
203
+ --motion-duration-exit: calc(200ms * var(--motion-scale));
204
+ --motion-ease-standard: cubic-bezier(0.6, 0, 0.3, 1);
205
+ --motion-ease-decelerate: cubic-bezier(0.16, 1, 0.3, 1);
206
+ --motion-ease-emphasized: cubic-bezier(0.785, 0.135, 0.15, 0.86);
207
+ --motion-ease-spring: cubic-bezier(0.34, 1.35, 0.5, 1);
208
+ --motion-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
209
+ --motion-ease-linear: linear;
210
+ }
211
+
212
+ /* ==========================================================================
213
+ Semantic tokens — dark mode
214
+ ========================================================================== */
215
+ /* Scoped only — a bare `.dark` in this group leaks Ember's dark tokens into
216
+ every other theme's dark mode. That is a shipped bug the registry test now
217
+ pins, and the generator emitted it here again. */
218
+ .dark[data-sable-theme="ember"],
219
+ [data-sable-theme="ember"].dark,
220
+ /* A dark island inside a light page: an inspector, a dark sidebar, a dark
221
+ hero. Without this arm, a nested .dark kept the light tokens. */
222
+ [data-sable-theme="ember"] .dark,
223
+ /* …and the reverse: a preset-scoped subtree inside a dark page follows the page
224
+ into dark mode. Add `.light` to the subtree to pin it light. */
225
+ .dark [data-sable-theme="ember"]:not(.light) {
226
+ --background: oklch(14.1% 0.018 70.5);
227
+ --foreground: oklch(100% 0 0);
228
+ --card: oklch(21% 0.013 55.5);
229
+ --card-foreground: oklch(100% 0 0);
230
+ --popover: oklch(24.5% 0.013 57);
231
+ --popover-foreground: oklch(100% 0 0);
232
+ --muted: oklch(27% 0.010 60); /* above --popover: a hover row or chip inside a menu/dialog must still read */
233
+ --muted-foreground: oklch(66% 0.006 67.7);
234
+ --border: oklch(32% 0.012 67.2); /* lifted with the fills: a hairline must still show on muted */
235
+ --border-strong: oklch(37% 0.010 61.1);
236
+ --input: oklch(33% 0.012 65);
237
+ --ring: oklch(65.2% 0.235 32.9);
238
+ --primary: oklch(65.2% 0.235 32.9);
239
+ --primary-foreground: oklch(14.1% 0.018 70.5);
240
+ --secondary: oklch(26% 0.012 67.2); /* a step ABOVE the card, so a secondary Button reads on a card and on the page */
241
+ --secondary-foreground: oklch(100% 0 0);
242
+ --accent: oklch(29% 0.014 60);
243
+ --accent-foreground: oklch(100% 0 0);
244
+ --destructive: oklch(62% 0.16 25);
245
+ --destructive-foreground: oklch(14.1% 0.018 70.5);
246
+ --success: oklch(72% 0.12 165);
247
+ --success-foreground: oklch(14.1% 0.018 70.5);
248
+ --tone-standard: oklch(70% 0.09 130);
249
+ --tone-collectible: oklch(70% 0.12 285);
250
+ --tone-edition: oklch(68% 0.14 309);
251
+ --tone-info: oklch(72% 0.11 250);
252
+ --tone-warning: oklch(78% 0.13 60);
253
+ --highlight: oklch(65.2% 0.235 32.9);
254
+ --tone-standard-foreground: oklch(14.1% 0.018 70.5);
255
+ --tone-collectible-foreground: oklch(14.1% 0.018 70.5);
256
+ --tone-edition-foreground: oklch(14.1% 0.018 70.5);
257
+ --tone-info-foreground: oklch(14.1% 0.018 70.5);
258
+ --tone-warning-foreground: oklch(14.1% 0.018 70.5);
259
+ --highlight-foreground: oklch(14.1% 0.018 70.5);
260
+ --overlay: oklch(14.1% 0.018 70.5);
261
+ --overlay-foreground: oklch(100% 0 0);
262
+ --sidebar: oklch(15.9% 0.016 65);
263
+ --sidebar-foreground: oklch(100% 0 0);
264
+ --sidebar-primary: oklch(65.2% 0.235 32.9);
265
+ --sidebar-primary-foreground: oklch(14.1% 0.018 70.5);
266
+ --sidebar-accent: oklch(22% 0.010 60);
267
+ --sidebar-accent-foreground: oklch(100% 0 0);
268
+ --sidebar-border: oklch(25.2% 0.012 67.2);
269
+ --sidebar-ring: oklch(65.2% 0.235 32.9);
270
+ }
@@ -0,0 +1,9 @@
1
+ import { T as ThemeManifest } from '../../_contract-CYScOdf5.js';
2
+
3
+ /**
4
+ * Ember — a Sable theme. Concrete token values live in
5
+ * `ember.css`; this manifest is the typed, machine-readable description.
6
+ */
7
+ declare const emberTheme: ThemeManifest;
8
+
9
+ export { emberTheme as default, emberTheme };
@@ -0,0 +1 @@
1
+ export { ember_default as default, emberTheme } from '../../chunk-L4IEIQQA.js';
@@ -0,0 +1,10 @@
1
+ export { A as AnyThemeId, D as DEFAULT_THEME_ID, S as SABLE_COLOR_STORAGE_KEY, a as SABLE_THEME_ATTRIBUTE, b as SABLE_THEME_STORAGE_KEY, c as SableColorMode, d as SableThemeContextValue, e as SableThemePreference, f as SableThemeProvider, g as SableThemeProviderProps, T as ThemeId, h as applySableColorMode, i as applySableTheme, j as buildThemeManifestById, k as defaultThemeId, l as featuredThemeManifests, m as getThemeManifest, n as isKnownThemeId, o as isThemeId, t as themeIds, p as themeManifestById, q as themeManifests, u as useSableTheme } from '../theme-provider-BWcizhAt.js';
2
+ export { atelierTheme } from './atelier/index.js';
3
+ export { baseTheme } from './base/index.js';
4
+ export { default as emberTheme } from './ember/index.js';
5
+ export { default as meridianTheme } from './meridian/index.js';
6
+ export { default as poppyTheme } from './poppy/index.js';
7
+ export { default as prismTheme } from './prism/index.js';
8
+ export { default as verdantTheme } from './verdant/index.js';
9
+ import 'react';
10
+ import '../_contract-CYScOdf5.js';
@@ -0,0 +1,8 @@
1
+ export { DEFAULT_THEME_ID, SABLE_COLOR_STORAGE_KEY, SABLE_THEME_ATTRIBUTE, SABLE_THEME_STORAGE_KEY, SableThemeProvider, applySableColorMode, applySableTheme, buildThemeManifestById, defaultThemeId, featuredThemeManifests, getThemeManifest, isKnownThemeId, isThemeId, themeIds, themeManifestById, themeManifests, useSableTheme } from '../chunk-L6Y46C62.js';
2
+ export { verdantTheme } from '../chunk-KO3NAEBF.js';
3
+ export { emberTheme } from '../chunk-L4IEIQQA.js';
4
+ export { baseTheme } from '../chunk-EP55KSYA.js';
5
+ export { poppyTheme } from '../chunk-ADLLDWLW.js';
6
+ export { meridianTheme } from '../chunk-K7RUHUGC.js';
7
+ export { atelierTheme } from '../chunk-YXBOYWBN.js';
8
+ export { prismTheme } from '../chunk-7MG4SHYX.js';
@@ -0,0 +1,9 @@
1
+ import { T as ThemeManifest } from '../../_contract-CYScOdf5.js';
2
+
3
+ /**
4
+ * Meridian — a Sable theme. Concrete token values live in
5
+ * `meridian.css`; this manifest is the typed, machine-readable description.
6
+ */
7
+ declare const meridianTheme: ThemeManifest;
8
+
9
+ export { meridianTheme as default, meridianTheme };
@@ -0,0 +1 @@
1
+ export { meridian_default as default, meridianTheme } from '../../chunk-K7RUHUGC.js';
@@ -0,0 +1,255 @@
1
+ /* ==========================================================================
2
+ Meridian — a Sable theme, developed from reference analysis.
3
+
4
+ Components must reference the SEMANTIC tokens (--background, --primary,
5
+ --tone-edition, …), never any palette ramp directly. See themes/_contract.ts.
6
+ ========================================================================== */
7
+
8
+ /* Scoped to [data-sable-theme="meridian"]; no bare :root fallback (base owns the default). */
9
+ [data-sable-theme="meridian"] {
10
+ /* Font stacks (theme-internal; host app provides the actual font files) */
11
+ --font-sans: "Instrument Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
12
+ --font-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace;
13
+
14
+ /*
15
+ * Region/page-inset foundation vars, explicitly declared per the Sable theme
16
+ * plugin's theme contract (self-containment: never rely on another theme's bare
17
+ * :root fallback in styles.css). Reference measured NO max-width cap anywhere
18
+ * (full-bleed default, uniform 48px side padding at 1440w -> 48/1440 = 3.33vw,
19
+ * fluid floor derived); region caps are Sable's standard ladder, labeled
20
+ * derived — "no capped section observed in reference." Full-bleed sections in
21
+ * builds use Region `bleed`, never max="full".
22
+ */
23
+ --page-inset: clamp(20px, 3.4vw, 48px);
24
+ --region-form: 480px;
25
+ --region-feed: 640px;
26
+ --region-content: 896px;
27
+ --region-wide: 1280px;
28
+ --region-full: 1536px;
29
+ --region-ultrawide: 1800px;
30
+
31
+ /* Elevation does not exist in this language: zero box-shadows observed
32
+ anywhere on the reference — separation is surface-mode swaps + 1px
33
+ hairlines. Flatten the whole shadow ladder. */
34
+ --theme-shadow-2xs: 0 0 #0000;
35
+ --theme-shadow-xs: 0 0 #0000;
36
+ --theme-shadow-sm: 0 0 #0000;
37
+ --theme-shadow-md: 0 0 #0000;
38
+ --theme-shadow-lg: 0 0 #0000;
39
+ --theme-shadow-xl: 0 0 #0000;
40
+ --theme-shadow-2xl: 0 0 #0000;
41
+
42
+ /* Theme foundation vars consumed by styles.css. */
43
+ --theme-radius-none: 0px;
44
+ --theme-radius-xs: 0px;
45
+ --theme-radius-sm: 0px;
46
+ --theme-radius-md: 0px;
47
+ --theme-radius-lg: 0px;
48
+ --theme-radius-xl: 0px;
49
+ --theme-radius-full: 9999px;
50
+ /* Buttons follow the preset's square geometry in both density registers. */
51
+ --theme-button-radius: 0px;
52
+ --button-radius: var(--theme-button-radius);
53
+
54
+ /* Type-scale foundation vars consumed by styles.css's paired text-* utilities. */
55
+ --type-display-4xl-weight: 400;
56
+ --type-display-4xl-leading: 0.85;
57
+ --type-display-4xl-tracking: -0.033em;
58
+ --type-display-3xl-size: 5.7143rem /* 80px at the 14px desktop root */;
59
+ --type-display-3xl-weight: 400;
60
+ --type-display-3xl-leading: 1;
61
+ --type-display-3xl-tracking: -0.05em;
62
+ --type-display-2xl-size: 4.5714rem /* 64px at the 14px desktop root */;
63
+ --type-display-2xl-weight: 400;
64
+ --type-display-2xl-leading: 1;
65
+ --type-display-2xl-tracking: -0.045em;
66
+ --type-display-xl-size: 3.7143rem /* 52px at the 14px desktop root */;
67
+ --type-display-xl-weight: 400;
68
+ --type-display-xl-leading: 1.05;
69
+ --type-display-xl-tracking: -0.04em;
70
+ --type-display-lg-size: 2.8571rem /* 40px at the 14px desktop root */;
71
+ --type-display-lg-weight: 400;
72
+ --type-display-lg-leading: 1.1;
73
+ --type-display-lg-tracking: -0.02em;
74
+ --type-heading-weight: 400;
75
+ --type-heading-1-size: 2.2857rem /* 32px at the 14px desktop root */;
76
+ --type-heading-1-leading: 1.1;
77
+ --type-heading-1-tracking: -0.015em;
78
+ --type-heading-2-size: 1.7143rem /* 24px at the 14px desktop root */;
79
+ --type-heading-2-leading: 1.1;
80
+ --type-heading-2-tracking: -0.008em;
81
+ --type-heading-3-size: 1.4286rem /* 20px at the 14px desktop root */;
82
+ --type-heading-3-leading: 1.2;
83
+ --type-heading-3-tracking: -0.01em;
84
+ --type-heading-4-size: 1.2857rem /* 18px at the 14px desktop root */;
85
+ --type-heading-4-leading: 1.25;
86
+ --type-heading-4-tracking: -0.015em;
87
+ --type-title-weight: 400;
88
+ --type-title-leading: 1.2;
89
+ --type-title-tracking: -0.02em;
90
+ --type-title-sm-tracking: -0.033em;
91
+
92
+ /* Overline/eyebrow foundation vars consumed by styles.css's text-overline utility. */
93
+ --type-overline-size: 0.9286rem /* 13px at the 14px desktop root */;
94
+ --type-overline-weight: 400;
95
+ --type-overline-leading: 1.2;
96
+ --type-overline-tracking: 0.04em;
97
+ --type-overline-transform: uppercase;
98
+
99
+ /* ----------------------------------------------------------------------
100
+ Palette ramps. Theme-internal — never used directly by components.
101
+ ---------------------------------------------------------------------- */
102
+ /* meridian-ember */
103
+ --meridian-ember-50: oklch(97% 0.02 30);
104
+ --meridian-ember-100: oklch(93% 0.04 30);
105
+ --meridian-ember-200: oklch(87% 0.07 30);
106
+ --meridian-ember-300: oklch(79% 0.11 30);
107
+ --meridian-ember-400: oklch(70% 0.16 30);
108
+ --meridian-ember-500: oklch(63% 0.20 30);
109
+ --meridian-ember-600: oklch(56% 0.21 30);
110
+ --meridian-ember-700: oklch(48% 0.19 30);
111
+ --meridian-ember-800: oklch(40% 0.15 30);
112
+ --meridian-ember-900: oklch(30% 0.10 30);
113
+ --meridian-ember-950: oklch(22% 0.06 30);
114
+
115
+ /* ----------------------------------------------------------------------
116
+ Semantic tokens — light mode
117
+ ---------------------------------------------------------------------- */
118
+ --background: oklch(94.6% 0.0083 91.48);
119
+ --foreground: oklch(26.25% 0.0162 102.18);
120
+ --card: oklch(94.6% 0.0083 91.48);
121
+ --card-foreground: oklch(26.25% 0.0162 102.18);
122
+ --popover: oklch(94.6% 0.0083 91.48);
123
+ --popover-foreground: oklch(26.25% 0.0162 102.18);
124
+ --muted: oklch(91.24% 0.0138 92.99);
125
+ --muted-foreground: oklch(49.93% 0.0412 93.54);
126
+ --border: oklch(87.54% 0.0194 93.69);
127
+ --border-strong: oklch(81.94% 0.0252 94.12);
128
+ --input: oklch(87.54% 0.0194 93.69);
129
+ --ring: oklch(62% 0.2063 32.56);
130
+ --primary: oklch(26.25% 0.0162 102.18);
131
+ --primary-foreground: oklch(94.6% 0.0083 91.48);
132
+ --secondary: oklch(87.54% 0.0194 93.69);
133
+ --secondary-foreground: oklch(26.25% 0.0162 102.18);
134
+ /* One ember for selection and highlight, white ink, both modes. The observed
135
+ orange (65% L) only passed WCAG 2 with DARK ink (4.84:1, but APCA Lc 40),
136
+ and white on it failed WCAG 2 (3.43:1) while reading better (Lc 65) — the
137
+ known WCAG 2 blind spot on saturated orange. A slightly deeper ember lets
138
+ white pass both: ~4.6:1, Lc ~75. */
139
+ --accent: oklch(57.5% 0.2 31.5);
140
+ --accent-foreground: oklch(99% 0.004 91.5);
141
+ --destructive: oklch(48% 0.2 25);
142
+ --destructive-foreground: oklch(94.6% 0.0083 91.48);
143
+ --success: oklch(43% 0.1 165);
144
+ --success-foreground: oklch(94.6% 0.0083 91.48);
145
+ --tone-standard: oklch(40% 0.07 130);
146
+ --tone-collectible: oklch(46% 0.14 285);
147
+ --tone-edition: oklch(45% 0.15 309);
148
+ --tone-info: oklch(48% 0.13 250);
149
+ --tone-warning: oklch(50% 0.12 52);
150
+ --highlight: oklch(57.5% 0.2 31.5);
151
+ /* Ember as TEXT (eyebrow numbers, arrows). The fill ember carries white ink
152
+ but is too light to be read as ink itself (4.1:1 on the sand); this is the
153
+ same hue, deep enough for 5.2:1. A theme-local token: Meridian's art
154
+ direction is the only one that sets its accent as type. */
155
+ --meridian-ember-ink: oklch(52% 0.19 31.5);
156
+ --tone-standard-foreground: oklch(94.6% 0.0083 91.48);
157
+ --tone-collectible-foreground: oklch(94.6% 0.0083 91.48);
158
+ --tone-edition-foreground: oklch(94.6% 0.0083 91.48);
159
+ --tone-info-foreground: oklch(94.6% 0.0083 91.48);
160
+ --tone-warning-foreground: oklch(94.6% 0.0083 91.48);
161
+ --highlight-foreground: oklch(99% 0.004 91.5);
162
+ --overlay: oklch(22.46% 0.0094 107.13);
163
+ --overlay-foreground: oklch(94.3% 0.0042 91.45);
164
+ --sidebar: oklch(22.46% 0.0094 107.13);
165
+ --sidebar-foreground: oklch(94.3% 0.0042 91.45);
166
+ --sidebar-primary: oklch(94.3% 0.0042 91.45);
167
+ --sidebar-primary-foreground: oklch(22.46% 0.0094 107.13);
168
+ --sidebar-accent: oklch(27.1% 0.0143 101.41);
169
+ --sidebar-accent-foreground: oklch(94.3% 0.0042 91.45);
170
+ --sidebar-border: oklch(27.1% 0.0143 101.41);
171
+ --sidebar-ring: oklch(65.11% 0.2063 32.56);
172
+
173
+ /* ----------------------------------------------------------------------
174
+ Motion tokens (mode-independent)
175
+ ---------------------------------------------------------------------- */
176
+ --motion-scale: 1;
177
+ --motion-duration-instant: calc(90ms * var(--motion-scale));
178
+ --motion-duration-fast: calc(160ms * var(--motion-scale));
179
+ --motion-duration-base: calc(240ms * var(--motion-scale));
180
+ --motion-duration-slow: calc(350ms * var(--motion-scale));
181
+ --motion-duration-slower: calc(600ms * var(--motion-scale));
182
+ --motion-duration-enter: var(--motion-duration-base);
183
+ --motion-duration-exit: var(--motion-duration-fast);
184
+ --motion-ease-standard: cubic-bezier(0.65, 0, 0.35, 1);
185
+ --motion-ease-decelerate: cubic-bezier(0, 0.5, 0.25, 1);
186
+ --motion-ease-emphasized: cubic-bezier(0.215, 0.61, 0.355, 1);
187
+ --motion-ease-spring: cubic-bezier(0, 0.5, 0.25, 1);
188
+ --motion-ease-bounce: cubic-bezier(0.34, 1.15, 0.64, 1);
189
+ --motion-ease-linear: linear;
190
+ }
191
+
192
+ /* ==========================================================================
193
+ Semantic tokens — dark mode
194
+ ========================================================================== */
195
+ .dark[data-sable-theme="meridian"],
196
+ [data-sable-theme="meridian"].dark,
197
+ /* A dark island inside a light page: an inspector, a dark sidebar, a dark
198
+ hero. Without this arm, a nested .dark kept the light tokens. */
199
+ [data-sable-theme="meridian"] .dark,
200
+ /* …and the reverse: a preset-scoped subtree inside a dark page follows the page
201
+ into dark mode. Add `.light` to the subtree to pin it light. */
202
+ .dark [data-sable-theme="meridian"]:not(.light) {
203
+ --background: oklch(22.46% 0.0094 107.13);
204
+ --foreground: oklch(94.3% 0.0042 91.45);
205
+ --card: oklch(27% 0.0109 107.15);
206
+ --card-foreground: oklch(94.3% 0.0042 91.45);
207
+ --popover: oklch(30% 0.0109 107.15);
208
+ --popover-foreground: oklch(94.3% 0.0042 91.45);
209
+ --muted: oklch(32% 0.0143 101.41);
210
+ --muted-foreground: oklch(70% 0 0);
211
+ /*
212
+ * `border`/`input` were byte-identical to `--muted`, so a bordered control
213
+ * sitting in a muted well had literally no border (1.00:1) and read at
214
+ * 1.05:1 on `card` and `popover`. They now take the `border-strong` step —
215
+ * the theme's own next value up, so the warm neutral band is unchanged and
216
+ * only the edge separates. Caught by the non-text contrast gate.
217
+ */
218
+ --border: oklch(34.69% 0.0186 98.75);
219
+ --border-strong: oklch(34.69% 0.0186 98.75);
220
+ --input: oklch(34.69% 0.0186 98.75);
221
+ --ring: oklch(65.11% 0.2063 32.56);
222
+ --primary: oklch(94.3% 0.0042 91.45);
223
+ --primary-foreground: oklch(22.46% 0.0094 107.13);
224
+ --secondary: oklch(31.54% 0.0139 101.29);
225
+ --secondary-foreground: oklch(94.3% 0.0042 91.45);
226
+ --accent: oklch(57.5% 0.2 31.5);
227
+ --accent-foreground: oklch(99% 0.004 91.5);
228
+ --destructive: oklch(66% 0.21 25);
229
+ --destructive-foreground: oklch(22.46% 0.0094 107.13);
230
+ --success: oklch(72% 0.12 165);
231
+ --success-foreground: oklch(22.46% 0.0094 107.13);
232
+ --tone-standard: oklch(70% 0.09 130);
233
+ --tone-collectible: oklch(70% 0.12 285);
234
+ --tone-edition: oklch(68% 0.14 309);
235
+ --tone-info: oklch(72% 0.11 250);
236
+ --tone-warning: oklch(78% 0.13 60);
237
+ --highlight: oklch(57.5% 0.2 31.5);
238
+ --meridian-ember-ink: oklch(72% 0.17 33); /* 6.4:1 on the dark ground */
239
+ --tone-standard-foreground: oklch(22.46% 0.0094 107.13);
240
+ --tone-collectible-foreground: oklch(22.46% 0.0094 107.13);
241
+ --tone-edition-foreground: oklch(22.46% 0.0094 107.13);
242
+ --tone-info-foreground: oklch(22.46% 0.0094 107.13);
243
+ --tone-warning-foreground: oklch(22.46% 0.0094 107.13);
244
+ --highlight-foreground: oklch(99% 0.004 91.5);
245
+ --overlay: oklch(22.46% 0.0094 107.13);
246
+ --overlay-foreground: oklch(94.3% 0.0042 91.45);
247
+ --sidebar: oklch(22.46% 0.0094 107.13);
248
+ --sidebar-foreground: oklch(94.3% 0.0042 91.45);
249
+ --sidebar-primary: oklch(94.3% 0.0042 91.45);
250
+ --sidebar-primary-foreground: oklch(22.46% 0.0094 107.13);
251
+ --sidebar-accent: oklch(27.1% 0.0143 101.41);
252
+ --sidebar-accent-foreground: oklch(94.3% 0.0042 91.45);
253
+ --sidebar-border: oklch(27.1% 0.0143 101.41);
254
+ --sidebar-ring: oklch(65.11% 0.2063 32.56);
255
+ }
@@ -0,0 +1,6 @@
1
+ import { T as ThemeManifest } from '../../_contract-CYScOdf5.js';
2
+
3
+ /** Original Sable preset; no third-party artwork or reference-site code. */
4
+ declare const poppyTheme: ThemeManifest;
5
+
6
+ export { poppyTheme as default, poppyTheme };
@@ -0,0 +1 @@
1
+ export { poppy_default as default, poppyTheme } from '../../chunk-ADLLDWLW.js';