@evolve.ui/theme-system 1.0.1 → 1.2.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 (119) hide show
  1. package/{allThemes-CFS_9-tk.cjs → allThemes-3d8nhymo.cjs} +12 -2
  2. package/allThemes-3d8nhymo.cjs.map +1 -0
  3. package/{allThemes-OV-ayn4C.mjs → allThemes-Abn6KDm7.mjs} +7 -3
  4. package/allThemes-Abn6KDm7.mjs.map +1 -0
  5. package/allThemes.cjs +1 -1
  6. package/allThemes.d.cts +1 -0
  7. package/allThemes.d.cts.map +1 -1
  8. package/allThemes.d.mts +1 -0
  9. package/allThemes.d.mts.map +1 -1
  10. package/allThemes.mjs +1 -1
  11. package/brands-CE0wIkKX.d.cts +58 -0
  12. package/brands-CE0wIkKX.d.cts.map +1 -0
  13. package/brands-CE0wIkKX.d.mts +58 -0
  14. package/brands-CE0wIkKX.d.mts.map +1 -0
  15. package/brands.cjs +16 -13
  16. package/brands.cjs.map +1 -1
  17. package/brands.d.cts +2 -2
  18. package/brands.d.mts +2 -2
  19. package/brands.mjs +16 -13
  20. package/brands.mjs.map +1 -1
  21. package/css/EverydayHarbor.css +377 -0
  22. package/css/EverydayHarbor.effects.css +650 -0
  23. package/{default-b-tgfyxR.cjs → default-B6VWF0Js.cjs} +237 -36
  24. package/default-B6VWF0Js.cjs.map +1 -0
  25. package/{default-B2n4PnsJ.mjs → default-BogJDhKE.mjs} +238 -37
  26. package/default-BogJDhKE.mjs.map +1 -0
  27. package/effects.cjs +26 -0
  28. package/effects.cjs.map +1 -0
  29. package/effects.d.cts +22 -0
  30. package/effects.d.cts.map +1 -0
  31. package/effects.d.mts +22 -0
  32. package/effects.d.mts.map +1 -0
  33. package/effects.mjs +22 -0
  34. package/effects.mjs.map +1 -0
  35. package/evolve-ui.entries.json +51 -0
  36. package/index.cjs +12 -5
  37. package/index.cjs.map +1 -1
  38. package/index.d.cts +108 -4
  39. package/index.d.cts.map +1 -1
  40. package/index.d.mts +108 -4
  41. package/index.d.mts.map +1 -1
  42. package/index.mjs +9 -6
  43. package/index.mjs.map +1 -1
  44. package/package.json +5 -1
  45. package/{plugin-DPtvp4lp.cjs → plugin-B3PF4RMI.cjs} +299 -110
  46. package/plugin-B3PF4RMI.cjs.map +1 -0
  47. package/{plugin-D4eCyUJe.mjs → plugin-D6aLCeNB.mjs} +258 -111
  48. package/plugin-D6aLCeNB.mjs.map +1 -0
  49. package/src/effects/__fixtures__/fixtureLayer.ts +88 -0
  50. package/src/effects/brands/EverydayHarbor.ts +392 -0
  51. package/src/effects/classes.ts +19 -0
  52. package/src/effects/emit.ts +314 -0
  53. package/src/effects/hooks.ts +493 -0
  54. package/src/effects/index.ts +2 -0
  55. package/src/effects/layers.ts +18 -0
  56. package/src/effects/rules.ts +90 -0
  57. package/src/effects/rules.typecheck.ts +50 -0
  58. package/src/effects/tokens.ts +148 -0
  59. package/src/effects/validate.ts +683 -0
  60. package/src/effects/vocabulary.ts +32 -0
  61. package/src/index.ts +40 -0
  62. package/src/tailwind/animation.ts +30 -0
  63. package/src/tailwind/borderRadius.ts +32 -0
  64. package/src/tailwind/borderWidth.ts +14 -0
  65. package/src/tailwind/boxShadow.ts +19 -0
  66. package/src/tailwind/colors.ts +332 -0
  67. package/src/tailwind/cssVars.ts +301 -0
  68. package/src/tailwind/fontFamily.ts +14 -0
  69. package/src/tailwind/plugin.ts +299 -0
  70. package/src/tailwind/reducedMotion.ts +164 -0
  71. package/src/tailwind/screens.ts +22 -0
  72. package/src/tailwind/spacing.ts +20 -0
  73. package/src/tailwind/text.ts +172 -0
  74. package/src/tailwind/width.ts +14 -0
  75. package/src/themeValues.snapshot.ts +6735 -0
  76. package/src/themes/BasketballTraining.ts +166 -0
  77. package/src/themes/Default.ts +165 -0
  78. package/src/themes/EverydayHarbor.ts +147 -0
  79. package/src/themes/ProfessionalBrand.ts +166 -0
  80. package/src/themes/allThemes.ts +14 -0
  81. package/src/themes/brandSources.ts +37 -0
  82. package/src/themes/brands.ts +63 -0
  83. package/src/themes/common.ts +65 -0
  84. package/src/themes/contrastFloors.ts +26 -0
  85. package/src/themes/generateCSSVars.ts +123 -0
  86. package/src/themes/inkRamps.ts +43 -0
  87. package/src/themes/runtime/basketballTraining.ts +3 -0
  88. package/src/themes/runtime/buildTheme.ts +411 -0
  89. package/src/themes/runtime/default.ts +3 -0
  90. package/src/themes/runtime/everydayHarbor.ts +3 -0
  91. package/src/themes/runtime/professionalBrand.ts +3 -0
  92. package/src/themes/semanticColorTokenSteps.ts +23 -0
  93. package/src/themes/themeType.ts +169 -0
  94. package/src/themes/themeValues.ts +374 -0
  95. package/src/themes/wcag.ts +48 -0
  96. package/src/themes/writeToCSSFile.ts +11 -0
  97. package/src/utils/cn.ts +35 -0
  98. package/src/utils/color.ts +82 -0
  99. package/src/utils/wrapVar.ts +24 -0
  100. package/tailwind/plugin.cjs +5 -1
  101. package/tailwind/plugin.d.cts +458 -1
  102. package/tailwind/plugin.d.cts.map +1 -1
  103. package/tailwind/plugin.d.mts +458 -1
  104. package/tailwind/plugin.d.mts.map +1 -1
  105. package/tailwind/plugin.mjs +2 -2
  106. package/themes/runtime/default.cjs +1 -1
  107. package/themes/runtime/default.mjs +1 -1
  108. package/themes/themeType.d.cts +1 -1
  109. package/themes/themeType.d.mts +1 -1
  110. package/allThemes-CFS_9-tk.cjs.map +0 -1
  111. package/allThemes-OV-ayn4C.mjs.map +0 -1
  112. package/brands-n30rolHQ.d.cts +0 -33
  113. package/brands-n30rolHQ.d.cts.map +0 -1
  114. package/brands-n30rolHQ.d.mts +0 -33
  115. package/brands-n30rolHQ.d.mts.map +0 -1
  116. package/default-B2n4PnsJ.mjs.map +0 -1
  117. package/default-b-tgfyxR.cjs.map +0 -1
  118. package/plugin-D4eCyUJe.mjs.map +0 -1
  119. package/plugin-DPtvp4lp.cjs.map +0 -1
@@ -1,6 +1,52 @@
1
1
  import { $ as colorIconPrimary, $n as fontWeightLabelMini, $t as colorSurface100, A as colorBorderInverse, An as colorWarning300, At as colorPrimary700, B as colorCritical400, Bt as colorSecondary700, C as colorBackgroundWarningDark, Cn as colorTextInverse, Ct as colorPrimary100, D as colorBorderDisabled, Dn as colorTextWarning, Dr as widthPage, Dt as colorPrimary50, E as colorBorderCritical, En as colorTextSuccess, Er as widthDense, Et as colorPrimary400, F as colorBorderTertiary, Fn as colorWarning700, Ft as colorSecondary300, G as colorCritical800, Gt as colorSuccess300, H as colorCritical500, Ht as colorSecondary900, I as colorBorderWarning, In as colorWarning800, It as colorSecondary400, J as colorFocusPrimary, Jn as fontWeightH2, Jt as colorSuccess500, K as colorCritical900, Kn as fontWeightCaption, Kt as colorSuccess400, L as colorCritical100, Ln as colorWarning900, Lt as colorSecondary50, M as colorBorderSecondary, Mn as colorWarning50, Mt as colorPrimary900, N as colorBorderSelected, Nn as colorWarning500, Nt as colorSecondary100, O as colorBorderHover, On as colorWarning100, Or as wrapOpacity, Ot as colorPrimary500, P as colorBorderSuccess, Pn as colorWarning600, Pt as colorSecondary200, Q as colorIconInverse, Qn as fontWeightH6, Qt as colorSuccess900, R as colorCritical200, Rt as colorSecondary500, S as colorBackgroundTertiary, Sn as colorTextInfo, St as colorLinkSecondary, T as colorBorderBlack, Tn as colorTextSecondary, Tr as textTransformLabelMini, Tt as colorPrimary300, U as colorCritical600, Un as fontWeightBodyPrimary, Ut as colorSuccess100, V as colorCritical50, Vt as colorSecondary800, W as colorCritical700, Wn as fontWeightBodySecondary, Wt as colorSuccess200, X as colorIconDisabled, Xn as fontWeightH4, Xt as colorSuccess700, Y as colorIconCritical, Yn as fontWeightH3, Yt as colorSuccess600, Z as colorIconInfo, Zn as fontWeightH5, Zt as colorSuccess800, _ as colorBackgroundPrimary, _n as colorTertiary800, _t as colorLinkInverseHover, an as colorSurface600, ar as letterSpacingCaption, at as colorInfo300, b as colorBackgroundSuccessDark, bn as colorTextDisabled, bt as colorLinkPressed, c as colorBackgroundDisabled, cn as colorSurface900, cr as letterSpacingH2, ct as colorInfo500, d as colorBackgroundInfoDark, dn as colorTertiary300, dr as letterSpacingH3Mobile, dt as colorInfo800, en as colorSurface200, er as fontWeightLabelStrong, et as colorIconSecondary, f as colorBackgroundInfoLight, fn as colorTertiary400, fr as letterSpacingH4, ft as colorInfo900, g as colorBackgroundPressedInverse, gn as colorTertiary700, gr as letterSpacingLabelStrong, gt as colorLinkInverseDisabled, h as colorBackgroundPressed, hn as colorTertiary600, hr as letterSpacingLabelMini, ht as colorLinkInverse, in as colorSurface500, it as colorInfo200, j as colorBorderPrimary, jn as colorWarning400, jr as wrapVariableOpacity, jt as colorPrimary800, k as colorBorderInfo, kn as colorWarning200, kr as wrapVar, kt as colorPrimary600, l as colorBackgroundHover, ln as colorTertiary100, lr as letterSpacingH2Mobile, lt as colorInfo600, m as colorBackgroundOverlay, mn as colorTertiary500, mr as letterSpacingH6, mt as colorLinkHover, n as screens, nn as colorSurface400, nr as letterSpacingBodyPrimary, nt as colorIconWarning, o as colorBackgroundCriticalDark, on as colorSurface700, or as letterSpacingH1, ot as colorInfo400, p as colorBackgroundInverse, pn as colorTertiary50, pr as letterSpacingH5, pt as colorLinkDisabled, q as colorFocusInverse, qn as fontWeightH1, qt as colorSuccess50, r as borderRadius, rn as colorSurface50, rr as letterSpacingBodySecondary, rt as colorInfo100, s as colorBackgroundCriticalLight, sn as colorSurface800, sr as letterSpacingH1Mobile, st as colorInfo50, t as spacing, tn as colorSurface300, tt as colorIconSuccess, u as colorBackgroundHoverInverse, un as colorTertiary200, ur as letterSpacingH3, ut as colorInfo700, v as colorBackgroundSecondary, vn as colorTertiary900, vt as colorLinkInversePressed, w as colorBackgroundWarningLight, wn as colorTextPrimary, wr as textTransformH6, wt as colorPrimary200, x as colorBackgroundSuccessLight, xn as colorTextInactive, xt as colorLinkPrimary, y as colorBackgroundSubdued, yn as colorTextCritical, yt as colorLinkMonochrome, z as colorCritical300, zt as colorSecondary600 } from "./spacing-D43IZfIU.mjs";
