@fiestaboard/ui 1.6.3

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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/dist/components/board/board-display.d.ts +35 -0
  4. package/dist/components/board/board-display.js +514 -0
  5. package/dist/components/board/board-display.js.map +1 -0
  6. package/dist/components/board/board-teaser.d.ts +10 -0
  7. package/dist/components/board/board-teaser.js +110 -0
  8. package/dist/components/board/board-teaser.js.map +1 -0
  9. package/dist/components/board/scaled-board-display.d.ts +37 -0
  10. package/dist/components/board/scaled-board-display.js +118 -0
  11. package/dist/components/board/scaled-board-display.js.map +1 -0
  12. package/dist/components/board/static-board-display.d.ts +17 -0
  13. package/dist/components/board/static-board-display.js +140 -0
  14. package/dist/components/board/static-board-display.js.map +1 -0
  15. package/dist/components/chrome/board-icon.d.ts +11 -0
  16. package/dist/components/chrome/board-icon.js +31 -0
  17. package/dist/components/chrome/board-icon.js.map +1 -0
  18. package/dist/components/chrome/board-selector.d.ts +30 -0
  19. package/dist/components/chrome/board-selector.js +37 -0
  20. package/dist/components/chrome/board-selector.js.map +1 -0
  21. package/dist/components/chrome/fiesta-icon.d.ts +28 -0
  22. package/dist/components/chrome/fiesta-icon.js +129 -0
  23. package/dist/components/chrome/fiesta-icon.js.map +1 -0
  24. package/dist/components/chrome/fiesta-logo.d.ts +6 -0
  25. package/dist/components/chrome/fiesta-logo.js +20 -0
  26. package/dist/components/chrome/fiesta-logo.js.map +1 -0
  27. package/dist/components/chrome/language-selector.d.ts +21 -0
  28. package/dist/components/chrome/language-selector.js +29 -0
  29. package/dist/components/chrome/language-selector.js.map +1 -0
  30. package/dist/components/chrome/main-content.d.ts +28 -0
  31. package/dist/components/chrome/main-content.js +33 -0
  32. package/dist/components/chrome/main-content.js.map +1 -0
  33. package/dist/components/chrome/page-header.d.ts +23 -0
  34. package/dist/components/chrome/page-header.js +69 -0
  35. package/dist/components/chrome/page-header.js.map +1 -0
  36. package/dist/components/chrome/page-layout.d.ts +10 -0
  37. package/dist/components/chrome/page-layout.js +17 -0
  38. package/dist/components/chrome/page-layout.js.map +1 -0
  39. package/dist/components/chrome/page-toolbar.d.ts +7 -0
  40. package/dist/components/chrome/page-toolbar.js +21 -0
  41. package/dist/components/chrome/page-toolbar.js.map +1 -0
  42. package/dist/components/chrome/sidebar.d.ts +83 -0
  43. package/dist/components/chrome/sidebar.js +318 -0
  44. package/dist/components/chrome/sidebar.js.map +1 -0
  45. package/dist/components/chrome/skip-to-content.d.ts +8 -0
  46. package/dist/components/chrome/skip-to-content.js +15 -0
  47. package/dist/components/chrome/skip-to-content.js.map +1 -0
  48. package/dist/components/chrome/theme-toggle.d.ts +22 -0
  49. package/dist/components/chrome/theme-toggle.js +28 -0
  50. package/dist/components/chrome/theme-toggle.js.map +1 -0
  51. package/dist/components/seasons/aurora-canvas.d.ts +22 -0
  52. package/dist/components/seasons/aurora-canvas.js +88 -0
  53. package/dist/components/seasons/aurora-canvas.js.map +1 -0
  54. package/dist/components/seasons/sidebar-aurora-horizontal.d.ts +3 -0
  55. package/dist/components/seasons/sidebar-aurora-horizontal.js +47 -0
  56. package/dist/components/seasons/sidebar-aurora-horizontal.js.map +1 -0
  57. package/dist/components/seasons/sidebar-aurora.d.ts +3 -0
  58. package/dist/components/seasons/sidebar-aurora.js +57 -0
  59. package/dist/components/seasons/sidebar-aurora.js.map +1 -0
  60. package/dist/components/ui/accordion.d.ts +16 -0
  61. package/dist/components/ui/accordion.js +55 -0
  62. package/dist/components/ui/accordion.js.map +1 -0
  63. package/dist/components/ui/alert-dialog.d.ts +16 -0
  64. package/dist/components/ui/alert-dialog.js +78 -0
  65. package/dist/components/ui/alert-dialog.js.map +1 -0
  66. package/dist/components/ui/alert.d.ts +9 -0
  67. package/dist/components/ui/alert.js +41 -0
  68. package/dist/components/ui/alert.js.map +1 -0
  69. package/dist/components/ui/aurora.d.ts +9 -0
  70. package/dist/components/ui/aurora.js +105 -0
  71. package/dist/components/ui/aurora.js.map +1 -0
  72. package/dist/components/ui/badge.d.ts +9 -0
  73. package/dist/components/ui/badge.js +35 -0
  74. package/dist/components/ui/badge.js.map +1 -0
  75. package/dist/components/ui/box.d.ts +20 -0
  76. package/dist/components/ui/box.js +14 -0
  77. package/dist/components/ui/box.js.map +1 -0
  78. package/dist/components/ui/button.d.ts +10 -0
  79. package/dist/components/ui/button.js +52 -0
  80. package/dist/components/ui/button.js.map +1 -0
  81. package/dist/components/ui/card.d.ts +11 -0
  82. package/dist/components/ui/card.js +57 -0
  83. package/dist/components/ui/card.js.map +1 -0
  84. package/dist/components/ui/checkbox.d.ts +4 -0
  85. package/dist/components/ui/checkbox.js +16 -0
  86. package/dist/components/ui/checkbox.js.map +1 -0
  87. package/dist/components/ui/code.d.ts +8 -0
  88. package/dist/components/ui/code.js +15 -0
  89. package/dist/components/ui/code.js.map +1 -0
  90. package/dist/components/ui/collapsible.d.ts +8 -0
  91. package/dist/components/ui/collapsible.js +28 -0
  92. package/dist/components/ui/collapsible.js.map +1 -0
  93. package/dist/components/ui/dialog.d.ts +17 -0
  94. package/dist/components/ui/dialog.js +77 -0
  95. package/dist/components/ui/dialog.js.map +1 -0
  96. package/dist/components/ui/dropdown-menu.d.ts +32 -0
  97. package/dist/components/ui/dropdown-menu.js +129 -0
  98. package/dist/components/ui/dropdown-menu.js.map +1 -0
  99. package/dist/components/ui/empty-state.d.ts +23 -0
  100. package/dist/components/ui/empty-state.js +49 -0
  101. package/dist/components/ui/empty-state.js.map +1 -0
  102. package/dist/components/ui/flex.d.ts +24 -0
  103. package/dist/components/ui/flex.js +61 -0
  104. package/dist/components/ui/flex.js.map +1 -0
  105. package/dist/components/ui/grid.d.ts +20 -0
  106. package/dist/components/ui/grid.js +77 -0
  107. package/dist/components/ui/grid.js.map +1 -0
  108. package/dist/components/ui/heading.d.ts +18 -0
  109. package/dist/components/ui/heading.js +26 -0
  110. package/dist/components/ui/heading.js.map +1 -0
  111. package/dist/components/ui/input.d.ts +4 -0
  112. package/dist/components/ui/input.js +16 -0
  113. package/dist/components/ui/input.js.map +1 -0
  114. package/dist/components/ui/label.d.ts +4 -0
  115. package/dist/components/ui/label.js +15 -0
  116. package/dist/components/ui/label.js.map +1 -0
  117. package/dist/components/ui/list.d.ts +25 -0
  118. package/dist/components/ui/list.js +46 -0
  119. package/dist/components/ui/list.js.map +1 -0
  120. package/dist/components/ui/react-bits/decrypted-text.d.ts +14 -0
  121. package/dist/components/ui/react-bits/decrypted-text.js +88 -0
  122. package/dist/components/ui/react-bits/decrypted-text.js.map +1 -0
  123. package/dist/components/ui/react-bits/fade-content.d.ts +11 -0
  124. package/dist/components/ui/react-bits/fade-content.js +48 -0
  125. package/dist/components/ui/react-bits/fade-content.js.map +1 -0
  126. package/dist/components/ui/scroll-area.d.ts +5 -0
  127. package/dist/components/ui/scroll-area.js +39 -0
  128. package/dist/components/ui/scroll-area.js.map +1 -0
  129. package/dist/components/ui/select.d.ts +26 -0
  130. package/dist/components/ui/select.js +132 -0
  131. package/dist/components/ui/select.js.map +1 -0
  132. package/dist/components/ui/sheet.d.ts +29 -0
  133. package/dist/components/ui/sheet.js +114 -0
  134. package/dist/components/ui/sheet.js.map +1 -0
  135. package/dist/components/ui/skeleton.d.ts +2 -0
  136. package/dist/components/ui/skeleton.js +14 -0
  137. package/dist/components/ui/skeleton.js.map +1 -0
  138. package/dist/components/ui/slider.d.ts +9 -0
  139. package/dist/components/ui/slider.js +39 -0
  140. package/dist/components/ui/slider.js.map +1 -0
  141. package/dist/components/ui/stack.d.ts +16 -0
  142. package/dist/components/ui/stack.js +44 -0
  143. package/dist/components/ui/stack.js.map +1 -0
  144. package/dist/components/ui/switch.d.ts +4 -0
  145. package/dist/components/ui/switch.js +24 -0
  146. package/dist/components/ui/switch.js.map +1 -0
  147. package/dist/components/ui/table.d.ts +13 -0
  148. package/dist/components/ui/table.js +54 -0
  149. package/dist/components/ui/table.js.map +1 -0
  150. package/dist/components/ui/tabs.d.ts +7 -0
  151. package/dist/components/ui/tabs.js +37 -0
  152. package/dist/components/ui/tabs.js.map +1 -0
  153. package/dist/components/ui/text-link.d.ts +9 -0
  154. package/dist/components/ui/text-link.js +15 -0
  155. package/dist/components/ui/text-link.js.map +1 -0
  156. package/dist/components/ui/text.d.ts +22 -0
  157. package/dist/components/ui/text.js +48 -0
  158. package/dist/components/ui/text.js.map +1 -0
  159. package/dist/components/ui/textarea.d.ts +3 -0
  160. package/dist/components/ui/textarea.js +15 -0
  161. package/dist/components/ui/textarea.js.map +1 -0
  162. package/dist/components/ui/tooltip.d.ts +16 -0
  163. package/dist/components/ui/tooltip.js +38 -0
  164. package/dist/components/ui/tooltip.js.map +1 -0
  165. package/dist/fonts.css +16 -0
  166. package/dist/index.d.ts +66 -0
  167. package/dist/index.js +59 -0
  168. package/dist/lib/board-characters.d.ts +55 -0
  169. package/dist/lib/board-characters.js +151 -0
  170. package/dist/lib/board-characters.js.map +1 -0
  171. package/dist/lib/board-colors.d.ts +48 -0
  172. package/dist/lib/board-colors.js +93 -0
  173. package/dist/lib/board-colors.js.map +1 -0
  174. package/dist/lib/board-dimensions.d.ts +41 -0
  175. package/dist/lib/board-dimensions.js +38 -0
  176. package/dist/lib/board-dimensions.js.map +1 -0
  177. package/dist/lib/board-metrics.d.ts +19 -0
  178. package/dist/lib/board-metrics.js +22 -0
  179. package/dist/lib/board-metrics.js.map +1 -0
  180. package/dist/lib/seasons-drafts.d.ts +26 -0
  181. package/dist/lib/seasons-drafts.js +106 -0
  182. package/dist/lib/seasons-drafts.js.map +1 -0
  183. package/dist/lib/seasons.d.ts +52 -0
  184. package/dist/lib/seasons.js +59 -0
  185. package/dist/lib/seasons.js.map +1 -0
  186. package/dist/lib/select-items.d.ts +29 -0
  187. package/dist/lib/select-items.js +35 -0
  188. package/dist/lib/select-items.js.map +1 -0
  189. package/dist/lib/utils.d.ts +2 -0
  190. package/dist/lib/utils.js +11 -0
  191. package/dist/lib/utils.js.map +1 -0
  192. package/dist/seasons/christmas.css +64 -0
  193. package/dist/seasons/easter.css +62 -0
  194. package/dist/seasons/fathers-day.css +62 -0
  195. package/dist/seasons/halloween.css +69 -0
  196. package/dist/seasons/mothers-day.css +63 -0
  197. package/dist/seasons/new-year.css +66 -0
  198. package/dist/seasons/pride.css +68 -0
  199. package/dist/seasons/thanksgiving.css +64 -0
  200. package/dist/theme.css +1174 -0
  201. package/package.json +108 -0
