neon_sakura 0.1.4

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 (251) hide show
  1. checksums.yaml +7 -0
  2. data/.ai-reviewer/README.md +182 -0
  3. data/.ai-reviewer/ai-reviewer.sh +56 -0
  4. data/.ai-reviewer/build-system-prompt.sh +136 -0
  5. data/.ai-reviewer/extract-claude-sections.sh +32 -0
  6. data/.ai-reviewer/test-ai-reviewer.sh +40 -0
  7. data/.ai-reviewer-config.yml +190 -0
  8. data/.github/dependabot.yml +12 -0
  9. data/.github/settings.yml +70 -0
  10. data/.github/workflows/ai-pr-review-on-comment.yml +384 -0
  11. data/.github/workflows/ai-pr-review.yml +328 -0
  12. data/.github/workflows/license-check.yml +78 -0
  13. data/.github/workflows/lint.yml +79 -0
  14. data/.github/workflows/security.yml +131 -0
  15. data/.github/workflows/semgrep.yml +26 -0
  16. data/.github/workflows/test.yml +44 -0
  17. data/.gitignore +75 -0
  18. data/.rubocop.yml +33 -0
  19. data/.ruby-version +1 -0
  20. data/.simplecov +14 -0
  21. data/.stylelintignore +10 -0
  22. data/.stylelintrc.json +37 -0
  23. data/AGENTS.md +51 -0
  24. data/CHANGELOG.md +568 -0
  25. data/CLAUDE.md +632 -0
  26. data/Gemfile +8 -0
  27. data/Gemfile.lock +327 -0
  28. data/LICENSE +21 -0
  29. data/README.md +1209 -0
  30. data/Rakefile +25 -0
  31. data/app/assets/images/cherry_blossom.svg +1525 -0
  32. data/app/assets/images/cherry_blossom_tree.png +0 -0
  33. data/app/assets/images/prysm-icon.png +0 -0
  34. data/app/assets/stylesheets/base.css +29 -0
  35. data/app/assets/stylesheets/components.css +1652 -0
  36. data/app/assets/stylesheets/forms.css +152 -0
  37. data/app/assets/stylesheets/loading.css +145 -0
  38. data/app/assets/stylesheets/neon_sakura.css +40 -0
  39. data/app/assets/stylesheets/pagy-tailwind.css +120 -0
  40. data/app/assets/stylesheets/theme-default.css +40 -0
  41. data/app/assets/stylesheets/theme-green.css +84 -0
  42. data/app/assets/stylesheets/theme-purple.css +94 -0
  43. data/app/assets/stylesheets/theme-red.css +84 -0
  44. data/app/assets/stylesheets/utility-borders.css +29 -0
  45. data/app/assets/stylesheets/utility-colors.css +185 -0
  46. data/app/assets/stylesheets/utility-effects.css +123 -0
  47. data/app/assets/stylesheets/utility-gradients.css +158 -0
  48. data/app/assets/stylesheets/utility-layout.css +132 -0
  49. data/app/assets/stylesheets/utility-reset.css +13 -0
  50. data/app/assets/stylesheets/utility-responsive.css +145 -0
  51. data/app/assets/stylesheets/utility-sizing.css +99 -0
  52. data/app/assets/stylesheets/utility-spacing.css +174 -0
  53. data/app/assets/stylesheets/utility-typography.css +97 -0
  54. data/app/controllers/errors_controller.rb +120 -0
  55. data/app/controllers/style_guide_controller.rb +117 -0
  56. data/app/helpers/errors_helper.rb +12 -0
  57. data/app/helpers/neon_sakura/navbar_helper.rb +43 -0
  58. data/app/helpers/style_guide_helper.rb +36 -0
  59. data/app/javascript/neon_sakura/dropdown.js +22 -0
  60. data/app/javascript/neon_sakura/navbar.js +71 -0
  61. data/app/javascript/neon_sakura/theme_switcher.js +187 -0
  62. data/app/views/errors/show.html.erb +105 -0
  63. data/app/views/layouts/error.html.erb +19 -0
  64. data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +14 -0
  65. data/app/views/layouts/mission_control/jobs/_navigation.html.erb +21 -0
  66. data/app/views/layouts/mission_control/jobs/application.html.erb +453 -0
  67. data/app/views/layouts/style_guide.html.erb +416 -0
  68. data/app/views/shared/_file_upload.html.erb +184 -0
  69. data/app/views/shared/_footer.html.erb +23 -0
  70. data/app/views/shared/_header.html.erb +42 -0
  71. data/app/views/shared/_navbar.html.erb +306 -0
  72. data/app/views/shared/_profile_image_selector.html.erb +165 -0
  73. data/app/views/shared/_theme_switcher.html.erb +64 -0
  74. data/app/views/shared/icons/_adjustments.html.erb +10 -0
  75. data/app/views/shared/icons/_alert_circle.html.erb +3 -0
  76. data/app/views/shared/icons/_alert_triangle.html.erb +3 -0
  77. data/app/views/shared/icons/_archive.html.erb +3 -0
  78. data/app/views/shared/icons/_arrow_down.html.erb +3 -0
  79. data/app/views/shared/icons/_arrow_left.html.erb +3 -0
  80. data/app/views/shared/icons/_arrow_up.html.erb +3 -0
  81. data/app/views/shared/icons/_arrows_pointing_in.html.erb +10 -0
  82. data/app/views/shared/icons/_arrows_pointing_out.html.erb +10 -0
  83. data/app/views/shared/icons/_artemis_logo.html.erb +26 -0
  84. data/app/views/shared/icons/_auth_banner.html.erb +1 -0
  85. data/app/views/shared/icons/_bars.html.erb +10 -0
  86. data/app/views/shared/icons/_bell.html.erb +3 -0
  87. data/app/views/shared/icons/_book.html.erb +3 -0
  88. data/app/views/shared/icons/_bookmark.html.erb +3 -0
  89. data/app/views/shared/icons/_box.html.erb +3 -0
  90. data/app/views/shared/icons/_brain.html.erb +3 -0
  91. data/app/views/shared/icons/_briefcase.html.erb +3 -0
  92. data/app/views/shared/icons/_calendar.html.erb +3 -0
  93. data/app/views/shared/icons/_camera.html.erb +4 -0
  94. data/app/views/shared/icons/_chart_bar.html.erb +3 -0
  95. data/app/views/shared/icons/_chart_line.html.erb +10 -0
  96. data/app/views/shared/icons/_chart_pie.html.erb +11 -0
  97. data/app/views/shared/icons/_chat.html.erb +3 -0
  98. data/app/views/shared/icons/_check.html.erb +3 -0
  99. data/app/views/shared/icons/_check_circle.html.erb +3 -0
  100. data/app/views/shared/icons/_cherry_blossom.html.erb +1516 -0
  101. data/app/views/shared/icons/_cherry_blossom_silhouette.html.erb +1016 -0
  102. data/app/views/shared/icons/_cherry_blossom_single_flower.html.erb +1125 -0
  103. data/app/views/shared/icons/_cherry_blossom_tree.html.erb +159 -0
  104. data/app/views/shared/icons/_chevron_down.html.erb +3 -0
  105. data/app/views/shared/icons/_chevron_right.html.erb +9 -0
  106. data/app/views/shared/icons/_clipboard.html.erb +3 -0
  107. data/app/views/shared/icons/_clock.html.erb +3 -0
  108. data/app/views/shared/icons/_close.html.erb +3 -0
  109. data/app/views/shared/icons/_cog.html.erb +4 -0
  110. data/app/views/shared/icons/_crop.html.erb +10 -0
  111. data/app/views/shared/icons/_crown.html.erb +3 -0
  112. data/app/views/shared/icons/_disc.html.erb +3 -0
  113. data/app/views/shared/icons/_download.html.erb +3 -0
  114. data/app/views/shared/icons/_dragonfly.html.erb +58 -0
  115. data/app/views/shared/icons/_duplicate.html.erb +4 -0
  116. data/app/views/shared/icons/_edit.html.erb +3 -0
  117. data/app/views/shared/icons/_envelope.html.erb +3 -0
  118. data/app/views/shared/icons/_eraser.html.erb +10 -0
  119. data/app/views/shared/icons/_external_link.html.erb +3 -0
  120. data/app/views/shared/icons/_eye.html.erb +4 -0
  121. data/app/views/shared/icons/_file_csv.html.erb +10 -0
  122. data/app/views/shared/icons/_file_export.html.erb +10 -0
  123. data/app/views/shared/icons/_file_image.html.erb +10 -0
  124. data/app/views/shared/icons/_file_import.html.erb +10 -0
  125. data/app/views/shared/icons/_file_question.html.erb +6 -0
  126. data/app/views/shared/icons/_film.html.erb +3 -0
  127. data/app/views/shared/icons/_filter.html.erb +3 -0
  128. data/app/views/shared/icons/_folder.html.erb +3 -0
  129. data/app/views/shared/icons/_folder_open.html.erb +3 -0
  130. data/app/views/shared/icons/_folder_plus.html.erb +3 -0
  131. data/app/views/shared/icons/_globe.html.erb +3 -0
  132. data/app/views/shared/icons/_google.html.erb +11 -0
  133. data/app/views/shared/icons/_heart.html.erb +3 -0
  134. data/app/views/shared/icons/_heart_broken.html.erb +11 -0
  135. data/app/views/shared/icons/_heart_pulse.html.erb +4 -0
  136. data/app/views/shared/icons/_history.html.erb +11 -0
  137. data/app/views/shared/icons/_home.html.erb +10 -0
  138. data/app/views/shared/icons/_image.html.erb +3 -0
  139. data/app/views/shared/icons/_inbox.html.erb +3 -0
  140. data/app/views/shared/icons/_info_circle.html.erb +10 -0
  141. data/app/views/shared/icons/_key.html.erb +3 -0
  142. data/app/views/shared/icons/_layers.html.erb +10 -0
  143. data/app/views/shared/icons/_lightbulb.html.erb +10 -0
  144. data/app/views/shared/icons/_lightning.html.erb +3 -0
  145. data/app/views/shared/icons/_list.html.erb +3 -0
  146. data/app/views/shared/icons/_lock.html.erb +3 -0
  147. data/app/views/shared/icons/_logout.html.erb +3 -0
  148. data/app/views/shared/icons/_magazine.html.erb +3 -0
  149. data/app/views/shared/icons/_magic.html.erb +3 -0
  150. data/app/views/shared/icons/_minus.html.erb +10 -0
  151. data/app/views/shared/icons/_mobile.html.erb +10 -0
  152. data/app/views/shared/icons/_moon.html.erb +3 -0
  153. data/app/views/shared/icons/_network.html.erb +10 -0
  154. data/app/views/shared/icons/_new_item_banner.html.erb +1 -0
  155. data/app/views/shared/icons/_ouroboros.html.erb +24 -0
  156. data/app/views/shared/icons/_package.html.erb +3 -0
  157. data/app/views/shared/icons/_palette.html.erb +3 -0
  158. data/app/views/shared/icons/_paper_plane.html.erb +10 -0
  159. data/app/views/shared/icons/_photo.html.erb +10 -0
  160. data/app/views/shared/icons/_play.html.erb +4 -0
  161. data/app/views/shared/icons/_plus.html.erb +3 -0
  162. data/app/views/shared/icons/_pocket.html.erb +11 -0
  163. data/app/views/shared/icons/_prysm-icon.html.erb +34 -0
  164. data/app/views/shared/icons/_prysm.html.erb +13 -0
  165. data/app/views/shared/icons/_pushbullet-1.html.erb +29 -0
  166. data/app/views/shared/icons/_pushbullet-2.html.erb +2 -0
  167. data/app/views/shared/icons/_puzzle.html.erb +10 -0
  168. data/app/views/shared/icons/_qrcode.html.erb +3 -0
  169. data/app/views/shared/icons/_question.html.erb +3 -0
  170. data/app/views/shared/icons/_receipt.html.erb +10 -0
  171. data/app/views/shared/icons/_redo.html.erb +3 -0
  172. data/app/views/shared/icons/_refresh.html.erb +3 -0
  173. data/app/views/shared/icons/_rocket.html.erb +10 -0
  174. data/app/views/shared/icons/_rss.html.erb +3 -0
  175. data/app/views/shared/icons/_save.html.erb +3 -0
  176. data/app/views/shared/icons/_search.html.erb +3 -0
  177. data/app/views/shared/icons/_search_minus.html.erb +10 -0
  178. data/app/views/shared/icons/_search_plus.html.erb +10 -0
  179. data/app/views/shared/icons/_server_error.html.erb +6 -0
  180. data/app/views/shared/icons/_share.html.erb +3 -0
  181. data/app/views/shared/icons/_shield_check.html.erb +3 -0
  182. data/app/views/shared/icons/_sign_in.html.erb +3 -0
  183. data/app/views/shared/icons/_spinner.html.erb +4 -0
  184. data/app/views/shared/icons/_star.html.erb +3 -0
  185. data/app/views/shared/icons/_store.html.erb +10 -0
  186. data/app/views/shared/icons/_sun.html.erb +3 -0
  187. data/app/views/shared/icons/_sync.html.erb +3 -0
  188. data/app/views/shared/icons/_table.html.erb +3 -0
  189. data/app/views/shared/icons/_tag.html.erb +3 -0
  190. data/app/views/shared/icons/_tags.html.erb +11 -0
  191. data/app/views/shared/icons/_tools.html.erb +4 -0
  192. data/app/views/shared/icons/_trash.html.erb +3 -0
  193. data/app/views/shared/icons/_undo.html.erb +3 -0
  194. data/app/views/shared/icons/_unlock.html.erb +3 -0
  195. data/app/views/shared/icons/_upload.html.erb +3 -0
  196. data/app/views/shared/icons/_user.html.erb +3 -0
  197. data/app/views/shared/icons/_user_circle.html.erb +10 -0
  198. data/app/views/shared/icons/_user_plus.html.erb +10 -0
  199. data/app/views/shared/icons/_video.html.erb +3 -0
  200. data/app/views/shared/icons/_wrench.html.erb +11 -0
  201. data/app/views/style_guide/index.html.erb +77 -0
  202. data/app/views/style_guide/sections/_alerts.html.erb +114 -0
  203. data/app/views/style_guide/sections/_badges.html.erb +78 -0
  204. data/app/views/style_guide/sections/_buttons.html.erb +130 -0
  205. data/app/views/style_guide/sections/_cards.html.erb +84 -0
  206. data/app/views/style_guide/sections/_colors.html.erb +106 -0
  207. data/app/views/style_guide/sections/_file_upload.html.erb +135 -0
  208. data/app/views/style_guide/sections/_forms.html.erb +129 -0
  209. data/app/views/style_guide/sections/_gradients.html.erb +253 -0
  210. data/app/views/style_guide/sections/_header.html.erb +12 -0
  211. data/app/views/style_guide/sections/_icons.html.erb +55 -0
  212. data/app/views/style_guide/sections/_images.html.erb +40 -0
  213. data/app/views/style_guide/sections/_loading.html.erb +242 -0
  214. data/app/views/style_guide/sections/_pagination.html.erb +212 -0
  215. data/app/views/style_guide/sections/_profile_components.html.erb +203 -0
  216. data/app/views/style_guide/sections/_theme_switcher.html.erb +72 -0
  217. data/app/views/style_guide/sections/_typography.html.erb +65 -0
  218. data/bin/ai-optimize-claude-md +540 -0
  219. data/bin/ai-review-local +345 -0
  220. data/bin/ai-security-review +585 -0
  221. data/bin/brakeman +9 -0
  222. data/bin/install-hooks +57 -0
  223. data/bin/rake +7 -0
  224. data/bin/rubocop +10 -0
  225. data/bin/verify_setup.rb +31 -0
  226. data/config/brakeman.ignore +28 -0
  227. data/config/initializers/neon_sakura.rb +15 -0
  228. data/config/license_overrides.yml +13 -0
  229. data/config/routes.rb +21 -0
  230. data/config/theme_mappings.yml +61 -0
  231. data/docs/PRYSM_ASSETS.md +210 -0
  232. data/docs/plans/extract_ai_reviewer_plan.md +151 -0
  233. data/docs/plans/neon_sakura_gem_plan.md +138 -0
  234. data/lib/neon_sakura/configuration.rb +94 -0
  235. data/lib/neon_sakura/engine.rb +48 -0
  236. data/lib/neon_sakura/icon_helper.rb +54 -0
  237. data/lib/neon_sakura/profile_helper.rb +24 -0
  238. data/lib/neon_sakura/stylesheet_helper.rb +40 -0
  239. data/lib/neon_sakura/theme_helper.rb +63 -0
  240. data/lib/neon_sakura/theme_importer.rb +112 -0
  241. data/lib/neon_sakura/version.rb +5 -0
  242. data/lib/neon_sakura.rb +13 -0
  243. data/neon_sakura.gemspec +50 -0
  244. data/package.json +18 -0
  245. data/scripts/git-hooks/post-merge +132 -0
  246. data/scripts/git-hooks/pre-commit +123 -0
  247. data/scripts/git-hooks/pre-push +127 -0
  248. data/scripts/license-check.rb +587 -0
  249. data/settings.local.json +12 -0
  250. data/yarn.lock +778 -0
  251. metadata +503 -0