2
2
  import { n as boxShadow, t as fontFamily } from "./fontFamily-DTm-Yz5-.mjs";
3
3
  import plugin from "tailwindcss/plugin.js";
4
+ //#region src/tailwind/animation.ts
5
+ /**
6
+ * Animation registry for the theme system
7
+ *
8
+ * The `animate-*` utilities this library registers, extracted from `plugin.ts` so the
9
+ * reduced-motion policy can be checked against them (see `./reducedMotion`). These sit under
10
+ * `theme.extend`, so Tailwind's own defaults (`spin`, `ping`, `pulse`, `bounce`, `none`) survive
11
+ * alongside them — the resolved registry is this object layered over `defaultTheme.animation`,
12
+ * and the policy must cover both.
13
+ *
14
+ * Keyframes stay in `plugin.ts` next to the `addBase` block that emits some of them.
15
+ */
16
+ const animation = {
17
+ fadeIn: "fadeIn .2s ease-in-out",
18
+ fadeInOpacity: "fadeInOpacity 0.5s ease-in-out",
19
+ fadeInScaled: "fadeInScaled .2s ease-in",
20
+ fadeOut: "fadeOut .2s ease-in-out",
21
+ loading: "loading 1.4s infinite ease-in-out",
22
+ "progress-completion": "shrink 0.15s ease-in-out both, grow 0.15s ease-in-out 0.15s both",
23
+ "progress-icon-fade-in": "fadeInOpacity 0.15s ease-in-out 0.15s both",
24
+ "progress-wave": "progressWave 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, progressWaveRotate 1568ms linear infinite both",
25
+ saveButtonPulse: "saveButtonPulse 500ms cubic-bezier(0.34, 1.56, 0.64, 1)",
26
+ saveButtonWiggle: "saveButtonWiggle 500ms ease-in-out",
27
+ saveHeartColorFlash: "saveHeartColorFlash 500ms cubic-bezier(0.45, 0, 0.55, 1)",
28
+ saveHeartPop: "saveHeartPop 480ms cubic-bezier(0.34, 1.56, 0.64, 1)",
29
+ saveHeartTwirlBloom: "saveHeartTwirlBloom 500ms cubic-bezier(0.45, 0, 0.55, 1)",
30
+ saveLabelShimmer: "saveLabelShimmer 500ms ease-in-out",
31
+ slideDown: "slideDown 0.3s ease-in forwards",
32
+ slideUp: "slideUp 0.3s ease-out forwards"
33
+ };
34
+ //#endregion
35
+ //#region src/tailwind/borderWidth.ts
36
+ /**
37
+ * Border width scale the theme ships.
38
+ *
39
+ * These match the widths Tailwind uses when a plugin does not replace `borderWidth`.
40
+ * They sit on the theme object so the value snapshot locks the same scale.
41
+ */
42
+ const borderWidth = {
43
+ DEFAULT: "1px",
44
+ 0: "0px",
45
+ 2: "2px",
46
+ 4: "4px",
47
+ 8: "8px"
48
+ };
49
+ //#endregion
4
50
  //#region src/tailwind/colors.ts
5
51
  /**
6
52
  * Color configuration for Tailwind CSS
@@ -190,6 +236,120 @@ const colors = {
190
236
  }
191
237
  };
192
238
  //#endregion
239
+ //#region src/tailwind/reducedMotion.ts
240
+ const REDUCED_MOTION_POLICY = {
241
+ fadeIn: {
242
+ reason: "Opacity only, but collapsed alongside fadeInScaled so a modal opens the same way in both variants (ComposableModal picks between them on hasContentPager).",
243
+ tier: "instant"
244
+ },
245
+ fadeInOpacity: {
246
+ reason: "Opacity and visibility only; collapsing a fade is not a motion regression.",
247
+ tier: "instant"
248
+ },
249
+ fadeInScaled: {
250
+ reason: "Scales 0.7 to 1.",
251
+ tier: "instant"
252
+ },
253
+ fadeOut: {
254
+ reason: "Scales 1 to 0.7. Modal close depends on its animationend, so it is collapsed rather than removed.",
255
+ tier: "instant"
256
+ },
257
+ loading: {
258
+ reason: "Infinite indeterminate loading indicator (LoadingDot). Collapsing it removes the only signal that work is in progress.",
259
+ tier: "retain"
260
+ },
261
+ "progress-completion": {
262
+ reason: "Scales. Zeroing the delay matters here: the composite is \"shrink 0.15s both, grow 0.15s ease-in-out 0.15s both\", so a duration-only collapse would hold the ring at scale(0.5) for 150ms and then snap.",
263
+ tier: "instant"
264
+ },
265
+ "progress-icon-fade-in": {
266
+ reason: "Opacity only, but its 0.15s delay sequences it after progress-completion. Retaining it would leave a completed ProgressCircle ring with an empty centre for 150ms.",
267
+ tier: "instant"
268
+ },
269
+ "progress-wave": {
270
+ reason: "Infinite indeterminate progress indicator (ProgressCircle). Same essential-feedback rationale as loading.",
271
+ tier: "retain"
272
+ },
273
+ saveButtonPulse: {
274
+ reason: "Scales.",
275
+ tier: "instant"
276
+ },
277
+ saveButtonWiggle: {
278
+ reason: "Rotates and scales.",
279
+ tier: "instant"
280
+ },
281
+ saveHeartColorFlash: {
282
+ reason: "Animates fill only, but it was already gated before DS-95 and must stay gated. Shipped via .hui-fb-color-flash, not the animate-* utility (which has no call sites), so it needs the explicit selector below.",
283
+ selectors: [".hui-fb-color-flash .hui-fb-icon-frame svg path"],
284
+ tier: "instant"
285
+ },
286
+ saveHeartPop: {
287
+ reason: "Scales.",
288
+ tier: "instant"
289
+ },
290
+ saveHeartTwirlBloom: {
291
+ reason: "Rotates 180 degrees at 1.15x scale.",
292
+ tier: "instant"
293
+ },
294
+ saveLabelShimmer: {
295
+ reason: "Animates background-position. The .hui-fb-shimmer paint block in plugin.ts separately drops the gradient under reduce so the label stays legible.",
296
+ tier: "instant"
297
+ },
298
+ slideDown: {
299
+ reason: "Translates on Y. Collapsed rather than removed so CookieConsent still receives animationend.",
300
+ tier: "instant"
301
+ },
302
+ slideUp: {
303
+ reason: "Translates on Y. Same animationend rationale as slideDown.",
304
+ tier: "instant"
305
+ },
306
+ bounce: {
307
+ reason: "Translates on Y.",
308
+ tier: "instant"
309
+ },
310
+ none: {
311
+ reason: "Not an animation — animate-none is the absence utility.",
312
+ tier: "n/a"
313
+ },
314
+ ping: {
315
+ reason: "Scales and fades. No in-repo call site, but consumers can use it.",
316
+ tier: "instant"
317
+ },
318
+ pulse: {
319
+ reason: "Infinite, but opacity only — the conventional skeleton-loading indicator. Retained as essential feedback with no motion component.",
320
+ tier: "retain"
321
+ },
322
+ spin: {
323
+ reason: "Infinite indeterminate spinner (LoadingSpinner, ProgressCircle). A Tailwind default rather than a local entry, which is exactly why the policy is keyed on the resolved registry.",
324
+ tier: "retain"
325
+ }
326
+ };
327
+ const REDUCE_QUERY = "@media (prefers-reduced-motion: reduce)";
328
+ const COLLAPSED_DECLARATIONS = {
329
+ "animation-delay": "0ms !important",
330
+ "animation-duration": "1ms !important",
331
+ "animation-iteration-count": "1 !important"
332
+ };
333
+ /**
334
+ * Builds the `@media (prefers-reduced-motion: reduce)` block for `addBase`.
335
+ *
336
+ * Emitted from `addBase` rather than `addComponents` deliberately: `addComponents` is subject to
337
+ * caching discrepancies in this monorepo's Storybook build that stop newly added rules landing.
338
+ */
339
+ const buildReducedMotionBase = () => {
340
+ const rules = {};
341
+ const addRule = (selector) => {
342
+ if (rules[selector]) throw new Error(`Duplicate reduced-motion selector: ${selector}`);
343
+ rules[selector] = { ...COLLAPSED_DECLARATIONS };
344
+ };
345
+ Object.entries(REDUCED_MOTION_POLICY).forEach(([key, entry]) => {
346
+ if (entry.tier !== "instant") return;
347
+ addRule(`.animate-${key}.animate-${key}`);
348
+ entry.selectors?.forEach(addRule);
349
+ });
350
+ return { [REDUCE_QUERY]: rules };
351
+ };
352
+ //#endregion
193
353
  //#region src/tailwind/text.ts
