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.
- checksums.yaml +7 -0
- data/.ai-reviewer/README.md +182 -0
- data/.ai-reviewer/ai-reviewer.sh +56 -0
- data/.ai-reviewer/build-system-prompt.sh +136 -0
- data/.ai-reviewer/extract-claude-sections.sh +32 -0
- data/.ai-reviewer/test-ai-reviewer.sh +40 -0
- data/.ai-reviewer-config.yml +190 -0
- data/.github/dependabot.yml +12 -0
- data/.github/settings.yml +70 -0
- data/.github/workflows/ai-pr-review-on-comment.yml +384 -0
- data/.github/workflows/ai-pr-review.yml +328 -0
- data/.github/workflows/license-check.yml +78 -0
- data/.github/workflows/lint.yml +79 -0
- data/.github/workflows/security.yml +131 -0
- data/.github/workflows/semgrep.yml +26 -0
- data/.github/workflows/test.yml +44 -0
- data/.gitignore +75 -0
- data/.rubocop.yml +33 -0
- data/.ruby-version +1 -0
- data/.simplecov +14 -0
- data/.stylelintignore +10 -0
- data/.stylelintrc.json +37 -0
- data/AGENTS.md +51 -0
- data/CHANGELOG.md +568 -0
- data/CLAUDE.md +632 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +327 -0
- data/LICENSE +21 -0
- data/README.md +1209 -0
- data/Rakefile +25 -0
- data/app/assets/images/cherry_blossom.svg +1525 -0
- data/app/assets/images/cherry_blossom_tree.png +0 -0
- data/app/assets/images/prysm-icon.png +0 -0
- data/app/assets/stylesheets/base.css +29 -0
- data/app/assets/stylesheets/components.css +1652 -0
- data/app/assets/stylesheets/forms.css +152 -0
- data/app/assets/stylesheets/loading.css +145 -0
- data/app/assets/stylesheets/neon_sakura.css +40 -0
- data/app/assets/stylesheets/pagy-tailwind.css +120 -0
- data/app/assets/stylesheets/theme-default.css +40 -0
- data/app/assets/stylesheets/theme-green.css +84 -0
- data/app/assets/stylesheets/theme-purple.css +94 -0
- data/app/assets/stylesheets/theme-red.css +84 -0
- data/app/assets/stylesheets/utility-borders.css +29 -0
- data/app/assets/stylesheets/utility-colors.css +185 -0
- data/app/assets/stylesheets/utility-effects.css +123 -0
- data/app/assets/stylesheets/utility-gradients.css +158 -0
- data/app/assets/stylesheets/utility-layout.css +132 -0
- data/app/assets/stylesheets/utility-reset.css +13 -0
- data/app/assets/stylesheets/utility-responsive.css +145 -0
- data/app/assets/stylesheets/utility-sizing.css +99 -0
- data/app/assets/stylesheets/utility-spacing.css +174 -0
- data/app/assets/stylesheets/utility-typography.css +97 -0
- data/app/controllers/errors_controller.rb +120 -0
- data/app/controllers/style_guide_controller.rb +117 -0
- data/app/helpers/errors_helper.rb +12 -0
- data/app/helpers/neon_sakura/navbar_helper.rb +43 -0
- data/app/helpers/style_guide_helper.rb +36 -0
- data/app/javascript/neon_sakura/dropdown.js +22 -0
- data/app/javascript/neon_sakura/navbar.js +71 -0
- data/app/javascript/neon_sakura/theme_switcher.js +187 -0
- data/app/views/errors/show.html.erb +105 -0
- data/app/views/layouts/error.html.erb +19 -0
- data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +14 -0
- data/app/views/layouts/mission_control/jobs/_navigation.html.erb +21 -0
- data/app/views/layouts/mission_control/jobs/application.html.erb +453 -0
- data/app/views/layouts/style_guide.html.erb +416 -0
- data/app/views/shared/_file_upload.html.erb +184 -0
- data/app/views/shared/_footer.html.erb +23 -0
- data/app/views/shared/_header.html.erb +42 -0
- data/app/views/shared/_navbar.html.erb +306 -0
- data/app/views/shared/_profile_image_selector.html.erb +165 -0
- data/app/views/shared/_theme_switcher.html.erb +64 -0
- data/app/views/shared/icons/_adjustments.html.erb +10 -0
- data/app/views/shared/icons/_alert_circle.html.erb +3 -0
- data/app/views/shared/icons/_alert_triangle.html.erb +3 -0
- data/app/views/shared/icons/_archive.html.erb +3 -0
- data/app/views/shared/icons/_arrow_down.html.erb +3 -0
- data/app/views/shared/icons/_arrow_left.html.erb +3 -0
- data/app/views/shared/icons/_arrow_up.html.erb +3 -0
- data/app/views/shared/icons/_arrows_pointing_in.html.erb +10 -0
- data/app/views/shared/icons/_arrows_pointing_out.html.erb +10 -0
- data/app/views/shared/icons/_artemis_logo.html.erb +26 -0
- data/app/views/shared/icons/_auth_banner.html.erb +1 -0
- data/app/views/shared/icons/_bars.html.erb +10 -0
- data/app/views/shared/icons/_bell.html.erb +3 -0
- data/app/views/shared/icons/_book.html.erb +3 -0
- data/app/views/shared/icons/_bookmark.html.erb +3 -0
- data/app/views/shared/icons/_box.html.erb +3 -0
- data/app/views/shared/icons/_brain.html.erb +3 -0
- data/app/views/shared/icons/_briefcase.html.erb +3 -0
- data/app/views/shared/icons/_calendar.html.erb +3 -0
- data/app/views/shared/icons/_camera.html.erb +4 -0
- data/app/views/shared/icons/_chart_bar.html.erb +3 -0
- data/app/views/shared/icons/_chart_line.html.erb +10 -0
- data/app/views/shared/icons/_chart_pie.html.erb +11 -0
- data/app/views/shared/icons/_chat.html.erb +3 -0
- data/app/views/shared/icons/_check.html.erb +3 -0
- data/app/views/shared/icons/_check_circle.html.erb +3 -0
- data/app/views/shared/icons/_cherry_blossom.html.erb +1516 -0
- data/app/views/shared/icons/_cherry_blossom_silhouette.html.erb +1016 -0
- data/app/views/shared/icons/_cherry_blossom_single_flower.html.erb +1125 -0
- data/app/views/shared/icons/_cherry_blossom_tree.html.erb +159 -0
- data/app/views/shared/icons/_chevron_down.html.erb +3 -0
- data/app/views/shared/icons/_chevron_right.html.erb +9 -0
- data/app/views/shared/icons/_clipboard.html.erb +3 -0
- data/app/views/shared/icons/_clock.html.erb +3 -0
- data/app/views/shared/icons/_close.html.erb +3 -0
- data/app/views/shared/icons/_cog.html.erb +4 -0
- data/app/views/shared/icons/_crop.html.erb +10 -0
- data/app/views/shared/icons/_crown.html.erb +3 -0
- data/app/views/shared/icons/_disc.html.erb +3 -0
- data/app/views/shared/icons/_download.html.erb +3 -0
- data/app/views/shared/icons/_dragonfly.html.erb +58 -0
- data/app/views/shared/icons/_duplicate.html.erb +4 -0
- data/app/views/shared/icons/_edit.html.erb +3 -0
- data/app/views/shared/icons/_envelope.html.erb +3 -0
- data/app/views/shared/icons/_eraser.html.erb +10 -0
- data/app/views/shared/icons/_external_link.html.erb +3 -0
- data/app/views/shared/icons/_eye.html.erb +4 -0
- data/app/views/shared/icons/_file_csv.html.erb +10 -0
- data/app/views/shared/icons/_file_export.html.erb +10 -0
- data/app/views/shared/icons/_file_image.html.erb +10 -0
- data/app/views/shared/icons/_file_import.html.erb +10 -0
- data/app/views/shared/icons/_file_question.html.erb +6 -0
- data/app/views/shared/icons/_film.html.erb +3 -0
- data/app/views/shared/icons/_filter.html.erb +3 -0
- data/app/views/shared/icons/_folder.html.erb +3 -0
- data/app/views/shared/icons/_folder_open.html.erb +3 -0
- data/app/views/shared/icons/_folder_plus.html.erb +3 -0
- data/app/views/shared/icons/_globe.html.erb +3 -0
- data/app/views/shared/icons/_google.html.erb +11 -0
- data/app/views/shared/icons/_heart.html.erb +3 -0
- data/app/views/shared/icons/_heart_broken.html.erb +11 -0
- data/app/views/shared/icons/_heart_pulse.html.erb +4 -0
- data/app/views/shared/icons/_history.html.erb +11 -0
- data/app/views/shared/icons/_home.html.erb +10 -0
- data/app/views/shared/icons/_image.html.erb +3 -0
- data/app/views/shared/icons/_inbox.html.erb +3 -0
- data/app/views/shared/icons/_info_circle.html.erb +10 -0
- data/app/views/shared/icons/_key.html.erb +3 -0
- data/app/views/shared/icons/_layers.html.erb +10 -0
- data/app/views/shared/icons/_lightbulb.html.erb +10 -0
- data/app/views/shared/icons/_lightning.html.erb +3 -0
- data/app/views/shared/icons/_list.html.erb +3 -0
- data/app/views/shared/icons/_lock.html.erb +3 -0
- data/app/views/shared/icons/_logout.html.erb +3 -0
- data/app/views/shared/icons/_magazine.html.erb +3 -0
- data/app/views/shared/icons/_magic.html.erb +3 -0
- data/app/views/shared/icons/_minus.html.erb +10 -0
- data/app/views/shared/icons/_mobile.html.erb +10 -0
- data/app/views/shared/icons/_moon.html.erb +3 -0
- data/app/views/shared/icons/_network.html.erb +10 -0
- data/app/views/shared/icons/_new_item_banner.html.erb +1 -0
- data/app/views/shared/icons/_ouroboros.html.erb +24 -0
- data/app/views/shared/icons/_package.html.erb +3 -0
- data/app/views/shared/icons/_palette.html.erb +3 -0
- data/app/views/shared/icons/_paper_plane.html.erb +10 -0
- data/app/views/shared/icons/_photo.html.erb +10 -0
- data/app/views/shared/icons/_play.html.erb +4 -0
- data/app/views/shared/icons/_plus.html.erb +3 -0
- data/app/views/shared/icons/_pocket.html.erb +11 -0
- data/app/views/shared/icons/_prysm-icon.html.erb +34 -0
- data/app/views/shared/icons/_prysm.html.erb +13 -0
- data/app/views/shared/icons/_pushbullet-1.html.erb +29 -0
- data/app/views/shared/icons/_pushbullet-2.html.erb +2 -0
- data/app/views/shared/icons/_puzzle.html.erb +10 -0
- data/app/views/shared/icons/_qrcode.html.erb +3 -0
- data/app/views/shared/icons/_question.html.erb +3 -0
- data/app/views/shared/icons/_receipt.html.erb +10 -0
- data/app/views/shared/icons/_redo.html.erb +3 -0
- data/app/views/shared/icons/_refresh.html.erb +3 -0
- data/app/views/shared/icons/_rocket.html.erb +10 -0
- data/app/views/shared/icons/_rss.html.erb +3 -0
- data/app/views/shared/icons/_save.html.erb +3 -0
- data/app/views/shared/icons/_search.html.erb +3 -0
- data/app/views/shared/icons/_search_minus.html.erb +10 -0
- data/app/views/shared/icons/_search_plus.html.erb +10 -0
- data/app/views/shared/icons/_server_error.html.erb +6 -0
- data/app/views/shared/icons/_share.html.erb +3 -0
- data/app/views/shared/icons/_shield_check.html.erb +3 -0
- data/app/views/shared/icons/_sign_in.html.erb +3 -0
- data/app/views/shared/icons/_spinner.html.erb +4 -0
- data/app/views/shared/icons/_star.html.erb +3 -0
- data/app/views/shared/icons/_store.html.erb +10 -0
- data/app/views/shared/icons/_sun.html.erb +3 -0
- data/app/views/shared/icons/_sync.html.erb +3 -0
- data/app/views/shared/icons/_table.html.erb +3 -0
- data/app/views/shared/icons/_tag.html.erb +3 -0
- data/app/views/shared/icons/_tags.html.erb +11 -0
- data/app/views/shared/icons/_tools.html.erb +4 -0
- data/app/views/shared/icons/_trash.html.erb +3 -0
- data/app/views/shared/icons/_undo.html.erb +3 -0
- data/app/views/shared/icons/_unlock.html.erb +3 -0
- data/app/views/shared/icons/_upload.html.erb +3 -0
- data/app/views/shared/icons/_user.html.erb +3 -0
- data/app/views/shared/icons/_user_circle.html.erb +10 -0
- data/app/views/shared/icons/_user_plus.html.erb +10 -0
- data/app/views/shared/icons/_video.html.erb +3 -0
- data/app/views/shared/icons/_wrench.html.erb +11 -0
- data/app/views/style_guide/index.html.erb +77 -0
- data/app/views/style_guide/sections/_alerts.html.erb +114 -0
- data/app/views/style_guide/sections/_badges.html.erb +78 -0
- data/app/views/style_guide/sections/_buttons.html.erb +130 -0
- data/app/views/style_guide/sections/_cards.html.erb +84 -0
- data/app/views/style_guide/sections/_colors.html.erb +106 -0
- data/app/views/style_guide/sections/_file_upload.html.erb +135 -0
- data/app/views/style_guide/sections/_forms.html.erb +129 -0
- data/app/views/style_guide/sections/_gradients.html.erb +253 -0
- data/app/views/style_guide/sections/_header.html.erb +12 -0
- data/app/views/style_guide/sections/_icons.html.erb +55 -0
- data/app/views/style_guide/sections/_images.html.erb +40 -0
- data/app/views/style_guide/sections/_loading.html.erb +242 -0
- data/app/views/style_guide/sections/_pagination.html.erb +212 -0
- data/app/views/style_guide/sections/_profile_components.html.erb +203 -0
- data/app/views/style_guide/sections/_theme_switcher.html.erb +72 -0
- data/app/views/style_guide/sections/_typography.html.erb +65 -0
- data/bin/ai-optimize-claude-md +540 -0
- data/bin/ai-review-local +345 -0
- data/bin/ai-security-review +585 -0
- data/bin/brakeman +9 -0
- data/bin/install-hooks +57 -0
- data/bin/rake +7 -0
- data/bin/rubocop +10 -0
- data/bin/verify_setup.rb +31 -0
- data/config/brakeman.ignore +28 -0
- data/config/initializers/neon_sakura.rb +15 -0
- data/config/license_overrides.yml +13 -0
- data/config/routes.rb +21 -0
- data/config/theme_mappings.yml +61 -0
- data/docs/PRYSM_ASSETS.md +210 -0
- data/docs/plans/extract_ai_reviewer_plan.md +151 -0
- data/docs/plans/neon_sakura_gem_plan.md +138 -0
- data/lib/neon_sakura/configuration.rb +94 -0
- data/lib/neon_sakura/engine.rb +48 -0
- data/lib/neon_sakura/icon_helper.rb +54 -0
- data/lib/neon_sakura/profile_helper.rb +24 -0
- data/lib/neon_sakura/stylesheet_helper.rb +40 -0
- data/lib/neon_sakura/theme_helper.rb +63 -0
- data/lib/neon_sakura/theme_importer.rb +112 -0
- data/lib/neon_sakura/version.rb +5 -0
- data/lib/neon_sakura.rb +13 -0
- data/neon_sakura.gemspec +50 -0
- data/package.json +18 -0
- data/scripts/git-hooks/post-merge +132 -0
- data/scripts/git-hooks/pre-commit +123 -0
- data/scripts/git-hooks/pre-push +127 -0
- data/scripts/license-check.rb +587 -0
- data/settings.local.json +12 -0
- data/yarn.lock +778 -0
- metadata +503 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Responsive Utilities
|
|
3
|
+
* This file contains media query utilities for responsive design
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Responsive utilities */
|
|
7
|
+
@media (width >= 640px) {
|
|
8
|
+
.sm\:py-16 {
|
|
9
|
+
padding-top: 4rem;
|
|
10
|
+
padding-bottom: 4rem;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.sm\:px-6 {
|
|
14
|
+
padding-left: 1.5rem;
|
|
15
|
+
padding-right: 1.5rem;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sm\:flex-row {
|
|
19
|
+
flex-direction: row;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sm\:mr-4 {
|
|
23
|
+
margin-right: 1rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.sm\:mb-0 {
|
|
27
|
+
margin-bottom: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sm\:mt-12 {
|
|
31
|
+
margin-top: 3rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.sm\:text-sm {
|
|
35
|
+
font-size: 0.875rem;
|
|
36
|
+
line-height: 1.25rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.sm\:text-base {
|
|
40
|
+
font-size: 1rem;
|
|
41
|
+
line-height: 1.5rem;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sm\:text-lg {
|
|
45
|
+
font-size: 1.125rem;
|
|
46
|
+
line-height: 1.75rem;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sm\:text-2xl {
|
|
50
|
+
font-size: 1.5rem;
|
|
51
|
+
line-height: 2rem;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.sm\:text-3xl {
|
|
55
|
+
font-size: 1.875rem;
|
|
56
|
+
line-height: 2.25rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sm\:text-4xl {
|
|
60
|
+
font-size: 2.25rem;
|
|
61
|
+
line-height: 2.5rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sm\:grid-cols-2 {
|
|
65
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sm\:grid-cols-3 {
|
|
69
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sm\:grid-cols-4 {
|
|
73
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.sm\:gap-4 {
|
|
77
|
+
gap: 1rem;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.sm\:gap-5 {
|
|
81
|
+
gap: 1.25rem;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.sm\:p-4 {
|
|
85
|
+
padding: 1rem;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.sm\:inline {
|
|
89
|
+
display: inline;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.sm\:items-center {
|
|
93
|
+
align-items: center;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@media (width >= 768px) {
|
|
98
|
+
.md\:text-5xl {
|
|
99
|
+
font-size: 3rem;
|
|
100
|
+
line-height: 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.md\:gap-6 {
|
|
104
|
+
gap: 1.5rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.md\:grid-cols-2 {
|
|
108
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.md\:grid-cols-3 {
|
|
112
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.md\:grid-cols-4 {
|
|
116
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@media (width >= 1024px) {
|
|
121
|
+
.lg\:px-8 {
|
|
122
|
+
padding-left: 2rem;
|
|
123
|
+
padding-right: 2rem;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.lg\:grid-cols-2 {
|
|
127
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.lg\:grid-cols-3 {
|
|
131
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.lg\:grid-cols-4 {
|
|
135
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.lg\:grid-cols-5 {
|
|
139
|
+
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.lg\:flex {
|
|
143
|
+
display: flex;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Sizing Utilities
|
|
3
|
+
* This file contains width, height, and object-fit utility classes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Sizing utilities */
|
|
7
|
+
.w-full {
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.w-2\.5 {
|
|
12
|
+
width: 0.625rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.w-3 {
|
|
16
|
+
width: 0.75rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.w-4 {
|
|
20
|
+
width: 1rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.w-5 {
|
|
24
|
+
width: 1.25rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.w-6 {
|
|
28
|
+
width: 1.5rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.w-8 {
|
|
32
|
+
width: 2rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.w-12 {
|
|
36
|
+
width: 3rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.w-24 {
|
|
40
|
+
width: 6rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.w-32 {
|
|
44
|
+
width: 8rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.w-40 {
|
|
48
|
+
width: 10rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.h-2\.5 {
|
|
52
|
+
height: 0.625rem;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.h-3 {
|
|
56
|
+
height: 0.75rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.h-4 {
|
|
60
|
+
height: 1rem;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.h-5 {
|
|
64
|
+
height: 1.25rem;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.h-6 {
|
|
68
|
+
height: 1.5rem;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.h-8 {
|
|
72
|
+
height: 2rem;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.h-12 {
|
|
76
|
+
height: 3rem;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.h-24 {
|
|
80
|
+
height: 6rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.h-32 {
|
|
84
|
+
height: 8rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.h-40 {
|
|
88
|
+
height: 10rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Flex utilities */
|
|
92
|
+
.flex-shrink-0 {
|
|
93
|
+
flex-shrink: 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Object fit utilities */
|
|
97
|
+
.object-cover {
|
|
98
|
+
object-fit: cover;
|
|
99
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Spacing Utilities
|
|
3
|
+
* This file contains padding, margin, and gap utility classes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Spacing utilities - Padding */
|
|
7
|
+
.p-3 {
|
|
8
|
+
padding: 0.75rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.p-4 {
|
|
12
|
+
padding: 1rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.p-5 {
|
|
16
|
+
padding: 1.25rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.p-6 {
|
|
20
|
+
padding: 1.5rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.px-2 {
|
|
24
|
+
padding-left: 0.5rem;
|
|
25
|
+
padding-right: 0.5rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.px-3 {
|
|
29
|
+
padding-left: 0.75rem;
|
|
30
|
+
padding-right: 0.75rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.px-4 {
|
|
34
|
+
padding-left: 1rem;
|
|
35
|
+
padding-right: 1rem;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.px-6 {
|
|
39
|
+
padding-left: 1.5rem;
|
|
40
|
+
padding-right: 1.5rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.py-2 {
|
|
44
|
+
padding-top: 0.5rem;
|
|
45
|
+
padding-bottom: 0.5rem;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.py-2\.5 {
|
|
49
|
+
padding-top: 0.625rem;
|
|
50
|
+
padding-bottom: 0.625rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.py-3 {
|
|
54
|
+
padding-top: 0.75rem;
|
|
55
|
+
padding-bottom: 0.75rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.py-4 {
|
|
59
|
+
padding-top: 1rem;
|
|
60
|
+
padding-bottom: 1rem;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.py-8 {
|
|
64
|
+
padding-top: 2rem;
|
|
65
|
+
padding-bottom: 2rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.py-16 {
|
|
69
|
+
padding-top: 4rem;
|
|
70
|
+
padding-bottom: 4rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.pt-2 {
|
|
74
|
+
padding-top: 0.5rem;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Spacing utilities - Margin */
|
|
78
|
+
.mb-1 {
|
|
79
|
+
margin-bottom: 0.25rem;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.mb-2 {
|
|
83
|
+
margin-bottom: 0.5rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.mb-3 {
|
|
87
|
+
margin-bottom: 0.75rem;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.mb-4 {
|
|
91
|
+
margin-bottom: 1rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.mb-6 {
|
|
95
|
+
margin-bottom: 1.5rem;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.mb-8 {
|
|
99
|
+
margin-bottom: 2rem;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.mb-12 {
|
|
103
|
+
margin-bottom: 3rem;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.mt-2 {
|
|
107
|
+
margin-top: 0.5rem;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.mt-3 {
|
|
111
|
+
margin-top: 0.75rem;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.mt-8 {
|
|
115
|
+
margin-top: 2rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.mt-12 {
|
|
119
|
+
margin-top: 3rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.mr-2 {
|
|
123
|
+
margin-right: 0.5rem;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.mr-4 {
|
|
127
|
+
margin-right: 1rem;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ml-2 {
|
|
131
|
+
margin-left: 0.5rem;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.ml-3 {
|
|
135
|
+
margin-left: 0.75rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Gap utilities */
|
|
139
|
+
.gap-1 {
|
|
140
|
+
gap: 0.25rem;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.gap-2 {
|
|
144
|
+
gap: 0.5rem;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.gap-3 {
|
|
148
|
+
gap: 0.75rem;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.gap-4 {
|
|
152
|
+
gap: 1rem;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.gap-5 {
|
|
156
|
+
gap: 1.25rem;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Spacing stack utilities */
|
|
160
|
+
.space-y-3 > * + * {
|
|
161
|
+
margin-top: 0.75rem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.space-y-4 > * + * {
|
|
165
|
+
margin-top: 1rem;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.space-y-5 > * + * {
|
|
169
|
+
margin-top: 1.25rem;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.space-y-6 > * + * {
|
|
173
|
+
margin-top: 1.5rem;
|
|
174
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Typography Utilities
|
|
3
|
+
* This file contains font size, weight, and text utility classes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Typography */
|
|
7
|
+
.text-xs {
|
|
8
|
+
font-size: 0.75rem;
|
|
9
|
+
line-height: 1rem;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.text-sm {
|
|
13
|
+
font-size: 0.875rem;
|
|
14
|
+
line-height: 1.25rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.text-base {
|
|
18
|
+
font-size: 1rem;
|
|
19
|
+
line-height: 1.5rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.text-lg {
|
|
23
|
+
font-size: 1.125rem;
|
|
24
|
+
line-height: 1.75rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.text-xl {
|
|
28
|
+
font-size: 1.25rem;
|
|
29
|
+
line-height: 1.75rem;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.text-2xl {
|
|
33
|
+
font-size: 1.5rem;
|
|
34
|
+
line-height: 2rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.text-3xl {
|
|
38
|
+
font-size: 1.875rem;
|
|
39
|
+
line-height: 2.25rem;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.text-4xl {
|
|
43
|
+
font-size: 2.25rem;
|
|
44
|
+
line-height: 2.5rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.text-5xl {
|
|
48
|
+
font-size: 3rem;
|
|
49
|
+
line-height: 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.font-medium {
|
|
53
|
+
font-weight: 500;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.font-semibold {
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.font-bold {
|
|
61
|
+
font-weight: 700;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.text-center {
|
|
65
|
+
text-align: center;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.break-words {
|
|
69
|
+
overflow-wrap: break-word;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.line-clamp-3 {
|
|
73
|
+
display: -webkit-box;
|
|
74
|
+
-webkit-line-clamp: 3;
|
|
75
|
+
-webkit-box-orient: vertical;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.whitespace-nowrap {
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.no-underline {
|
|
84
|
+
text-decoration: none;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Bootstrap utility classes for compatibility */
|
|
88
|
+
.text-muted {
|
|
89
|
+
color: var(--color-text-muted) !important;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.form-text {
|
|
93
|
+
display: block;
|
|
94
|
+
margin-top: 0.25rem;
|
|
95
|
+
font-size: 0.875rem;
|
|
96
|
+
color: var(--color-text-muted);
|
|
97
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Controller for handling application errors with custom pages
|
|
4
|
+
# Provides consistent error pages for both UI and API requests
|
|
5
|
+
# nosemgrep: ruby.lang.security.missing-csrf-protection.missing-csrf-protection
|
|
6
|
+
class ErrorsController < ActionController::Base
|
|
7
|
+
# Include errors helper for route helpers in views
|
|
8
|
+
helper ErrorsHelper
|
|
9
|
+
|
|
10
|
+
# Skip CSRF protection for error pages (no forms to submit)
|
|
11
|
+
protect_from_forgery with: :null_session
|
|
12
|
+
# Don't check for modern browsers on error pages
|
|
13
|
+
skip_before_action :verify_authenticity_token, raise: false
|
|
14
|
+
layout "error"
|
|
15
|
+
|
|
16
|
+
# 400 Bad Request
|
|
17
|
+
def bad_request
|
|
18
|
+
@error_code = 400
|
|
19
|
+
@error_title = "Bad Request"
|
|
20
|
+
@error_message = params[:message] || "The request could not be understood by the server."
|
|
21
|
+
@error_details = params[:details]
|
|
22
|
+
@status = :bad_request
|
|
23
|
+
|
|
24
|
+
respond_to_error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# 401 Unauthorized
|
|
28
|
+
def unauthorized
|
|
29
|
+
@error_code = 401
|
|
30
|
+
@error_title = "Unauthorized"
|
|
31
|
+
@error_message = params[:message] || "You need to sign in or sign up before continuing."
|
|
32
|
+
@error_details = params[:details]
|
|
33
|
+
@status = :unauthorized
|
|
34
|
+
|
|
35
|
+
respond_to_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# 403 Forbidden
|
|
39
|
+
def forbidden
|
|
40
|
+
@error_code = 403
|
|
41
|
+
@error_title = "Forbidden"
|
|
42
|
+
@error_message = params[:message] || "You don't have permission to access this resource."
|
|
43
|
+
@error_details = params[:details]
|
|
44
|
+
@status = :forbidden
|
|
45
|
+
|
|
46
|
+
respond_to_error
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# 404 Not Found
|
|
50
|
+
def not_found
|
|
51
|
+
@error_code = 404
|
|
52
|
+
@error_title = "Page Not Found"
|
|
53
|
+
@error_message = params[:message] || "The page you're looking for doesn't exist."
|
|
54
|
+
@error_details = params[:details]
|
|
55
|
+
@status = :not_found
|
|
56
|
+
|
|
57
|
+
respond_to_error
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# 406 Not Acceptable
|
|
61
|
+
def not_acceptable
|
|
62
|
+
@error_code = 406
|
|
63
|
+
@error_title = "Not Acceptable"
|
|
64
|
+
@error_message = params[:message] || "The requested resource cannot be provided in a format your browser accepts. Please try using a different browser or update your current browser."
|
|
65
|
+
@error_details = params[:details]
|
|
66
|
+
@status = :not_acceptable
|
|
67
|
+
|
|
68
|
+
respond_to_error
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# 422 Unprocessable Entity
|
|
72
|
+
def unprocessable_entity
|
|
73
|
+
@error_code = 422
|
|
74
|
+
@error_title = "Unprocessable Entity"
|
|
75
|
+
@error_message = params[:message] || "The request was well-formed but contains invalid data."
|
|
76
|
+
@error_details = params[:details]
|
|
77
|
+
@status = :unprocessable_entity
|
|
78
|
+
|
|
79
|
+
respond_to_error
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# 500 Internal Server Error
|
|
83
|
+
def internal_server_error
|
|
84
|
+
@error_code = 500
|
|
85
|
+
@error_title = "Internal Server Error"
|
|
86
|
+
@error_message = params[:message] || "Something went wrong on our end. We're working to fix it."
|
|
87
|
+
@error_details = params[:details]
|
|
88
|
+
@status = :internal_server_error
|
|
89
|
+
|
|
90
|
+
respond_to_error
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# 503 Service Unavailable
|
|
94
|
+
def service_unavailable
|
|
95
|
+
@error_code = 503
|
|
96
|
+
@error_title = "Service Unavailable"
|
|
97
|
+
@error_message = params[:message] || "The service is temporarily unavailable. Please try again later."
|
|
98
|
+
@error_details = params[:details]
|
|
99
|
+
@status = :service_unavailable
|
|
100
|
+
|
|
101
|
+
respond_to_error
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
# Respond with appropriate format (HTML or JSON)
|
|
107
|
+
def respond_to_error
|
|
108
|
+
respond_to do |format|
|
|
109
|
+
format.html { render "errors/show", status: @status }
|
|
110
|
+
format.json do
|
|
111
|
+
response_data = {
|
|
112
|
+
success: false,
|
|
113
|
+
error: @error_message
|
|
114
|
+
}
|
|
115
|
+
response_data[:details] = @error_details if @error_details.present?
|
|
116
|
+
render json: response_data, status: @status
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|