@@ -0,0 +1,22 @@
1
+ //#region src/lib/board-metrics.ts
2
+ var e = {
3
+ sm: "w-[14px] h-[18px]",
4
+ md: "w-[14px] h-[20px] sm:w-[20px] sm:h-[28px] md:w-[24px] md:h-[34px] lg:w-[28px] lg:h-[40px]",
5
+ lg: "w-[18px] h-[26px] sm:w-[24px] sm:h-[34px] md:w-[28px] md:h-[40px] lg:w-[32px] lg:h-[46px]"
6
+ }, t = {
7
+ sm: "text-[7px]",
8
+ md: "text-[7px] sm:text-[10px] md:text-[13px] lg:text-[16px]",
9
+ lg: "text-[10px] sm:text-[13px] md:text-[16px] lg:text-[20px]"
10
+ }, n = {
11
+ sm: "px-3 py-4",
12
+ md: "px-2 py-3 sm:px-4 sm:py-6 md:px-5 md:py-8 lg:px-6 lg:py-10",
13
+ lg: "px-3 py-4 sm:px-5 sm:py-7 md:px-6 md:py-9 lg:px-8 lg:py-12"
14
+ }, r = {
15
+ sm: "gap-[3px]",
16
+ md: "gap-[2px] sm:gap-[4px] md:gap-[5px]",
17
+ lg: "gap-[3px] sm:gap-[5px] md:gap-[6px] lg:gap-[7px]"
18
+ };
19
+ //#endregion
20
+ export { r as gapClasses, n as paddingClasses, e as sizeClasses, t as textSizeClasses };
21
+
22
+ //# sourceMappingURL=board-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-metrics.js","names":[],"sources":["../../src/lib/board-metrics.ts"],"mappings":";AAiBA,IAAa,IAAyC;CACpD,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEa,IAA6C;CACxD,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEa,IAA4C;CACvD,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEa,IAAwC;CACnD,IAAI;CACJ,IAAI;CACJ,IAAI;AACN"}
@@ -0,0 +1,26 @@
1
+ import { type Season } from "./seasons";
2
+ /**
3
+ * Design drafts: fully styled seasons that are NOT live — they appear in
4
+ * the Storybook Season selector (marked as drafts) but getActiveSeason()
5
+ * never consults them, so consuming apps ship only SEASONS. Promote a
6
+ * finished design by moving its entry into SEASONS in seasons.tsx.
7
+ *
8
+ * This module is deliberately NOT re-exported from the package barrel:
9
+ * the draft objects are Storybook-only data, and keeping them out of
10
+ * src/index.ts keeps them tree-shakeable out of every production bundle.
11
+ * Storybook (and anyone previewing drafts) imports it directly via the
12
+ * `./*` subpath export: `@fiestaboard/ui/lib/seasons-drafts`.
13
+ *
14
+ * Each draft's CSS lives in src/styles/seasons/<id>.css and ships to
15
+ * dist/seasons/<id>.css. It is NOT imported by theme.css (only the live
16
+ * pride season is) — a consumer promoting a draft opts in with
17
+ * `@import "@fiestaboard/ui/seasons/<id>.css"`. Storybook imports every
18
+ * draft in storybook.css so the Season toolbar previews them.
19
+ *
20
+ * `colors` MUST mirror the season CSS's --icon-g1..6 ramp: the CSS is the
21
+ * design intent, and the aurora/confetti render alongside the CSS-tinted
22
+ * chrome, so a diverging palette reads as two different seasons at once.
23
+ */
24
+ export declare const DRAFT_SEASONS: Season[];
25
+ /** Every season, live and draft — for previews (Storybook selector). */
26
+ export declare const ALL_SEASONS: Season[];
@@ -0,0 +1,106 @@
1
+ import { SEASONS as e } from "./seasons.js";
2
+ //#region src/lib/seasons-drafts.ts
3
+ var t = [
4
+ {
5
+ id: "halloween",
6
+ label: "Halloween",
7
+ months: [9],
8
+ htmlClass: "halloween-season",
9
+ colors: [
10
+ "#ff7518",
11
+ "#ff9838",
12
+ "#39d353",
13
+ "#a855f7",
14
+ "#7c3aed",
15
+ "#6a0dad"
16
+ ]
17
+ },
18
+ {
19
+ id: "thanksgiving",
20
+ label: "Thanksgiving",
21
+ months: [10],
22
+ htmlClass: "thanksgiving-season",
23
+ colors: [
24
+ "#a0522d",
25
+ "#c9682a",
26
+ "#e0a030",
27
+ "#eec659",
28
+ "#b5651d",
29
+ "#8c3b1b"
30
+ ]
31
+ },
32
+ {
33
+ id: "christmas",
34
+ label: "Christmas",
35
+ months: [11],
36
+ htmlClass: "christmas-season",
37
+ colors: [
38
+ "#c8102e",
39
+ "#d94a3d",
40
+ "#ffd700",
41
+ "#2aa457",
42
+ "#0f8a3d",
43
+ "#0b6b30"
44
+ ]
45
+ },
46
+ {
47
+ id: "new-year",
48
+ label: "New Year",
49
+ months: [0],
50
+ htmlClass: "new-year-season",
51
+ colors: [
52
+ "#ffd700",
53
+ "#f5da6e",
54
+ "#d8dde8",
55
+ "#a9b6d0",
56
+ "#5b6fd4",
57
+ "#2c3e8c"
58
+ ]
59
+ },
60
+ {
61
+ id: "easter",
62
+ label: "Easter",
63
+ months: [3],
64
+ htmlClass: "easter-season",
65
+ colors: [
66
+ "#e8879e",
67
+ "#d9a520",
68
+ "#5cbf8a",
69
+ "#6fb3e0",
70
+ "#a98ed9",
71
+ "#e8879e"
72
+ ]
73
+ },
74
+ {
75
+ id: "mothers-day",
76
+ label: "Mother's Day",
77
+ months: [4],
78
+ htmlClass: "mothers-day-season",
79
+ colors: [
80
+ "#b03060",
81
+ "#d1608a",
82
+ "#e79ab0",
83
+ "#d8b98a",
84
+ "#c76a94",
85
+ "#b03060"
86
+ ]
87
+ },
88
+ {
89
+ id: "fathers-day",
90
+ label: "Father's Day",
91
+ months: [5],
92
+ htmlClass: "fathers-day-season",
93
+ colors: [
94
+ "#2f5d8a",
95
+ "#4a7ba6",
96
+ "#5f9ea0",
97
+ "#6d7f93",
98
+ "#3f6e7e",
99
+ "#2f5d8a"
100
+ ]
101
+ }
102
+ ], n = [...e, ...t];
103
+ //#endregion
104
+ export { n as ALL_SEASONS, t as DRAFT_SEASONS };
105
+
106
+ //# sourceMappingURL=seasons-drafts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seasons-drafts.js","names":[],"sources":["../../src/lib/seasons-drafts.ts"],"mappings":";;AAwBA,IAAa,IAA0B;CACrC;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,CAAC;EACV,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,EAAE;EACX,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,EAAE;EACX,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,CAAC;EACV,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,CAAC;EACV,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EACE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,CAAC;EACV,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;CACA;EAKE,IAAI;EACJ,OAAO;EACP,QAAQ,CAAC,CAAC;EACV,WAAW;EACX,QAAQ;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;CAC3E;AACF,GAGa,IAAwB,CAAC,GAAG,GAAS,GAAG,CAAa"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Seasonal theming — festive treatments that activate on the calendar.
3
+ *
4
+ * Each season declares when it runs, the class the app shell stamps on
5
+ * <html> (which theme.css styles), and its color palette (used by the
6
+ * sidebar auroras and the confetti burst). Pride is the first season;
7
+ * add more by extending SEASONS and shipping a matching CSS block.
8
+ *
9
+ * The opt-out cookie (set by the consuming app — FiestaBoard: Settings →
10
+ * Advanced → Festive Months) disables all seasons at once.
11
+ */
12
+ export interface Season {
13
+ id: string;
14
+ /** English display name — apps localize by id if needed. */
15
+ label: string;
16
+ /** Active months, 0-indexed like Date.getMonth(). */
17
+ months: number[];
18
+ /** Class the app shell applies to <html>; theme.css styles it. */
19
+ htmlClass: string;
20
+ /** Palette for auroras and the celebration burst. */
21
+ colors: string[];
22
+ }
23
+ export declare const PRIDE_SEASON: Season;
24
+ /** All registered seasons, in priority order (first match wins). */
25
+ export declare const SEASONS: Season[];
26
+ export declare const HIDE_FESTIVE_COOKIE = "hide_festive_months";
27
+ export declare function readCookieString(): string;
28
+ /** The season active for `now`, or null (calendar + opt-out cookie). */
29
+ export declare function getActiveSeason(now?: Date, cookieString?: string): Season | null;
30
+ /**
31
+ * Returns the active season, or null. Returns null on the first render to
32
+ * avoid hydration mismatch, then resolves in an effect.
33
+ */
34
+ export declare function useActiveSeason(): Season | null;
35
+ /**
36
+ * Spawns the seasonal confetti burst at the click position. Particles use
37
+ * the `.pride-burst-particle` class from theme.css and clean themselves up
38
+ * on animation end. Pure DOM — callers layer their own toast on top.
39
+ *
40
+ * All 48 particles are built off-tree and appended to a single container in
41
+ * one DOM mutation; a single delegated `animationend` listener on the
42
+ * container removes the whole subtree once the last particle finishes. No
43
+ * burst plays when the user prefers reduced motion.
44
+ */
45
+ export declare function fireSeasonBurst(e: {
46
+ clientX: number;
47
+ clientY: number;
48
+ }, colors?: string[]): void;
49
+ /** @deprecated Use getActiveSeason() — pride is now a registered season. */
50
+ export declare function shouldShowPride(now?: Date, cookieString?: string): boolean;
51
+ /** @deprecated Use useActiveSeason(). */
52
+ export declare function usePrideActive(): boolean;
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { useEffect as e, useState as t } from "react";
3
+ //#region src/lib/seasons.tsx
4
+ var n = {
5
+ id: "pride",
6
+ label: "Pride",
7
+ months: [5],
8
+ htmlClass: "pride-month",
9
+ colors: [
10
+ "#e40303",
11
+ "#ff8c00",
12
+ "#ffed00",
13
+ "#008026",
14
+ "#004dff",
15
+ "#750787"
16
+ ]
17
+ }, r = [n], i = "hide_festive_months";
18
+ function a() {
19
+ return typeof document < "u" ? document.cookie : "";
20
+ }
21
+ function o(e) {
22
+ return e.split("; ").some((e) => e === `${i}=true`);
23
+ }
24
+ var s = -1, c = null, l = null;
25
+ function u(e = /* @__PURE__ */ new Date(), t = "") {
26
+ let n = e.getMonth();
27
+ return (n !== s || t !== c) && (s = n, c = t, l = o(t) ? null : r.find((e) => e.months.includes(n)) ?? null), l;
28
+ }
29
+ function d() {
30
+ let [n, r] = t(null);
31
+ return e(() => {
32
+ r(u(/* @__PURE__ */ new Date(), a()));
33
+ }, []), n;
34
+ }
35
+ function f(e, t = n.colors) {
36
+ if (typeof window < "u" && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
37
+ let r = document.createElement("div");
38
+ r.className = "pride-burst";
39
+ for (let n = 0; n < 48; n++) {
40
+ let i = document.createElement("div");
41
+ i.className = "pride-burst-particle";
42
+ let a = n / 48 * Math.PI * 2 + (Math.random() - .5) * .5, o = 80 + Math.random() * 160;
43
+ i.style.setProperty("--tx", `${Math.cos(a) * o}px`), i.style.setProperty("--ty", `${Math.sin(a) * o}px`), i.style.setProperty("--rot", `${Math.random() * 720 - 360}deg`), i.style.setProperty("--dur", `${.5 + Math.random() * .5}s`), i.style.background = t[n % t.length], i.style.left = `${e.clientX - 3.5}px`, i.style.top = `${e.clientY - 3.5}px`, r.appendChild(i);
44
+ }
45
+ let i = 48;
46
+ r.addEventListener("animationend", () => {
47
+ --i === 0 && r.remove();
48
+ }), setTimeout(() => r.remove(), 1500), document.body.appendChild(r);
49
+ }
50
+ function p(e = /* @__PURE__ */ new Date(), t = "") {
51
+ return u(e, t)?.id === "pride";
52
+ }
53
+ function m() {
54
+ return d()?.id === "pride";
55
+ }
56
+ //#endregion
57
+ export { i as HIDE_FESTIVE_COOKIE, n as PRIDE_SEASON, r as SEASONS, f as fireSeasonBurst, u as getActiveSeason, a as readCookieString, p as shouldShowPride, d as useActiveSeason, m as usePrideActive };
58
+
59
+ //# sourceMappingURL=seasons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seasons.js","names":[],"sources":["../../src/lib/seasons.tsx"],"mappings":";;;AA4BA,IAAa,IAAuB;CAClC,IAAI;CACJ,OAAO;CACP,QAAQ,CAAC,CAAC;CACV,WAAW;CACX,QAAQ;EAAC;EAAW;EAAW;EAAW;EAAW;EAAW;CAAS;AAC3E,GAGa,IAAoB,CAAC,CAAY,GAOjC,IAAsB;AAEnC,SAAgB,IAA2B;CACzC,OAAO,OAAO,WAAa,MAAc,SAAS,SAAS;AAC7D;AAEA,SAAS,EAAgB,GAA+B;CACtD,OAAO,EAAa,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,GAAG,EAAoB,MAAM;AACjF;AAMA,IAAI,IAAc,IACd,IAA8B,MAC9B,IAA8B;AAGlC,SAAgB,EAAgB,oBAAY,IAAI,KAAK,GAAG,IAAe,IAAmB;CACxF,IAAM,IAAQ,EAAI,SAAS;CAU3B,QATI,MAAU,KAAe,MAAiB,OAC5C,IAAc,GACd,IAAe,GACf,AAGE,IAHE,EAAgB,CAAY,IACf,OAEA,EAAQ,MAAM,MAAM,EAAE,OAAO,SAAS,CAAK,CAAC,KAAK,OAG7D;AACT;AAMA,SAAgB,IAAiC;CAC/C,IAAM,CAAC,GAAQ,KAAa,EAAwB,IAAI;CAMxD,OAJA,QAAgB;EACd,EAAU,kBAAgB,IAAI,KAAK,GAAG,EAAiB,CAAC,CAAC;CAC3D,GAAG,CAAC,CAAC,GAEE;AACT;AAYA,SAAgB,EAAgB,GAAyC,IAAmB,EAAa,QAAQ;CAC/G,IAAI,OAAO,SAAW,OAAe,OAAO,WAAW,kCAAkC,CAAC,CAAC,SAAS;CAEpG,IACM,IAAY,SAAS,cAAc,KAAK;CAC9C,EAAU,YAAY;CACtB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAO,KAAK;EAC9B,IAAM,IAAI,SAAS,cAAc,KAAK;EACtC,EAAE,YAAY;EACd,IAAM,IAAS,IAAI,KAAS,KAAK,KAAK,KAAK,KAAK,OAAO,IAAI,MAAO,IAC5D,IAAO,KAAK,KAAK,OAAO,IAAI;EAQlC,AAPA,EAAE,MAAM,YAAY,QAAQ,GAAG,KAAK,IAAI,CAAK,IAAI,EAAK,GAAG,GACzD,EAAE,MAAM,YAAY,QAAQ,GAAG,KAAK,IAAI,CAAK,IAAI,EAAK,GAAG,GACzD,EAAE,MAAM,YAAY,SAAS,GAAG,KAAK,OAAO,IAAI,MAAM,IAAI,IAAI,GAC9D,EAAE,MAAM,YAAY,SAAS,GAAG,KAAM,KAAK,OAAO,IAAI,GAAI,EAAE,GAC5D,EAAE,MAAM,aAAa,EAAO,IAAI,EAAO,SACvC,EAAE,MAAM,OAAO,GAAG,EAAE,UAAU,IAAI,KAClC,EAAE,MAAM,MAAM,GAAG,EAAE,UAAU,IAAI,KACjC,EAAU,YAAY,CAAC;CACzB;CAEA,IAAI,IAAY;CAShB,AARA,EAAU,iBAAiB,sBAAsB;EAC/C,AAAI,EAAE,MAAc,KAAG,EAAU,OAAO;CAC1C,CAAC,GAKD,iBAAiB,EAAU,OAAO,GAAG,IAAI,GACzC,SAAS,KAAK,YAAY,CAAS;AACrC;AAKA,SAAgB,EAAgB,oBAAY,IAAI,KAAK,GAAG,IAAe,IAAa;CAClF,OAAO,EAAgB,GAAK,CAAY,CAAC,EAAE,OAAO;AACpD;AAGA,SAAgB,IAA0B;CAExC,OADe,EACR,CAAA,EAAQ,OAAO;AACxB"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Content-key stabilization for the items collected from Select children
3
+ * (issue #62). `children` is a freshly-built element tree on every parent
4
+ * render, so memoizing on its identity never holds; these helpers derive a
5
+ * structural signature instead, letting `Select` reuse the previous items
6
+ * array whenever the logical option set is unchanged.
7
+ *
8
+ * Deliberately React-free (labels are treated as plain element-shaped
9
+ * objects) so it can be unit-tested under `node --test`.
10
+ */
11
+ export type SelectItemRecord = {
12
+ value: unknown;
13
+ label: unknown;
14
+ };
15
+ export type StableSelectItems<T extends SelectItemRecord = SelectItemRecord> = {
16
+ key: string;
17
+ items: T[];
18
+ };
19
+ /**
20
+ * Derive a stable string signature for a collected item list: two
21
+ * structurally-equal option sets yield the same key even when every array,
22
+ * object, and label element has a fresh identity.
23
+ */
24
+ export declare function selectItemsContentKey(items: ReadonlyArray<SelectItemRecord>): string;
25
+ /**
26
+ * Return `prev` unchanged when `next` has the same content key — preserving
27
+ * the previous items array reference — otherwise a new state adopting `next`.
28
+ */
29
+ export declare function stabilizeSelectItems<T extends SelectItemRecord>(prev: StableSelectItems<T> | null, next: T[]): StableSelectItems<T>;
@@ -0,0 +1,35 @@
1
+ function e(t, n) {
2
+ if (t != null && typeof t != "boolean") {
3
+ if (typeof t == "string" || typeof t == "number" || typeof t == "bigint") {
4
+ n.push(String(t));
5
+ return;
6
+ }
7
+ if (Array.isArray(t)) {
8
+ for (let r of t) e(r, n);
9
+ return;
10
+ }
11
+ if (typeof t == "object") {
12
+ let r = t, i = r.type;
13
+ n.push(typeof i == "string" ? i : typeof i == "function" ? `fn:${i.name}` : "#"), n.push(""), e(r.props?.children, n);
14
+ }
15
+ }
16
+ }
17
+ function t(t) {
18
+ let n = [];
19
+ for (let r of t) {
20
+ let t = [];
21
+ e(r.label, t), n.push(`${String(r.value)}${t.join("")}`);
22
+ }
23
+ return n.join("\0");
24
+ }
25
+ function n(e, n) {
26
+ let r = t(n);
27
+ return e !== null && e.key === r ? e : {
28
+ key: r,
29
+ items: n
30
+ };
31
+ }
32
+ //#endregion
33
+ export { t as selectItemsContentKey, n as stabilizeSelectItems };
34
+
35
+ //# sourceMappingURL=select-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-items.js","names":[],"sources":["../../src/lib/select-items.ts"],"mappings":"AAsBA,SAAS,EAAc,GAAe,GAAqB;CACrD,SAAQ,QAAQ,OAAO,KAAS,WACpC;MAAI,OAAO,KAAS,YAAY,OAAO,KAAS,YAAY,OAAO,KAAS,UAAU;GACpF,EAAI,KAAK,OAAO,CAAI,CAAC;GACrB;EACF;EACA,IAAI,MAAM,QAAQ,CAAI,GAAG;GACvB,KAAK,IAAM,KAAS,GAAM,EAAc,GAAO,CAAG;GAClD;EACF;EACA,IAAI,OAAO,KAAS,UAAU;GAG5B,IAAM,IAAK,GACL,IAAO,EAAG;GAGhB,AAFA,EAAI,KAAK,OAAO,KAAS,WAAW,IAAO,OAAO,KAAS,aAAa,MAAM,EAAK,SAAS,GAAG,GAC/F,EAAI,KAAK,GAAQ,GACjB,EAAc,EAAG,OAAO,UAAU,CAAG;EACvC;CAbA;AAcF;AAOA,SAAgB,EAAsB,GAAgD;CACpF,IAAM,IAAkB,CAAC;CACzB,KAAK,IAAM,KAAQ,GAAO;EACxB,IAAM,IAAuB,CAAC;EAE9B,AADA,EAAc,EAAK,OAAO,CAAU,GACpC,EAAM,KAAK,GAAG,OAAO,EAAK,KAAK,KAAgB,EAAW,KAAK,EAAE,GAAG;CACtE;CACA,OAAO,EAAM,KAAK,IAAQ;AAC5B;AAMA,SAAgB,EACd,GACA,GACsB;CACtB,IAAM,IAAM,EAAsB,CAAI;CAEtC,OADI,MAAS,QAAQ,EAAK,QAAQ,IAAY,IACvC;EAAE;EAAK,OAAO;CAAK;AAC5B"}
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,11 @@
1
+ import { clsx as e } from "clsx";
2
+ import { extendTailwindMerge as t } from "tailwind-merge";
3
+ //#region src/lib/utils.ts
4
+ var n = t({ cacheSize: 8e3 });
5
+ function r(...t) {
6
+ return n(e(t));
7
+ }
8
+ //#endregion
9
+ export { r as cn };
10
+
11
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/lib/utils.ts"],"mappings":";;;AAWA,IAAM,IAAU,EAAoB,EAAE,WAAW,IAAK,CAAC;AAEvD,SAAgB,EAAG,GAAG,GAAsB;CAC1C,OAAO,EAAQ,EAAK,CAAM,CAAC;AAC7B"}
@@ -0,0 +1,64 @@
1
+ /* christmas — draft seasonal theme. Styles activate only when the
2
+ .christmas-season class is stamped on <html> (Storybook Season selector).
3
+ Not consulted by getActiveSeason() until promoted to SEASONS.
4
+
5
+ Design intent: classic and tasteful — cranberry red and evergreen joined
6
+ by a ribbon of gold, over a deep pine-night base so the aurora drifts
7
+ like lights on a tree. Rich, not garish. */
8
+
9
+ /* Logo: deep cranberry → bright gold ribbon → deep evergreen. Stops are
10
+ split deep/bright on purpose: the light sidebar animates all three stops
11
+ under the wordmark, so every stop holds ≥1.5:1 against all of them
12
+ (lowest: #0b6b30 at 1.57:1) while the golds keep the sparkle on the
13
+ dark pine-night base. */
14
+ .christmas-season .logo-fiesta-text {
15
+ background: linear-gradient(90deg, #a8102a, #ffd700, #ffe066, #0b6b30, #07481f);
16
+ -webkit-background-clip: text;
17
+ -webkit-text-fill-color: transparent;
18
+ background-clip: text;
19
+ }
20
+
21
+ /* Page-icon gradient: red through gold into deepening evergreen */
22
+ .christmas-season {
23
+ --icon-g1: #c8102e;
24
+ --icon-g2: #d94a3d;
25
+ --icon-g3: #ffd700;
26
+ --icon-g4: #2aa457;
27
+ --icon-g5: #0f8a3d;
28
+ --icon-g6: #0b6b30;
29
+ }
30
+
31
+ /* Dark mode sidebar: flat deep pine-night green — the WebGL aurora
32
+ (red/green/gold/snow palette) plays the part of the tree lights. */
33
+ .dark.christmas-season .sidebar-gradient,
34
+ .dark.christmas-season .sidebar-gradient-horizontal {
35
+ background: #0d1811;
36
+ animation: none;
37
+ color: oklch(1 0 0);
38
+ --sidebar-foreground: oklch(1 0 0);
39
+ --sidebar-accent: oklch(1 0 0 / 14%);
40
+ --sidebar-accent-foreground: oklch(1 0 0);
41
+ --sidebar-border: oklch(1 0 0 / 10%);
42
+ --foreground: oklch(1 0 0);
43
+ --muted-foreground: oklch(1 0 0 / 75%);
44
+ }
45
+
46
+ /* Light mode sidebar: retint the flowing gradient stops to soft holly red,
47
+ antique gold, and wreath green (black text stays ≥4.5:1 on these). */
48
+ .christmas-season:not(.dark) .sidebar-gradient,
49
+ .christmas-season:not(.dark) .sidebar-gradient-horizontal {
50
+ --sidebar-fiesta-red: #bd5f5f;
51
+ --sidebar-fiesta-orange: #c4a34e;
52
+ --sidebar-fiesta-purple: #5e9670;
53
+ }
54
+
55
+ /* Reduced motion: authored here rather than inherited — these selectors
56
+ out-specific the base .sidebar-gradient rules in theme.css, so a future
57
+ edit that re-declares animation above would silently escape the base
58
+ @media block. Keeping the guard in-file makes that impossible. */
59
+ @media (prefers-reduced-motion: reduce) {
60
+ .christmas-season .sidebar-gradient,
61
+ .christmas-season .sidebar-gradient-horizontal {
62
+ animation: none;
63
+ }
64
+ }
@@ -0,0 +1,62 @@
1
+ /* easter — draft seasonal theme. Styles activate only when the
2
+ .easter-season class is stamped on <html> (Storybook Season selector).
3
+ Not consulted by getActiveSeason() until promoted to SEASONS.
4
+
5
+ Design intent: springtime pastels — blush pink, baby blue, butter
6
+ yellow, mint, and lilac. Logo/icon gradients use slightly deepened
7
+ pastels so they hold contrast on white; the dark sidebar is a muted
8
+ dusk-lavender so white text and the pastel aurora both read. */
9
+
10
+ /* Page-icon SVG gradient stops */
11
+ .easter-season {
12
+ --icon-g1: #e8879e; /* blush */
13
+ --icon-g2: #d9a520; /* butter gold */
14
+ --icon-g3: #5cbf8a; /* spring mint */
15
+ --icon-g4: #6fb3e0; /* baby blue */
16
+ --icon-g5: #a98ed9; /* lilac */
17
+ --icon-g6: #e8879e; /* blush (loop) */
18
+ }
19
+
20
+ /* "Fiesta" logo word — the same spring sequence one shade deeper than the
21
+ icon ramp: the light sidebar animates pastel egg-shell stops under the
22
+ wordmark, so every logo stop holds ≥1.5:1 against all of them (lowest:
23
+ #b8860b at 1.64:1) where the raw pastels would wash out. */
24
+ .easter-season .logo-fiesta-text {
25
+ background: linear-gradient(90deg, #d4677f, #b8860b, #2f9e68, #3f8dc4, #8a6cc9);
26
+ -webkit-background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ background-clip: text;
29
+ }
30
+
31
+ /* Light mode sidebar: pastel egg-shell gradient stops (mechanics unchanged) */
32
+ .easter-season:not(.dark) .sidebar-gradient,
33
+ .easter-season:not(.dark) .sidebar-gradient-horizontal {
34
+ --sidebar-fiesta-red: #e3a8b8; /* blush pink */
35
+ --sidebar-fiesta-orange: #e0d193; /* butter yellow */
36
+ --sidebar-fiesta-purple: #a8c9e6; /* baby blue */
37
+ }
38
+
39
+ /* Dark mode sidebar: muted dusk-lavender base; aurora provides the color */
40
+ .dark.easter-season .sidebar-gradient,
41
+ .dark.easter-season .sidebar-gradient-horizontal {
42
+ background: #16131f;
43
+ animation: none;
44
+ color: oklch(1 0 0);
45
+ --sidebar-foreground: oklch(1 0 0);
46
+ --sidebar-accent: oklch(1 0 0 / 14%);
47
+ --sidebar-accent-foreground: oklch(1 0 0);
48
+ --sidebar-border: oklch(1 0 0 / 10%);
49
+ --foreground: oklch(1 0 0);
50
+ --muted-foreground: oklch(1 0 0 / 75%);
51
+ }
52
+
53
+ /* Reduced motion: authored here rather than inherited — these selectors
54
+ out-specific the base .sidebar-gradient rules in theme.css, so a future
55
+ edit that re-declares animation above would silently escape the base
56
+ @media block. Keeping the guard in-file makes that impossible. */
57
+ @media (prefers-reduced-motion: reduce) {
58
+ .easter-season .sidebar-gradient,
59
+ .easter-season .sidebar-gradient-horizontal {
60
+ animation: none;
61
+ }
62
+ }
@@ -0,0 +1,62 @@
1
+ /* fathers-day — draft seasonal theme. Styles activate only when the
2
+ .fathers-day-season class is stamped on <html> (Storybook Season selector).
3
+ Not consulted by getActiveSeason() until promoted to SEASONS.
4
+
5
+ Design intent: grounded and calm — steel blue, slate, and sea-glass
6
+ teal, like worn denim and a quiet coastline. Dark sidebar is a deep
7
+ harbor slate so white text and the cool aurora read cleanly. */
8
+
9
+ /* Page-icon SVG gradient stops */
10
+ .fathers-day-season {
11
+ --icon-g1: #2f5d8a; /* steel blue */
12
+ --icon-g2: #4a7ba6; /* harbor blue */
13
+ --icon-g3: #5f9ea0; /* sea-glass teal */
14
+ --icon-g4: #6d7f93; /* slate */
15
+ --icon-g5: #3f6e7e; /* deep teal */
16
+ --icon-g6: #2f5d8a; /* steel blue (loop) */
17
+ }
18
+
19
+ /* "Fiesta" logo word — steel-to-sea-glass gradient, inked one shade
20
+ deeper than the icon ramp: the light sidebar animates coastal-slate
21
+ stops under the wordmark, so every logo stop holds ≥1.5:1 against all
22
+ of them (lowest: #35707a at 1.67:1) where the mid-tone ramp would sink
23
+ into the slate. */
24
+ .fathers-day-season .logo-fiesta-text {
25
+ background: linear-gradient(90deg, #2f5d8a, #3d6b96, #35707a, #55677a, #2f5d8a);
26
+ -webkit-background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ background-clip: text;
29
+ }
30
+
31
+ /* Light mode sidebar: coastal slate gradient stops (mechanics unchanged) */
32
+ .fathers-day-season:not(.dark) .sidebar-gradient,
33
+ .fathers-day-season:not(.dark) .sidebar-gradient-horizontal {
34
+ --sidebar-fiesta-red: #8aa7c4; /* steel blue */
35
+ --sidebar-fiesta-orange: #9bc0ba; /* sea glass */
36
+ --sidebar-fiesta-purple: #7d8ea3; /* slate */
37
+ }
38
+
39
+ /* Dark mode sidebar: deep harbor-slate base; aurora provides the color */
40
+ .dark.fathers-day-season .sidebar-gradient,
41
+ .dark.fathers-day-season .sidebar-gradient-horizontal {
42
+ background: #0d141c;
43
+ animation: none;
44
+ color: oklch(1 0 0);
45
+ --sidebar-foreground: oklch(1 0 0);
46
+ --sidebar-accent: oklch(1 0 0 / 14%);
47
+ --sidebar-accent-foreground: oklch(1 0 0);
48
+ --sidebar-border: oklch(1 0 0 / 10%);
49
+ --foreground: oklch(1 0 0);
50
+ --muted-foreground: oklch(1 0 0 / 75%);
51
+ }
52
+
53
+ /* Reduced motion: authored here rather than inherited — these selectors
54
+ out-specific the base .sidebar-gradient rules in theme.css, so a future
55
+ edit that re-declares animation above would silently escape the base
56
+ @media block. Keeping the guard in-file makes that impossible. */
57
+ @media (prefers-reduced-motion: reduce) {
58
+ .fathers-day-season .sidebar-gradient,
59
+ .fathers-day-season .sidebar-gradient-horizontal {
60
+ animation: none;
61
+ }
62
+ }
@@ -0,0 +1,69 @@
1
+ /* halloween — draft seasonal theme. Styles activate only when the
2
+ .halloween-season class is stamped on <html> (Storybook Season selector).
3
+ Not consulted by getActiveSeason() until promoted to SEASONS.
4
+
5
+ Design intent: jack-o'-lantern glow in a haunted night — pumpkin orange
6
+ burning into witch purple with a flicker of eerie green, all set against
7
+ a near-black purple-tinged dark base so the aurora reads like fog. */
8
+
9
+ /* Logo: deep ember igniting into candle glow, a toxic-green flicker, then
10
+ dying into witch purple. Stops are split deep/bright on purpose: the
11
+ light sidebar animates all three stops under the wordmark, so every stop
12
+ holds ≥1.5:1 against all of them (lowest: #7c3aed at 1.57:1) while the
13
+ bright stops keep the glow on the dark base. */
14
+ .halloween-season .logo-fiesta-text {
15
+ background: linear-gradient(90deg, #a33b00, #ffc274, #7de394, #7c3aed, #56189e);
16
+ -webkit-background-clip: text;
17
+ -webkit-text-fill-color: transparent;
18
+ background-clip: text;
19
+ }
20
+
21
+ /* Page-icon gradient: ember orange through toxic green into deep purple —
22
+ the vivid ramp (mirrored by colors[] for the aurora/confetti); the logo
23
+ uses deep/bright variants of the same hues for sidebar legibility. */
24
+ .halloween-season {
25
+ --icon-g1: #ff7518;
26
+ --icon-g2: #ff9838;
27
+ --icon-g3: #39d353;
28
+ --icon-g4: #a855f7;
29
+ --icon-g5: #7c3aed;
30
+ --icon-g6: #6a0dad;
31
+ }
32
+
33
+ /* Dark mode sidebar: flat near-black with a purple cast — the WebGL aurora
34
+ (pumpkin/purple/green palette) supplies the movement. */
35
+ .dark.halloween-season .sidebar-gradient,
36
+ .dark.halloween-season .sidebar-gradient-horizontal {
37
+ background: #140b1c;
38
+ animation: none;
39
+ color: oklch(1 0 0);
40
+ --sidebar-foreground: oklch(1 0 0);
41
+ --sidebar-accent: oklch(1 0 0 / 14%);
42
+ --sidebar-accent-foreground: oklch(1 0 0);
43
+ --sidebar-border: oklch(1 0 0 / 10%);
44
+ --foreground: oklch(1 0 0);
45
+ --muted-foreground: oklch(1 0 0 / 75%);
46
+ }
47
+
48
+ /* Light mode sidebar: retint the flowing gradient stops to vivid pumpkin,
49
+ bright marigold, and lavender-purple — orange-into-purple is the
50
+ Halloween signature, and dropping the earlier khaki-amber middle keeps
51
+ it distinct from Thanksgiving's harvest sidebar. Black text verified
52
+ ≥4.5:1 on all three stops; the lowest is #9d76c2 at 5.80:1. */
53
+ .halloween-season:not(.dark) .sidebar-gradient,
54
+ .halloween-season:not(.dark) .sidebar-gradient-horizontal {
55
+ --sidebar-fiesta-red: #cd7435;
56
+ --sidebar-fiesta-orange: #dd9040;
57
+ --sidebar-fiesta-purple: #9d76c2;
58
+ }
59
+
60
+ /* Reduced motion: authored here rather than inherited — these selectors
61
+ out-specific the base .sidebar-gradient rules in theme.css, so a future
62
+ edit that re-declares animation above would silently escape the base
63
+ @media block. Keeping the guard in-file makes that impossible. */
64
+ @media (prefers-reduced-motion: reduce) {
65
+ .halloween-season .sidebar-gradient,
66
+ .halloween-season .sidebar-gradient-horizontal {
67
+ animation: none;
68
+ }
69
+ }