tempest-react-sdk 0.58.0 → 0.60.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 (93) hide show
  1. package/README.md +35 -3
  2. package/bin/lib/css/findings.mjs +1 -0
  3. package/bin/lib/css/semantic.mjs +70 -6
  4. package/bin/lib/css/semantic.test.mjs +52 -1
  5. package/dist/components/Alert/Alert.module.cjs.map +1 -1
  6. package/dist/components/Alert/Alert.module.js.map +1 -1
  7. package/dist/components/Badge/Badge.module.cjs.map +1 -1
  8. package/dist/components/Badge/Badge.module.js.map +1 -1
  9. package/dist/components/BarList/BarList.module.cjs.map +1 -1
  10. package/dist/components/BarList/BarList.module.js.map +1 -1
  11. package/dist/components/BottomSheet/BottomSheet.module.cjs.map +1 -1
  12. package/dist/components/BottomSheet/BottomSheet.module.js.map +1 -1
  13. package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
  14. package/dist/components/DataTable/DataTable.module.js.map +1 -1
  15. package/dist/components/Dropzone/Dropzone.module.cjs.map +1 -1
  16. package/dist/components/Dropzone/Dropzone.module.js.map +1 -1
  17. package/dist/components/ErrorText/ErrorText.module.cjs.map +1 -1
  18. package/dist/components/ErrorText/ErrorText.module.js.map +1 -1
  19. package/dist/components/Markdown/Markdown.module.cjs.map +1 -1
  20. package/dist/components/Markdown/Markdown.module.js.map +1 -1
  21. package/dist/components/PasswordInput/PasswordInput.module.cjs.map +1 -1
  22. package/dist/components/PasswordInput/PasswordInput.module.js.map +1 -1
  23. package/dist/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
  24. package/dist/components/SegmentedControl/SegmentedControl.module.js.map +1 -1
  25. package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
  26. package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
  27. package/dist/components/StepperInput/StepperInput.module.cjs.map +1 -1
  28. package/dist/components/StepperInput/StepperInput.module.js.map +1 -1
  29. package/dist/components/Tag/Tag.module.cjs.map +1 -1
  30. package/dist/components/Tag/Tag.module.js.map +1 -1
  31. package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
  32. package/dist/components/Timeline/Timeline.module.js.map +1 -1
  33. package/dist/components/Toggle/Toggle.module.cjs.map +1 -1
  34. package/dist/components/Toggle/Toggle.module.js.map +1 -1
  35. package/dist/components/ToggleGroup/ToggleGroup.module.cjs.map +1 -1
  36. package/dist/components/ToggleGroup/ToggleGroup.module.js.map +1 -1
  37. package/dist/http/describe-api-error.cjs +1 -1
  38. package/dist/http/describe-api-error.cjs.map +1 -1
  39. package/dist/http/describe-api-error.js +12 -8
  40. package/dist/http/describe-api-error.js.map +1 -1
  41. package/dist/http/errors.cjs +1 -1
  42. package/dist/http/errors.cjs.map +1 -1
  43. package/dist/http/errors.js +21 -16
  44. package/dist/http/errors.js.map +1 -1
  45. package/dist/styles/Alert.css +1 -1
  46. package/dist/styles/Badge.css +1 -1
  47. package/dist/styles/BarList.css +3 -3
  48. package/dist/styles/BottomSheet.css +1 -1
  49. package/dist/styles/DataTable.css +1 -1
  50. package/dist/styles/Dropzone.css +1 -1
  51. package/dist/styles/ErrorText.css +1 -1
  52. package/dist/styles/Markdown.css +1 -1
  53. package/dist/styles/PasswordInput.css +1 -1
  54. package/dist/styles/SegmentedControl.css +1 -1
  55. package/dist/styles/Sidebar.css +2 -2
  56. package/dist/styles/StepperInput.css +1 -1
  57. package/dist/styles/Tag.css +1 -1
  58. package/dist/styles/Timeline.css +1 -1
  59. package/dist/styles/Toggle.css +1 -1
  60. package/dist/styles/ToggleGroup.css +1 -1
  61. package/dist/styles/advanced.css +2 -2
  62. package/dist/styles/auto.css +4 -0
  63. package/dist/styles/base.css +33 -0
  64. package/dist/styles/core.css +4 -2
  65. package/dist/styles/data.css +6 -6
  66. package/dist/styles/feedback.css +3 -3
  67. package/dist/styles/forms.css +3 -3
  68. package/dist/styles/manifest.json +496 -0
  69. package/dist/styles/navigation.css +3 -3
  70. package/dist/styles/overlay.css +1 -1
  71. package/dist/styles/scoped.css +131 -0
  72. package/dist/styles/tokens.css +10 -0
  73. package/dist/styles/utility.css +1 -1
  74. package/dist/styles.css +1 -1
  75. package/dist/tempest-react-sdk.cjs +1 -1
  76. package/dist/tempest-react-sdk.d.ts +81 -7
  77. package/dist/tempest-react-sdk.js +347 -346
  78. package/dist/theme/create-theme.cjs +3 -3
  79. package/dist/theme/create-theme.cjs.map +1 -1
  80. package/dist/theme/create-theme.js +15 -14
  81. package/dist/theme/create-theme.js.map +1 -1
  82. package/dist/utils/dev-mode.cjs +1 -1
  83. package/dist/utils/dev-mode.cjs.map +1 -1
  84. package/dist/utils/dev-mode.js +7 -2
  85. package/dist/utils/dev-mode.js.map +1 -1
  86. package/dist/vite/tempest-styles.cjs +5 -0
  87. package/dist/vite/tempest-styles.cjs.map +1 -0
  88. package/dist/vite/tempest-styles.js +103 -0
  89. package/dist/vite/tempest-styles.js.map +1 -0
  90. package/dist/vite.cjs +1 -1
  91. package/dist/vite.d.ts +82 -0
  92. package/dist/vite.js +2 -1
  93. package/package.json +3 -2
package/README.md CHANGED
@@ -201,18 +201,40 @@ import "tempest-react-sdk/styles.css";
201
201
 