194
354
  const textComponents = {
195
355
  ".hui-link-md": {
@@ -265,9 +425,9 @@ const textComponents = {
265
425
  letterSpacing: wrapVar(letterSpacingH3),
266
426
  lineHeight: "30px",
267
427
  [`@media (width < ${screens.smMax.max})`]: {
268
- fontSize: "16px",
428
+ fontSize: "18px",
269
429
  letterSpacing: wrapVar(letterSpacingH3Mobile),
270
- lineHeight: "24px"
430
+ lineHeight: "27px"
271
431
  }
272
432
  },
273
433
  ".hui-text-h4": {
@@ -344,109 +504,13 @@ const autofillStyles = {
344
504
  "-webkit-box-shadow": "0 0 0 12px rgb(var(--color-background-primary)) inset !important",
345
505
  "box-shadow": "0 0 0 12px rgb(var(--color-background-primary)) inset !important"
346
506
  };
347
- const themePlugin = plugin(({ addBase, addComponents, matchUtilities }) => {
348
- addComponents(textComponents);
349
- addComponents({
350
- ".hui-autofill-transparent": {
351
- "&:-webkit-autofill": autofillStyles,
352
- "&:-webkit-autofill:active": autofillStyles,
353
- "&:-webkit-autofill:focus": autofillStyles,
354
- "&:-webkit-autofill:hover": autofillStyles
355
- },
356
- ".hui-focus-visible-outline": { "@apply focus-visible:outline-focus-primary focus-visible:outline focus-visible:outline-4": {} },
357
- ".hui-focus-visible-outline-inverse": { "@apply focus-visible:outline-focus-inverse focus-visible:outline focus-visible:outline-4": {} },
358
- ".scrollbar-default": {
359
- "&::-webkit-scrollbar": { display: "block" },
360
- "-ms-overflow-style": "auto",
361
- "scrollbar-width": "auto"
362
- },
363
- ".scrollbar-hide": {
364
- "&::-webkit-scrollbar": { display: "none" },
365
- "-ms-overflow-style": "none",
366
- "scrollbar-width": "none"
367
- }
368
- });
369
- addBase({
370
- "@keyframes saveButtonWiggle": {
371
- "0%, 100%": { transform: "rotate(0deg) scale(1)" },
372
- "10%": { transform: "rotate(-6deg) scale(1.03)" },
373
- "25%": { transform: "rotate(5deg) scale(1.03)" },
374
- "40%": { transform: "rotate(-4deg) scale(1.02)" },
375
- "55%": { transform: "rotate(3deg) scale(1.02)" },
376
- "70%": { transform: "rotate(-1.5deg) scale(1.01)" },
377
- "85%": { transform: "rotate(0.5deg) scale(1)" }
378
- },
379
- "@keyframes saveHeartTwirlBloom": {
380
- "0%": { transform: "rotateY(0deg) scale(1)" },
381
- "50%": { transform: "rotateY(180deg) scale(1.35)" },
382
- "100%": { transform: "rotateY(360deg) scale(1)" }
383
- },
384
- "@keyframes saveHeartColorFlash": {
385
- "0%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" },
386
- "40%": { fill: "rgb(var(--hui-save-color-critical-300, var(--color-critical-300)))" },
387
- "60%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" },
388
- "100%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" }
389
- },
390
- "@keyframes saveLabelShimmer": {
391
- "0%": { backgroundPosition: "200% center" },
392
- "100%": { backgroundPosition: "-200% center" }
393
- },
394
- "@keyframes saveButtonPulse": {
395
- "0%": { transform: "scale(1)" },
396
- "35%": { transform: "scale(1.08)" },
397
- "65%": { transform: "scale(0.97)" },
398
- "100%": { transform: "scale(1)" }
399
- },
400
- "@keyframes saveHeartPop": {
401
- "0%": { transform: "scale(1)" },
402
- "20%": { transform: "scale(0.6)" },
403
- "60%": { transform: "scale(1.35)" },
404
- "100%": { transform: "scale(1)" }
405
- },
406
- ".hui-fb-shimmer": {
407
- lineHeight: "normal",
408
- backgroundImage: "linear-gradient(90deg, currentColor 0%, currentColor 20%, rgb(var(--hui-save-color-critical-200, var(--color-critical-200))) 33%, rgb(var(--hui-save-color-critical-500, var(--color-critical-500))) 50%, rgb(var(--hui-save-color-tertiary-400, var(--color-tertiary-400))) 67%, currentColor 80%, currentColor 100%)",
409
- backgroundSize: "200% 100%",
410
- backgroundClip: "text",
411
- "-webkit-background-clip": "text",
412
- "-webkit-text-fill-color": "transparent",
413
- "@media (prefers-reduced-motion: reduce)": {
414
- backgroundImage: "none !important",
415
- "-webkit-text-fill-color": "currentColor !important"
416
- }
417
- },
418
- ".hui-fb-color-flash .hui-fb-icon-frame svg path": {
419
- animation: "saveHeartColorFlash 1100ms cubic-bezier(0.45, 0, 0.55, 1) 1",
420
- animationFillMode: "forwards"
421
- },
422
- "@media (prefers-reduced-motion: reduce)": { ".hui-fb-color-flash .hui-fb-icon-frame svg path": { animation: "none !important" } }
423
- });
424
- matchUtilities({ "grid-area": (value) => {
425
- return { "grid-area": value };
426
- } });
427
- }, { theme: {
507
+ const tailwindTheme = {
428
508
  borderRadius,
509
+ borderWidth,
429
510
  boxShadow,
430
511
  colors,
431
512
  extend: {
432
- animation: {
433
- fadeIn: "fadeIn .2s ease-in-out",
434
- fadeInOpacity: "fadeInOpacity 0.5s ease-in-out",
435
- fadeInScaled: "fadeInScaled .2s ease-in",
436
- fadeOut: "fadeOut .2s ease-in-out",
437
- loading: "loading 1.4s infinite ease-in-out",
438
- "progress-completion": "shrink 0.15s ease-in-out both, grow 0.15s ease-in-out 0.15s both",
439
- "progress-icon-fade-in": "fadeInOpacity 0.15s ease-in-out 0.15s both",
440
- "progress-wave": "progressWave 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, progressWaveRotate 1568ms linear infinite both",
441
- saveButtonPulse: "saveButtonPulse 500ms cubic-bezier(0.34, 1.56, 0.64, 1)",
442
- saveButtonWiggle: "saveButtonWiggle 1.3s cubic-bezier(0.36, 0, 0.66, -0.56)",
443
- saveHeartColorFlash: "saveHeartColorFlash 1100ms cubic-bezier(0.45, 0, 0.55, 1)",
444
- saveHeartPop: "saveHeartPop 480ms cubic-bezier(0.34, 1.56, 0.64, 1)",
445
- saveHeartTwirlBloom: "saveHeartTwirlBloom 1100ms cubic-bezier(0.45, 0, 0.55, 1)",
446
- saveLabelShimmer: "saveLabelShimmer 1100ms ease-in-out",
447
- slideDown: "slideDown 0.3s ease-in forwards",
448
- slideUp: "slideUp 0.3s ease-out forwards"
449
- },
513
+ animation,
450
514
  keyframes: {
451
515
  fadeIn: {
452
516
  from: { opacity: "0" },
@@ -516,11 +580,11 @@ const themePlugin = plugin(({ addBase, addComponents, matchUtilities }) => {
516
580
  },
517
581
  saveButtonWiggle: {
518
582
  "0%, 100%": { transform: "rotate(0deg) scale(1)" },
519
- "10%": { transform: "rotate(-6deg) scale(1.03)" },
520
- "25%": { transform: "rotate(5deg) scale(1.03)" },
521
- "40%": { transform: "rotate(-4deg) scale(1.02)" },
522
- "55%": { transform: "rotate(3deg) scale(1.02)" },
523
- "70%": { transform: "rotate(-1.5deg) scale(1.01)" },
583
+ "10%": { transform: "rotate(-4deg) scale(1.02)" },
584
+ "25%": { transform: "rotate(3.5deg) scale(1.02)" },
585
+ "40%": { transform: "rotate(-2.5deg) scale(1.015)" },
586
+ "55%": { transform: "rotate(2deg) scale(1.015)" },
587
+ "70%": { transform: "rotate(-1deg) scale(1.01)" },
524
588
  "85%": { transform: "rotate(0.5deg) scale(1)" }
525
589
  },
526
590
  saveHeartColorFlash: {
@@ -537,8 +601,8 @@ const themePlugin = plugin(({ addBase, addComponents, matchUtilities }) => {
537
601
  },
538
602
  saveHeartTwirlBloom: {
539
603
  "0%": { transform: "rotateY(0deg) scale(1)" },
540
- "50%": { transform: "rotateY(180deg) scale(1.35)" },
541
- "100%": { transform: "rotateY(360deg) scale(1)" }
604
+ "30%": { transform: "rotateY(54deg) scale(1.15)" },
605
+ "100%": { transform: "rotateY(180deg) scale(1)" }
542
606
  },
543
607
  saveLabelShimmer: {
544
608
  "0%": { backgroundPosition: "200% center" },
@@ -576,8 +640,91 @@ const themePlugin = plugin(({ addBase, addComponents, matchUtilities }) => {
576
640
  },
577
641
  fontFamily,
578
642
  screens
579
- } });
643
+ };
644
+ const pluginComponentStyles = {
645
+ ".hui-autofill-transparent": {
646
+ "&:-webkit-autofill": autofillStyles,
647
+ "&:-webkit-autofill:active": autofillStyles,
648
+ "&:-webkit-autofill:focus": autofillStyles,
649
+ "&:-webkit-autofill:hover": autofillStyles
650
+ },
651
+ ".hui-focus-visible-outline": { "@apply focus-visible:outline-focus-primary focus-visible:outline focus-visible:outline-4": {} },
652
+ ".hui-focus-visible-outline-inverse": { "@apply focus-visible:outline-focus-inverse focus-visible:outline focus-visible:outline-4": {} },
653
+ ".scrollbar-default": {
654
+ "&::-webkit-scrollbar": { display: "block" },
655
+ "-ms-overflow-style": "auto",
656
+ "scrollbar-width": "auto"
657
+ },
658
+ ".scrollbar-hide": {
659
+ "&::-webkit-scrollbar": { display: "none" },
660
+ "-ms-overflow-style": "none",
661
+ "scrollbar-width": "none"
662
+ }
663
+ };
664
+ const pluginBaseStyles = {
665
+ "@keyframes saveButtonWiggle": {
666
+ "0%, 100%": { transform: "rotate(0deg) scale(1)" },
667
+ "10%": { transform: "rotate(-4deg) scale(1.02)" },
668
+ "25%": { transform: "rotate(3.5deg) scale(1.02)" },
669
+ "40%": { transform: "rotate(-2.5deg) scale(1.015)" },
670
+ "55%": { transform: "rotate(2deg) scale(1.015)" },
671
+ "70%": { transform: "rotate(-1deg) scale(1.01)" },
672
+ "85%": { transform: "rotate(0.5deg) scale(1)" }
673
+ },
674
+ "@keyframes saveHeartTwirlBloom": {
675
+ "0%": { transform: "rotateY(0deg) scale(1)" },
676
+ "30%": { transform: "rotateY(54deg) scale(1.15)" },
677
+ "100%": { transform: "rotateY(180deg) scale(1)" }
678
+ },
679
+ "@keyframes saveHeartColorFlash": {
680
+ "0%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" },
681
+ "40%": { fill: "rgb(var(--hui-save-color-critical-300, var(--color-critical-300)))" },
682
+ "60%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" },
683
+ "100%": { fill: "rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))" }
684
+ },
685
+ "@keyframes saveLabelShimmer": {
686
+ "0%": { backgroundPosition: "200% center" },
687
+ "100%": { backgroundPosition: "-200% center" }
688
+ },
689
+ "@keyframes saveButtonPulse": {
690
+ "0%": { transform: "scale(1)" },
691
+ "35%": { transform: "scale(1.08)" },
692
+ "65%": { transform: "scale(0.97)" },
693
+ "100%": { transform: "scale(1)" }
694
+ },
695
+ "@keyframes saveHeartPop": {
696
+ "0%": { transform: "scale(1)" },
697
+ "20%": { transform: "scale(0.6)" },
698
+ "60%": { transform: "scale(1.35)" },
699
+ "100%": { transform: "scale(1)" }
700
+ },
701
+ ".hui-fb-shimmer": {
702
+ lineHeight: "normal",
703
+ backgroundImage: "linear-gradient(90deg, currentColor 0%, currentColor 20%, rgb(var(--hui-save-color-critical-200, var(--color-critical-200))) 33%, rgb(var(--hui-save-color-critical-500, var(--color-critical-500))) 50%, rgb(var(--hui-save-color-tertiary-400, var(--color-tertiary-400))) 67%, currentColor 80%, currentColor 100%)",
704
+ backgroundSize: "200% 100%",
705
+ backgroundClip: "text",
706
+ "-webkit-background-clip": "text",
707
+ "-webkit-text-fill-color": "transparent",
708
+ "@media (prefers-reduced-motion: reduce)": {
709
+ backgroundImage: "none !important",
710
+ "-webkit-text-fill-color": "currentColor !important"
711
+ }
712
+ },
713
+ ".hui-fb-color-flash .hui-fb-icon-frame svg path": {
714
+ animation: "saveHeartColorFlash 500ms cubic-bezier(0.45, 0, 0.55, 1) 1",
715
+ animationFillMode: "forwards"
716
+ },
717
+ ...buildReducedMotionBase()
718
+ };
719
+ const themePlugin = plugin(({ addBase, addComponents, matchUtilities }) => {
720
+ addComponents(textComponents);
721
+ addComponents(pluginComponentStyles);
722
+ addBase(pluginBaseStyles);
723
+ matchUtilities({ "grid-area": (value) => {
724
+ return { "grid-area": value };
725
+ } });
726
+ }, { theme: tailwindTheme });
580
727
  //#endregion
581
- export { textComponents as n, colors as r, themePlugin as t };
728
+ export { themePlugin as a, buildReducedMotionBase as c, tailwindTheme as i, colors as l, pluginBaseStyles as n, textComponents as o, pluginComponentStyles as r, REDUCED_MOTION_POLICY as s, autofillStyles as t, animation as u };
582
729
 
583
- //# sourceMappingURL=plugin-D4eCyUJe.mjs.map
730
+ //# sourceMappingURL=plugin-D6aLCeNB.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-D6aLCeNB.mjs","names":[],"sources":["../src/tailwind/animation.ts","../src/tailwind/borderWidth.ts","../src/tailwind/colors.ts","../src/tailwind/reducedMotion.ts","../src/tailwind/text.ts","../src/tailwind/width.ts","../src/tailwind/plugin.ts"],"sourcesContent":["/**\n * Animation registry for the theme system\n *\n * The `animate-*` utilities this library registers, extracted from `plugin.ts` so the\n * reduced-motion policy can be checked against them (see `./reducedMotion`). These sit under\n * `theme.extend`, so Tailwind's own defaults (`spin`, `ping`, `pulse`, `bounce`, `none`) survive\n * alongside them — the resolved registry is this object layered over `defaultTheme.animation`,\n * and the policy must cover both.\n *\n * Keyframes stay in `plugin.ts` next to the `addBase` block that emits some of them.\n */\nexport const animation = {\n fadeIn: 'fadeIn .2s ease-in-out',\n fadeInOpacity: 'fadeInOpacity 0.5s ease-in-out',\n fadeInScaled: 'fadeInScaled .2s ease-in',\n fadeOut: 'fadeOut .2s ease-in-out',\n loading: 'loading 1.4s infinite ease-in-out',\n 'progress-completion': 'shrink 0.15s ease-in-out both, grow 0.15s ease-in-out 0.15s both',\n 'progress-icon-fade-in': 'fadeInOpacity 0.15s ease-in-out 0.15s both',\n 'progress-wave':\n 'progressWave 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, progressWaveRotate 1568ms linear infinite both',\n saveButtonPulse: 'saveButtonPulse 500ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n saveButtonWiggle: 'saveButtonWiggle 500ms ease-in-out',\n saveHeartColorFlash: 'saveHeartColorFlash 500ms cubic-bezier(0.45, 0, 0.55, 1)',\n saveHeartPop: 'saveHeartPop 480ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n saveHeartTwirlBloom: 'saveHeartTwirlBloom 500ms cubic-bezier(0.45, 0, 0.55, 1)',\n saveLabelShimmer: 'saveLabelShimmer 500ms ease-in-out',\n slideDown: 'slideDown 0.3s ease-in forwards',\n slideUp: 'slideUp 0.3s ease-out forwards',\n};\n","/**\n * Border width scale the theme ships.\n *\n * These match the widths Tailwind uses when a plugin does not replace `borderWidth`.\n * They sit on the theme object so the value snapshot locks the same scale.\n */\n\nexport const borderWidth = {\n DEFAULT: '1px',\n 0: '0px',\n 2: '2px',\n 4: '4px',\n 8: '8px',\n};\n","/**\n * Color configuration for Tailwind CSS\n *\n * Maps CSS custom properties to Tailwind color utilities using nested objects.\n * Uses wrapVariableOpacity() for dynamic alpha support (e.g., `bg-primary-500/50`)\n * and wrapOpacity() for fixed opacity values.\n *\n * @see https://tailwindcss.com/docs/customizing-colors#using-css-variables\n * Internal reference: Hammer UI patterns\n * Ported from the upstream theme system.\n */\n\nimport { wrapOpacity, wrapVar, wrapVariableOpacity } from '../utils/wrapVar';\nimport {\n colorBackgroundCriticalDark,\n colorBackgroundCriticalLight,\n colorBackgroundDisabled,\n colorBackgroundHover,\n colorBackgroundHoverInverse,\n colorBackgroundInfoDark,\n colorBackgroundInfoLight,\n colorBackgroundInverse,\n colorBackgroundOverlay,\n colorBackgroundPressed,\n colorBackgroundPressedInverse,\n colorBackgroundPrimary,\n colorBackgroundSecondary,\n colorBackgroundSubdued,\n colorBackgroundSuccessDark,\n colorBackgroundSuccessLight,\n colorBackgroundTertiary,\n colorBackgroundWarningDark,\n colorBackgroundWarningLight,\n colorBorderBlack,\n colorBorderCritical,\n colorBorderDisabled,\n colorBorderHover,\n colorBorderInfo,\n colorBorderInverse,\n colorBorderPrimary,\n colorBorderSecondary,\n colorBorderSelected,\n colorBorderSuccess,\n colorBorderTertiary,\n colorBorderWarning,\n colorCritical100,\n colorCritical200,\n colorCritical300,\n colorCritical400,\n colorCritical50,\n colorCritical500,\n colorCritical600,\n colorCritical700,\n colorCritical800,\n colorCritical900,\n colorFocusInverse,\n colorFocusPrimary,\n colorIconCritical,\n colorIconDisabled,\n colorIconInfo,\n colorIconInverse,\n colorIconPrimary,\n colorIconSecondary,\n colorIconSuccess,\n colorIconWarning,\n colorInfo100,\n colorInfo200,\n colorInfo300,\n colorInfo400,\n colorInfo50,\n colorInfo500,\n colorInfo600,\n colorInfo700,\n colorInfo800,\n colorInfo900,\n colorLinkDisabled,\n colorLinkHover,\n colorLinkInverse,\n colorLinkInverseDisabled,\n colorLinkInverseHover,\n colorLinkInversePressed,\n colorLinkMonochrome,\n colorLinkPressed,\n colorLinkPrimary,\n colorLinkSecondary,\n colorPrimary100,\n colorPrimary200,\n colorPrimary300,\n colorPrimary400,\n colorPrimary50,\n colorPrimary500,\n colorPrimary600,\n colorPrimary700,\n colorPrimary800,\n colorPrimary900,\n colorSecondary100,\n colorSecondary200,\n colorSecondary300,\n colorSecondary400,\n colorSecondary50,\n colorSecondary500,\n colorSecondary600,\n colorSecondary700,\n colorSecondary800,\n colorSecondary900,\n colorSuccess100,\n colorSuccess200,\n colorSuccess300,\n colorSuccess400,\n colorSuccess50,\n colorSuccess500,\n colorSuccess600,\n colorSuccess700,\n colorSuccess800,\n colorSuccess900,\n colorSurface100,\n colorSurface200,\n colorSurface300,\n colorSurface400,\n colorSurface50,\n colorSurface500,\n colorSurface600,\n colorSurface700,\n colorSurface800,\n colorSurface900,\n colorTertiary100,\n colorTertiary200,\n colorTertiary300,\n colorTertiary400,\n colorTertiary50,\n colorTertiary500,\n colorTertiary600,\n colorTertiary700,\n colorTertiary800,\n colorTertiary900,\n colorTextCritical,\n colorTextDisabled,\n colorTextInactive,\n colorTextInfo,\n colorTextInverse,\n colorTextPrimary,\n colorTextSecondary,\n colorTextSuccess,\n colorTextWarning,\n colorWarning100,\n colorWarning200,\n colorWarning300,\n colorWarning400,\n colorWarning50,\n colorWarning500,\n colorWarning600,\n colorWarning700,\n colorWarning800,\n colorWarning900,\n} from './cssVars';\n\nexport const colors: Record<string, Record<string, string> | string> = {\n background: {\n 'critical-dark': wrapVariableOpacity(wrapVar(colorBackgroundCriticalDark)),\n 'critical-light': wrapVariableOpacity(wrapVar(colorBackgroundCriticalLight)),\n disabled: wrapVariableOpacity(wrapVar(colorBackgroundDisabled)),\n hover: wrapOpacity(wrapVar(colorBackgroundHover), 5),\n 'hover-inverse': wrapOpacity(wrapVar(colorBackgroundHoverInverse), 5),\n 'info-dark': wrapVariableOpacity(wrapVar(colorBackgroundInfoDark)),\n 'info-light': wrapVariableOpacity(wrapVar(colorBackgroundInfoLight)),\n inverse: wrapVariableOpacity(wrapVar(colorBackgroundInverse)),\n overlay: wrapOpacity(wrapVar(colorBackgroundOverlay), 40),\n pressed: wrapOpacity(wrapVar(colorBackgroundPressed), 20),\n 'pressed-inverse': wrapOpacity(wrapVar(colorBackgroundPressedInverse), 20),\n primary: wrapVariableOpacity(wrapVar(colorBackgroundPrimary)),\n secondary: wrapVariableOpacity(wrapVar(colorBackgroundSecondary)),\n subdued: wrapVariableOpacity(wrapVar(colorBackgroundSubdued)),\n 'success-dark': wrapVariableOpacity(wrapVar(colorBackgroundSuccessDark)),\n 'success-light': wrapVariableOpacity(wrapVar(colorBackgroundSuccessLight)),\n tertiary: wrapVariableOpacity(wrapVar(colorBackgroundTertiary)),\n 'warning-dark': wrapVariableOpacity(wrapVar(colorBackgroundWarningDark)),\n 'warning-light': wrapVariableOpacity(wrapVar(colorBackgroundWarningLight)),\n },\n border: {\n black: wrapVariableOpacity(wrapVar(colorBorderBlack)),\n critical: wrapVariableOpacity(wrapVar(colorBorderCritical)),\n disabled: wrapVariableOpacity(wrapVar(colorBorderDisabled)),\n hover: wrapVariableOpacity(wrapVar(colorBorderHover)),\n info: wrapVariableOpacity(wrapVar(colorBorderInfo)),\n inverse: wrapVariableOpacity(wrapVar(colorBorderInverse)),\n primary: wrapVariableOpacity(wrapVar(colorBorderPrimary)),\n secondary: wrapVariableOpacity(wrapVar(colorBorderSecondary)),\n selected: wrapVariableOpacity(wrapVar(colorBorderSelected)),\n success: wrapVariableOpacity(wrapVar(colorBorderSuccess)),\n tertiary: wrapVariableOpacity(wrapVar(colorBorderTertiary)),\n warning: wrapVariableOpacity(wrapVar(colorBorderWarning)),\n },\n critical: {\n '100': wrapVariableOpacity(wrapVar(colorCritical100)),\n '200': wrapVariableOpacity(wrapVar(colorCritical200)),\n '300': wrapVariableOpacity(wrapVar(colorCritical300)),\n '400': wrapVariableOpacity(wrapVar(colorCritical400)),\n '50': wrapVariableOpacity(wrapVar(colorCritical50)),\n '500': wrapVariableOpacity(wrapVar(colorCritical500)),\n '600': wrapVariableOpacity(wrapVar(colorCritical600)),\n '700': wrapVariableOpacity(wrapVar(colorCritical700)),\n '800': wrapVariableOpacity(wrapVar(colorCritical800)),\n '900': wrapVariableOpacity(wrapVar(colorCritical900)),\n },\n current: 'currentColor',\n focus: {\n inverse: wrapOpacity(wrapVar(colorFocusInverse), 50),\n primary: wrapOpacity(wrapVar(colorFocusPrimary), 50),\n },\n 'focus-inverse': wrapVariableOpacity(wrapVar(colorFocusInverse)),\n 'focus-primary': wrapVariableOpacity(wrapVar(colorFocusPrimary)),\n icon: {\n critical: wrapVariableOpacity(wrapVar(colorIconCritical)),\n default: wrapVariableOpacity(wrapVar(colorIconPrimary)),\n disabled: wrapVariableOpacity(wrapVar(colorIconDisabled)),\n hover: wrapVariableOpacity(wrapVar(colorIconSecondary)),\n info: wrapVariableOpacity(wrapVar(colorIconInfo)),\n inverse: wrapVariableOpacity(wrapVar(colorIconInverse)),\n primary: wrapVariableOpacity(wrapVar(colorIconPrimary)),\n secondary: wrapVariableOpacity(wrapVar(colorIconSecondary)),\n success: wrapVariableOpacity(wrapVar(colorIconSuccess)),\n warning: wrapVariableOpacity(wrapVar(colorIconWarning)),\n },\n info: {\n '100': wrapVariableOpacity(wrapVar(colorInfo100)),\n '200': wrapVariableOpacity(wrapVar(colorInfo200)),\n '300': wrapVariableOpacity(wrapVar(colorInfo300)),\n '400': wrapVariableOpacity(wrapVar(colorInfo400)),\n '50': wrapVariableOpacity(wrapVar(colorInfo50)),\n '500': wrapVariableOpacity(wrapVar(colorInfo500)),\n '600': wrapVariableOpacity(wrapVar(colorInfo600)),\n '700': wrapVariableOpacity(wrapVar(colorInfo700)),\n '800': wrapVariableOpacity(wrapVar(colorInfo800)),\n '900': wrapVariableOpacity(wrapVar(colorInfo900)),\n },\n link: {\n disabled: wrapVariableOpacity(wrapVar(colorLinkDisabled)),\n hover: wrapVariableOpacity(wrapVar(colorLinkHover)),\n inverse: wrapVariableOpacity(wrapVar(colorLinkInverse)),\n 'inverse-disabled': wrapVariableOpacity(wrapVar(colorLinkInverseDisabled)),\n 'inverse-hover': wrapVariableOpacity(wrapVar(colorLinkInverseHover)),\n 'inverse-pressed': wrapVariableOpacity(wrapVar(colorLinkInversePressed)),\n monochrome: wrapVariableOpacity(wrapVar(colorLinkMonochrome)),\n pressed: wrapVariableOpacity(wrapVar(colorLinkPressed)),\n primary: wrapVariableOpacity(wrapVar(colorLinkPrimary)),\n secondary: wrapVariableOpacity(wrapVar(colorLinkSecondary)),\n },\n primary: {\n '100': wrapVariableOpacity(wrapVar(colorPrimary100)),\n '200': wrapVariableOpacity(wrapVar(colorPrimary200)),\n '300': wrapVariableOpacity(wrapVar(colorPrimary300)),\n '400': wrapVariableOpacity(wrapVar(colorPrimary400)),\n '50': wrapVariableOpacity(wrapVar(colorPrimary50)),\n '500': wrapVariableOpacity(wrapVar(colorPrimary500)),\n '600': wrapVariableOpacity(wrapVar(colorPrimary600)),\n '700': wrapVariableOpacity(wrapVar(colorPrimary700)),\n '800': wrapVariableOpacity(wrapVar(colorPrimary800)),\n '900': wrapVariableOpacity(wrapVar(colorPrimary900)),\n },\n secondary: {\n '100': wrapVariableOpacity(wrapVar(colorSecondary100)),\n '200': wrapVariableOpacity(wrapVar(colorSecondary200)),\n '300': wrapVariableOpacity(wrapVar(colorSecondary300)),\n '400': wrapVariableOpacity(wrapVar(colorSecondary400)),\n '50': wrapVariableOpacity(wrapVar(colorSecondary50)),\n '500': wrapVariableOpacity(wrapVar(colorSecondary500)),\n '600': wrapVariableOpacity(wrapVar(colorSecondary600)),\n '700': wrapVariableOpacity(wrapVar(colorSecondary700)),\n '800': wrapVariableOpacity(wrapVar(colorSecondary800)),\n '900': wrapVariableOpacity(wrapVar(colorSecondary900)),\n },\n success: {\n '100': wrapVariableOpacity(wrapVar(colorSuccess100)),\n '200': wrapVariableOpacity(wrapVar(colorSuccess200)),\n '300': wrapVariableOpacity(wrapVar(colorSuccess300)),\n '400': wrapVariableOpacity(wrapVar(colorSuccess400)),\n '50': wrapVariableOpacity(wrapVar(colorSuccess50)),\n '500': wrapVariableOpacity(wrapVar(colorSuccess500)),\n '600': wrapVariableOpacity(wrapVar(colorSuccess600)),\n '700': wrapVariableOpacity(wrapVar(colorSuccess700)),\n '800': wrapVariableOpacity(wrapVar(colorSuccess800)),\n '900': wrapVariableOpacity(wrapVar(colorSuccess900)),\n },\n surface: {\n '100': wrapVariableOpacity(wrapVar(colorSurface100)),\n '200': wrapVariableOpacity(wrapVar(colorSurface200)),\n '300': wrapVariableOpacity(wrapVar(colorSurface300)),\n '400': wrapVariableOpacity(wrapVar(colorSurface400)),\n '50': wrapVariableOpacity(wrapVar(colorSurface50)),\n '500': wrapVariableOpacity(wrapVar(colorSurface500)),\n '600': wrapVariableOpacity(wrapVar(colorSurface600)),\n '700': wrapVariableOpacity(wrapVar(colorSurface700)),\n '800': wrapVariableOpacity(wrapVar(colorSurface800)),\n '900': wrapVariableOpacity(wrapVar(colorSurface900)),\n },\n tertiary: {\n '100': wrapVariableOpacity(wrapVar(colorTertiary100)),\n '200': wrapVariableOpacity(wrapVar(colorTertiary200)),\n '300': wrapVariableOpacity(wrapVar(colorTertiary300)),\n '400': wrapVariableOpacity(wrapVar(colorTertiary400)),\n '50': wrapVariableOpacity(wrapVar(colorTertiary50)),\n '500': wrapVariableOpacity(wrapVar(colorTertiary500)),\n '600': wrapVariableOpacity(wrapVar(colorTertiary600)),\n '700': wrapVariableOpacity(wrapVar(colorTertiary700)),\n '800': wrapVariableOpacity(wrapVar(colorTertiary800)),\n '900': wrapVariableOpacity(wrapVar(colorTertiary900)),\n },\n text: {\n critical: wrapVariableOpacity(wrapVar(colorTextCritical)),\n disabled: wrapVariableOpacity(wrapVar(colorTextDisabled)),\n inactive: wrapVariableOpacity(wrapVar(colorTextInactive)),\n info: wrapVariableOpacity(wrapVar(colorTextInfo)),\n inverse: wrapVariableOpacity(wrapVar(colorTextInverse)),\n primary: wrapVariableOpacity(wrapVar(colorTextPrimary)),\n secondary: wrapVariableOpacity(wrapVar(colorTextSecondary)),\n success: wrapVariableOpacity(wrapVar(colorTextSuccess)),\n warning: wrapVariableOpacity(wrapVar(colorTextWarning)),\n },\n transparent: 'transparent',\n warning: {\n '100': wrapVariableOpacity(wrapVar(colorWarning100)),\n '200': wrapVariableOpacity(wrapVar(colorWarning200)),\n '300': wrapVariableOpacity(wrapVar(colorWarning300)),\n '400': wrapVariableOpacity(wrapVar(colorWarning400)),\n '50': wrapVariableOpacity(wrapVar(colorWarning50)),\n '500': wrapVariableOpacity(wrapVar(colorWarning500)),\n '600': wrapVariableOpacity(wrapVar(colorWarning600)),\n '700': wrapVariableOpacity(wrapVar(colorWarning700)),\n '800': wrapVariableOpacity(wrapVar(colorWarning800)),\n '900': wrapVariableOpacity(wrapVar(colorWarning900)),\n },\n};\n","/**\n * Reduced-motion policy for the animation registry (DS-95 / audit findings SA-02 + SA-03).\n *\n * Every animation Tailwind resolves for this library — the local `theme.extend.animation`\n * entries *and* Tailwind's own defaults — gets exactly one entry here. `reducedMotion.spec.ts`\n * fails if the two key sets ever diverge, so a new animation cannot ship untriaged.\n *\n * ## Why duration-collapse rather than `animation: none`\n *\n * `animation: none` fires no `animationend`. `Modal/ComposableModal` and\n * `Modal/hooks/useCloseModal` both depend on that event to finish closing — `useCloseModal`\n * clears a 450ms watchdog there that otherwise logs an error and rejects an awaited promise. A\n * naive `none` gate would strand the modal open *for reduced-motion users only*, which is worse\n * than the gap it fixes. Collapsing the duration keeps the event, and keeps `forwards`/`both`\n * fill end-states intact (`slideUp`, `slideDown`, `progress-completion`).\n *\n * ## Why the doubled class selector\n *\n * Tailwind emits `base` before `utilities`. A consumer building with `important: true` gets\n * `!important` utilities too, and two equal-specificity `!important` rules resolve by source\n * order — the utility would win. `.animate-x.animate-x` (0-2-0) beats it on specificity instead,\n * and is inert for everyone else.\n *\n * Two known limitations, both external-consumer only:\n * - `prefix` renames the utility classes (`.tw-animate-*`), which these selectors will not match.\n * - `important: '#selector'` (the selector strategy, not `important: true`) emits\n * `#selector .animate-x` at specificity 0-1-0 *plus* an id — which outranks 0-2-0 regardless\n * of `!important`. The doubled class only defends against `important: true`.\n *\n * Components in this repo hardcode unprefixed class strings and no in-repo config sets either\n * option, so neither affects this monorepo.\n */\nexport type ReducedMotionTier =\n /** Collapse to ~1ms under reduce. The animation still runs, so `animationend` still fires. */\n | 'instant'\n /** Left alone — infinite indeterminate status indicators, where stopping removes feedback. */\n | 'retain'\n /** Not an animation (`animate-none` is the absence utility). */\n | 'n/a';\n\n/**\n * `selectors` is only meaningful on `instant` entries — nothing is emitted for `retain`/`n/a`,\n * so allowing it there would let a future entry declare a selector that silently does nothing.\n * The union makes that a type error rather than a quiet no-op.\n */\nexport type ReducedMotionPolicyEntry =\n | {\n /** Why this tier was chosen. Asserted non-empty, so every entry carries a justification. */\n reason: string;\n /**\n * Extra selectors for animations applied through a component class rather than an\n * `animate-*` utility. Emitted verbatim, so they are written at full specificity.\n */\n selectors?: readonly string[];\n tier: 'instant';\n }\n | { reason: string; selectors?: never; tier: 'n/a' | 'retain' };\n\nexport const REDUCED_MOTION_POLICY: Record<string, ReducedMotionPolicyEntry> = {\n // --- Local registry (theme.extend.animation) ---\n fadeIn: {\n reason: 'Opacity only, but collapsed alongside fadeInScaled so a modal opens the same way in both variants (ComposableModal picks between them on hasContentPager).',\n tier: 'instant',\n },\n fadeInOpacity: {\n reason: 'Opacity and visibility only; collapsing a fade is not a motion regression.',\n tier: 'instant',\n },\n fadeInScaled: { reason: 'Scales 0.7 to 1.', tier: 'instant' },\n fadeOut: {\n reason: 'Scales 1 to 0.7. Modal close depends on its animationend, so it is collapsed rather than removed.',\n tier: 'instant',\n },\n loading: {\n reason: 'Infinite indeterminate loading indicator (LoadingDot). Collapsing it removes the only signal that work is in progress.',\n tier: 'retain',\n },\n 'progress-completion': {\n reason: 'Scales. Zeroing the delay matters here: the composite is \"shrink 0.15s both, grow 0.15s ease-in-out 0.15s both\", so a duration-only collapse would hold the ring at scale(0.5) for 150ms and then snap.',\n tier: 'instant',\n },\n 'progress-icon-fade-in': {\n reason: 'Opacity only, but its 0.15s delay sequences it after progress-completion. Retaining it would leave a completed ProgressCircle ring with an empty centre for 150ms.',\n tier: 'instant',\n },\n 'progress-wave': {\n reason: 'Infinite indeterminate progress indicator (ProgressCircle). Same essential-feedback rationale as loading.',\n tier: 'retain',\n },\n saveButtonPulse: { reason: 'Scales.', tier: 'instant' },\n saveButtonWiggle: { reason: 'Rotates and scales.', tier: 'instant' },\n saveHeartColorFlash: {\n reason: 'Animates fill only, but it was already gated before DS-95 and must stay gated. Shipped via .hui-fb-color-flash, not the animate-* utility (which has no call sites), so it needs the explicit selector below.',\n selectors: ['.hui-fb-color-flash .hui-fb-icon-frame svg path'],\n tier: 'instant',\n },\n saveHeartPop: { reason: 'Scales.', tier: 'instant' },\n saveHeartTwirlBloom: { reason: 'Rotates 180 degrees at 1.15x scale.', tier: 'instant' },\n saveLabelShimmer: {\n reason: 'Animates background-position. The .hui-fb-shimmer paint block in plugin.ts separately drops the gradient under reduce so the label stays legible.',\n tier: 'instant',\n },\n slideDown: {\n reason: 'Translates on Y. Collapsed rather than removed so CookieConsent still receives animationend.',\n tier: 'instant',\n },\n slideUp: { reason: 'Translates on Y. Same animationend rationale as slideDown.', tier: 'instant' },\n\n // --- Tailwind defaults, which survive theme.extend and are reachable by consumers ---\n bounce: { reason: 'Translates on Y.', tier: 'instant' },\n none: { reason: 'Not an animation — animate-none is the absence utility.', tier: 'n/a' },\n ping: { reason: 'Scales and fades. No in-repo call site, but consumers can use it.', tier: 'instant' },\n pulse: {\n reason: 'Infinite, but opacity only — the conventional skeleton-loading indicator. Retained as essential feedback with no motion component.',\n tier: 'retain',\n },\n spin: {\n reason: 'Infinite indeterminate spinner (LoadingSpinner, ProgressCircle). A Tailwind default rather than a local entry, which is exactly why the policy is keyed on the resolved registry.',\n tier: 'retain',\n },\n};\n\nconst REDUCE_QUERY = '@media (prefers-reduced-motion: reduce)';\n\nconst COLLAPSED_DECLARATIONS = {\n 'animation-delay': '0ms !important',\n 'animation-duration': '1ms !important',\n 'animation-iteration-count': '1 !important',\n};\n\n/**\n * Builds the `@media (prefers-reduced-motion: reduce)` block for `addBase`.\n *\n * Emitted from `addBase` rather than `addComponents` deliberately: `addComponents` is subject to\n * caching discrepancies in this monorepo's Storybook build that stop newly added rules landing.\n */\nexport const buildReducedMotionBase = () => {\n const rules: Record<string, typeof COLLAPSED_DECLARATIONS> = {};\n\n const addRule = (selector: string) => {\n if (rules[selector]) {\n // Two policy entries claiming one selector would silently overwrite each other.\n // Every rule emits identical declarations today, so this can only fire on a\n // genuine authoring mistake — fail loudly rather than ship half a gate.\n throw new Error(`Duplicate reduced-motion selector: ${selector}`);\n }\n\n rules[selector] = { ...COLLAPSED_DECLARATIONS };\n };\n\n Object.entries(REDUCED_MOTION_POLICY).forEach(([key, entry]) => {\n if (entry.tier !== 'instant') {\n return;\n }\n\n // Doubled class (0-2-0) so an `important: true` consumer's utility cannot win on\n // source order — Tailwind emits `base` before `utilities`.\n addRule(`.animate-${key}.animate-${key}`);\n\n entry.selectors?.forEach(addRule);\n });\n\n return { [REDUCE_QUERY]: rules };\n};\n","/**\n * Typography component classes for Tailwind CSS plugin\n *\n * Defines .hui-text-* and .hui-link-* utility classes that apply\n * complete typography styles (font, size, weight, spacing, line-height).\n *\n * Internal reference: Hammer UI patterns\n * Ported from the upstream theme system.\n */\n\nimport { CSSRuleObject } from 'tailwindcss/types/config';\n\nimport { wrapVar } from '../utils/wrapVar';\nimport {\n fontWeightBodyPrimary,\n fontWeightBodySecondary,\n fontWeightCaption,\n fontWeightH1,\n fontWeightH2,\n fontWeightH3,\n fontWeightH4,\n fontWeightH5,\n fontWeightH6,\n fontWeightLabelMini,\n fontWeightLabelStrong,\n letterSpacingBodyPrimary,\n letterSpacingBodySecondary,\n letterSpacingCaption,\n letterSpacingH1,\n letterSpacingH1Mobile,\n letterSpacingH2,\n letterSpacingH2Mobile,\n letterSpacingH3,\n letterSpacingH3Mobile,\n letterSpacingH4,\n letterSpacingH5,\n letterSpacingH6,\n letterSpacingLabelMini,\n letterSpacingLabelStrong,\n textTransformH6,\n textTransformLabelMini,\n} from './cssVars';\nimport { fontFamily } from './fontFamily';\nimport { screens } from './screens';\n\nexport const textComponents = {\n '.hui-link-md': {\n fontFamily: fontFamily.primary,\n fontSize: '16px',\n fontWeight: wrapVar(fontWeightBodyPrimary),\n letterSpacing: wrapVar(letterSpacingBodyPrimary),\n lineHeight: '24px',\n },\n '.hui-link-sm': {\n fontFamily: fontFamily.primary,\n fontSize: '14px',\n fontWeight: wrapVar(fontWeightBodyPrimary),\n letterSpacing: wrapVar(letterSpacingBodyPrimary),\n lineHeight: '22px',\n },\n '.hui-link-xs': {\n fontFamily: fontFamily.primary,\n fontSize: '12px',\n fontWeight: wrapVar(fontWeightBodyPrimary),\n letterSpacing: wrapVar(letterSpacingBodyPrimary),\n lineHeight: '18px',\n },\n '.hui-text-body-primary': {\n fontFamily: fontFamily.primary,\n fontSize: '16px',\n fontWeight: wrapVar(fontWeightBodyPrimary),\n letterSpacing: wrapVar(letterSpacingBodyPrimary),\n lineHeight: '24px',\n },\n '.hui-text-body-secondary': {\n fontFamily: fontFamily.primary,\n fontSize: '14px',\n fontWeight: wrapVar(fontWeightBodySecondary),\n letterSpacing: wrapVar(letterSpacingBodySecondary),\n lineHeight: '22px',\n },\n '.hui-text-caption': {\n fontFamily: fontFamily.primary,\n fontSize: '12px',\n fontWeight: wrapVar(fontWeightCaption),\n letterSpacing: wrapVar(letterSpacingCaption),\n lineHeight: '18px',\n },\n '.hui-text-h1': {\n fontFamily: fontFamily.secondary,\n fontSize: '32px',\n fontWeight: wrapVar(fontWeightH1),\n letterSpacing: wrapVar(letterSpacingH1),\n lineHeight: '48px',\n [`@media (width < ${screens.smMax.max})`]: {\n fontSize: '24px',\n letterSpacing: wrapVar(letterSpacingH1Mobile),\n lineHeight: '36px',\n },\n },\n '.hui-text-h2': {\n fontFamily: fontFamily.secondary,\n fontSize: '24px',\n fontWeight: wrapVar(fontWeightH2),\n letterSpacing: wrapVar(letterSpacingH2),\n lineHeight: '36px',\n [`@media (width < ${screens.smMax.max})`]: {\n fontSize: '20px',\n letterSpacing: wrapVar(letterSpacingH2Mobile),\n lineHeight: '30px',\n },\n },\n '.hui-text-h3': {\n fontFamily: fontFamily.secondary,\n fontSize: '20px',\n fontWeight: wrapVar(fontWeightH3),\n letterSpacing: wrapVar(letterSpacingH3),\n lineHeight: '30px',\n [`@media (width < ${screens.smMax.max})`]: {\n // 18px/27px, not 16px/24px: at 16px this rule rendered identically to `.hui-text-h4`\n // below the breakpoint, collapsing two adjacent heading levels (DS-97 / SA-04).\n fontSize: '18px',\n letterSpacing: wrapVar(letterSpacingH3Mobile),\n lineHeight: '27px',\n },\n },\n '.hui-text-h4': {\n fontFamily: fontFamily.secondary,\n fontSize: '16px',\n fontWeight: wrapVar(fontWeightH4),\n letterSpacing: wrapVar(letterSpacingH4),\n lineHeight: '24px',\n },\n '.hui-text-h5': {\n fontFamily: fontFamily.primary,\n fontSize: '16px',\n fontWeight: wrapVar(fontWeightH5),\n letterSpacing: wrapVar(letterSpacingH5),\n lineHeight: '24px',\n },\n '.hui-text-h6': {\n fontFamily: fontFamily.primary,\n fontSize: '14px',\n fontWeight: wrapVar(fontWeightH6),\n letterSpacing: wrapVar(letterSpacingH6),\n lineHeight: '22px',\n textTransform: wrapVar(textTransformH6),\n },\n '.hui-text-label-mini': {\n fontFamily: fontFamily.primary,\n fontSize: '12px',\n fontWeight: wrapVar(fontWeightLabelMini),\n letterSpacing: wrapVar(letterSpacingLabelMini),\n lineHeight: '14px',\n textTransform: wrapVar(textTransformLabelMini),\n },\n '.hui-text-label-mini-strong': {\n fontFamily: fontFamily.primary,\n fontSize: '12px',\n fontWeight: wrapVar(fontWeightLabelStrong),\n letterSpacing: wrapVar(letterSpacingLabelMini),\n lineHeight: '14px',\n textTransform: wrapVar(textTransformLabelMini),\n },\n '.hui-text-label-strong': {\n fontFamily: fontFamily.primary,\n fontSize: '14px',\n fontWeight: wrapVar(fontWeightLabelStrong),\n letterSpacing: wrapVar(letterSpacingLabelStrong),\n lineHeight: '22px',\n },\n} satisfies Record<string, CSSRuleObject>;\n","/**\n * Layout width configuration for Tailwind CSS\n *\n * Internal reference: Hammer UI patterns\n * Ported from the upstream theme system.\n */\n\nimport { wrapVar } from '../utils/wrapVar';\nimport { widthDense, widthPage } from './cssVars';\n\nexport const width = {\n dense: wrapVar(widthDense),\n page: wrapVar(widthPage),\n} as const;\n","/**\n * Main Tailwind CSS plugin for the theme system\n *\n * Composes all theme configuration modules (colors, spacing, typography, etc.)\n * into a single Tailwind plugin. The plugin's second argument defines the complete\n * theme, so consumers only need `plugins: [themePlugin]` — no separate theme extension.\n *\n * Internal reference: Hammer UI patterns\n * Ported from the upstream theme system.\n */\n\nimport plugin from 'tailwindcss/plugin';\n\nimport { animation } from './animation';\nimport { borderRadius } from './borderRadius';\nimport { borderWidth } from './borderWidth';\nimport { boxShadow } from './boxShadow';\nimport { colors } from './colors';\nimport { fontFamily } from './fontFamily';\nimport { buildReducedMotionBase } from './reducedMotion';\nimport { screens } from './screens';\nimport { spacing } from './spacing';\nimport { textComponents } from './text';\nimport { width } from './width';\n\nexport const autofillStyles = {\n '-webkit-box-shadow': '0 0 0 12px rgb(var(--color-background-primary)) inset !important',\n 'box-shadow': '0 0 0 12px rgb(var(--color-background-primary)) inset !important',\n};\n\nexport const tailwindTheme = {\n borderRadius,\n borderWidth,\n boxShadow,\n colors,\n extend: {\n animation,\n keyframes: {\n fadeIn: {\n from: {\n opacity: '0',\n },\n to: {\n opacity: '1',\n },\n },\n fadeInOpacity: {\n from: {\n opacity: '0',\n visibility: 'hidden',\n },\n to: {\n opacity: '1',\n visibility: 'visible',\n },\n },\n fadeInScaled: {\n from: {\n opacity: '0',\n transform: 'scale(0.7)',\n },\n to: {\n opacity: '1',\n transform: 'scale(1)',\n },\n },\n fadeOut: {\n from: {\n opacity: '1',\n transform: 'scale(1)',\n },\n to: {\n opacity: '0',\n transform: 'scale(0.7)',\n },\n },\n grow: {\n from: { transform: 'scale(0.5)' },\n to: { transform: 'scale(1)' },\n },\n loading: {\n '0%, 100%, 80%': { transform: 'scale(0)' },\n '40%': { transform: 'scale(1)' },\n },\n progressWave: {\n '0%': {\n strokeDasharray: 'var(--progress-wave-start)',\n strokeDashoffset: '0',\n },\n '100%': {\n strokeDasharray: 'var(--progress-wave-end)',\n strokeDashoffset: 'var(--progress-wave-full)',\n },\n '50%': {\n strokeDasharray: 'var(--progress-wave-mid)',\n strokeDashoffset: 'var(--progress-wave-offset)',\n },\n },\n progressWaveRotate: {\n '0%': { transform: 'rotate(-90deg)' },\n '100%': { transform: 'rotate(270deg)' },\n },\n saveButtonPulse: {\n '0%': { transform: 'scale(1)' },\n '35%': { transform: 'scale(1.08)' },\n '65%': { transform: 'scale(0.97)' },\n '100%': { transform: 'scale(1)' },\n },\n saveButtonWiggle: {\n '0%, 100%': { transform: 'rotate(0deg) scale(1)' },\n '10%': { transform: 'rotate(-4deg) scale(1.02)' },\n '25%': { transform: 'rotate(3.5deg) scale(1.02)' },\n '40%': { transform: 'rotate(-2.5deg) scale(1.015)' },\n '55%': { transform: 'rotate(2deg) scale(1.015)' },\n '70%': { transform: 'rotate(-1deg) scale(1.01)' },\n '85%': { transform: 'rotate(0.5deg) scale(1)' },\n },\n saveHeartColorFlash: {\n '0%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n '40%': {\n fill: 'rgb(var(--hui-save-color-critical-300, var(--color-critical-300)))',\n },\n '60%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n '100%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n },\n saveHeartPop: {\n '0%': { transform: 'scale(1)' },\n '20%': { transform: 'scale(0.6)' },\n '60%': { transform: 'scale(1.35)' },\n '100%': { transform: 'scale(1)' },\n },\n saveHeartTwirlBloom: {\n '0%': { transform: 'rotateY(0deg) scale(1)' },\n '30%': { transform: 'rotateY(54deg) scale(1.15)' },\n '100%': { transform: 'rotateY(180deg) scale(1)' },\n },\n saveLabelShimmer: {\n '0%': { backgroundPosition: '200% center' },\n '100%': { backgroundPosition: '-200% center' },\n },\n shrink: {\n from: { transform: 'scale(1)' },\n to: { transform: 'scale(0.5)' },\n },\n slideDown: {\n '0%': { opacity: '1', transform: 'translateY(0)' },\n '100%': { opacity: '0', transform: 'translateY(100%)' },\n },\n slideUp: {\n '0%': { opacity: '0', transform: 'translateY(100%)' },\n '100%': { opacity: '1', transform: 'translateY(0)' },\n },\n },\n\n maxWidth: width,\n minWidth: width,\n spacing,\n width,\n },\n fontFamily,\n screens,\n};\n\nexport const pluginComponentStyles = {\n '.hui-autofill-transparent': {\n '&:-webkit-autofill': autofillStyles,\n '&:-webkit-autofill:active': autofillStyles,\n '&:-webkit-autofill:focus': autofillStyles,\n '&:-webkit-autofill:hover': autofillStyles,\n },\n '.hui-focus-visible-outline': {\n '@apply focus-visible:outline-focus-primary focus-visible:outline focus-visible:outline-4': {},\n },\n '.hui-focus-visible-outline-inverse': {\n '@apply focus-visible:outline-focus-inverse focus-visible:outline focus-visible:outline-4': {},\n },\n '.scrollbar-default': {\n /* Safari and Chrome */\n '&::-webkit-scrollbar': {\n display: 'block',\n },\n /* IE and Edge */\n '-ms-overflow-style': 'auto',\n /* Firefox */\n 'scrollbar-width': 'auto',\n },\n '.scrollbar-hide': {\n /* Safari and Chrome */\n '&::-webkit-scrollbar': {\n display: 'none',\n },\n /* IE and Edge */\n '-ms-overflow-style': 'none',\n /* Firefox */\n 'scrollbar-width': 'none',\n },\n};\n\n// Save/Favorite button keyframes — emitted unconditionally via addBase so they are\n// available in all consumer builds regardless of Tailwind content scanning.\n// The corresponding animate-* utilities are registered in theme.extend.animation.\nexport const pluginBaseStyles = {\n '@keyframes saveButtonWiggle': {\n '0%, 100%': { transform: 'rotate(0deg) scale(1)' },\n '10%': { transform: 'rotate(-4deg) scale(1.02)' },\n '25%': { transform: 'rotate(3.5deg) scale(1.02)' },\n '40%': { transform: 'rotate(-2.5deg) scale(1.015)' },\n '55%': { transform: 'rotate(2deg) scale(1.015)' },\n '70%': { transform: 'rotate(-1deg) scale(1.01)' },\n '85%': { transform: 'rotate(0.5deg) scale(1)' },\n },\n '@keyframes saveHeartTwirlBloom': {\n '0%': { transform: 'rotateY(0deg) scale(1)' },\n '30%': { transform: 'rotateY(54deg) scale(1.15)' },\n '100%': { transform: 'rotateY(180deg) scale(1)' },\n },\n '@keyframes saveHeartColorFlash': {\n '0%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n '40%': {\n fill: 'rgb(var(--hui-save-color-critical-300, var(--color-critical-300)))',\n },\n '60%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n '100%': {\n fill: 'rgb(var(--hui-save-color-critical-500, var(--color-critical-500)))',\n },\n },\n '@keyframes saveLabelShimmer': {\n '0%': { backgroundPosition: '200% center' },\n '100%': { backgroundPosition: '-200% center' },\n },\n '@keyframes saveButtonPulse': {\n '0%': { transform: 'scale(1)' },\n '35%': { transform: 'scale(1.08)' },\n '65%': { transform: 'scale(0.97)' },\n '100%': { transform: 'scale(1)' },\n },\n '@keyframes saveHeartPop': {\n '0%': { transform: 'scale(1)' },\n '20%': { transform: 'scale(0.6)' },\n '60%': { transform: 'scale(1.35)' },\n '100%': { transform: 'scale(1)' },\n },\n // Save/Favorite button animated variant — shimmer and color-flash helpers.\n // Placed in addBase (not addComponents) so Vite's PostCSS pipeline emits\n // them unconditionally. addComponents is subject to caching discrepancies\n // in this monorepo's Storybook build that prevent new rules from landing.\n '.hui-fb-shimmer': {\n lineHeight: 'normal',\n backgroundImage:\n 'linear-gradient(90deg, currentColor 0%, currentColor 20%, rgb(var(--hui-save-color-critical-200, var(--color-critical-200))) 33%, rgb(var(--hui-save-color-critical-500, var(--color-critical-500))) 50%, rgb(var(--hui-save-color-tertiary-400, var(--color-tertiary-400))) 67%, currentColor 80%, currentColor 100%)',\n backgroundSize: '200% 100%',\n backgroundClip: 'text',\n '-webkit-background-clip': 'text',\n '-webkit-text-fill-color': 'transparent',\n '@media (prefers-reduced-motion: reduce)': {\n backgroundImage: 'none !important',\n '-webkit-text-fill-color': 'currentColor !important',\n },\n },\n '.hui-fb-color-flash .hui-fb-icon-frame svg path': {\n animation: 'saveHeartColorFlash 500ms cubic-bezier(0.45, 0, 0.55, 1) 1',\n animationFillMode: 'forwards',\n },\n // Reduced-motion gating for the whole animation registry (DS-95). This replaces the\n // per-selector `animation: none` block that used to live here — see\n // `./reducedMotion` for why duration-collapse rather than removal, and why the\n // `.hui-fb-shimmer` paint block above is a deliberate exception to it.\n ...buildReducedMotionBase(),\n};\n\nexport const themePlugin = plugin(\n ({ addBase, addComponents, matchUtilities }) => {\n // https://tailwindcss.com/docs/plugins#css-in-js-syntax\n addComponents(textComponents);\n addComponents(pluginComponentStyles);\n addBase(pluginBaseStyles);\n\n matchUtilities({\n 'grid-area': (value) => {\n return {\n 'grid-area': value,\n };\n },\n });\n },\n {\n theme: tailwindTheme,\n }\n);\n"],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Fixture brand for the emitter spec. Not a registered brand.
3
+ * Values follow the approved Harbor sheet where that sheet has the same token.
4
+ * `cta-fill-hover` is required and is not in the approved sheet; its angle is the earlier fixture.
5
+ * `cta-ink-rgb` is channels (the approved sheet stored that navy as a hex on a different token).
6
+ * `text-muted-*` and `backdrop` are not separate tokens on the approved sheet.
7
+ */
8
+ import type { EffectLayer } from '../rules';
9
+
10
+ import { fx, type EffectTokenValues } from '../tokens';
11
+
12
+ export const FIXTURE_CLASS = 'brand-fixture';
13
+ export const FIXTURE_SIBLINGS = ['brand-basketball', 'brand-default', 'brand-professional'] as const;
14
+
15
+ export const fixtureTokens = {
16
+ 'solid-fill': '#12223a',
17
+ edge: 'linear-gradient(135deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.06) 35%, rgba(142, 197, 232, 0.1) 65%, rgba(142, 197, 232, 0.4))',
18
+ 'surface-fill':
19
+ 'linear-gradient(160deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0) 45%), rgba(14, 28, 48, 0.42)',
20
+ 'surface-filter': 'blur(18px) saturate(180%)',
21
+ 'surface-shadow':
22
+ 'inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 20px 60px rgba(0, 0, 0, 0.45)',
23
+ 'surface-radius': '18px',
24
+ 'raised-fill':
25
+ 'linear-gradient(160deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 45%), rgba(14, 28, 48, 0.58)',
26
+ 'raised-filter': 'blur(26px) saturate(180%)',
27
+ 'raised-shadow':
28
+ 'inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 0 40px rgba(142, 197, 232, 0.22), 0 30px 80px rgba(0, 0, 0, 0.55)',
29
+ 'scrim-fill': 'rgba(11, 22, 38, 0.45)',
30
+ 'scrim-filter': 'blur(10px) saturate(180%)',
31
+ 'hover-fill':
32
+ 'linear-gradient(160deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0) 45%), rgba(46, 107, 166, 0.3)',
33
+ featured:
34
+ 'inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 0 1px rgba(227, 179, 65, 0.45), 0 0 36px rgba(227, 179, 65, 0.28), 0 20px 60px rgba(0, 0, 0, 0.45)',
35
+ halo: 'inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 28px rgba(46, 107, 166, 0.35), 0 20px 60px rgba(0, 0, 0, 0.45)',
36
+ glow: '0 0 24px rgba(46, 107, 166, 0.55)',
37
+ hover: 'inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 0 28px rgba(46, 107, 166, 0.4), 0 20px 60px rgba(0, 0, 0, 0.4)',
38
+ selected:
39
+ 'inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 0 1px rgba(227, 179, 65, 0.55), 0 0 32px rgba(227, 179, 65, 0.28), 0 20px 60px rgba(0, 0, 0, 0.4)',
40
+ success:
41
+ 'inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 0 1px rgba(180, 193, 90, 0.35), 0 20px 60px rgba(0, 0, 0, 0.4)',
42
+ error: 'inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 0 1px rgb(var(--color-border-critical) / 45%), 0 20px 60px rgba(0, 0, 0, 0.4)',
43
+ 'accept-glow': '0 0 36px rgba(227, 179, 65, 0.3), inset 0 0 36px rgba(227, 179, 65, 0.12)',
44
+ 'reject-glow':
45
+ '0 0 36px rgb(var(--color-border-critical) / 28%), inset 0 0 36px rgb(var(--color-border-critical) / 10%)',
46
+ dash: 'rgba(142, 197, 232, 0.4)',
47
+ 'dash-strong': 'rgba(142, 197, 232, 0.85)',
48
+ 'dash-disabled': 'rgba(185, 197, 211, 0.35)',
49
+ 'dash-accept': 'rgba(227, 179, 65, 0.9)',
50
+ 'dash-reject': 'rgb(var(--color-border-critical) / 90%)',
51
+ 'cta-fill': 'linear-gradient(90deg, #f2cf7a, #e3b341 55%, #d9963e)',
52
+ 'cta-fill-hover': 'linear-gradient(180deg, #f2cf7a, #e3b341 40%, #d9963e)',
53
+ 'cta-ink-rgb': '11 22 38',
54
+ 'text-muted-rgb': '185 197 211',
55
+ 'text-muted-solid-rgb': '169 182 198',
56
+ 'text-success-rgb': '180 193 90',
57
+ 'text-success-solid-rgb': '163 176 78',
58
+ 'text-critical-glass-rgb': '247 162 157',
59
+ 'text-critical-solid-rgb': '234 117 111',
60
+ 'font-accent': 'var(--font-family-primary)',
61
+ 'font-serif': "'DejaVu Serif', Georgia, serif",
62
+ backdrop:
63
+ 'radial-gradient(circle at 18% 12%, rgba(91, 155, 216, 0.45), transparent 38%), radial-gradient(circle at 85% 80%, rgba(227, 179, 65, 0.3), transparent 42%), #0b1626',
64
+ } as const satisfies EffectTokenValues;
65
+
66
+ export const fixtureLayer: EffectLayer = {
67
+ tokens: fixtureTokens,
68
+ rules: [
69
+ { on: 'modal', material: 'raised' },
70
+ { on: 'bottomSheet', material: 'raised' },
71
+ { on: 'listFileCard', material: 'surface', acknowledge: ['hover'] },
72
+ { on: 'listFileCard', when: 'hover', paint: { background: fx.hoverFill } },
73
+ { on: 'listFileCard.selected', shadow: 'selected' },
74
+ { on: 'gridFileCard', shadow: 'featured' },
75
+ {
76
+ on: 'dropzoneOverlay.accept',
77
+ material: 'scrim',
78
+ after: {
79
+ inset: '12px',
80
+ borderWidth: '2px',
81
+ borderStyle: 'dashed',
82
+ borderRadius: '14px',
83
+ borderColor: fx.dashAccept,
84
+ boxShadow: fx.acceptGlow,
85
+ },
86
+ },
87
+ ],
88
+ };