@@ -0,0 +1,152 @@
1
+ /*
2
+ * Form styles
3
+ * This file contains all form-related styling including inputs, selects, buttons, and checkboxes
4
+ */
5
+
6
+ /* Base input and select styling */
7
+ input[type="text"],
8
+ input[type="email"],
9
+ input[type="password"],
10
+ input[type="number"],
11
+ input[type="date"],
12
+ input[type="search"],
13
+ textarea,
14
+ select {
15
+ appearance: none;
16
+ box-sizing: border-box;
17
+ font-size: 1rem;
18
+ line-height: 1.5;
19
+ background-color: var(--color-surface);
20
+ color: var(--color-text-primary);
21
+ border: 2px solid var(--color-border);
22
+ border-radius: 0.375rem;
23
+ padding: 0.5rem 0.75rem;
24
+ transition: border-color 150ms ease, box-shadow 150ms ease;
25
+ }
26
+
27
+ /* Focus state for inputs */
28
+ input[type="text"]:focus,
29
+ input[type="email"]:focus,
30
+ input[type="password"]:focus,
31
+ input[type="number"]:focus,
32
+ input[type="date"]:focus,
33
+ input[type="search"]:focus,
34
+ textarea:focus,
35
+ select:focus {
36
+ border-color: var(--color-accent);
37
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);
38
+ }
39
+
40
+ /* Removed fixed height to allow utility classes (py-*) to control input sizing consistently */
41
+
42
+ /* Textarea specific */
43
+ textarea {
44
+ resize: vertical;
45
+ min-height: 60px;
46
+ padding: 0.75rem 1rem;
47
+ }
48
+
49
+ /* Select dropdown arrow */
50
+ select {
51
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%239ca3af' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
52
+ background-position: right 0.5rem center;
53
+ background-repeat: no-repeat;
54
+ background-size: 1.5em 1.5em;
55
+ padding-right: 2.5rem;
56
+ }
57
+
58
+ /* Reset focus styles */
59
+ input:focus,
60
+ select:focus,
61
+ textarea:focus,
62
+ button:focus {
63
+ outline: none;
64
+ }
65
+
66
+ /* Fieldset and legend */
67
+ fieldset {
68
+ border-width: 1px;
69
+ }
70
+
71
+ legend {
72
+ padding: 0 0.5rem;
73
+ }
74
+
75
+ /* Checkbox styling */
76
+ input[type="checkbox"] {
77
+ cursor: pointer;
78
+ }
79
+
80
+ /* Submit button styling */
81
+ input[type="submit"],
82
+ button[type="submit"] {
83
+ background-image: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
84
+ border: none;
85
+ cursor: pointer;
86
+ font-weight: 600;
87
+ color: var(--button-text-color);
88
+ }
89
+
90
+ input[type="submit"]:hover,
91
+ button[type="submit"]:hover {
92
+ background-image: linear-gradient(to right, var(--gradient-from-hover), var(--gradient-to-hover));
93
+ transform: scale(1.05);
94
+ }
95
+
96
+ input[type="submit"]:focus,
97
+ button[type="submit"]:focus {
98
+ outline: none;
99
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 5px color-mix(in srgb, var(--color-accent) 50%, transparent);
100
+ }
101
+
102
+ /* Form labels */
103
+ label {
104
+ cursor: pointer;
105
+ }
106
+
107
+ /* Advanced search toggle button */
108
+ .advanced-search-toggle {
109
+ background: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
110
+ border: none;
111
+ color: var(--button-text-color);
112
+ }
113
+
114
+ .advanced-search-toggle:hover {
115
+ background: linear-gradient(to right, var(--gradient-from-hover), var(--gradient-to-hover));
116
+ }
117
+
118
+ .advanced-search-toggle:focus {
119
+ outline: none;
120
+ box-shadow: 0 0 0 2px var(--color-background), 0 0 0 5px color-mix(in srgb, var(--color-accent) 50%, transparent);
121
+ }
122
+
123
+ /* Action button (for delete/icon-only buttons) */
124
+ button.action-button,
125
+ button.action-button[type="submit"] {
126
+ background: none !important;
127
+ background-image: none !important;
128
+ border: none !important;
129
+ padding: 0 !important;
130
+ cursor: pointer;
131
+ transform: none !important;
132
+ box-shadow: none !important;
133
+ display: inline-flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ }
137
+
138
+ button.action-button:hover,
139
+ button.action-button[type="submit"]:hover {
140
+ background: none !important;
141
+ background-image: none !important;
142
+ transform: none !important;
143
+ box-shadow: none !important;
144
+ }
145
+
146
+ button.action-button:focus,
147
+ button.action-button[type="submit"]:focus {
148
+ background: none !important;
149
+ background-image: none !important;
150
+ box-shadow: none !important;
151
+ outline: none;
152
+ }
@@ -0,0 +1,145 @@
1
+ /*
2
+ * Loading Indicators
3
+ * Spinners, progress bars, and skeleton loaders
4
+ */
5
+
6
+ /* Spinners */
7
+ .spinner-basic,
8
+ .spinner-accent,
9
+ .spinner-small,
10
+ .spinner-large {
11
+ display: inline-block;
12
+ border-radius: 50%;
13
+ border-style: solid;
14
+ animation: spin 1s linear infinite;
15
+ box-sizing: border-box;
16
+ }
17
+
18
+ .spinner-basic {
19
+ width: 32px;
20
+ height: 32px;
21
+ border-width: 3px;
22
+ border-color: var(--color-border);
23
+ border-top-color: var(--color-text-primary);
24
+ }
25
+
26
+ .spinner-accent {
27
+ width: 32px;
28
+ height: 32px;
29
+ border-width: 3px;
30
+ border-color: color-mix(in srgb, var(--color-accent) 20%, transparent);
31
+ border-top-color: var(--color-accent);
32
+ }
33
+
34
+ .spinner-small {
35
+ width: 16px;
36
+ height: 16px;
37
+ border-width: 2px;
38
+ border-color: color-mix(in srgb, var(--color-accent) 20%, transparent);
39
+ border-top-color: var(--color-accent);
40
+ }
41
+
42
+ .spinner-large {
43
+ width: 48px;
44
+ height: 48px;
45
+ border-width: 4px;
46
+ border-color: color-mix(in srgb, var(--color-accent) 20%, transparent);
47
+ border-top-color: var(--color-accent);
48
+ }
49
+
50
+ @keyframes spin {
51
+ to {
52
+ transform: rotate(360deg);
53
+ }
54
+ }
55
+
56
+ /* Progress Bars */
57
+ .progress-bar-container {
58
+ width: 100%;
59
+ height: 8px;
60
+ background-color: var(--color-border);
61
+ border-radius: 9999px;
62
+ overflow: hidden;
63
+ position: relative;
64
+ display: block;
65
+ }
66
+
67
+ .progress-bar-fill {
68
+ height: 100%;
69
+ background: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
70
+ border-radius: 9999px;
71
+ transition: width 0.3s ease;
72
+ }
73
+
74
+ .progress-bar-indeterminate {
75
+ height: 100%;
76
+ background: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
77
+ border-radius: 9999px;
78
+ animation: progress-indeterminate 1.5s ease-in-out infinite;
79
+ width: 40%;
80
+ }
81
+
82
+ @keyframes progress-indeterminate {
83
+ 0% {
84
+ transform: translateX(-100%);
85
+ }
86
+
87
+ 100% {
88
+ transform: translateX(350%);
89
+ }
90
+ }
91
+
92
+ /* Skeleton Loaders */
93
+ .skeleton-text,
94
+ .skeleton-avatar {
95
+ display: block;
96
+ background: linear-gradient(
97
+ 90deg,
98
+ var(--color-surface) 0%,
99
+ color-mix(in srgb, var(--color-border) 50%, var(--color-surface)) 50%,
100
+ var(--color-surface) 100%
101
+ );
102
+ background-size: 200% 100%;
103
+ animation: skeleton-loading 1.5s ease-in-out infinite;
104
+ border-radius: 0.25rem;
105
+ }
106
+
107
+ .skeleton-text {
108
+ height: 1rem;
109
+ width: 100%;
110
+ margin-bottom: 0.5rem;
111
+ }
112
+
113
+ .skeleton-avatar {
114
+ width: 48px;
115
+ height: 48px;
116
+ border-radius: 50%;
117
+ flex-shrink: 0;
118
+ }
119
+
120
+ @keyframes skeleton-loading {
121
+ 0% {
122
+ background-position: 200% 0;
123
+ }
124
+
125
+ 100% {
126
+ background-position: -200% 0;
127
+ }
128
+ }
129
+
130
+ /* Loading overlay */
131
+ .loading-overlay {
132
+ position: fixed;
133
+ inset: 0;
134
+ background-color: color-mix(in srgb, var(--color-background) 80%, transparent);
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: center;
138
+ z-index: 9999;
139
+ }
140
+
141
+ .loading-overlay .spinner-accent {
142
+ width: 64px;
143
+ height: 64px;
144
+ border-width: 4px;
145
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css by Rails' asset pipeline.
3
+ *
4
+ * With Propshaft, each @import creates a separate <link> tag. This manifest
5
+ * imports all the gem's CSS components in the proper order for consistent theming.
6
+ *
7
+ * The gem's styling components are organized as:
8
+ * - themes/: Color definitions for each theme (purple, green, red)
9
+ * - utilities/: Reusable utility classes (layout, spacing, typography, etc.)
10
+ * - components.css: UI components (navigation, cards, badges, buttons, tables, etc.)
11
+ * - forms.css: Form element styling
12
+ * - pagy-tailwind.css: Pagination styling with Tailwind CSS
13
+ *
14
+ * Include this manifest in your application layout with:
15
+ * <%= stylesheet_link_tag "neon_sakura", "data-turbo-track": "reload" %>
16
+ */
17
+
18
+ /* Import themes first - defines CSS variables */
19
+ @import "theme-default.css";
20
+ @import "theme-purple.css";
21
+ @import "theme-green.css";
22
+ @import "theme-red.css";
23
+
24
+ /* Import utilities - uses CSS variables */
25
+ @import "utility-reset.css";
26
+ @import "utility-layout.css";
27
+ @import "utility-sizing.css";
28
+ @import "utility-spacing.css";
29
+ @import "utility-colors.css";
30
+ @import "utility-borders.css";
31
+ @import "utility-typography.css";
32
+ @import "utility-gradients.css";
33
+ @import "utility-effects.css";
34
+ @import "utility-responsive.css";
35
+ @import "loading.css";
36
+
37
+ /* Import components and forms - uses both themes and utilities */
38
+ @import "components.css";
39
+ @import "forms.css";
40
+ @import "pagy-tailwind.css";
@@ -0,0 +1,120 @@
1
+ /*
2
+ * Pagy Pagination Styles
3
+ * Theme-aware pagination styles for Pagy gem (v43+)
4
+ * Based on Pagy's official CSS structure, adapted for neon_sakura themes
5
+ * NOTE: Uses plain CSS (no Tailwind build required) for Propshaft compatibility
6
+ */
7
+
8
+ /* Main pagination container */
9
+ .pagy {
10
+ display: flex;
11
+ flex-wrap: wrap;
12
+ justify-content: center;
13
+ gap: 0.25rem;
14
+ max-width: 100%;
15
+ color: var(--color-text-primary);
16
+ font-size: 0.875rem;
17
+ font-weight: 600;
18
+ line-height: 1.75;
19
+ }
20
+
21
+ /* All links except gaps */
22
+ .pagy a:not([role="separator"]) {
23
+ display: block;
24
+ text-decoration: none;
25
+ background-color: var(--color-surface);
26
+ color: var(--color-text-primary);
27
+ padding: 0.5rem 0.75rem;
28
+ border: 1px solid var(--color-border);
29
+ border-radius: 0.375rem;
30
+ transition: all 150ms ease;
31
+ }
32
+
33
+ /* Hover state for all links */
34
+ .pagy a[href]:hover {
35
+ background: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
36
+ color: var(--color-white);
37
+ border-color: var(--color-accent);
38
+ }
39
+
40
+ /* All non-links (current page, disabled) */
41
+ .pagy a:not([href]) {
42
+ cursor: default;
43
+ }
44
+
45
+ /* Disabled links */
46
+ .pagy a[role="link"]:not([aria-current]) {
47
+ opacity: 0.4;
48
+ cursor: not-allowed;
49
+ pointer-events: none;
50
+ }
51
+
52
+ /* Current page */
53
+ .pagy a[aria-current] {
54
+ background: linear-gradient(to right, var(--gradient-from), var(--gradient-to));
55
+ color: var(--color-white);
56
+ border-color: var(--color-accent);
57
+ font-weight: 700;
58
+ }
59
+
60
+ /* Label wrapper for input/select */
61
+ .pagy label {
62
+ white-space: nowrap;
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 0.5rem;
66
+ border: 1px solid var(--color-border);
67
+ border-radius: 0.375rem;
68
+ background-color: var(--color-surface);
69
+ padding: 0.5rem 0.75rem;
70
+ color: var(--color-text-primary);
71
+ }
72
+
73
+ /* Input field inside label */
74
+ .pagy label input {
75
+ all: unset;
76
+ width: 4rem;
77
+ padding: 0.25rem 0.5rem;
78
+ border: 1px solid var(--color-border);
79
+ border-radius: 0.25rem;
80
+ background-color: var(--color-background);
81
+ color: var(--color-text-primary);
82
+ text-align: center;
83
+ font-size: 0.875rem;
84
+ font-weight: 500;
85
+ }
86
+
87
+ .pagy label input:focus {
88
+ outline: none;
89
+ border-color: var(--color-accent);
90
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);
91
+ }
92
+
93
+ /* Select dropdown inside label */
94
+ .pagy label select {
95
+ all: unset;
96
+ width: 4rem;
97
+ padding: 0.25rem 0.5rem;
98
+ border: 1px solid var(--color-border);
99
+ border-radius: 0.25rem;
100
+ background-color: var(--color-background);
101
+ color: var(--color-text-primary);
102
+ text-align: center;
103
+ font-size: 0.875rem;
104
+ font-weight: 500;
105
+ cursor: pointer;
106
+ }
107
+
108
+ .pagy label select:focus {
109
+ outline: none;
110
+ border-color: var(--color-accent);
111
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);
112
+ }
113
+
114
+ /* Info text (e.g., "Showing 1-10 of 100") */
115
+ .pagy-info {
116
+ color: var(--color-text-secondary);
117
+ font-size: 0.875rem;
118
+ text-align: center;
119
+ margin: 1rem 0;
120
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Default Theme Colors (Purple Dark)
3
+ * This file defines the default :root CSS custom properties for the theme system
4
+ */
5
+
6
+ /* CSS Custom Properties - Default Theme (Purple Dark) */
7
+ :root {
8
+ --color-text-primary: #fff;
9
+ --color-text-secondary: #cbd5e1;
10
+ --color-text-muted: #94a3b8;
11
+ --color-background: #111827;
12
+ --color-surface: #1f2937;
13
+ --color-accent: #a855f7;
14
+ --color-notification: #10b981;
15
+ --color-alert: #ef4444;
16
+ --color-warning: #f59e0b;
17
+ --color-border: #374151;
18
+ --color-white: #fff;
19
+
20
+ /* Gradient colors for buttons and backgrounds */
21
+ --gradient-from: #2563eb;
22
+ --gradient-to: #9333ea;
23
+ --gradient-from-hover: #1d4ed8;
24
+ --gradient-to-hover: #7e22ce;
25
+
26
+ /* Text gradient colors for headings and links */
27
+ --text-gradient-from: #60a5fa;
28
+ --text-gradient-to: #a855f7;
29
+
30
+ /* Secondary blue gradient - cyan to blue (theme-independent) */
31
+ --gradient-secondary-blue-from: #0891b2;
32
+ --gradient-secondary-blue-to: #2563eb;
33
+
34
+ /* Navbar link colors - bright cyan for dark mode (default) */
35
+ --navbar-link-color: #06b6d4;
36
+ --navbar-link-hover: #22d3ee;
37
+
38
+ /* Button text color - white for good contrast on gradients */
39
+ --button-text-color: #fff;
40
+ }
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Green Theme - Light and Dark Variants
3
+ * This file contains color definitions for both green light and green dark themes
4
+ */
5
+
6
+ /* Green Light Theme */
7
+ [data-theme-name="green"][data-theme-mode="light"] {
8
+ --color-text-primary: #545E75;
9
+ --color-text-secondary: #6c757d;
10
+ --color-text-muted: #8b95a8;
11
+ --color-background: #FFF;
12
+ --color-surface: #f8f9fa;
13
+ --color-accent: #009990;
14
+ --color-notification: #009990;
15
+ --color-alert: #DE5959;
16
+ --color-warning: #f59e0b;
17
+ --color-border: #dee2e6;
18
+ --color-white: #fff;
19
+
20
+ /* Green to cyan gradients for light theme */
21
+ --gradient-from: #059669;
22
+ --gradient-to: #0891b2;
23
+ --gradient-from-hover: #047857;
24
+ --gradient-to-hover: #0e7490;
25
+
26
+ /* Text gradient colors - green to cyan for headings */
27
+ --text-gradient-from: #10b981;
28
+ --text-gradient-to: #06b6d4;
29
+
30
+ /* Navbar gradient - accent to notification (green to green) */
31
+ --gradient-navbar-from: var(--color-accent);
32
+ --gradient-navbar-to: var(--color-notification);
33
+
34
+ /* Secondary blue gradient - cyan to blue (theme-independent) */
35
+ --gradient-secondary-blue-from: #0891b2;
36
+ --gradient-secondary-blue-to: #2563eb;
37
+
38
+ /* Navbar link colors - darker cyan for light mode */
39
+ --navbar-link-color: #0891b2;
40
+ --navbar-link-hover: #0e7490;
41
+
42
+ /* Button text color - white for good contrast on gradients */
43
+ --button-text-color: #fff;
44
+ }
45
+
46
+ /* Green Dark Theme */
47
+ [data-theme-name="green"][data-theme-mode="dark"] {
48
+ --color-text-primary: #e2e8f0;
49
+ --color-text-secondary: #94a3b8;
50
+ --color-text-muted: #64748b;
51
+ --color-background: #0f172a;
52
+ --color-surface: #1e293b;
53
+ --color-accent: #10b981;
54
+ --color-notification: #10b981;
55
+ --color-alert: #ef4444;
56
+ --color-warning: #f59e0b;
57
+ --color-border: #334155;
58
+ --color-white: #fff;
59
+
60
+ /* Green to cyan gradients for dark theme */
61
+ --gradient-from: #10b981;
62
+ --gradient-to: #06b6d4;
63
+ --gradient-from-hover: #059669;
64
+ --gradient-to-hover: #0891b2;
65
+
66
+ /* Text gradient colors - green to cyan for headings */
67
+ --text-gradient-from: #34d399;
68
+ --text-gradient-to: #22d3ee;
69
+
70
+ /* Navbar gradient - accent to notification (green to green) */
71
+ --gradient-navbar-from: var(--color-accent);
72
+ --gradient-navbar-to: var(--color-notification);
73
+
74
+ /* Secondary blue gradient - cyan to blue (theme-independent) */
75
+ --gradient-secondary-blue-from: #0891b2;
76
+ --gradient-secondary-blue-to: #2563eb;
77
+
78
+ /* Navbar link colors - white for dark mode, cyan on hover */
79
+ --navbar-link-color: #fff;
80
+ --navbar-link-hover: #22d3ee;
81
+
82
+ /* Button text color - white for good contrast on gradients */
83
+ --button-text-color: #fff;
84
+ }
@@ -0,0 +1,94 @@
1
+ /*
2
+ * Purple Theme - Light and Dark Variants
3
+ * This file contains color definitions for both purple light and purple dark themes
4
+ */
5
+
6
+ /* Purple Light Theme */
7
+ [data-theme-name="purple"][data-theme-mode="light"] {
8
+ --color-text-primary: #374151;
9
+ --color-text-secondary: #6b7280;
10
+ --color-text-muted: #9ca3af;
11
+ --color-background: #FFF;
12
+ --color-surface: #f9fafb;
13
+ --color-accent: #a855f7;
14
+ --color-notification: #10b981;
15
+ --color-alert: #ef4444;
16
+ --color-warning: #f59e0b;
17
+ --color-border: #e5e7eb;
18
+ --color-white: #fff;
19
+
20
+ /* Purple gradients for light theme - darker for visibility */
21
+ --gradient-from: #7c3aed;
22
+ --gradient-to: #9333ea;
23
+ --gradient-from-hover: #6d28d9;
24
+ --gradient-to-hover: #7c3aed;
25
+
26
+ /* Text gradient colors - purple/blue for headings */
27
+ --text-gradient-from: #60a5fa;
28
+ --text-gradient-to: #a855f7;
29
+
30
+ /* Secondary gradient - alternative purple gradient (lighter for light theme) */
31
+ --gradient-secondary-start: #b038dc;
32
+ --gradient-secondary-mid: #4c3ba5;
33
+ --gradient-secondary-end: #393e9c;
34
+
35
+ /* Navbar gradient - accent to notification (purple to green) */
36
+ --gradient-navbar-from: var(--color-accent);
37
+ --gradient-navbar-to: var(--color-notification);
38
+
39
+ /* Secondary blue gradient - cyan to blue (theme-independent) */
40
+ --gradient-secondary-blue-from: #0891b2;
41
+ --gradient-secondary-blue-to: #2563eb;
42
+
43
+ /* Navbar link colors - darker cyan for light mode */
44
+ --navbar-link-color: #0891b2;
45
+ --navbar-link-hover: #0e7490;
46
+
47
+ /* Button text color - white for good contrast on gradients */
48
+ --button-text-color: #fff;
49
+ }
50
+
51
+ /* Purple Dark Theme */
52
+ [data-theme-name="purple"][data-theme-mode="dark"] {
53
+ --color-text-primary: #fff;
54
+ --color-text-secondary: #cbd5e1;
55
+ --color-text-muted: #94a3b8;
56
+ --color-background: #111827;
57
+ --color-surface: #1f2937;
58
+ --color-accent: #a855f7;
59
+ --color-notification: #10b981;
60
+ --color-alert: #ef4444;
61
+ --color-warning: #f59e0b;
62
+ --color-border: #374151;
63
+ --color-white: #fff;
64
+
65
+ /* Purple gradients for dark theme */
66
+ --gradient-from: #2563eb;
67
+ --gradient-to: #9333ea;
68
+ --gradient-from-hover: #1d4ed8;
69
+ --gradient-to-hover: #7e22ce;
70
+
71
+ /* Text gradient colors - purple/blue for headings */
72
+ --text-gradient-from: #60a5fa;
73
+ --text-gradient-to: #a855f7;
74
+
75
+ /* Secondary gradient - alternative purple gradient */
76
+ --gradient-secondary-start: #b038dc;
77
+ --gradient-secondary-mid: #4c3ba5;
78
+ --gradient-secondary-end: #393e9c;
79
+
80
+ /* Navbar gradient - accent to notification (purple to green) */
81
+ --gradient-navbar-from: var(--color-accent);
82
+ --gradient-navbar-to: var(--color-notification);
83
+
84
+ /* Secondary blue gradient - cyan to blue (theme-independent) */
85
+ --gradient-secondary-blue-from: #0891b2;
86
+ --gradient-secondary-blue-to: #2563eb;
87
+
88
+ /* Navbar link colors - white for dark mode, cyan on hover */
89
+ --navbar-link-color: #fff;
90
+ --navbar-link-hover: #22d3ee;
91
+
92
+ /* Button text color - white for good contrast on gradients */
93
+ --button-text-color: #fff;
94
+ }