202
202
  This injects the design tokens (`--tempest-primary`, `--tempest-radius-md`, ...), a minimal CSS reset, and the per-component CSS Modules. Tokens live on `:root` and on `[data-tempest-theme="dark"]`, so the app can override them globally or per subtree (see [Theming](#theming-reference)).
203
203
 
204
+ The reset claims the document surface too — `body { margin: 0 }` plus the theme's background and text colour, and a zero-specificity `height: 100%` chain down to `#root`. Without it an `AppShell` app opens with a spurious scrollbar and an unpainted frame around the shell in dark mode. All four are one ordinary declaration away from being overridden; see [The document surface](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/styles/#the-document-surface).
205
+
204
206
  The styles ship hashed under the `tempest_` namespace — they do **not** collide with Tailwind, Stitches, Linaria, or app-level CSS Modules.
205
207
 
206
208
  **Importing less.** The JavaScript you import is tree-shaken; the CSS is not, so `styles.css` carries all ~150 components whether you mount thirteen or all of them. Pay for what you use by taking the foundation plus the sheets you need:
207
209
 
208
210
  ```ts
209
- import "tempest-react-sdk/styles/core.css"; // reset + tokensalways required
211
+ import "tempest-react-sdk/styles/core.css"; // tokens + global reset see below
210
212
  import "tempest-react-sdk/styles/Button.css";
211
213
  import "tempest-react-sdk/styles/forms.css"; // or a whole family
212
214
  ```
213
215
 
214
216
  Measured in a real Vite app mounting twelve components: **236.71 kB raw / 35.38 kB gzip** with `styles.css`, **38.94 kB / 7.70 kB** with `core.css` plus those twelve — 78% less. See [Styles](https://mauriciobenjamin700.github.io/tempest-react-sdk/styles/) for the full list of groups.
215
217
 
218
+ **Letting the build keep that list.** `tempestStyles()` reads the imports your source already writes and resolves `styles/auto.css` to exactly the sheets your app can reach — including the ones it reaches _transitively_, which is where a hand-kept list goes wrong (`<DataTable>` alone needs six, `<AIChat>` seven):
219
+
220
+ ```ts
221
+ // vite.config.ts
222
+ import { tempestStyles } from "tempest-react-sdk/vite";
223
+ export default defineConfig({ plugins: [react(), tempestStyles()] });
224
+
225
+ // src/main.tsx — one line, forever
226
+ import "tempest-react-sdk/styles/auto.css";
227
+ ```
228
+
229
+ **If your app owns its own layout,** do not reach for `core.css`: 44 of its 46 selectors dress markup you own (`html`, `body`, `#root`, `button`, `table`, `:where(ul, ol)[class]`). Dropping it is not the fix either — the components are written _against_ that reset, so without it they lose their box model, not their polish. Take the foundation in two pieces instead, which is also what `tempestStyles()` emits by default:
230
+
231
+ ```ts
232
+ import "tempest-react-sdk/styles/tokens.css"; // the 373 --tempest-* tokens
233
+ import "tempest-react-sdk/styles/scoped.css"; // the reset, confined to :where([class*="tempest_"])
234
+ ```
235
+
236
+ **3.03 kB brotli** against `core.css`'s 3.23 kB — near enough the same bytes, which is the point: what you drop is not weight, it is the SDK reaching outside its own components.
237
+
216
238
  **Rebranding.** The `--tempest-*` tokens are the only theming API, and `createTheme` writes them for you — `primary` alone yields the ten-step scale for **both** color schemes (dark inverts the ramp), plus the status families, the radius scale and the focus ring:
217
239
 
218
240
  ```ts
@@ -271,7 +293,7 @@ Every module is re-exported from the package root — `import { Button, useDebou
271
293
  | `perf` | `createInferenceProfiler`, `readDeviceProfile`, `cachedResponseBytes`, `formatDurationMs`, types: `InferenceProfiler`, `InferenceReport`, `InferenceReportOptions`, `DeviceProfile`, `ProfiledModel`, `ProfiledModelSize` — custo de inferência on-device: cronômetro por etapa, perfil do dispositivo (cores/RAM/heap) e tamanho dos modelos em Cache Storage |
272
294
  | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
273
295
  | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
274
- | `utils` | `cn`, format BR (`formatCurrency`, `formatDate`, `formatDateForInput`, `formatDateTime`, `formatPhone`, `formatCPF`, `formatPercent`), `storage`, strings (`slugify`, `truncate`, `capitalize`, `camelCase`, `kebabCase`, `pluralize`), numbers (`clamp`, `formatBytes`, `formatCompactNumber`, `percentOf`), arrays (`groupBy`, `uniqueBy`, `chunk`, `range`), objects (`pick`, `omit`, `deepMerge`, `isEmpty`), guards (`isDefined`, `isString`, `isNumber`, `isPlainObject`, `assertNever`), functions (`debounce`, `throttle`, `once`, `memoizeOne`), promises (`sleep`, `withTimeout`), `randomId`, `relativeTime`, `writeXlsx` (generic single-sheet OOXML `.xlsx` writer → `Uint8Array`), CSV (`toCsv`, `downloadCsv` — RFC 4180 escaping + BOM) |
296
+ | `utils` | `cn`, format BR (`formatCurrency`, `formatDate`, `formatDateForInput`, `formatDateTime`, `formatPhone`, `formatCPF`, `formatPercent`), `storage`, strings (`slugify`, `truncate`, `capitalize`, `camelCase`, `kebabCase`, `pluralize`), numbers (`clamp`, `formatBytes`, `formatCompactNumber`, `percentOf`), arrays (`groupBy`, `uniqueBy`, `chunk`, `range`), objects (`pick`, `omit`, `deepMerge`, `isEmpty`), guards (`isDefined`, `isString`, `isNumber`, `isPlainObject`, `assertNever`), functions (`debounce`, `throttle`, `once`, `memoizeOne`), promises (`sleep`, `withTimeout`), `randomId`, `relativeTime`, `writeXlsx` (generic single-sheet OOXML `.xlsx` writer → `Uint8Array`), CSV (`toCsv`, `downloadCsv` — RFC 4180 escaping + BOM), `setDevBuild` (tell the SDK your build is dev — required under Vite) |
275
297
  | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
276
298
  | Module | Exports |
277
299
  | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -309,7 +331,7 @@ Every module is re-exported from the package root — `import { Button, useDebou
309
331
  | `perf` | `createInferenceProfiler`, `readDeviceProfile`, `cachedResponseBytes`, `formatDurationMs`, types: `InferenceProfiler`, `InferenceReport`, `InferenceReportOptions`, `DeviceProfile`, `ProfiledModel`, `ProfiledModelSize` — custo de inferência on-device: cronômetro por etapa, perfil do dispositivo (cores/RAM/heap) e tamanho dos modelos em Cache Storage |
310
332
  | `feature-flags` | `FeatureFlagsProvider`, `useFeatureFlag`, `useFlagValue`, `createInMemoryFlags`, `createGrowthBookFeatureFlagsAdapter`, `createLaunchDarklyFeatureFlagsAdapter`, types: `FeatureFlagsAdapter`, `FlagValue`, `GrowthBookLike`, `LDClientLike` |
311
333
  | `share` | `share`, `isShareSupported`, `shareOrDownloadBlob` (Web Share file → download fallback), types: `SharePayload`, `ShareResult`, `ShareOrDownloadOptions` |
312
- | `utils` | `cn`, format BR (`formatCurrency`, `formatDate`, `formatDateForInput`, `formatDateTime`, `formatPhone`, `formatCPF`, `formatPercent`), `storage`, strings (`slugify`, `truncate`, `capitalize`, `camelCase`, `kebabCase`, `pluralize`), numbers (`clamp`, `formatBytes`, `formatCompactNumber`, `percentOf`), arrays (`groupBy`, `uniqueBy`, `chunk`, `range`), objects (`pick`, `omit`, `deepMerge`, `isEmpty`), guards (`isDefined`, `isString`, `isNumber`, `isPlainObject`, `assertNever`), functions (`debounce`, `throttle`, `once`, `memoizeOne`), promises (`sleep`, `withTimeout`), `randomId`, `relativeTime`, `writeXlsx` (generic single-sheet OOXML `.xlsx` writer → `Uint8Array`), CSV (`toCsv`, `downloadCsv` — RFC 4180 escaping + BOM) |
334
+ | `utils` | `cn`, format BR (`formatCurrency`, `formatDate`, `formatDateForInput`, `formatDateTime`, `formatPhone`, `formatCPF`, `formatPercent`), `storage`, strings (`slugify`, `truncate`, `capitalize`, `camelCase`, `kebabCase`, `pluralize`), numbers (`clamp`, `formatBytes`, `formatCompactNumber`, `percentOf`), arrays (`groupBy`, `uniqueBy`, `chunk`, `range`), objects (`pick`, `omit`, `deepMerge`, `isEmpty`), guards (`isDefined`, `isString`, `isNumber`, `isPlainObject`, `assertNever`), functions (`debounce`, `throttle`, `once`, `memoizeOne`), promises (`sleep`, `withTimeout`), `randomId`, `relativeTime`, `writeXlsx` (generic single-sheet OOXML `.xlsx` writer → `Uint8Array`), CSV (`toCsv`, `downloadCsv` — RFC 4180 escaping + BOM), `setDevBuild` (tell the SDK your build is dev — required under Vite) |
313
335
  | generic components | display (`CopyButton`, `RelativeTime`, `Money`, `TruncateText`, `VisuallyHidden`), headless (`Portal`, `ClickOutside`, `ConditionalWrapper`, `For`, `ErrorText`), media/content (`Image`, `DataList`, `DescriptionList`) |
314
336
 
315
337
  Full per-module docs are published as a bilingual MkDocs site on GitHub Pages — **[Português (BR)](https://mauriciobenjamin700.github.io/tempest-react-sdk/)** / **[English (US)](https://mauriciobenjamin700.github.io/tempest-react-sdk/en/)** (one page per module + draw.io diagrams in [`docs/diagrams/`](./docs/diagrams)). The source markdown lives in [`docs/`](./docs) (PT-BR base files + `.en.md` translations).
@@ -632,6 +654,16 @@ export async function getUser(id: string) {
632
654
 
633
655
  On validation failure `parseResponse` throws an `Error` whose `message` includes the request label and the zod issues — exactly the diagnostic you want during a wire-protocol drift.
634
656
 
657
+ **Under Vite that report needs one line to turn on.** The SDK detects a dev build by reading `process.env.NODE_ENV`, which webpack, Rspack and Parcel substitute while building your app; Vite substitutes neither half, and a browser bundle has no `process` at all, so the read fails and the SDK stays on the safe side — the generic sentence, `vite dev` included. Say so once at bootstrap:
658
+
659
+ ```ts
660
+ import { setDevBuild } from "tempest-react-sdk";
661
+
662
+ setDevBuild(import.meta.env.DEV);
663
+ ```
664
+
665
+ The SDK cannot read `import.meta.env.DEV` for you: Vite would replace it while building _this package_ and the published artifact would carry the constant. The same line un-mutes every other development-only diagnostic in the SDK.
666
+
635
667
  ### Upload with progress recipe
636
668
 
637
669
  `fetch` cannot report upload progress in browsers. `uploadWithProgress` falls back to `XMLHttpRequest` internally while keeping the same `ApiError` contract:
@@ -24,6 +24,7 @@ export const SEVERITY = {
24
24
  "unknown-at-rule": "warn",
25
25
  "unknown-property": "warn",
26
26
  "unknown-token": "warn",
27
+ "token-family-typo": "warn",
27
28
  "undefined-var": "warn",
28
29
  "duplicate-declaration": "warn",
29
30
  "overridden-declaration": "warn",
@@ -219,14 +219,64 @@ function reportDuplicateRule({ block, previous, at }) {
219
219
  );
220
220
  }
221
221
 
222
+ /**
223
+ * The family a token name belongs to: everything up to the last segment.
224
+ *
225
+ * `--tempest-primary-soft` → `--tempest-primary`. Returns `null` when nothing is
226
+ * left after the prefix, which is what keeps two-segment names like
227
+ * `--tempest-tx` out of the family check: their family is the bare prefix, and
228
+ * that matches every token there is.
229
+ *
230
+ * @param {string} name - A custom property name.
231
+ * @returns {string | null} The family, or null when the name has no family.
232
+ */
233
+ function familyOf(name) {
234
+ const family = name.slice(0, name.lastIndexOf("-"));
235
+ return family === "--tempest" || !family.startsWith("--tempest-") ? null : family;
236
+ }
237
+
238
+ /** Per-name-set cache, so the families are derived once per run and not per declaration. */
239
+ const FAMILY_CACHE = new WeakMap();
240
+
241
+ /**
242
+ * The families the SDK's own tokens form, derived once per token set.
243
+ *
244
+ * @param {Set<string>} names - Declared SDK token names.
245
+ * @returns {Set<string>} Every family with at least one declared member.
246
+ */
247
+ function familiesOf(names) {
248
+ const cached = FAMILY_CACHE.get(names);
249
+ if (cached) return cached;
250
+ const families = new Set();
251
+ for (const name of names) {
252
+ const family = familyOf(name);
253
+ if (family) families.add(family);
254
+ }
255
+ FAMILY_CACHE.set(names, families);
256
+ return families;
257
+ }
258
+
222
259
  /**
223
260
  * Property-level and value-level checks for a single declaration.
224
261
  *
225
- * A `var()` **with a fallback** is never reported. That is the SDK's own knob
226
- * idiom — `var(--tempest-card-padding, var(--tempest-space-5))` is a component
227
- * offering an override nobody is required to set — so "this name is not a token"
228
- * would fire on the pattern the docs teach. Without a fallback the same
229
- * declaration resolves to nothing, which is a real defect and is reported.
262
+ * A `var()` **with a fallback** is *almost* never reported. That is the SDK's own
263
+ * knob idiom — `var(--tempest-card-padding, var(--tempest-space-5))` is a
264
+ * component offering an override nobody is required to set — so "this name is
265
+ * not a token" would fire on the pattern the docs teach. Without a fallback the
266
+ * same declaration resolves to nothing, which is a real defect and is reported.
267
+ *
268
+ * The exception is the one case where a knob and a typo stop being
269
+ * indistinguishable: **the family already exists.** `--tempest-primary-contrast`
270
+ * is undeclared, but `--tempest-primary-*` has twelve declared siblings, so the
271
+ * name reads as a member of a real family that is missing — a misspelling.
272
+ * `--tempest-card-padding` has no declared `--tempest-card-*` sibling at all, so
273
+ * it reads as what it is, a knob this component invented.
274
+ *
275
+ * Measured over the SDK's own `src/` when the rule was written: five hits, five
276
+ * real defects, no false positive. Two weaker signals were measured and dropped
277
+ * — matching on the *last* segment instead (`--tempest-font-size-sm` looks like
278
+ * `--tempest-text-sm`) fired on sixteen names of which three were real, because
279
+ * every layout knob in `utilities.css` ends in `-gap` or `-width`.
230
280
  */
231
281
  function checkDecl({ decl, prop, tokens, definedVars, at }) {
232
282
  if (isCheckableProperty(prop) && !KNOWN_PROPERTIES.has(prop)) {
@@ -240,8 +290,22 @@ function checkDecl({ decl, prop, tokens, definedVars, at }) {
240
290
  }
241
291
  }
242
292
 
293
+ const families = familiesOf(tokens.names);
243
294
  for (const ref of varReferences(decl.value)) {
244
- if (ref.hasFallback || definedVars.has(ref.name)) continue;
295
+ if (definedVars.has(ref.name) || tokens.names.has(ref.name)) continue;
296
+ if (ref.hasFallback) {
297
+ if (!ref.name.startsWith("--tempest-") || tokens.names.size === 0) continue;
298
+ const family = familyOf(ref.name);
299
+ if (!family || !families.has(family)) continue;
300
+ const suggestion = nearest(ref.name, tokens.names, 3);
301
+ at(
302
+ "token-family-typo",
303
+ decl.line,
304
+ `\`${ref.name}\` is not a token, but \`${family}-*\` is a real family — the fallback ` +
305
+ `hides the misspelling instead of failing${suggestion ? `. Did you mean \`${suggestion}\`?` : ""}`,
306
+ );
307
+ continue;
308
+ }
245
309
  if (ref.name.startsWith("--tempest-")) {
246
310
  if (tokens.names.size === 0) continue;
247
311
  const suggestion = nearest(ref.name, tokens.names, 3);
@@ -4,7 +4,13 @@ import { parseCss } from "./parse.mjs";
4
4
  import { analyzeParsed, declSignature, definedCustomProperties } from "./semantic.mjs";
5
5
 
6
6
  const TOKENS = {
7
- names: new Set(["--tempest-space-2", "--tempest-primary", "--tempest-text"]),
7
+ names: new Set([
8
+ "--tempest-space-2",
9
+ "--tempest-primary",
10
+ "--tempest-text",
11
+ "--tempest-primary-soft",
12
+ "--tempest-primary-hover",
13
+ ]),
8
14
  byValue: new Map([
9
15
  ["8px", ["--tempest-space-2"]],
10
16
  ["#0d6efd", ["--tempest-primary"]],
@@ -152,6 +158,51 @@ describe("analyzeParsed — custom properties", () => {
152
158
  expect(codes(".a { width: var(--row-height, 40px); }")).toEqual([]);
153
159
  });
154
160
 
161
+ it("flags a fallback whose name belongs to a family the SDK actually declares", () => {
162
+ // The one case where a knob and a typo stop being indistinguishable.
163
+ // `--tempest-primary-*` has declared siblings, so an undeclared member of
164
+ // it reads as a misspelling rather than as a hook an app may set.
165
+ const found = first(
166
+ ".a { color: var(--tempest-primary-contrast, #fff); }",
167
+ "token-family-typo",
168
+ );
169
+ expect(found.severity).toBe("warn");
170
+ expect(found.message).toContain("--tempest-primary-*");
171
+ });
172
+
173
+ it("adds a suggestion only when a declared token is actually close", () => {
174
+ // The family match is the finding; the "did you mean" is best effort. A
175
+ // real misspelling is often far from every token — `-contrast` is nowhere
176
+ // near `-soft` — and inventing a suggestion there would send the reader to
177
+ // the wrong token with the tool's confidence behind it.
178
+ const far = first(
179
+ ".a { color: var(--tempest-primary-contrast, #fff); }",
180
+ "token-family-typo",
181
+ );
182
+ expect(far.message).not.toContain("Did you mean");
183
+
184
+ const near = first(".a { color: var(--tempest-primary-sofr, #fff); }", "token-family-typo");
185
+ expect(near.message).toContain("Did you mean `--tempest-primary-soft`");
186
+ });
187
+
188
+ it("stays quiet on a knob whose family the SDK never declares", () => {
189
+ // `--tempest-card-*` has no declared sibling at all — this is a component
190
+ // inventing a hook, which is the idiom the docs teach. Reporting it is what
191
+ // made the first version of this analysis fire 43 times on the SDK's own CSS.
192
+ expect(codes(".a { padding: var(--tempest-card-padding, 8px); }")).toEqual([]);
193
+ });
194
+
195
+ it("stays quiet on a two-segment name, whose family is the bare prefix", () => {
196
+ // `--tempest-tx` has no family: everything before the last segment is
197
+ // `--tempest`, which matches every token there is. Treating that as a match
198
+ // is how a naive version of this rule fires on `Tooltip`'s transform knobs.
199
+ expect(codes(".a { translate: var(--tempest-tx, 0); }")).toEqual([]);
200
+ });
201
+
202
+ it("stays quiet when the name is a token, fallback or not", () => {
203
+ expect(codes(".a { color: var(--tempest-primary-soft, #fff); }")).toEqual([]);
204
+ });
205
+
155
206
  it("accepts a var() the same sheet defines", () => {
156
207
  const text = ":root { --mine: 4px; }\n.a { gap: var(--mine); }\n";
157
208
  const parsed = parseCss(text);
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.module.cjs","names":[],"sources":["../../../src/components/Alert/Alert.module.css"],"sourcesContent":[".alert {\n display: flex;\n align-items: flex-start;\n gap: var(--tempest-space-3);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-lg);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text);\n width: 100%;\n}\n\n.content {\n flex: 1;\n min-width: 0;\n}\n\n.title {\n margin: 0;\n font-size: var(--tempest-text-base);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n}\n\n.description {\n margin: 2px 0 0 0;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text-muted);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n margin-top: 1px;\n}\n\n.close {\n margin-left: auto;\n background: none;\n border: none;\n color: inherit;\n opacity: 0.7;\n padding: 4px;\n border-radius: var(--tempest-radius-sm);\n display: flex;\n align-items: center;\n transition:\n var(--tempest-transition-color),\n opacity var(--tempest-duration-fast) var(--tempest-ease-out);\n}\n\n.close:hover {\n opacity: 1;\n background-color: rgba(15, 23, 42, 0.06);\n}\n\n.close:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n\n/* ============================================================\n * Tone × Appearance matrix\n * ============================================================ */\n\n/* neutral */\n.neutral {\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n border-color: var(--tempest-border);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: #ffffff;\n border-color: transparent;\n}\n.neutral.outline {\n background-color: transparent;\n border-color: var(--tempest-border-strong);\n}\n\n/* info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n border-color: var(--tempest-info-border);\n}\n.info .description {\n color: var(--tempest-info-fg);\n opacity: 0.85;\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n border-color: transparent;\n}\n.info.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info);\n}\n\n/* success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n border-color: var(--tempest-success-border);\n}\n.success .description {\n color: var(--tempest-success-fg);\n opacity: 0.85;\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n border-color: transparent;\n}\n.success.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success);\n}\n\n/* warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n border-color: var(--tempest-warning-border);\n}\n.warning .description {\n color: var(--tempest-warning-fg);\n opacity: 0.85;\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n border-color: transparent;\n}\n.warning.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning);\n}\n\n/* danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n border-color: var(--tempest-danger-border);\n}\n.danger .description {\n color: var(--tempest-danger-fg);\n opacity: 0.85;\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n border-color: transparent;\n}\n.danger.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger);\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Alert.module.cjs","names":[],"sources":["../../../src/components/Alert/Alert.module.css"],"sourcesContent":[".alert {\n display: flex;\n align-items: flex-start;\n gap: var(--tempest-space-3);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-lg);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text);\n width: 100%;\n}\n\n.content {\n flex: 1;\n min-width: 0;\n}\n\n.title {\n margin: 0;\n font-size: var(--tempest-text-base);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n}\n\n.description {\n margin: 2px 0 0 0;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text-muted);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n margin-top: 1px;\n}\n\n.close {\n margin-left: auto;\n background: none;\n border: none;\n color: inherit;\n opacity: 0.7;\n padding: 4px;\n border-radius: var(--tempest-radius-sm);\n display: flex;\n align-items: center;\n transition:\n var(--tempest-transition-color),\n opacity var(--tempest-duration-fast) var(--tempest-ease-out);\n}\n\n.close:hover {\n opacity: 1;\n background-color: rgba(15, 23, 42, 0.06);\n}\n\n.close:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n\n/* ============================================================\n * Tone × Appearance matrix\n * ============================================================ */\n\n/* neutral */\n.neutral {\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n border-color: var(--tempest-border);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: var(--tempest-neutral-on-solid);\n border-color: transparent;\n}\n.neutral.outline {\n background-color: transparent;\n border-color: var(--tempest-border-strong);\n}\n\n/* info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n border-color: var(--tempest-info-border);\n}\n.info .description {\n color: var(--tempest-info-fg);\n opacity: 0.85;\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n border-color: transparent;\n}\n.info.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info);\n}\n\n/* success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n border-color: var(--tempest-success-border);\n}\n.success .description {\n color: var(--tempest-success-fg);\n opacity: 0.85;\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n border-color: transparent;\n}\n.success.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success);\n}\n\n/* warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n border-color: var(--tempest-warning-border);\n}\n.warning .description {\n color: var(--tempest-warning-fg);\n opacity: 0.85;\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n border-color: transparent;\n}\n.warning.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning);\n}\n\n/* danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n border-color: var(--tempest-danger-border);\n}\n.danger .description {\n color: var(--tempest-danger-fg);\n opacity: 0.85;\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n border-color: transparent;\n}\n.danger.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.module.js","names":[],"sources":["../../../src/components/Alert/Alert.module.css"],"sourcesContent":[".alert {\n display: flex;\n align-items: flex-start;\n gap: var(--tempest-space-3);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-lg);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text);\n width: 100%;\n}\n\n.content {\n flex: 1;\n min-width: 0;\n}\n\n.title {\n margin: 0;\n font-size: var(--tempest-text-base);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n}\n\n.description {\n margin: 2px 0 0 0;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text-muted);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n margin-top: 1px;\n}\n\n.close {\n margin-left: auto;\n background: none;\n border: none;\n color: inherit;\n opacity: 0.7;\n padding: 4px;\n border-radius: var(--tempest-radius-sm);\n display: flex;\n align-items: center;\n transition:\n var(--tempest-transition-color),\n opacity var(--tempest-duration-fast) var(--tempest-ease-out);\n}\n\n.close:hover {\n opacity: 1;\n background-color: rgba(15, 23, 42, 0.06);\n}\n\n.close:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n\n/* ============================================================\n * Tone × Appearance matrix\n * ============================================================ */\n\n/* neutral */\n.neutral {\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n border-color: var(--tempest-border);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: #ffffff;\n border-color: transparent;\n}\n.neutral.outline {\n background-color: transparent;\n border-color: var(--tempest-border-strong);\n}\n\n/* info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n border-color: var(--tempest-info-border);\n}\n.info .description {\n color: var(--tempest-info-fg);\n opacity: 0.85;\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n border-color: transparent;\n}\n.info.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info);\n}\n\n/* success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n border-color: var(--tempest-success-border);\n}\n.success .description {\n color: var(--tempest-success-fg);\n opacity: 0.85;\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n border-color: transparent;\n}\n.success.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success);\n}\n\n/* warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n border-color: var(--tempest-warning-border);\n}\n.warning .description {\n color: var(--tempest-warning-fg);\n opacity: 0.85;\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n border-color: transparent;\n}\n.warning.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning);\n}\n\n/* danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n border-color: var(--tempest-danger-border);\n}\n.danger .description {\n color: var(--tempest-danger-fg);\n opacity: 0.85;\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n border-color: transparent;\n}\n.danger.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger);\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Alert.module.js","names":[],"sources":["../../../src/components/Alert/Alert.module.css"],"sourcesContent":[".alert {\n display: flex;\n align-items: flex-start;\n gap: var(--tempest-space-3);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-lg);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text);\n width: 100%;\n}\n\n.content {\n flex: 1;\n min-width: 0;\n}\n\n.title {\n margin: 0;\n font-size: var(--tempest-text-base);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n}\n\n.description {\n margin: 2px 0 0 0;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-snug);\n color: var(--tempest-text-muted);\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n margin-top: 1px;\n}\n\n.close {\n margin-left: auto;\n background: none;\n border: none;\n color: inherit;\n opacity: 0.7;\n padding: 4px;\n border-radius: var(--tempest-radius-sm);\n display: flex;\n align-items: center;\n transition:\n var(--tempest-transition-color),\n opacity var(--tempest-duration-fast) var(--tempest-ease-out);\n}\n\n.close:hover {\n opacity: 1;\n background-color: rgba(15, 23, 42, 0.06);\n}\n\n.close:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n\n/* ============================================================\n * Tone × Appearance matrix\n * ============================================================ */\n\n/* neutral */\n.neutral {\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n border-color: var(--tempest-border);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: var(--tempest-neutral-on-solid);\n border-color: transparent;\n}\n.neutral.outline {\n background-color: transparent;\n border-color: var(--tempest-border-strong);\n}\n\n/* info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n border-color: var(--tempest-info-border);\n}\n.info .description {\n color: var(--tempest-info-fg);\n opacity: 0.85;\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n border-color: transparent;\n}\n.info.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info);\n}\n\n/* success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n border-color: var(--tempest-success-border);\n}\n.success .description {\n color: var(--tempest-success-fg);\n opacity: 0.85;\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n border-color: transparent;\n}\n.success.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success);\n}\n\n/* warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n border-color: var(--tempest-warning-border);\n}\n.warning .description {\n color: var(--tempest-warning-fg);\n opacity: 0.85;\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n border-color: transparent;\n}\n.warning.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning);\n}\n\n/* danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n border-color: var(--tempest-danger-border);\n}\n.danger .description {\n color: var(--tempest-danger-fg);\n opacity: 0.85;\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n border-color: transparent;\n}\n.danger.solid .description {\n color: rgba(255, 255, 255, 0.9);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.module.cjs","names":[],"sources":["../../../src/components/Badge/Badge.module.css"],"sourcesContent":[".badge {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 2px var(--tempest-space-2);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-full);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n letter-spacing: var(--tempest-tracking-normal);\n white-space: nowrap;\n}\n\n/* ============================================================\n * Sizes\n * ============================================================ */\n.sm {\n padding: 1px var(--tempest-space-2);\n font-size: var(--tempest-text-2xs);\n}\n.md {\n padding: 2px var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n.lg {\n padding: 3px var(--tempest-space-3);\n font-size: var(--tempest-text-sm);\n}\n\n/* ============================================================\n * Shapes — pill is the default (border-radius-full).\n * `square` flips to a small radius for chip-style badges.\n * ============================================================ */\n.square {\n border-radius: var(--tempest-radius-sm);\n}\n\n/* ============================================================\n * Tone × Style matrix.\n * Soft (default) = tinted bg + colored fg.\n * Solid = filled colored bg + white fg.\n * Outline = transparent bg + colored fg + colored border.\n * ============================================================ */\n\n/* Neutral */\n.neutral {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: #ffffff;\n}\n.neutral.outline {\n background-color: transparent;\n color: var(--tempest-text);\n border-color: var(--tempest-border-strong);\n}\n\n/* Success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success-border);\n}\n\n/* Warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning-border);\n}\n\n/* Danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger-border);\n}\n\n/* Info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info-border);\n}\n\n/* Primary */\n.primary {\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n.primary.solid {\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n.primary.outline {\n background-color: transparent;\n color: var(--tempest-primary);\n border-color: var(--tempest-primary);\n}\n\n/* Status dot — small leading dot, color inherits from text. */\n.dot {\n width: 6px;\n height: 6px;\n border-radius: var(--tempest-radius-full);\n background-color: currentColor;\n display: inline-block;\n flex-shrink: 0;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Badge.module.cjs","names":[],"sources":["../../../src/components/Badge/Badge.module.css"],"sourcesContent":[".badge {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 2px var(--tempest-space-2);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-full);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n letter-spacing: var(--tempest-tracking-normal);\n white-space: nowrap;\n}\n\n/* ============================================================\n * Sizes\n * ============================================================ */\n.sm {\n padding: 1px var(--tempest-space-2);\n font-size: var(--tempest-text-2xs);\n}\n.md {\n padding: 2px var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n.lg {\n padding: 3px var(--tempest-space-3);\n font-size: var(--tempest-text-sm);\n}\n\n/* ============================================================\n * Shapes — pill is the default (border-radius-full).\n * `square` flips to a small radius for chip-style badges.\n * ============================================================ */\n.square {\n border-radius: var(--tempest-radius-sm);\n}\n\n/* ============================================================\n * Tone × Style matrix.\n * Soft (default) = tinted bg + colored fg.\n * Solid = filled colored bg + white fg.\n * Outline = transparent bg + colored fg + colored border.\n * ============================================================ */\n\n/* Neutral */\n.neutral {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: var(--tempest-neutral-on-solid);\n}\n.neutral.outline {\n background-color: transparent;\n color: var(--tempest-text);\n border-color: var(--tempest-border-strong);\n}\n\n/* Success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success-border);\n}\n\n/* Warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning-border);\n}\n\n/* Danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger-border);\n}\n\n/* Info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info-border);\n}\n\n/* Primary */\n.primary {\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n.primary.solid {\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n.primary.outline {\n background-color: transparent;\n color: var(--tempest-primary);\n border-color: var(--tempest-primary);\n}\n\n/* Status dot — small leading dot, color inherits from text. */\n.dot {\n width: 6px;\n height: 6px;\n border-radius: var(--tempest-radius-full);\n background-color: currentColor;\n display: inline-block;\n flex-shrink: 0;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.module.js","names":[],"sources":["../../../src/components/Badge/Badge.module.css"],"sourcesContent":[".badge {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 2px var(--tempest-space-2);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-full);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n letter-spacing: var(--tempest-tracking-normal);\n white-space: nowrap;\n}\n\n/* ============================================================\n * Sizes\n * ============================================================ */\n.sm {\n padding: 1px var(--tempest-space-2);\n font-size: var(--tempest-text-2xs);\n}\n.md {\n padding: 2px var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n.lg {\n padding: 3px var(--tempest-space-3);\n font-size: var(--tempest-text-sm);\n}\n\n/* ============================================================\n * Shapes — pill is the default (border-radius-full).\n * `square` flips to a small radius for chip-style badges.\n * ============================================================ */\n.square {\n border-radius: var(--tempest-radius-sm);\n}\n\n/* ============================================================\n * Tone × Style matrix.\n * Soft (default) = tinted bg + colored fg.\n * Solid = filled colored bg + white fg.\n * Outline = transparent bg + colored fg + colored border.\n * ============================================================ */\n\n/* Neutral */\n.neutral {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: #ffffff;\n}\n.neutral.outline {\n background-color: transparent;\n color: var(--tempest-text);\n border-color: var(--tempest-border-strong);\n}\n\n/* Success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success-border);\n}\n\n/* Warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning-border);\n}\n\n/* Danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger-border);\n}\n\n/* Info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info-border);\n}\n\n/* Primary */\n.primary {\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n.primary.solid {\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n.primary.outline {\n background-color: transparent;\n color: var(--tempest-primary);\n border-color: var(--tempest-primary);\n}\n\n/* Status dot — small leading dot, color inherits from text. */\n.dot {\n width: 6px;\n height: 6px;\n border-radius: var(--tempest-radius-full);\n background-color: currentColor;\n display: inline-block;\n flex-shrink: 0;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Badge.module.js","names":[],"sources":["../../../src/components/Badge/Badge.module.css"],"sourcesContent":[".badge {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 2px var(--tempest-space-2);\n border: 1px solid transparent;\n border-radius: var(--tempest-radius-full);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-snug);\n letter-spacing: var(--tempest-tracking-normal);\n white-space: nowrap;\n}\n\n/* ============================================================\n * Sizes\n * ============================================================ */\n.sm {\n padding: 1px var(--tempest-space-2);\n font-size: var(--tempest-text-2xs);\n}\n.md {\n padding: 2px var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n.lg {\n padding: 3px var(--tempest-space-3);\n font-size: var(--tempest-text-sm);\n}\n\n/* ============================================================\n * Shapes — pill is the default (border-radius-full).\n * `square` flips to a small radius for chip-style badges.\n * ============================================================ */\n.square {\n border-radius: var(--tempest-radius-sm);\n}\n\n/* ============================================================\n * Tone × Style matrix.\n * Soft (default) = tinted bg + colored fg.\n * Solid = filled colored bg + white fg.\n * Outline = transparent bg + colored fg + colored border.\n * ============================================================ */\n\n/* Neutral */\n.neutral {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n}\n.neutral.solid {\n background-color: var(--tempest-gray-700);\n color: var(--tempest-neutral-on-solid);\n}\n.neutral.outline {\n background-color: transparent;\n color: var(--tempest-text);\n border-color: var(--tempest-border-strong);\n}\n\n/* Success */\n.success {\n background-color: var(--tempest-success-bg);\n color: var(--tempest-success-fg);\n}\n.success.solid {\n background-color: var(--tempest-success-solid);\n color: var(--tempest-success-on-solid);\n}\n.success.outline {\n background-color: transparent;\n color: var(--tempest-success);\n border-color: var(--tempest-success-border);\n}\n\n/* Warning */\n.warning {\n background-color: var(--tempest-warning-bg);\n color: var(--tempest-warning-fg);\n}\n.warning.solid {\n background-color: var(--tempest-warning-solid);\n color: var(--tempest-warning-on-solid);\n}\n.warning.outline {\n background-color: transparent;\n color: var(--tempest-warning);\n border-color: var(--tempest-warning-border);\n}\n\n/* Danger */\n.danger {\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n}\n.danger.solid {\n background-color: var(--tempest-danger-solid);\n color: var(--tempest-danger-on-solid);\n}\n.danger.outline {\n background-color: transparent;\n color: var(--tempest-danger);\n border-color: var(--tempest-danger-border);\n}\n\n/* Info */\n.info {\n background-color: var(--tempest-info-bg);\n color: var(--tempest-info-fg);\n}\n.info.solid {\n background-color: var(--tempest-info-solid);\n color: var(--tempest-info-on-solid);\n}\n.info.outline {\n background-color: transparent;\n color: var(--tempest-info);\n border-color: var(--tempest-info-border);\n}\n\n/* Primary */\n.primary {\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n.primary.solid {\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n.primary.outline {\n background-color: transparent;\n color: var(--tempest-primary);\n border-color: var(--tempest-primary);\n}\n\n/* Status dot — small leading dot, color inherits from text. */\n.dot {\n width: 6px;\n height: 6px;\n border-radius: var(--tempest-radius-full);\n background-color: currentColor;\n display: inline-block;\n flex-shrink: 0;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"BarList.module.cjs","names":[],"sources":["../../../src/components/BarList/BarList.module.css"],"sourcesContent":[".list {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n}\n\n.line {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--tempest-space-3, 0.75rem);\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n}\n\n/*\n * The label truncates instead of wrapping: a plan name long enough to wrap would\n * push its own bar down and break the alignment the list exists to show.\n */\n.label {\n min-width: 0;\n overflow: hidden;\n color: var(--tempest-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value {\n display: inline-flex;\n align-items: baseline;\n gap: var(--tempest-space-2, 0.5rem);\n color: var(--tempest-text);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/*\n * The share is de-emphasised by size, and only then by colour — and the colour it\n * uses is resolved against the page background, which is where this text actually\n * sits. Putting the label on top of the bar would need the fill's own foreground\n * re-verified per series, which is the trap this layout avoids entirely.\n */\n.percentage {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-font-size-xs, 0.75rem);\n}\n\n.track {\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-surface-2);\n}\n\n.fill {\n height: 100%;\n border-radius: inherit;\n transition: width var(--tempest-duration-normal, 200ms) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fill {\n transition: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"BarList.module.cjs","names":[],"sources":["../../../src/components/BarList/BarList.module.css"],"sourcesContent":[".list {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n}\n\n.line {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--tempest-space-3, 0.75rem);\n font-size: var(--tempest-text-sm);\n}\n\n/*\n * The label truncates instead of wrapping: a plan name long enough to wrap would\n * push its own bar down and break the alignment the list exists to show.\n */\n.label {\n min-width: 0;\n overflow: hidden;\n color: var(--tempest-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value {\n display: inline-flex;\n align-items: baseline;\n gap: var(--tempest-space-2, 0.5rem);\n color: var(--tempest-text);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/*\n * The share is de-emphasised by size, and only then by colour — and the colour it\n * uses is resolved against the page background, which is where this text actually\n * sits. Putting the label on top of the bar would need the fill's own foreground\n * re-verified per series, which is the trap this layout avoids entirely.\n */\n.percentage {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.track {\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-surface-2);\n}\n\n.fill {\n height: 100%;\n border-radius: inherit;\n transition: width var(--tempest-duration-base) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fill {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"BarList.module.js","names":[],"sources":["../../../src/components/BarList/BarList.module.css"],"sourcesContent":[".list {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n}\n\n.line {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--tempest-space-3, 0.75rem);\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n}\n\n/*\n * The label truncates instead of wrapping: a plan name long enough to wrap would\n * push its own bar down and break the alignment the list exists to show.\n */\n.label {\n min-width: 0;\n overflow: hidden;\n color: var(--tempest-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value {\n display: inline-flex;\n align-items: baseline;\n gap: var(--tempest-space-2, 0.5rem);\n color: var(--tempest-text);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/*\n * The share is de-emphasised by size, and only then by colour — and the colour it\n * uses is resolved against the page background, which is where this text actually\n * sits. Putting the label on top of the bar would need the fill's own foreground\n * re-verified per series, which is the trap this layout avoids entirely.\n */\n.percentage {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-font-size-xs, 0.75rem);\n}\n\n.track {\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-surface-2);\n}\n\n.fill {\n height: 100%;\n border-radius: inherit;\n transition: width var(--tempest-duration-normal, 200ms) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fill {\n transition: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"BarList.module.js","names":[],"sources":["../../../src/components/BarList/BarList.module.css"],"sourcesContent":[".list {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n}\n\n.line {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--tempest-space-3, 0.75rem);\n font-size: var(--tempest-text-sm);\n}\n\n/*\n * The label truncates instead of wrapping: a plan name long enough to wrap would\n * push its own bar down and break the alignment the list exists to show.\n */\n.label {\n min-width: 0;\n overflow: hidden;\n color: var(--tempest-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.value {\n display: inline-flex;\n align-items: baseline;\n gap: var(--tempest-space-2, 0.5rem);\n color: var(--tempest-text);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n\n/*\n * The share is de-emphasised by size, and only then by colour — and the colour it\n * uses is resolved against the page background, which is where this text actually\n * sits. Putting the label on top of the bar would need the fill's own foreground\n * re-verified per series, which is the trap this layout avoids entirely.\n */\n.percentage {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.track {\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-surface-2);\n}\n\n.fill {\n height: 100%;\n border-radius: inherit;\n transition: width var(--tempest-duration-base) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fill {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.module.cjs","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.module.css"],"sourcesContent":[".root {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgb(0 0 0 / 0.45);\n animation: fadeIn var(--tempest-duration-base, 200ms) var(--tempest-ease-out, ease-out);\n}\n\n.sheet {\n position: relative;\n width: 100%;\n max-width: 720px;\n max-height: 90dvh;\n background: var(--tempest-surface);\n border-top-left-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n border-top-right-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n box-shadow: var(--tempest-shadow-xl, 0 -10px 30px rgb(0 0 0 / 0.25));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding-bottom: env(safe-area-inset-bottom, 0);\n animation: slideUp var(--tempest-duration-base, 240ms) var(--tempest-ease-out, ease-out);\n font-family: var(--tempest-font-sans);\n}\n\n.handle {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: 0;\n padding: var(--tempest-space-2) 0;\n cursor: grab;\n flex: 0 0 auto;\n}\n\n.handleBar {\n display: block;\n width: 36px;\n height: 4px;\n background: var(--tempest-gray-300);\n border-radius: var(--tempest-radius-full);\n}\n\n.title {\n flex: 0 0 auto;\n padding: var(--tempest-space-2) var(--tempest-space-4) var(--tempest-space-3);\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-semibold);\n color: var(--tempest-text);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.body {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: var(--tempest-space-4);\n color: var(--tempest-text);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .sheet {\n animation: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"BottomSheet.module.cjs","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.module.css"],"sourcesContent":[".root {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgb(0 0 0 / 0.45);\n animation: fadeIn var(--tempest-duration-base, 200ms) var(--tempest-ease-out, ease-out);\n}\n\n.sheet {\n position: relative;\n width: 100%;\n max-width: 720px;\n max-height: 90dvh;\n background: var(--tempest-surface);\n border-top-left-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n border-top-right-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n box-shadow: var(--tempest-shadow-xl, 0 -10px 30px rgb(0 0 0 / 0.25));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding-bottom: env(safe-area-inset-bottom, 0);\n animation: slideUp var(--tempest-duration-base, 240ms) var(--tempest-ease-out, ease-out);\n font-family: var(--tempest-font-sans);\n}\n\n.handle {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: 0;\n padding: var(--tempest-space-2) 0;\n cursor: grab;\n flex: 0 0 auto;\n}\n\n.handleBar {\n display: block;\n width: 36px;\n height: 4px;\n background: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-full);\n}\n\n.title {\n flex: 0 0 auto;\n padding: var(--tempest-space-2) var(--tempest-space-4) var(--tempest-space-3);\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-semibold);\n color: var(--tempest-text);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.body {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: var(--tempest-space-4);\n color: var(--tempest-text);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .sheet {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.module.js","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.module.css"],"sourcesContent":[".root {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgb(0 0 0 / 0.45);\n animation: fadeIn var(--tempest-duration-base, 200ms) var(--tempest-ease-out, ease-out);\n}\n\n.sheet {\n position: relative;\n width: 100%;\n max-width: 720px;\n max-height: 90dvh;\n background: var(--tempest-surface);\n border-top-left-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n border-top-right-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n box-shadow: var(--tempest-shadow-xl, 0 -10px 30px rgb(0 0 0 / 0.25));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding-bottom: env(safe-area-inset-bottom, 0);\n animation: slideUp var(--tempest-duration-base, 240ms) var(--tempest-ease-out, ease-out);\n font-family: var(--tempest-font-sans);\n}\n\n.handle {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: 0;\n padding: var(--tempest-space-2) 0;\n cursor: grab;\n flex: 0 0 auto;\n}\n\n.handleBar {\n display: block;\n width: 36px;\n height: 4px;\n background: var(--tempest-gray-300);\n border-radius: var(--tempest-radius-full);\n}\n\n.title {\n flex: 0 0 auto;\n padding: var(--tempest-space-2) var(--tempest-space-4) var(--tempest-space-3);\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-semibold);\n color: var(--tempest-text);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.body {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: var(--tempest-space-4);\n color: var(--tempest-text);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .sheet {\n animation: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"BottomSheet.module.js","names":[],"sources":["../../../src/components/BottomSheet/BottomSheet.module.css"],"sourcesContent":[".root {\n position: fixed;\n inset: 0;\n z-index: 60;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n}\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: rgb(0 0 0 / 0.45);\n animation: fadeIn var(--tempest-duration-base, 200ms) var(--tempest-ease-out, ease-out);\n}\n\n.sheet {\n position: relative;\n width: 100%;\n max-width: 720px;\n max-height: 90dvh;\n background: var(--tempest-surface);\n border-top-left-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n border-top-right-radius: var(--tempest-radius-2xl, var(--tempest-radius-lg));\n box-shadow: var(--tempest-shadow-xl, 0 -10px 30px rgb(0 0 0 / 0.25));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding-bottom: env(safe-area-inset-bottom, 0);\n animation: slideUp var(--tempest-duration-base, 240ms) var(--tempest-ease-out, ease-out);\n font-family: var(--tempest-font-sans);\n}\n\n.handle {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: 0;\n padding: var(--tempest-space-2) 0;\n cursor: grab;\n flex: 0 0 auto;\n}\n\n.handleBar {\n display: block;\n width: 36px;\n height: 4px;\n background: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-full);\n}\n\n.title {\n flex: 0 0 auto;\n padding: var(--tempest-space-2) var(--tempest-space-4) var(--tempest-space-3);\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-semibold);\n color: var(--tempest-text);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.body {\n flex: 1 1 auto;\n overflow-y: auto;\n padding: var(--tempest-space-4);\n color: var(--tempest-text);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(100%);\n }\n to {\n transform: translateY(0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .sheet {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.module.cjs","names":[],"sources":["../../../src/components/DataTable/DataTable.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n}\n\n.search {\n max-width: 20rem;\n}\n\n/*\n * A page swap keeps the rows it already has, dimmed. Replacing them with a\n * spinner would collapse the table to nothing and bounce whatever sits below it\n * back up, which is the jump the user's cursor was resting on.\n */\n.pending {\n opacity: 0.6;\n transition: opacity var(--tempest-duration-fast, 120ms) ease;\n pointer-events: none;\n}\n\n.loading {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n padding: var(--tempest-space-3, 0.75rem) 0;\n}\n\n.loadingRow {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n gap: var(--tempest-space-4, 1rem);\n align-items: center;\n}\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n user-select: none;\n}\n\n.sortIndicator {\n font-size: 0.75em;\n opacity: 0.7;\n}\n\n/* ── Inline editing ─────────────────────────────────────────────────────────── */\n\n.cellWrap {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n align-items: stretch;\n width: 100%;\n}\n\n/*\n * The dashed bottom edge is a resting affordance, not only a hover one: on a touch\n * screen there is no hover, so an editable cell that looks exactly like a read-only\n * one is undiscoverable. It is the weakest mark that still says \"this is editable\";\n * hover and focus then promote it to a full box.\n */\n.cellButton {\n position: relative;\n display: block;\n width: 100%;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px dashed transparent;\n border-bottom-color: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background: none;\n font: inherit;\n color: inherit;\n text-align: inherit;\n cursor: pointer;\n}\n\n.cellButton:hover {\n border-color: var(--tempest-border-strong);\n background-color: var(--tempest-surface-2);\n}\n\n.cellButton:focus-visible {\n outline: none;\n border-color: transparent;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellButtonInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * Touch: grow the hit area to the cell's own padding — exactly `--tempest-space-3`\n * vertically and `--tempest-space-4` horizontally in `Table.module.css` — so the\n * whole `<td>` is tappable and the target clears 44px without spilling into the\n * neighbouring row, which a symmetric slop would do in a dense table.\n */\n@media (pointer: coarse) {\n .cellButton::after {\n content: \"\";\n position: absolute;\n inset-block: calc(-1 * var(--tempest-space-3, 0.75rem));\n inset-inline: calc(-1 * var(--tempest-space-4, 1rem));\n }\n}\n\n.cellButton[aria-busy=\"true\"] {\n opacity: 0.6;\n}\n\n.cellEditor {\n width: 100%;\n min-width: 0;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px solid var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-bg);\n font: inherit;\n color: var(--tempest-text);\n}\n\n.cellEditor:focus {\n outline: none;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellEditorInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * The message sits on a tinted fill because `--tempest-danger-fg` over\n * `--tempest-danger-bg` is a pair `contrast.test.ts` verifies in both themes;\n * danger text straight onto the table background is not.\n */\n.cellError {\n padding: 0.125rem var(--tempest-space-2, 0.5rem);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n line-height: 1.4;\n white-space: normal;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"DataTable.module.cjs","names":[],"sources":["../../../src/components/DataTable/DataTable.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n}\n\n.search {\n max-width: 20rem;\n}\n\n/*\n * A page swap keeps the rows it already has, dimmed. Replacing them with a\n * spinner would collapse the table to nothing and bounce whatever sits below it\n * back up, which is the jump the user's cursor was resting on.\n */\n.pending {\n opacity: 0.6;\n transition: opacity var(--tempest-duration-fast, 120ms) ease;\n pointer-events: none;\n}\n\n.loading {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n padding: var(--tempest-space-3, 0.75rem) 0;\n}\n\n.loadingRow {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n gap: var(--tempest-space-4, 1rem);\n align-items: center;\n}\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n user-select: none;\n}\n\n.sortIndicator {\n font-size: 0.75em;\n opacity: 0.7;\n}\n\n/* ── Inline editing ─────────────────────────────────────────────────────────── */\n\n.cellWrap {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n align-items: stretch;\n width: 100%;\n}\n\n/*\n * The dashed bottom edge is a resting affordance, not only a hover one: on a touch\n * screen there is no hover, so an editable cell that looks exactly like a read-only\n * one is undiscoverable. It is the weakest mark that still says \"this is editable\";\n * hover and focus then promote it to a full box.\n */\n.cellButton {\n position: relative;\n display: block;\n width: 100%;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px dashed transparent;\n border-bottom-color: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background: none;\n font: inherit;\n color: inherit;\n text-align: inherit;\n cursor: pointer;\n}\n\n.cellButton:hover {\n border-color: var(--tempest-border-strong);\n background-color: var(--tempest-surface-2);\n}\n\n.cellButton:focus-visible {\n outline: none;\n border-color: transparent;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellButtonInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * Touch: grow the hit area to the cell's own padding — exactly `--tempest-space-3`\n * vertically and `--tempest-space-4` horizontally in `Table.module.css` — so the\n * whole `<td>` is tappable and the target clears 44px without spilling into the\n * neighbouring row, which a symmetric slop would do in a dense table.\n */\n@media (pointer: coarse) {\n .cellButton::after {\n content: \"\";\n position: absolute;\n inset-block: calc(-1 * var(--tempest-space-3, 0.75rem));\n inset-inline: calc(-1 * var(--tempest-space-4, 1rem));\n }\n}\n\n.cellButton[aria-busy=\"true\"] {\n opacity: 0.6;\n}\n\n.cellEditor {\n width: 100%;\n min-width: 0;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px solid var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-bg);\n font: inherit;\n color: var(--tempest-text);\n}\n\n.cellEditor:focus {\n outline: none;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellEditorInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * The message sits on a tinted fill because `--tempest-danger-fg` over\n * `--tempest-danger-bg` is a pair `contrast.test.ts` verifies in both themes;\n * danger text straight onto the table background is not.\n */\n.cellError {\n padding: 0.125rem var(--tempest-space-2, 0.5rem);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n font-size: var(--tempest-text-sm);\n line-height: 1.4;\n white-space: normal;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.module.js","names":[],"sources":["../../../src/components/DataTable/DataTable.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n}\n\n.search {\n max-width: 20rem;\n}\n\n/*\n * A page swap keeps the rows it already has, dimmed. Replacing them with a\n * spinner would collapse the table to nothing and bounce whatever sits below it\n * back up, which is the jump the user's cursor was resting on.\n */\n.pending {\n opacity: 0.6;\n transition: opacity var(--tempest-duration-fast, 120ms) ease;\n pointer-events: none;\n}\n\n.loading {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n padding: var(--tempest-space-3, 0.75rem) 0;\n}\n\n.loadingRow {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n gap: var(--tempest-space-4, 1rem);\n align-items: center;\n}\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n user-select: none;\n}\n\n.sortIndicator {\n font-size: 0.75em;\n opacity: 0.7;\n}\n\n/* ── Inline editing ─────────────────────────────────────────────────────────── */\n\n.cellWrap {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n align-items: stretch;\n width: 100%;\n}\n\n/*\n * The dashed bottom edge is a resting affordance, not only a hover one: on a touch\n * screen there is no hover, so an editable cell that looks exactly like a read-only\n * one is undiscoverable. It is the weakest mark that still says \"this is editable\";\n * hover and focus then promote it to a full box.\n */\n.cellButton {\n position: relative;\n display: block;\n width: 100%;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px dashed transparent;\n border-bottom-color: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background: none;\n font: inherit;\n color: inherit;\n text-align: inherit;\n cursor: pointer;\n}\n\n.cellButton:hover {\n border-color: var(--tempest-border-strong);\n background-color: var(--tempest-surface-2);\n}\n\n.cellButton:focus-visible {\n outline: none;\n border-color: transparent;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellButtonInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * Touch: grow the hit area to the cell's own padding — exactly `--tempest-space-3`\n * vertically and `--tempest-space-4` horizontally in `Table.module.css` — so the\n * whole `<td>` is tappable and the target clears 44px without spilling into the\n * neighbouring row, which a symmetric slop would do in a dense table.\n */\n@media (pointer: coarse) {\n .cellButton::after {\n content: \"\";\n position: absolute;\n inset-block: calc(-1 * var(--tempest-space-3, 0.75rem));\n inset-inline: calc(-1 * var(--tempest-space-4, 1rem));\n }\n}\n\n.cellButton[aria-busy=\"true\"] {\n opacity: 0.6;\n}\n\n.cellEditor {\n width: 100%;\n min-width: 0;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px solid var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-bg);\n font: inherit;\n color: var(--tempest-text);\n}\n\n.cellEditor:focus {\n outline: none;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellEditorInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * The message sits on a tinted fill because `--tempest-danger-fg` over\n * `--tempest-danger-bg` is a pair `contrast.test.ts` verifies in both themes;\n * danger text straight onto the table background is not.\n */\n.cellError {\n padding: 0.125rem var(--tempest-space-2, 0.5rem);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n line-height: 1.4;\n white-space: normal;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"DataTable.module.js","names":[],"sources":["../../../src/components/DataTable/DataTable.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n}\n\n.search {\n max-width: 20rem;\n}\n\n/*\n * A page swap keeps the rows it already has, dimmed. Replacing them with a\n * spinner would collapse the table to nothing and bounce whatever sits below it\n * back up, which is the jump the user's cursor was resting on.\n */\n.pending {\n opacity: 0.6;\n transition: opacity var(--tempest-duration-fast, 120ms) ease;\n pointer-events: none;\n}\n\n.loading {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-3, 0.75rem);\n padding: var(--tempest-space-3, 0.75rem) 0;\n}\n\n.loadingRow {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n gap: var(--tempest-space-4, 1rem);\n align-items: center;\n}\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n border: none;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n user-select: none;\n}\n\n.sortIndicator {\n font-size: 0.75em;\n opacity: 0.7;\n}\n\n/* ── Inline editing ─────────────────────────────────────────────────────────── */\n\n.cellWrap {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1, 0.25rem);\n align-items: stretch;\n width: 100%;\n}\n\n/*\n * The dashed bottom edge is a resting affordance, not only a hover one: on a touch\n * screen there is no hover, so an editable cell that looks exactly like a read-only\n * one is undiscoverable. It is the weakest mark that still says \"this is editable\";\n * hover and focus then promote it to a full box.\n */\n.cellButton {\n position: relative;\n display: block;\n width: 100%;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px dashed transparent;\n border-bottom-color: var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background: none;\n font: inherit;\n color: inherit;\n text-align: inherit;\n cursor: pointer;\n}\n\n.cellButton:hover {\n border-color: var(--tempest-border-strong);\n background-color: var(--tempest-surface-2);\n}\n\n.cellButton:focus-visible {\n outline: none;\n border-color: transparent;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellButtonInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * Touch: grow the hit area to the cell's own padding — exactly `--tempest-space-3`\n * vertically and `--tempest-space-4` horizontally in `Table.module.css` — so the\n * whole `<td>` is tappable and the target clears 44px without spilling into the\n * neighbouring row, which a symmetric slop would do in a dense table.\n */\n@media (pointer: coarse) {\n .cellButton::after {\n content: \"\";\n position: absolute;\n inset-block: calc(-1 * var(--tempest-space-3, 0.75rem));\n inset-inline: calc(-1 * var(--tempest-space-4, 1rem));\n }\n}\n\n.cellButton[aria-busy=\"true\"] {\n opacity: 0.6;\n}\n\n.cellEditor {\n width: 100%;\n min-width: 0;\n margin: calc(-1 * var(--tempest-space-1, 0.25rem)) calc(-1 * var(--tempest-space-2, 0.5rem));\n padding: var(--tempest-space-1, 0.25rem) var(--tempest-space-2, 0.5rem);\n border: 1px solid var(--tempest-border-strong);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-bg);\n font: inherit;\n color: var(--tempest-text);\n}\n\n.cellEditor:focus {\n outline: none;\n box-shadow: 0 0 0 var(--tempest-focus-ring-width) var(--tempest-focus-ring-color);\n}\n\n.cellEditorInvalid {\n border-color: var(--tempest-danger-border);\n}\n\n/*\n * The message sits on a tinted fill because `--tempest-danger-fg` over\n * `--tempest-danger-bg` is a pair `contrast.test.ts` verifies in both themes;\n * danger text straight onto the table background is not.\n */\n.cellError {\n padding: 0.125rem var(--tempest-space-2, 0.5rem);\n border-radius: var(--tempest-radius-sm, 0.25rem);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-danger-fg);\n font-size: var(--tempest-text-sm);\n line-height: 1.4;\n white-space: normal;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Dropzone.module.cjs","names":[],"sources":["../../../src/components/Dropzone/Dropzone.module.css"],"sourcesContent":[".zone {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n min-height: 120px;\n padding: var(--tempest-space-6, 24px);\n border: 2px dashed var(--tempest-border);\n border-radius: var(--tempest-radius-lg, 12px);\n background: var(--tempest-surface);\n color: var(--tempest-text-muted);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-sm);\n cursor: pointer;\n transition:\n border-color var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out),\n background var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out);\n}\n\n.zone:hover,\n.zone:focus-visible {\n border-color: var(--tempest-primary);\n color: var(--tempest-text);\n outline: none;\n}\n\n.dragging {\n border-color: var(--tempest-primary);\n background: var(--tempest-primary-subtle, var(--tempest-surface));\n color: var(--tempest-text);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.prompt {\n line-height: 1.4;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Dropzone.module.cjs","names":[],"sources":["../../../src/components/Dropzone/Dropzone.module.css"],"sourcesContent":[".zone {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n min-height: 120px;\n padding: var(--tempest-space-6, 24px);\n border: 2px dashed var(--tempest-border);\n border-radius: var(--tempest-radius-lg, 12px);\n background: var(--tempest-surface);\n color: var(--tempest-text-muted);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-sm);\n cursor: pointer;\n transition:\n border-color var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out),\n background var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out);\n}\n\n.zone:hover,\n.zone:focus-visible {\n border-color: var(--tempest-primary);\n color: var(--tempest-text);\n outline: none;\n}\n\n.dragging {\n border-color: var(--tempest-primary);\n background: var(--tempest-primary-soft);\n color: var(--tempest-text);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.prompt {\n line-height: 1.4;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Dropzone.module.js","names":[],"sources":["../../../src/components/Dropzone/Dropzone.module.css"],"sourcesContent":[".zone {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n min-height: 120px;\n padding: var(--tempest-space-6, 24px);\n border: 2px dashed var(--tempest-border);\n border-radius: var(--tempest-radius-lg, 12px);\n background: var(--tempest-surface);\n color: var(--tempest-text-muted);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-sm);\n cursor: pointer;\n transition:\n border-color var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out),\n background var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out);\n}\n\n.zone:hover,\n.zone:focus-visible {\n border-color: var(--tempest-primary);\n color: var(--tempest-text);\n outline: none;\n}\n\n.dragging {\n border-color: var(--tempest-primary);\n background: var(--tempest-primary-subtle, var(--tempest-surface));\n color: var(--tempest-text);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.prompt {\n line-height: 1.4;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Dropzone.module.js","names":[],"sources":["../../../src/components/Dropzone/Dropzone.module.css"],"sourcesContent":[".zone {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n min-height: 120px;\n padding: var(--tempest-space-6, 24px);\n border: 2px dashed var(--tempest-border);\n border-radius: var(--tempest-radius-lg, 12px);\n background: var(--tempest-surface);\n color: var(--tempest-text-muted);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-sm);\n cursor: pointer;\n transition:\n border-color var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out),\n background var(--tempest-duration-fast, 120ms) var(--tempest-ease-out, ease-out);\n}\n\n.zone:hover,\n.zone:focus-visible {\n border-color: var(--tempest-primary);\n color: var(--tempest-text);\n outline: none;\n}\n\n.dragging {\n border-color: var(--tempest-primary);\n background: var(--tempest-primary-soft);\n color: var(--tempest-text);\n}\n\n.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.input {\n display: none;\n}\n\n.prompt {\n line-height: 1.4;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorText.module.cjs","names":[],"sources":["../../../src/components/ErrorText/ErrorText.module.css"],"sourcesContent":[".errorText {\n margin: 0;\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n line-height: 1.4;\n color: var(--tempest-danger, var(--tempest-color-danger, #dc2626));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"ErrorText.module.cjs","names":[],"sources":["../../../src/components/ErrorText/ErrorText.module.css"],"sourcesContent":[".errorText {\n margin: 0;\n font-size: var(--tempest-text-sm);\n line-height: 1.4;\n color: var(--tempest-danger);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorText.module.js","names":[],"sources":["../../../src/components/ErrorText/ErrorText.module.css"],"sourcesContent":[".errorText {\n margin: 0;\n font-size: var(--tempest-font-size-sm, 0.8125rem);\n line-height: 1.4;\n color: var(--tempest-danger, var(--tempest-color-danger, #dc2626));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"ErrorText.module.js","names":[],"sources":["../../../src/components/ErrorText/ErrorText.module.css"],"sourcesContent":[".errorText {\n margin: 0;\n font-size: var(--tempest-text-sm);\n line-height: 1.4;\n color: var(--tempest-danger);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.module.cjs","names":[],"sources":["../../../src/components/Markdown/Markdown.module.css"],"sourcesContent":[".root {\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-relaxed);\n overflow-wrap: anywhere;\n}\n\n/*\n * Every block spaces itself with `margin-block-end` and the last child clears it,\n * so a Markdown body dropped into a card does not add a phantom gap at the bottom.\n */\n.root > * {\n margin-block: 0 var(--tempest-space-3);\n}\n\n.root > *:last-child {\n margin-block-end: 0;\n}\n\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n margin-block-start: var(--tempest-space-5);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-tight);\n}\n\n.root > .h1:first-child,\n.root > .h2:first-child,\n.root > .h3:first-child,\n.root > .h4:first-child,\n.root > .h5:first-child,\n.root > .h6:first-child {\n margin-block-start: 0;\n}\n\n.h1 {\n font-size: var(--tempest-text-2xl);\n}\n\n.h2 {\n font-size: var(--tempest-text-xl);\n}\n\n.h3 {\n font-size: var(--tempest-text-lg);\n}\n\n.h4,\n.h5,\n.h6 {\n font-size: var(--tempest-text-base);\n}\n\n.list {\n padding-inline-start: var(--tempest-space-6);\n}\n\n.list .list {\n margin-block: var(--tempest-space-1) 0;\n}\n\n.item {\n margin-block-end: var(--tempest-space-1);\n}\n\n.item > p {\n margin: 0;\n}\n\n.quote {\n padding-inline-start: var(--tempest-space-4);\n border-inline-start: 3px solid var(--tempest-border-strong);\n color: var(--tempest-text-muted);\n}\n\n.rule {\n height: 1px;\n border: 0;\n background-color: var(--tempest-border);\n}\n\n.inlineCode {\n padding: 0.1em 0.35em;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-code-text, var(--tempest-text));\n font-family: var(--tempest-font-mono);\n font-size: 0.9em;\n}\n\n.link {\n color: var(--tempest-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.image {\n max-width: 100%;\n height: auto;\n border-radius: var(--tempest-radius-md);\n}\n\n/*\n * A wide table scrolls inside its own box, and that box is focusable — a scroll\n * container with nothing focusable inside cannot be reached by keyboard, which is\n * the same defect the Table fix addressed.\n */\n.tableScroll {\n overflow-x: auto;\n}\n\n.tableScroll:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: 2px;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tempest-text-sm);\n}\n\n.table th,\n.table td {\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n text-align: left;\n}\n\n.table th {\n color: var(--tempest-text-muted);\n font-weight: var(--tempest-weight-semibold);\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Markdown.module.cjs","names":[],"sources":["../../../src/components/Markdown/Markdown.module.css"],"sourcesContent":[".root {\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-relaxed);\n overflow-wrap: anywhere;\n}\n\n/*\n * Every block spaces itself with `margin-block-end` and the last child clears it,\n * so a Markdown body dropped into a card does not add a phantom gap at the bottom.\n */\n.root > * {\n margin-block: 0 var(--tempest-space-3);\n}\n\n.root > *:last-child {\n margin-block-end: 0;\n}\n\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n margin-block-start: var(--tempest-space-5);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-tight);\n}\n\n.root > .h1:first-child,\n.root > .h2:first-child,\n.root > .h3:first-child,\n.root > .h4:first-child,\n.root > .h5:first-child,\n.root > .h6:first-child {\n margin-block-start: 0;\n}\n\n.h1 {\n font-size: var(--tempest-text-2xl);\n}\n\n.h2 {\n font-size: var(--tempest-text-xl);\n}\n\n.h3 {\n font-size: var(--tempest-text-lg);\n}\n\n.h4,\n.h5,\n.h6 {\n font-size: var(--tempest-text-base);\n}\n\n.list {\n padding-inline-start: var(--tempest-space-6);\n}\n\n.list .list {\n margin-block: var(--tempest-space-1) 0;\n}\n\n.item {\n margin-block-end: var(--tempest-space-1);\n}\n\n.item > p {\n margin: 0;\n}\n\n.quote {\n padding-inline-start: var(--tempest-space-4);\n border-inline-start: 3px solid var(--tempest-border-strong);\n color: var(--tempest-text-muted);\n}\n\n.rule {\n height: 1px;\n border: 0;\n background-color: var(--tempest-border);\n}\n\n.inlineCode {\n padding: 0.1em 0.35em;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n font-family: var(--tempest-font-mono);\n font-size: 0.9em;\n}\n\n.link {\n color: var(--tempest-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.image {\n max-width: 100%;\n height: auto;\n border-radius: var(--tempest-radius-md);\n}\n\n/*\n * A wide table scrolls inside its own box, and that box is focusable — a scroll\n * container with nothing focusable inside cannot be reached by keyboard, which is\n * the same defect the Table fix addressed.\n */\n.tableScroll {\n overflow-x: auto;\n}\n\n.tableScroll:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: 2px;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tempest-text-sm);\n}\n\n.table th,\n.table td {\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n text-align: left;\n}\n\n.table th {\n color: var(--tempest-text-muted);\n font-weight: var(--tempest-weight-semibold);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.module.js","names":[],"sources":["../../../src/components/Markdown/Markdown.module.css"],"sourcesContent":[".root {\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-relaxed);\n overflow-wrap: anywhere;\n}\n\n/*\n * Every block spaces itself with `margin-block-end` and the last child clears it,\n * so a Markdown body dropped into a card does not add a phantom gap at the bottom.\n */\n.root > * {\n margin-block: 0 var(--tempest-space-3);\n}\n\n.root > *:last-child {\n margin-block-end: 0;\n}\n\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n margin-block-start: var(--tempest-space-5);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-tight);\n}\n\n.root > .h1:first-child,\n.root > .h2:first-child,\n.root > .h3:first-child,\n.root > .h4:first-child,\n.root > .h5:first-child,\n.root > .h6:first-child {\n margin-block-start: 0;\n}\n\n.h1 {\n font-size: var(--tempest-text-2xl);\n}\n\n.h2 {\n font-size: var(--tempest-text-xl);\n}\n\n.h3 {\n font-size: var(--tempest-text-lg);\n}\n\n.h4,\n.h5,\n.h6 {\n font-size: var(--tempest-text-base);\n}\n\n.list {\n padding-inline-start: var(--tempest-space-6);\n}\n\n.list .list {\n margin-block: var(--tempest-space-1) 0;\n}\n\n.item {\n margin-block-end: var(--tempest-space-1);\n}\n\n.item > p {\n margin: 0;\n}\n\n.quote {\n padding-inline-start: var(--tempest-space-4);\n border-inline-start: 3px solid var(--tempest-border-strong);\n color: var(--tempest-text-muted);\n}\n\n.rule {\n height: 1px;\n border: 0;\n background-color: var(--tempest-border);\n}\n\n.inlineCode {\n padding: 0.1em 0.35em;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-code-text, var(--tempest-text));\n font-family: var(--tempest-font-mono);\n font-size: 0.9em;\n}\n\n.link {\n color: var(--tempest-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.image {\n max-width: 100%;\n height: auto;\n border-radius: var(--tempest-radius-md);\n}\n\n/*\n * A wide table scrolls inside its own box, and that box is focusable — a scroll\n * container with nothing focusable inside cannot be reached by keyboard, which is\n * the same defect the Table fix addressed.\n */\n.tableScroll {\n overflow-x: auto;\n}\n\n.tableScroll:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: 2px;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tempest-text-sm);\n}\n\n.table th,\n.table td {\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n text-align: left;\n}\n\n.table th {\n color: var(--tempest-text-muted);\n font-weight: var(--tempest-weight-semibold);\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Markdown.module.js","names":[],"sources":["../../../src/components/Markdown/Markdown.module.css"],"sourcesContent":[".root {\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n font-size: var(--tempest-text-base);\n line-height: var(--tempest-leading-relaxed);\n overflow-wrap: anywhere;\n}\n\n/*\n * Every block spaces itself with `margin-block-end` and the last child clears it,\n * so a Markdown body dropped into a card does not add a phantom gap at the bottom.\n */\n.root > * {\n margin-block: 0 var(--tempest-space-3);\n}\n\n.root > *:last-child {\n margin-block-end: 0;\n}\n\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n margin-block-start: var(--tempest-space-5);\n font-weight: var(--tempest-weight-semibold);\n line-height: var(--tempest-leading-tight);\n}\n\n.root > .h1:first-child,\n.root > .h2:first-child,\n.root > .h3:first-child,\n.root > .h4:first-child,\n.root > .h5:first-child,\n.root > .h6:first-child {\n margin-block-start: 0;\n}\n\n.h1 {\n font-size: var(--tempest-text-2xl);\n}\n\n.h2 {\n font-size: var(--tempest-text-xl);\n}\n\n.h3 {\n font-size: var(--tempest-text-lg);\n}\n\n.h4,\n.h5,\n.h6 {\n font-size: var(--tempest-text-base);\n}\n\n.list {\n padding-inline-start: var(--tempest-space-6);\n}\n\n.list .list {\n margin-block: var(--tempest-space-1) 0;\n}\n\n.item {\n margin-block-end: var(--tempest-space-1);\n}\n\n.item > p {\n margin: 0;\n}\n\n.quote {\n padding-inline-start: var(--tempest-space-4);\n border-inline-start: 3px solid var(--tempest-border-strong);\n color: var(--tempest-text-muted);\n}\n\n.rule {\n height: 1px;\n border: 0;\n background-color: var(--tempest-border);\n}\n\n.inlineCode {\n padding: 0.1em 0.35em;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n font-family: var(--tempest-font-mono);\n font-size: 0.9em;\n}\n\n.link {\n color: var(--tempest-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.image {\n max-width: 100%;\n height: auto;\n border-radius: var(--tempest-radius-md);\n}\n\n/*\n * A wide table scrolls inside its own box, and that box is focusable — a scroll\n * container with nothing focusable inside cannot be reached by keyboard, which is\n * the same defect the Table fix addressed.\n */\n.tableScroll {\n overflow-x: auto;\n}\n\n.tableScroll:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: 2px;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--tempest-text-sm);\n}\n\n.table th,\n.table td {\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n text-align: left;\n}\n\n.table th {\n color: var(--tempest-text-muted);\n font-weight: var(--tempest-weight-semibold);\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordInput.module.cjs","names":[],"sources":["../../../src/components/PasswordInput/PasswordInput.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n font-family: var(--tempest-font-sans);\n width: 100%;\n}\n\n.label {\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n color: var(--tempest-text);\n}\n\n.field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background: var(--tempest-surface);\n transition: border-color var(--tempest-duration-fast, 120ms);\n}\n\n.field:focus-within {\n border-color: var(--tempest-primary);\n box-shadow: 0 0 0 var(--tempest-focus-ring-width, 2px)\n var(--tempest-focus-ring-color, var(--tempest-primary-100));\n}\n\n.input {\n flex: 1 1 auto;\n border: 0;\n background: transparent;\n outline: 0;\n color: var(--tempest-text);\n font: inherit;\n font-family: var(--tempest-font-sans);\n}\n\n.sm .input {\n padding: 6px 8px;\n font-size: var(--tempest-text-sm);\n}\n\n.md .input {\n padding: 8px 12px;\n font-size: var(--tempest-text-md);\n}\n\n.lg .input {\n padding: 10px 14px;\n font-size: var(--tempest-text-lg);\n}\n\n.toggle {\n flex: 0 0 auto;\n background: none;\n border: 0;\n cursor: pointer;\n padding: 0 12px;\n font-size: 16px;\n color: var(--tempest-text-muted);\n}\n\n.toggle:hover {\n color: var(--tempest-text);\n}\n\n.error .field {\n border-color: var(--tempest-danger-border, var(--tempest-danger));\n}\n\n.helper {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n}\n\n.errorText {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-danger-fg, var(--tempest-danger));\n}\n\n.strength {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n\n.strengthBar {\n flex: 1 1 auto;\n height: 4px;\n background: var(--tempest-gray-200, var(--tempest-border));\n border-radius: var(--tempest-radius-full);\n overflow: hidden;\n}\n\n.strengthBar > span {\n display: block;\n height: 100%;\n transition: width var(--tempest-duration-base, 200ms);\n}\n\n.strengthLabel {\n color: var(--tempest-text-muted);\n flex: 0 0 auto;\n}\n\n.level0 .strengthBar > span,\n.level1 .strengthBar > span {\n background: var(--tempest-danger-solid, var(--tempest-danger));\n}\n\n.level2 .strengthBar > span {\n background: var(--tempest-warning-solid, var(--tempest-warning));\n}\n\n.level3 .strengthBar > span,\n.level4 .strengthBar > span {\n background: var(--tempest-success-solid, var(--tempest-success));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"PasswordInput.module.cjs","names":[],"sources":["../../../src/components/PasswordInput/PasswordInput.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n font-family: var(--tempest-font-sans);\n width: 100%;\n}\n\n.label {\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n color: var(--tempest-text);\n}\n\n.field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background: var(--tempest-surface);\n transition: border-color var(--tempest-duration-fast, 120ms);\n}\n\n.field:focus-within {\n border-color: var(--tempest-primary);\n box-shadow: 0 0 0 var(--tempest-focus-ring-width, 2px)\n var(--tempest-focus-ring-color, var(--tempest-primary-100));\n}\n\n.input {\n flex: 1 1 auto;\n border: 0;\n background: transparent;\n outline: 0;\n color: var(--tempest-text);\n font: inherit;\n font-family: var(--tempest-font-sans);\n}\n\n.sm .input {\n padding: 6px 8px;\n font-size: var(--tempest-text-sm);\n}\n\n.md .input {\n padding: 8px 12px;\n font-size: var(--tempest-text-md);\n}\n\n.lg .input {\n padding: 10px 14px;\n font-size: var(--tempest-text-lg);\n}\n\n.toggle {\n flex: 0 0 auto;\n background: none;\n border: 0;\n cursor: pointer;\n padding: 0 12px;\n font-size: 16px;\n color: var(--tempest-text-muted);\n}\n\n.toggle:hover {\n color: var(--tempest-text);\n}\n\n.error .field {\n border-color: var(--tempest-danger-border, var(--tempest-danger));\n}\n\n.helper {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n}\n\n.errorText {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-danger-fg, var(--tempest-danger));\n}\n\n.strength {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n\n.strengthBar {\n flex: 1 1 auto;\n height: 4px;\n background: var(--tempest-border);\n border-radius: var(--tempest-radius-full);\n overflow: hidden;\n}\n\n.strengthBar > span {\n display: block;\n height: 100%;\n transition: width var(--tempest-duration-base, 200ms);\n}\n\n.strengthLabel {\n color: var(--tempest-text-muted);\n flex: 0 0 auto;\n}\n\n.level0 .strengthBar > span,\n.level1 .strengthBar > span {\n background: var(--tempest-danger-solid, var(--tempest-danger));\n}\n\n.level2 .strengthBar > span {\n background: var(--tempest-warning-solid, var(--tempest-warning));\n}\n\n.level3 .strengthBar > span,\n.level4 .strengthBar > span {\n background: var(--tempest-success-solid, var(--tempest-success));\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordInput.module.js","names":[],"sources":["../../../src/components/PasswordInput/PasswordInput.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n font-family: var(--tempest-font-sans);\n width: 100%;\n}\n\n.label {\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n color: var(--tempest-text);\n}\n\n.field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background: var(--tempest-surface);\n transition: border-color var(--tempest-duration-fast, 120ms);\n}\n\n.field:focus-within {\n border-color: var(--tempest-primary);\n box-shadow: 0 0 0 var(--tempest-focus-ring-width, 2px)\n var(--tempest-focus-ring-color, var(--tempest-primary-100));\n}\n\n.input {\n flex: 1 1 auto;\n border: 0;\n background: transparent;\n outline: 0;\n color: var(--tempest-text);\n font: inherit;\n font-family: var(--tempest-font-sans);\n}\n\n.sm .input {\n padding: 6px 8px;\n font-size: var(--tempest-text-sm);\n}\n\n.md .input {\n padding: 8px 12px;\n font-size: var(--tempest-text-md);\n}\n\n.lg .input {\n padding: 10px 14px;\n font-size: var(--tempest-text-lg);\n}\n\n.toggle {\n flex: 0 0 auto;\n background: none;\n border: 0;\n cursor: pointer;\n padding: 0 12px;\n font-size: 16px;\n color: var(--tempest-text-muted);\n}\n\n.toggle:hover {\n color: var(--tempest-text);\n}\n\n.error .field {\n border-color: var(--tempest-danger-border, var(--tempest-danger));\n}\n\n.helper {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n}\n\n.errorText {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-danger-fg, var(--tempest-danger));\n}\n\n.strength {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n\n.strengthBar {\n flex: 1 1 auto;\n height: 4px;\n background: var(--tempest-gray-200, var(--tempest-border));\n border-radius: var(--tempest-radius-full);\n overflow: hidden;\n}\n\n.strengthBar > span {\n display: block;\n height: 100%;\n transition: width var(--tempest-duration-base, 200ms);\n}\n\n.strengthLabel {\n color: var(--tempest-text-muted);\n flex: 0 0 auto;\n}\n\n.level0 .strengthBar > span,\n.level1 .strengthBar > span {\n background: var(--tempest-danger-solid, var(--tempest-danger));\n}\n\n.level2 .strengthBar > span {\n background: var(--tempest-warning-solid, var(--tempest-warning));\n}\n\n.level3 .strengthBar > span,\n.level4 .strengthBar > span {\n background: var(--tempest-success-solid, var(--tempest-success));\n}\n"],"mappings":""}
1
+ {"version":3,"file":"PasswordInput.module.js","names":[],"sources":["../../../src/components/PasswordInput/PasswordInput.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n font-family: var(--tempest-font-sans);\n width: 100%;\n}\n\n.label {\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n color: var(--tempest-text);\n}\n\n.field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background: var(--tempest-surface);\n transition: border-color var(--tempest-duration-fast, 120ms);\n}\n\n.field:focus-within {\n border-color: var(--tempest-primary);\n box-shadow: 0 0 0 var(--tempest-focus-ring-width, 2px)\n var(--tempest-focus-ring-color, var(--tempest-primary-100));\n}\n\n.input {\n flex: 1 1 auto;\n border: 0;\n background: transparent;\n outline: 0;\n color: var(--tempest-text);\n font: inherit;\n font-family: var(--tempest-font-sans);\n}\n\n.sm .input {\n padding: 6px 8px;\n font-size: var(--tempest-text-sm);\n}\n\n.md .input {\n padding: 8px 12px;\n font-size: var(--tempest-text-md);\n}\n\n.lg .input {\n padding: 10px 14px;\n font-size: var(--tempest-text-lg);\n}\n\n.toggle {\n flex: 0 0 auto;\n background: none;\n border: 0;\n cursor: pointer;\n padding: 0 12px;\n font-size: 16px;\n color: var(--tempest-text-muted);\n}\n\n.toggle:hover {\n color: var(--tempest-text);\n}\n\n.error .field {\n border-color: var(--tempest-danger-border, var(--tempest-danger));\n}\n\n.helper {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n}\n\n.errorText {\n font-size: var(--tempest-text-xs);\n color: var(--tempest-danger-fg, var(--tempest-danger));\n}\n\n.strength {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n font-size: var(--tempest-text-xs);\n}\n\n.strengthBar {\n flex: 1 1 auto;\n height: 4px;\n background: var(--tempest-border);\n border-radius: var(--tempest-radius-full);\n overflow: hidden;\n}\n\n.strengthBar > span {\n display: block;\n height: 100%;\n transition: width var(--tempest-duration-base, 200ms);\n}\n\n.strengthLabel {\n color: var(--tempest-text-muted);\n flex: 0 0 auto;\n}\n\n.level0 .strengthBar > span,\n.level1 .strengthBar > span {\n background: var(--tempest-danger-solid, var(--tempest-danger));\n}\n\n.level2 .strengthBar > span {\n background: var(--tempest-warning-solid, var(--tempest-warning));\n}\n\n.level3 .strengthBar > span,\n.level4 .strengthBar > span {\n background: var(--tempest-success-solid, var(--tempest-success));\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.module.cjs","names":[],"sources":["../../../src/components/SegmentedControl/SegmentedControl.module.css"],"sourcesContent":[".group {\n display: inline-flex;\n background: var(--tempest-gray-100);\n border-radius: var(--tempest-radius-md);\n padding: 2px;\n font-family: var(--tempest-font-sans);\n gap: 0;\n}\n\n.group.fullWidth {\n display: flex;\n width: 100%;\n}\n\n.segment {\n flex: 1 1 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--tempest-space-1);\n padding: 6px 12px;\n border: 0;\n background: transparent;\n color: var(--tempest-text-muted);\n cursor: pointer;\n border-radius: calc(var(--tempest-radius-md) - 2px);\n font-weight: var(--tempest-weight-medium);\n transition:\n background var(--tempest-duration-fast, 120ms),\n color var(--tempest-duration-fast, 120ms);\n white-space: nowrap;\n}\n\n.group.sm .segment {\n padding: 4px 10px;\n font-size: var(--tempest-text-xs);\n min-height: 24px;\n}\n\n.group.md .segment {\n padding: 6px 12px;\n font-size: var(--tempest-text-sm);\n min-height: 32px;\n}\n\n.group.lg .segment {\n padding: 8px 14px;\n font-size: var(--tempest-text-md);\n min-height: 40px;\n}\n\n.segment:hover {\n color: var(--tempest-text);\n}\n\n.segment.active {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n box-shadow: var(--tempest-shadow-xs, 0 1px 2px rgb(0 0 0 / 0.08));\n}\n\n.segment:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n}\n\n.label {\n line-height: 1;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"SegmentedControl.module.cjs","names":[],"sources":["../../../src/components/SegmentedControl/SegmentedControl.module.css"],"sourcesContent":[".group {\n display: inline-flex;\n background: var(--tempest-surface-2);\n border-radius: var(--tempest-radius-md);\n padding: 2px;\n font-family: var(--tempest-font-sans);\n gap: 0;\n}\n\n.group.fullWidth {\n display: flex;\n width: 100%;\n}\n\n.segment {\n flex: 1 1 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--tempest-space-1);\n padding: 6px 12px;\n border: 0;\n background: transparent;\n color: var(--tempest-text-muted);\n cursor: pointer;\n border-radius: calc(var(--tempest-radius-md) - 2px);\n font-weight: var(--tempest-weight-medium);\n transition:\n background var(--tempest-duration-fast, 120ms),\n color var(--tempest-duration-fast, 120ms);\n white-space: nowrap;\n}\n\n.group.sm .segment {\n padding: 4px 10px;\n font-size: var(--tempest-text-xs);\n min-height: 24px;\n}\n\n.group.md .segment {\n padding: 6px 12px;\n font-size: var(--tempest-text-sm);\n min-height: 32px;\n}\n\n.group.lg .segment {\n padding: 8px 14px;\n font-size: var(--tempest-text-md);\n min-height: 40px;\n}\n\n.segment:hover {\n color: var(--tempest-text);\n}\n\n.segment.active {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n box-shadow: var(--tempest-shadow-xs, 0 1px 2px rgb(0 0 0 / 0.08));\n}\n\n.segment:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.icon {\n display: inline-flex;\n align-items: center;\n}\n\n.label {\n line-height: 1;\n}\n"],"mappings":""}