panda-core 0.12.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +53 -0
  4. data/app/assets/builds/panda_core_admin.css +2 -0
  5. data/app/assets/tailwind/application.css +413 -131
  6. data/app/builders/panda/core/form_builder.rb +129 -27
  7. data/app/components/panda/core/UI/badge.html.erb +10 -0
  8. data/app/components/panda/core/UI/badge.rb +14 -30
  9. data/app/components/panda/core/UI/button.html.erb +5 -0
  10. data/app/components/panda/core/UI/button.rb +15 -19
  11. data/app/components/panda/core/UI/card.html.erb +3 -0
  12. data/app/components/panda/core/UI/card.rb +7 -6
  13. data/app/components/panda/core/admin/attribute_diff_component.html.erb +21 -0
  14. data/app/components/panda/core/admin/attribute_diff_component.rb +29 -0
  15. data/app/components/panda/core/admin/breadcrumb_component.html.erb +36 -0
  16. data/app/components/panda/core/admin/breadcrumb_component.rb +12 -64
  17. data/app/components/panda/core/admin/breadcrumbs_component.html.erb +16 -0
  18. data/app/components/panda/core/admin/breadcrumbs_component.rb +26 -0
  19. data/app/components/panda/core/admin/button_component.html.erb +9 -0
  20. data/app/components/panda/core/admin/button_component.rb +37 -32
  21. data/app/components/panda/core/admin/callout_component.html.erb +17 -0
  22. data/app/components/panda/core/admin/callout_component.rb +57 -0
  23. data/app/components/panda/core/admin/code_block_component.html.erb +9 -0
  24. data/app/components/panda/core/admin/code_block_component.rb +23 -0
  25. data/app/components/panda/core/admin/container_component.html.erb +27 -0
  26. data/app/components/panda/core/admin/container_component.rb +11 -77
  27. data/app/components/panda/core/admin/contributors_summary_component.html.erb +15 -0
  28. data/app/components/panda/core/admin/contributors_summary_component.rb +23 -0
  29. data/app/components/panda/core/admin/dashboard_default_content_component.html.erb +70 -0
  30. data/app/components/panda/core/admin/dashboard_default_content_component.rb +32 -0
  31. data/app/components/panda/core/admin/delete_button_component.html.erb +4 -0
  32. data/app/components/panda/core/admin/delete_button_component.rb +41 -0
  33. data/app/components/panda/core/admin/dropdown_button_component.html.erb +28 -0
  34. data/app/components/panda/core/admin/dropdown_button_component.rb +100 -0
  35. data/app/components/panda/core/admin/dropdown_component.html.erb +32 -0
  36. data/app/components/panda/core/admin/dropdown_component.rb +65 -0
  37. data/app/components/panda/core/admin/empty_state_component.html.erb +16 -0
  38. data/app/components/panda/core/admin/empty_state_component.rb +25 -0
  39. data/app/components/panda/core/admin/file_gallery_component.html.erb +58 -0
  40. data/app/components/panda/core/admin/file_gallery_component.rb +26 -98
  41. data/app/components/panda/core/admin/filter_pills_component.html.erb +6 -0
  42. data/app/components/panda/core/admin/filter_pills_component.rb +29 -0
  43. data/app/components/panda/core/admin/flash_message_component.html.erb +11 -0
  44. data/app/components/panda/core/admin/flash_message_component.rb +33 -60
  45. data/app/components/panda/core/admin/form_error_component.html.erb +7 -0
  46. data/app/components/panda/core/admin/form_error_component.rb +8 -16
  47. data/app/components/panda/core/admin/form_footer_component.html.erb +16 -0
  48. data/app/components/panda/core/admin/form_footer_component.rb +65 -0
  49. data/app/components/panda/core/admin/form_input_component.html.erb +1 -0
  50. data/app/components/panda/core/admin/form_input_component.rb +21 -13
  51. data/app/components/panda/core/admin/form_section_component.html.erb +16 -0
  52. data/app/components/panda/core/admin/form_section_component.rb +64 -0
  53. data/app/components/panda/core/admin/form_select_component.html.erb +5 -0
  54. data/app/components/panda/core/admin/form_select_component.rb +25 -26
  55. data/app/components/panda/core/admin/heading_component.html.erb +26 -0
  56. data/app/components/panda/core/admin/heading_component.rb +23 -60
  57. data/app/components/panda/core/admin/login_form_component.html.erb +38 -0
  58. data/app/components/panda/core/admin/login_form_component.rb +28 -0
  59. data/app/components/panda/core/admin/main_layout_component.html.erb +88 -0
  60. data/app/components/panda/core/admin/main_layout_component.rb +19 -0
  61. data/app/components/panda/core/admin/my_profile/connected_account_component.html.erb +41 -0
  62. data/app/components/panda/core/admin/my_profile/connected_account_component.rb +27 -0
  63. data/app/components/panda/core/admin/navigation/item_component.html.erb +34 -0
  64. data/app/components/panda/core/admin/navigation/item_component.rb +69 -0
  65. data/app/components/panda/core/admin/navigation/sub_item_component.html.erb +9 -0
  66. data/app/components/panda/core/admin/navigation/sub_item_component.rb +44 -0
  67. data/app/components/panda/core/admin/navigation/user_menu_component.html.erb +30 -0
  68. data/app/components/panda/core/admin/navigation/user_menu_component.rb +36 -0
  69. data/app/components/panda/core/admin/page_header_component.html.erb +28 -0
  70. data/app/components/panda/core/admin/page_header_component.rb +19 -35
  71. data/app/components/panda/core/admin/pagination_component.html.erb +33 -0
  72. data/app/components/panda/core/admin/pagination_component.rb +56 -0
  73. data/app/components/panda/core/admin/panel_component.html.erb +19 -0
  74. data/app/components/panda/core/admin/panel_component.rb +4 -29
  75. data/app/components/panda/core/admin/prose_panel_component.html.erb +6 -0
  76. data/app/components/panda/core/admin/prose_panel_component.rb +43 -0
  77. data/app/components/panda/core/admin/search_bar_component.html.erb +19 -0
  78. data/app/components/panda/core/admin/search_bar_component.rb +31 -0
  79. data/app/components/panda/core/admin/search_filter_bar_component.html.erb +22 -0
  80. data/app/components/panda/core/admin/search_filter_bar_component.rb +27 -0
  81. data/app/components/panda/core/admin/secret_field_component.html.erb +24 -0
  82. data/app/components/panda/core/admin/secret_field_component.rb +31 -0
  83. data/app/components/panda/core/admin/sidebar_component.html.erb +160 -0
  84. data/app/components/panda/core/admin/sidebar_component.rb +55 -0
  85. data/app/components/panda/core/admin/slideover_component.html.erb +67 -0
  86. data/app/components/panda/core/admin/slideover_component.rb +31 -70
  87. data/app/components/panda/core/admin/statistics_component.html.erb +4 -0
  88. data/app/components/panda/core/admin/statistics_component.rb +6 -8
  89. data/app/components/panda/core/admin/tab_bar_component.html.erb +48 -0
  90. data/app/components/panda/core/admin/tab_bar_component.rb +34 -69
  91. data/app/components/panda/core/admin/table_component.html.erb +82 -0
  92. data/app/components/panda/core/admin/table_component.rb +54 -87
  93. data/app/components/panda/core/admin/tag_badge_component.html.erb +7 -0
  94. data/app/components/panda/core/admin/tag_badge_component.rb +21 -0
  95. data/app/components/panda/core/admin/tag_component.html.erb +1 -0
  96. data/app/components/panda/core/admin/tag_component.rb +51 -20
  97. data/app/components/panda/core/admin/tag_input_component.html.erb +37 -0
  98. data/app/components/panda/core/admin/tag_input_component.rb +22 -0
  99. data/app/components/panda/core/admin/tags_panel_component.html.erb +8 -0
  100. data/app/components/panda/core/admin/tags_panel_component.rb +33 -0
  101. data/app/components/panda/core/admin/user_activity_component.html.erb +15 -0
  102. data/app/components/panda/core/admin/user_activity_component.rb +9 -22
  103. data/app/components/panda/core/admin/user_display_component.html.erb +8 -0
  104. data/app/components/panda/core/admin/user_display_component.rb +19 -22
  105. data/app/components/panda/core/base.rb +35 -42
  106. data/app/components/panda/core/shared/footer_component.html.erb +2 -0
  107. data/app/components/panda/core/shared/footer_component.rb +11 -0
  108. data/app/components/panda/core/shared/header_component.html.erb +32 -0
  109. data/app/components/panda/core/shared/header_component.rb +19 -0
  110. data/app/constraints/panda/core/admin_constraint.rb +2 -2
  111. data/app/controllers/concerns/panda/core/admin_authorization.rb +58 -0
  112. data/app/controllers/concerns/panda/core/authorizable.rb +107 -0
  113. data/app/controllers/panda/core/admin/base_controller.rb +62 -3
  114. data/app/controllers/panda/core/admin/editor/search_controller.rb +17 -0
  115. data/app/controllers/panda/core/admin/feature_flags_controller.rb +35 -0
  116. data/app/controllers/panda/core/admin/file_categories_controller.rb +84 -0
  117. data/app/controllers/panda/core/admin/files_controller.rb +230 -0
  118. data/app/controllers/panda/core/admin/import_sessions_controller.rb +120 -0
  119. data/app/controllers/panda/core/admin/my_profile/logins_controller.rb +24 -0
  120. data/app/controllers/panda/core/admin/my_profile_controller.rb +31 -0
  121. data/app/controllers/panda/core/admin/search_controller.rb +15 -0
  122. data/app/controllers/panda/core/admin/sessions_controller.rb +85 -8
  123. data/app/controllers/panda/core/admin/tags_controller.rb +77 -0
  124. data/app/controllers/panda/core/admin/test_sessions_controller.rb +5 -6
  125. data/app/controllers/panda/core/admin/users_controller.rb +184 -0
  126. data/app/controllers/panda/core/application_controller.rb +13 -1
  127. data/app/helpers/panda/core/active_storage_helper.rb +24 -0
  128. data/app/helpers/panda/core/feature_flag_helper.rb +11 -0
  129. data/app/helpers/panda/core/form_helper.rb +15 -0
  130. data/app/javascript/panda/core/controllers/avatar_upload_controller.js +73 -0
  131. data/app/javascript/panda/core/controllers/clipboard_controller.js +119 -0
  132. data/app/javascript/panda/core/controllers/collapsible_item_controller.js +45 -0
  133. data/app/javascript/panda/core/controllers/custom_select_controller.js +256 -0
  134. data/app/javascript/panda/core/controllers/datepicker_controller.js +121 -0
  135. data/app/javascript/panda/core/controllers/daterange_controller.js +193 -0
  136. data/app/javascript/panda/core/controllers/file_gallery_controller.js +134 -0
  137. data/app/javascript/panda/core/controllers/file_upload_controller.js +165 -0
  138. data/app/javascript/panda/core/controllers/global_search_controller.js +184 -0
  139. data/app/javascript/panda/core/controllers/index.js +36 -0
  140. data/app/javascript/panda/core/controllers/mobile_sidebar_controller.js +58 -0
  141. data/app/javascript/panda/core/controllers/navigation_toggle_controller.js +49 -24
  142. data/app/javascript/panda/core/controllers/row_link_controller.js +27 -0
  143. data/app/javascript/panda/core/controllers/tag_input_controller.js +183 -0
  144. data/app/javascript/panda/core/tailwindcss-stimulus-components.js +2 -3
  145. data/app/javascript/panda/core/vendor/@fortawesome--fontawesome-free@7.2.0.js +8129 -0
  146. data/app/javascript/panda/core/vendor/@hotwired--turbo.js +7197 -100
  147. data/app/javascript/panda/core/vendor/@rails--actioncable--src.js +511 -2
  148. data/app/javascript/panda/core/vendor/@tailwindplus--elements@1.0.22.js +65 -0
  149. data/app/javascript/panda/core/vendor/cropperjs@2.1.0.js +3 -0
  150. data/app/javascript/panda/core/vendor/vanilla-calendar-pro.js +2 -0
  151. data/app/models/concerns/panda/core/has_metadata.rb +164 -0
  152. data/app/models/concerns/panda/core/importable.rb +79 -0
  153. data/app/models/concerns/panda/core/searchable.rb +66 -0
  154. data/app/models/concerns/panda/core/taggable.rb +37 -0
  155. data/app/models/panda/core/feature_flag.rb +56 -0
  156. data/app/models/panda/core/file_categorization.rb +14 -0
  157. data/app/models/panda/core/file_category.rb +45 -0
  158. data/app/models/panda/core/import_session.rb +79 -0
  159. data/app/models/panda/core/presence.rb +24 -0
  160. data/app/models/panda/core/tag.rb +33 -0
  161. data/app/models/panda/core/tagging.rb +14 -0
  162. data/app/models/panda/core/user.rb +96 -18
  163. data/app/models/panda/core/user_activity.rb +42 -0
  164. data/app/models/panda/core/user_session.rb +35 -0
  165. data/app/services/panda/core/attach_avatar_service.rb +15 -3
  166. data/app/services/panda/core/csv_import_service.rb +65 -0
  167. data/app/services/panda/core/file_categorizer.rb +52 -0
  168. data/app/services/panda/core/file_parser.rb +76 -0
  169. data/app/services/panda/core/invite_user_service.rb +44 -0
  170. data/app/services/panda/core/presence_service.rb +49 -0
  171. data/app/views/layouts/panda/core/admin.html.erb +6 -67
  172. data/app/views/layouts/panda/core/admin_simple.html.erb +2 -2
  173. data/app/views/panda/core/admin/dashboard/_default_content.html.erb +1 -73
  174. data/app/views/panda/core/admin/dashboard/show.html.erb +12 -15
  175. data/app/views/panda/core/admin/feature_flags/index.html.erb +56 -0
  176. data/app/views/panda/core/admin/file_categories/_form.html.erb +20 -0
  177. data/app/views/panda/core/admin/file_categories/edit.html.erb +5 -0
  178. data/app/views/panda/core/admin/file_categories/index.html.erb +55 -0
  179. data/app/views/panda/core/admin/file_categories/new.html.erb +5 -0
  180. data/app/views/panda/core/admin/files/_file_details.html.erb +156 -0
  181. data/app/views/panda/core/admin/files/index.html.erb +61 -0
  182. data/app/views/panda/core/admin/import_sessions/column_map.html.erb +43 -0
  183. data/app/views/panda/core/admin/import_sessions/index.html.erb +48 -0
  184. data/app/views/panda/core/admin/import_sessions/new.html.erb +37 -0
  185. data/app/views/panda/core/admin/import_sessions/preview.html.erb +51 -0
  186. data/app/views/panda/core/admin/import_sessions/show.html.erb +87 -0
  187. data/app/views/panda/core/admin/my_profile/edit.html.erb +51 -39
  188. data/app/views/panda/core/admin/my_profile/logins/show.html.erb +72 -0
  189. data/app/views/panda/core/admin/sessions/new.html.erb +1 -38
  190. data/app/views/panda/core/admin/shared/_breadcrumbs.html.erb +1 -18
  191. data/app/views/panda/core/admin/shared/_sidebar.html.erb +1 -99
  192. data/app/views/panda/core/admin/shared/_slideover.html.erb +3 -3
  193. data/app/views/panda/core/admin/tags/_form.html.erb +21 -0
  194. data/app/views/panda/core/admin/tags/edit.html.erb +4 -0
  195. data/app/views/panda/core/admin/tags/index.html.erb +41 -0
  196. data/app/views/panda/core/admin/tags/new.html.erb +4 -0
  197. data/app/views/panda/core/admin/users/activity.html.erb +90 -0
  198. data/app/views/panda/core/admin/users/edit.html.erb +48 -0
  199. data/app/views/panda/core/admin/users/index.html.erb +161 -0
  200. data/app/views/panda/core/admin/users/sessions.html.erb +103 -0
  201. data/app/views/panda/core/admin/users/show.html.erb +224 -0
  202. data/app/views/panda/core/shared/_footer.html.erb +1 -2
  203. data/app/views/panda/core/shared/_header.html.erb +4 -22
  204. data/config/brakeman.ignore +68 -31
  205. data/config/importmap.rb +13 -11
  206. data/config/routes.rb +49 -2
  207. data/db/migrate/20260202171614_create_panda_core_file_categories.rb +30 -0
  208. data/db/migrate/20260203000001_add_user_management_fields_to_panda_core_users.rb +21 -0
  209. data/db/migrate/20260203000002_create_panda_core_user_activities.rb +24 -0
  210. data/db/migrate/20260203000003_create_panda_core_user_sessions.rb +25 -0
  211. data/db/migrate/20260207100000_create_panda_core_presences.rb +21 -0
  212. data/db/migrate/20260213000001_fix_active_storage_attachments_record_id_type.rb +44 -0
  213. data/db/migrate/20260217000001_create_panda_core_feature_flags.rb +14 -0
  214. data/db/migrate/20260303000001_add_metadata_to_panda_core_users.rb +11 -0
  215. data/db/migrate/20260310000001_create_panda_core_tags.rb +27 -0
  216. data/db/migrate/20260310000002_create_panda_core_import_sessions.rb +29 -0
  217. data/lib/generators/panda/core/install_generator.rb +32 -0
  218. data/lib/generators/panda/core/templates/panda.rb +63 -0
  219. data/lib/panda/core/asset_loader.rb +6 -3
  220. data/lib/panda/core/authentication.rb +3 -3
  221. data/lib/panda/core/configuration.rb +195 -1
  222. data/lib/panda/core/engine/admin_controller_config.rb +4 -3
  223. data/lib/panda/core/engine/autoload_config.rb +21 -9
  224. data/lib/panda/core/engine/omniauth_config.rb +114 -32
  225. data/lib/panda/core/engine/pending_migrations_check.rb +46 -0
  226. data/lib/panda/core/engine/route_config.rb +1 -1
  227. data/lib/panda/core/engine/sqlite_schema_compatibility.rb +36 -0
  228. data/lib/panda/core/engine/{phlex_config.rb → view_component_config.rb} +5 -7
  229. data/lib/panda/core/engine.rb +90 -25
  230. data/lib/panda/core/middleware.rb +35 -0
  231. data/lib/panda/core/module_registry.rb +21 -13
  232. data/lib/panda/core/navigation_registry.rb +455 -0
  233. data/lib/panda/core/oauth_providers.rb +27 -0
  234. data/lib/panda/core/permission_registry.rb +89 -0
  235. data/lib/panda/core/search_registry.rb +69 -0
  236. data/lib/panda/core/seeds/file_categories.rb +30 -0
  237. data/lib/panda/core/shared/inflections_config.rb +1 -5
  238. data/lib/panda/core/testing/rails_helper.rb +87 -0
  239. data/lib/panda/core/testing/support/authentication_test_helpers.rb +22 -18
  240. data/lib/panda/core/testing/support/system/cuprite_helpers.rb +4 -4
  241. data/lib/panda/core/testing/view_component_test_controller.rb +19 -0
  242. data/lib/panda/core/version.rb +1 -1
  243. data/lib/panda/core/widget_registry.rb +50 -0
  244. data/lib/panda/core.rb +20 -0
  245. data/lib/tasks/panda/core/file_categories.rake +41 -0
  246. data/public/panda-core-assets/panda-core-0.12.2.css +2 -0
  247. data/public/panda-core-assets/panda-core-0.12.3.css +2 -0
  248. data/public/panda-core-assets/panda-core-0.12.5.css +2 -0
  249. data/public/panda-core-assets/panda-core-0.13.0.css +2 -0
  250. data/public/panda-core-assets/panda-core-0.14.0.css +2 -0
  251. data/public/panda-core-assets/panda-core-0.14.4.css +2 -0
  252. data/public/panda-core-assets/panda-core.css +2 -2
  253. data/public/panda-core-assets/vanilla-calendar.css +47 -0
  254. metadata +205 -26
  255. data/lib/panda/core/engine/inflections_config.rb +0 -23
@@ -1,30 +1,66 @@
1
1
  @import 'tailwindcss';
2
2
 
3
3
  @theme {
4
- /* Legacy colors */
5
- --color-white: var(--color-white);
6
- --color-black: var(--color-black);
7
- --color-light: var(--color-light);
8
- --color-mid: var(--color-mid);
9
- --color-dark: var(--color-dark);
10
- --color-highlight: var(--color-highlight);
11
- --color-active: var(--color-active);
12
- --color-inactive: var(--color-inactive);
13
- --color-warning: var(--color-warning);
14
- --color-error: var(--color-error);
15
-
16
- /* Tailwind UI compatible primary scale */
17
- --color-primary-50: var(--color-primary-50);
18
- --color-primary-100: var(--color-primary-100);
19
- --color-primary-200: var(--color-primary-200);
20
- --color-primary-300: var(--color-primary-300);
21
- --color-primary-400: var(--color-primary-400);
22
- --color-primary-500: var(--color-primary-500);
23
- --color-primary-600: var(--color-primary-600);
24
- --color-primary-700: var(--color-primary-700);
25
- --color-primary-800: var(--color-primary-800);
26
- --color-primary-900: var(--color-primary-900);
27
- --color-primary-950: var(--color-primary-950);
4
+ /* Custom spacing for page tree indentation */
5
+ --spacing-18: 4.5rem;
6
+
7
+ /* Legacy colors - DEPRECATED: Use primary-* scale instead */
8
+ /* Fallback values ensure UI is visible even without data-theme attribute */
9
+ --color-white: #f9f9f9;
10
+ --color-black: #1a161d;
11
+ --color-light: #f1f9fa;
12
+ --color-mid: #3c879e;
13
+ --color-dark: #182934;
14
+ --color-highlight: #d04014;
15
+ --color-active: #16a34a;
16
+ --color-inactive: #dbeafe;
17
+ --color-warning: #f59e0b;
18
+ --color-error: #dc2626;
19
+
20
+ /* Primary color scale (Glacier/Teal) - with fallback values */
21
+ --color-primary-50: #f1f9fa;
22
+ --color-primary-100: #dbeef2;
23
+ --color-primary-200: #bcdde5;
24
+ --color-primary-300: #83bfcf;
25
+ --color-primary-400: #57a3b9;
26
+ --color-primary-500: #3c879e;
27
+ --color-primary-600: #346e86;
28
+ --color-primary-700: #305b6e;
29
+ --color-primary-800: #2e4d5c;
30
+ --color-primary-900: #2a424f;
31
+ --color-primary-950: #182934;
32
+
33
+ /* Semantic colors - Success (Green) */
34
+ --color-success-50: #f0fdf4;
35
+ --color-success-100: #dcfce7;
36
+ --color-success-200: #bbf7d0;
37
+ --color-success-300: #86efac;
38
+ --color-success-500: #22c55e;
39
+ --color-success-600: #16a34a;
40
+ --color-success-700: #15803d;
41
+
42
+ /* Semantic colors - Error (Red) */
43
+ --color-error-50: #fef2f2;
44
+ --color-error-100: #fee2e2;
45
+ --color-error-200: #fecaca;
46
+ --color-error-300: #fca5a5;
47
+ --color-error-500: #ef4444;
48
+ --color-error-600: #dc2626;
49
+ --color-error-700: #b91c1c;
50
+
51
+ /* Semantic colors - Warning (Amber) */
52
+ --color-warning-50: #fffbeb;
53
+ --color-warning-100: #fef3c7;
54
+ --color-warning-500: #f59e0b;
55
+ --color-warning-600: #d97706;
56
+ --color-warning-700: #b45309;
57
+
58
+ /* Semantic colors - Info (Blue) */
59
+ --color-info-50: #eff6ff;
60
+ --color-info-100: #dbeafe;
61
+ --color-info-500: #3b82f6;
62
+ --color-info-600: #2563eb;
63
+ --color-info-700: #1d4ed8;
28
64
 
29
65
  /* Map indigo to primary for Tailwind UI compatibility */
30
66
  --color-indigo-50: var(--color-primary-50);
@@ -39,18 +75,18 @@
39
75
  --color-indigo-900: var(--color-primary-900);
40
76
  --color-indigo-950: var(--color-primary-950);
41
77
 
42
- /* Gray scale */
43
- --color-gray-50: var(--color-gray-50);
44
- --color-gray-100: var(--color-gray-100);
45
- --color-gray-200: var(--color-gray-200);
46
- --color-gray-300: var(--color-gray-300);
47
- --color-gray-400: var(--color-gray-400);
48
- --color-gray-500: var(--color-gray-500);
49
- --color-gray-600: var(--color-gray-600);
50
- --color-gray-700: var(--color-gray-700);
51
- --color-gray-800: var(--color-gray-800);
52
- --color-gray-900: var(--color-gray-900);
53
- --color-gray-950: var(--color-gray-950);
78
+ /* Gray scale - with fallback values */
79
+ --color-gray-50: #f9fafb;
80
+ --color-gray-100: #f3f4f6;
81
+ --color-gray-200: #e5e7eb;
82
+ --color-gray-300: #d1d5db;
83
+ --color-gray-400: #9ca3af;
84
+ --color-gray-500: #6b7280;
85
+ --color-gray-600: #4b5563;
86
+ --color-gray-700: #374151;
87
+ --color-gray-800: #1f2937;
88
+ --color-gray-900: #111827;
89
+ --color-gray-950: #030712;
54
90
  }
55
91
 
56
92
  @layer base {
@@ -58,30 +94,62 @@
58
94
  --color-white: rgb(249, 249, 249); /* #F9F9F9 */
59
95
  --color-black: rgb(26, 22, 29); /* #1A161D */
60
96
 
61
- /* Legacy color variables (kept for backwards compatibility) */
62
- --color-light: rgb(238, 206, 230); /* #EECEE6 */
63
- --color-mid: rgb(141, 94, 183); /* #8D5EB7 */
64
- --color-dark: rgb(33, 29, 73); /* #211D49 */
97
+ /* Legacy color variables - DEPRECATED: Map to primary scale */
98
+ --color-light: rgb(241, 249, 250); /* Maps to primary-50 */
99
+ --color-mid: rgb(60, 135, 158); /* Maps to primary-500 */
100
+ --color-dark: rgb(24, 41, 52); /* Maps to primary-950 */
65
101
 
66
102
  --color-highlight: rgb(208, 64, 20); /* #D04014 */
67
103
 
68
- --color-active: rgb(0, 135, 85); /* #008755 */
69
- --color-warning: rgb(250, 207, 142); /* #FACF8E */
70
- --color-inactive: rgb(216, 247, 245); /* #d6e4f7 */
71
- --color-error: rgb(245, 129, 129); /* #F58181 */
72
-
73
- /* Full Tailwind UI compatible color scale - Primary (Purple palette) */
74
- --color-primary-50: rgb(250, 245, 255); /* Very light purple */
75
- --color-primary-100: rgb(243, 232, 255); /* Lighter purple */
76
- --color-primary-200: rgb(233, 213, 255); /* Light purple */
77
- --color-primary-300: rgb(216, 180, 254); /* Medium light purple */
78
- --color-primary-400: rgb(192, 132, 252); /* Medium purple */
79
- --color-primary-500: rgb(141, 94, 183); /* Main brand color (mid) */
80
- --color-primary-600: rgb(120, 80, 160); /* Darker purple */
81
- --color-primary-700: rgb(100, 65, 140); /* Dark purple */
82
- --color-primary-800: rgb(60, 45, 100); /* Very dark purple */
83
- --color-primary-900: rgb(33, 29, 73); /* Darkest (dark) */
84
- --color-primary-950: rgb(24, 20, 50); /* Ultra dark */
104
+ --color-active: rgb(22, 163, 74); /* green-600 - success */
105
+ --color-warning: rgb(245, 158, 11); /* amber-500 */
106
+ --color-inactive: rgb(219, 234, 254); /* blue-100 */
107
+ --color-error: rgb(220, 38, 38); /* red-600 */
108
+
109
+ /* Primary color scale - Glacier (Teal) */
110
+ --color-primary-50: rgb(241, 249, 250); /* #f1f9fa */
111
+ --color-primary-100: rgb(219, 238, 242); /* #dbeef2 */
112
+ --color-primary-200: rgb(188, 221, 229); /* #bcdde5 */
113
+ --color-primary-300: rgb(131, 191, 207); /* #83bfcf */
114
+ --color-primary-400: rgb(87, 163, 185); /* #57a3b9 */
115
+ --color-primary-500: rgb(60, 135, 158); /* #3c879e */
116
+ --color-primary-600: rgb(52, 110, 134); /* #346e86 */
117
+ --color-primary-700: rgb(48, 91, 110); /* #305b6e */
118
+ --color-primary-800: rgb(46, 77, 92); /* #2e4d5c */
119
+ --color-primary-900: rgb(42, 66, 79); /* #2a424f */
120
+ --color-primary-950: rgb(24, 41, 52); /* #182934 */
121
+
122
+ /* Semantic colors - Success (Green) */
123
+ --color-success-50: rgb(240, 253, 244); /* green-50 */
124
+ --color-success-100: rgb(220, 252, 231); /* green-100 */
125
+ --color-success-200: rgb(187, 247, 208); /* green-200 */
126
+ --color-success-300: rgb(134, 239, 172); /* green-300 */
127
+ --color-success-500: rgb(34, 197, 94); /* green-500 */
128
+ --color-success-600: rgb(22, 163, 74); /* green-600 */
129
+ --color-success-700: rgb(21, 128, 61); /* green-700 */
130
+
131
+ /* Semantic colors - Error (Red) */
132
+ --color-error-50: rgb(254, 242, 242); /* red-50 */
133
+ --color-error-100: rgb(254, 226, 226); /* red-100 */
134
+ --color-error-200: rgb(254, 202, 202); /* red-200 */
135
+ --color-error-300: rgb(252, 165, 165); /* red-300 */
136
+ --color-error-500: rgb(239, 68, 68); /* red-500 */
137
+ --color-error-600: rgb(220, 38, 38); /* red-600 */
138
+ --color-error-700: rgb(185, 28, 28); /* red-700 */
139
+
140
+ /* Semantic colors - Warning (Amber) */
141
+ --color-warning-50: rgb(255, 251, 235); /* amber-50 */
142
+ --color-warning-100: rgb(254, 243, 199); /* amber-100 */
143
+ --color-warning-500: rgb(245, 158, 11); /* amber-500 */
144
+ --color-warning-600: rgb(217, 119, 6); /* amber-600 */
145
+ --color-warning-700: rgb(180, 83, 9); /* amber-700 */
146
+
147
+ /* Semantic colors - Info (Blue) */
148
+ --color-info-50: rgb(239, 246, 255); /* blue-50 */
149
+ --color-info-100: rgb(219, 234, 254); /* blue-100 */
150
+ --color-info-500: rgb(59, 130, 246); /* blue-500 */
151
+ --color-info-600: rgb(37, 99, 235); /* blue-600 */
152
+ --color-info-700: rgb(29, 78, 216); /* blue-700 */
85
153
 
86
154
  /* Gray scale for UI elements */
87
155
  --color-gray-50: rgb(249, 250, 251);
@@ -95,35 +163,114 @@
95
163
  --color-gray-800: rgb(31, 41, 55);
96
164
  --color-gray-900: rgb(17, 24, 39);
97
165
  --color-gray-950: rgb(3, 7, 18);
166
+
167
+ /*
168
+ * Panda admin chrome tokens — opt-in theming for the residual gem-rendered
169
+ * admin surfaces (PanelComponent, TableComponent, TagComponent badges, form
170
+ * inputs, the custom-select trigger, checkbox accent). Every value below is
171
+ * a var() reference to an existing token, so it resolves to exactly today's
172
+ * literal colour — this block changes nothing visually for the default
173
+ * theme. Host apps (e.g. Panda CMS) that never set a theme, or that use
174
+ * "default"/"sky", are unaffected. A host app can override any of these
175
+ * tokens directly instead of adopting a whole new html[data-theme] block.
176
+ */
177
+ --panda-panel-bg: var(--color-white);
178
+ --panda-panel-border: var(--color-gray-200);
179
+ --panda-panel-radius: var(--radius-2xl);
180
+ --panda-table-header-bg: var(--color-gray-50);
181
+ --panda-table-border: var(--color-gray-200);
182
+ --panda-table-row-border: color-mix(in srgb, var(--color-gray-200) 70%, transparent);
183
+ --panda-table-cell-color: var(--color-gray-600);
184
+ --panda-badge-success-bg: var(--color-emerald-50);
185
+ --panda-badge-success-fg: var(--color-emerald-600);
186
+ --panda-badge-warning-bg: var(--color-amber-50);
187
+ --panda-badge-warning-fg: var(--color-amber-600);
188
+ --panda-badge-info-bg: var(--color-sky-50);
189
+ --panda-badge-info-fg: var(--color-sky-600);
190
+ --panda-badge-error-bg: var(--color-rose-50);
191
+ --panda-badge-error-fg: var(--color-rose-600);
192
+ --panda-badge-neutral-bg: var(--color-gray-100);
193
+ --panda-badge-neutral-fg: var(--color-gray-600);
194
+ --panda-input-border: var(--color-gray-300);
195
+ --panda-input-radius: var(--radius-xl);
196
+ --panda-input-focus-ring: var(--color-primary-500);
197
+ --panda-select-trigger-border: var(--color-gray-200);
198
+ --panda-checkbox-accent: var(--color-primary-500);
98
199
  }
99
200
 
201
+ /*
202
+ * NAMING NOTE (2026-07): this block was briefly named `html[data-theme='ocean']`
203
+ * (commit aa7f021, "Update color palette to Glacier/Teal theme"), diverging from
204
+ * `Panda::Core.config.available_themes`, which has always shipped
205
+ * `[["Default", "default"], ["Sky", "sky"]]` (since the auth migration from
206
+ * panda-cms). Since `available_themes` populates the theme <select> in
207
+ * my_profile/edit.html.erb, any user who picked the second theme before aa7f021
208
+ * — or since, via a host app that left available_themes at its default — has
209
+ * "sky" persisted in `current_theme`, not "ocean". Renaming the CSS block back
210
+ * to `sky` (rather than renaming the config to `ocean`) restores that match
211
+ * without silently losing anyone's saved preference. Do not rename this block
212
+ * without also migrating `Panda::Core::User#current_theme` data.
213
+ */
100
214
  html[data-theme='sky'] {
101
215
  --color-white: rgb(249, 249, 249); /* #F9F9F9 */
102
216
  --color-black: rgb(26, 22, 29); /* #1A161D */
103
217
 
104
- /* Legacy color variables (kept for backwards compatibility) */
105
- --color-light: rgb(204, 238, 242); /* #CCEEF2 */
106
- --color-mid: rgb(42, 102, 159); /* #2A669F */
107
- --color-dark: rgb(20, 32, 74); /* #14204A */
218
+ /* Legacy color variables - DEPRECATED: Map to primary scale */
219
+ --color-light: rgb(239, 246, 255); /* Maps to primary-50 (blue-50) */
220
+ --color-mid: rgb(59, 130, 246); /* Maps to primary-500 (blue-500) */
221
+ --color-dark: rgb(30, 58, 138); /* Maps to primary-950 (blue-950) */
222
+
108
223
  --color-highlight: rgb(208, 64, 20); /* #D04014 */
109
224
 
110
- --color-active: rgb(69, 154, 89); /* #459A59 - darker green with better contrast */
111
- --color-warning: rgb(244, 190, 102); /* #F4BE66 */
112
- --color-inactive: rgb(216, 247, 245); /* #d6e4f7 */
113
- --color-error: rgb(208, 64, 20); /* #D04014 */
114
-
115
- /* Full Tailwind UI compatible color scale - Primary (Blue palette) */
116
- --color-primary-50: rgb(240, 249, 255); /* Very light blue */
117
- --color-primary-100: rgb(224, 242, 254); /* Lighter blue */
118
- --color-primary-200: rgb(186, 230, 253); /* Light blue */
119
- --color-primary-300: rgb(125, 211, 252); /* Medium light blue */
120
- --color-primary-400: rgb(56, 189, 248); /* Medium blue */
121
- --color-primary-500: rgb(42, 102, 159); /* Main brand color (mid) */
122
- --color-primary-600: rgb(35, 85, 132); /* Darker blue */
123
- --color-primary-700: rgb(28, 68, 106); /* Dark blue */
124
- --color-primary-800: rgb(22, 52, 82); /* Very dark blue */
125
- --color-primary-900: rgb(20, 32, 74); /* Darkest (dark) */
126
- --color-primary-950: rgb(15, 24, 55); /* Ultra dark */
225
+ --color-active: rgb(22, 163, 74); /* green-600 - success */
226
+ --color-warning: rgb(245, 158, 11); /* amber-500 */
227
+ --color-inactive: rgb(219, 234, 254); /* blue-100 */
228
+ --color-error: rgb(220, 38, 38); /* red-600 */
229
+
230
+ /* Primary color scale - Sky (Blue) */
231
+ --color-primary-50: rgb(239, 246, 255); /* blue-50 */
232
+ --color-primary-100: rgb(219, 234, 254); /* blue-100 */
233
+ --color-primary-200: rgb(191, 219, 254); /* blue-200 */
234
+ --color-primary-300: rgb(147, 197, 253); /* blue-300 */
235
+ --color-primary-400: rgb(96, 165, 250); /* blue-400 */
236
+ --color-primary-500: rgb(59, 130, 246); /* blue-500 */
237
+ --color-primary-600: rgb(37, 99, 235); /* blue-600 */
238
+ --color-primary-700: rgb(29, 78, 216); /* blue-700 */
239
+ --color-primary-800: rgb(30, 64, 175); /* blue-800 */
240
+ --color-primary-900: rgb(30, 58, 138); /* blue-900 */
241
+ --color-primary-950: rgb(23, 37, 84); /* blue-950 */
242
+
243
+ /* Semantic colors - Success (Green) */
244
+ --color-success-50: rgb(240, 253, 244);
245
+ --color-success-100: rgb(220, 252, 231);
246
+ --color-success-200: rgb(187, 247, 208);
247
+ --color-success-300: rgb(134, 239, 172);
248
+ --color-success-500: rgb(34, 197, 94);
249
+ --color-success-600: rgb(22, 163, 74);
250
+ --color-success-700: rgb(21, 128, 61);
251
+
252
+ /* Semantic colors - Error (Red) */
253
+ --color-error-50: rgb(254, 242, 242);
254
+ --color-error-100: rgb(254, 226, 226);
255
+ --color-error-200: rgb(254, 202, 202);
256
+ --color-error-300: rgb(252, 165, 165);
257
+ --color-error-500: rgb(239, 68, 68);
258
+ --color-error-600: rgb(220, 38, 38);
259
+ --color-error-700: rgb(185, 28, 28);
260
+
261
+ /* Semantic colors - Warning (Amber) */
262
+ --color-warning-50: rgb(255, 251, 235);
263
+ --color-warning-100: rgb(254, 243, 199);
264
+ --color-warning-500: rgb(245, 158, 11);
265
+ --color-warning-600: rgb(217, 119, 6);
266
+ --color-warning-700: rgb(180, 83, 9);
267
+
268
+ /* Semantic colors - Info (Teal - different from primary for sky theme) */
269
+ --color-info-50: rgb(241, 249, 250);
270
+ --color-info-100: rgb(219, 238, 242);
271
+ --color-info-500: rgb(60, 135, 158);
272
+ --color-info-600: rgb(52, 110, 134);
273
+ --color-info-700: rgb(48, 91, 110);
127
274
 
128
275
  /* Gray scale for UI elements (same across themes) */
129
276
  --color-gray-50: rgb(249, 250, 251);
@@ -137,32 +284,74 @@
137
284
  --color-gray-800: rgb(31, 41, 55);
138
285
  --color-gray-900: rgb(17, 24, 39);
139
286
  --color-gray-950: rgb(3, 7, 18);
140
- }
141
-
142
- a.block-link:after {
143
- position: absolute;
144
- content: '';
145
- inset: 0;
146
- }
147
-
148
- /* Admin gradient backgrounds */
149
- html[data-theme='default'] .bg-gradient-admin {
150
- background: linear-gradient(to bottom right, rgb(33, 29, 73), rgb(141, 94, 183));
151
- }
152
287
 
153
- html[data-theme='sky'] .bg-gradient-admin {
154
- background: linear-gradient(to bottom right, rgb(20, 32, 74), rgb(42, 102, 159));
288
+ /* Panda admin chrome tokens — see html[data-theme='default'] for the
289
+ full explanation. Same literal colours as default: these are
290
+ theme-agnostic chrome tokens, unaffected by the sky/default primary
291
+ colour split. */
292
+ --panda-panel-bg: var(--color-white);
293
+ --panda-panel-border: var(--color-gray-200);
294
+ --panda-panel-radius: var(--radius-2xl);
295
+ --panda-table-header-bg: var(--color-gray-50);
296
+ --panda-table-border: var(--color-gray-200);
297
+ --panda-table-row-border: color-mix(in srgb, var(--color-gray-200) 70%, transparent);
298
+ --panda-table-cell-color: var(--color-gray-600);
299
+ --panda-badge-success-bg: var(--color-emerald-50);
300
+ --panda-badge-success-fg: var(--color-emerald-600);
301
+ --panda-badge-warning-bg: var(--color-amber-50);
302
+ --panda-badge-warning-fg: var(--color-amber-600);
303
+ --panda-badge-info-bg: var(--color-sky-50);
304
+ --panda-badge-info-fg: var(--color-sky-600);
305
+ --panda-badge-error-bg: var(--color-rose-50);
306
+ --panda-badge-error-fg: var(--color-rose-600);
307
+ --panda-badge-neutral-bg: var(--color-gray-100);
308
+ --panda-badge-neutral-fg: var(--color-gray-600);
309
+ --panda-input-border: var(--color-gray-300);
310
+ --panda-input-radius: var(--radius-xl);
311
+ --panda-input-focus-ring: var(--color-primary-500);
312
+ --panda-select-trigger-border: var(--color-gray-200);
313
+ --panda-checkbox-accent: var(--color-primary-500);
155
314
  }
156
315
 
157
- /* Remove rounded bottom-left corner on admin sidebar */
316
+ /*
317
+ * Bring-your-own theme: host apps can supply additional theme blocks in
318
+ * their own stylesheets — the gem does not need to know about them. A
319
+ * consuming app:
320
+ *
321
+ * 1. Registers the theme so it appears in the My Profile dropdown and
322
+ * can be the default:
323
+ * config.available_themes = [["Default", "default"], ["Acme", "acme"]]
324
+ * config.default_theme = "acme"
325
+ * (assigning available_themes REPLACES the gem's default list)
326
+ * 2. Ships a stylesheet defining the variables, loaded on gem-rendered
327
+ * pages via config.additional_head_content (rendered in the <head>
328
+ * of every admin layout, including the login page):
329
+ * html[data-theme='acme'] {
330
+ * --color-primary-500: ...; /- brand scale, if desired -/
331
+ * --gradient-admin-from: ...; /- sidebar/login gradient -/
332
+ * --panda-panel-bg: ...; /- any of the chrome tokens -/
333
+ * }
334
+ *
335
+ * HeaderComponent stamps data-theme from Current.user&.current_theme ||
336
+ * config.default_theme on <html>, so the block activates automatically.
337
+ * Any token left undefined falls back to the gem default.
338
+ */
339
+
340
+ /* Admin gradient backgrounds - customizable via CSS custom properties */
158
341
  .bg-gradient-admin {
342
+ background: linear-gradient(to bottom right, var(--gradient-admin-from, rgb(17, 24, 39)), var(--gradient-admin-to, rgb(55, 65, 81)));
159
343
  border-bottom-left-radius: 0;
160
344
  }
345
+
346
+ /* Clickable table rows containing a block-link */
347
+ .table-row:has(a.block-link) {
348
+ cursor: pointer;
349
+ }
161
350
  }
162
351
 
163
352
  /* Form input styles */
164
353
  @layer components {
165
- /* Base form field styles - matches panda-cms admin pattern */
354
+ /* Base form field styles */
166
355
  input[type='text'],
167
356
  input[type='email'],
168
357
  input[type='password'],
@@ -174,33 +363,61 @@
174
363
  input[type='month'],
175
364
  input[type='week'],
176
365
  input[type='time'],
177
- input[type='search'],
366
+ input[type='search'] {
367
+ @apply block w-full h-11 rounded-xl border border-gray-300 px-3 py-2 text-gray-900;
368
+ @apply placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-primary-500;
369
+ @apply dark:bg-white/5 dark:text-white dark:border-white/10 dark:placeholder:text-gray-500;
370
+ @apply disabled:border-gray-200 disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed;
371
+ background-color: #fff;
372
+ /* Themeable border/radius/focus-ring — see --panda-input-* tokens above.
373
+ Fallbacks match the @apply values on this rule exactly, so this is a
374
+ no-op for consumers that never set a data-theme. */
375
+ border-color: var(--panda-input-border, var(--color-gray-300));
376
+ border-radius: var(--panda-input-radius, var(--radius-xl));
377
+
378
+ &:focus {
379
+ outline-color: var(--panda-input-focus-ring, var(--color-primary-500));
380
+ }
381
+ }
382
+
178
383
  textarea {
179
- @apply block w-full rounded-md border-0 p-2 text-gray-900 bg-white;
180
- @apply ring-1 ring-inset ring-mid placeholder:text-gray-300;
181
- @apply focus:ring-1 focus:ring-inset focus:ring-dark;
182
- @apply hover:cursor-pointer sm:leading-6;
183
- @apply disabled:ring-gray-300 disabled:focus:ring-gray-300 disabled:bg-gray-50 disabled:cursor-not-allowed;
384
+ @apply block w-full rounded-xl border border-gray-300 px-3 py-2 text-gray-900;
385
+ @apply placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-primary-500;
386
+ @apply dark:bg-white/5 dark:text-white dark:border-white/10 dark:placeholder:text-gray-500;
387
+ @apply disabled:border-gray-200 disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed;
388
+ background-color: #fff;
389
+ border-color: var(--panda-input-border, var(--color-gray-300));
390
+ border-radius: var(--panda-input-radius, var(--radius-xl));
391
+
392
+ &:focus {
393
+ outline-color: var(--panda-input-focus-ring, var(--color-primary-500));
394
+ }
184
395
  }
185
396
 
186
- /* Select specific styling - matches panda-cms admin pattern */
397
+ /* Select specific styling */
187
398
  select {
188
- @apply block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 bg-white;
189
- @apply ring-1 ring-inset ring-mid;
190
- @apply focus:ring-1 focus:ring-inset focus:ring-dark;
191
- @apply hover:cursor-pointer sm:leading-6;
192
- @apply disabled:ring-gray-300 disabled:focus:ring-gray-300 disabled:bg-gray-50 disabled:cursor-not-allowed;
399
+ @apply block w-full h-11 rounded-xl border border-gray-300 px-3 py-2 text-gray-900;
400
+ @apply focus:outline-2 focus:-outline-offset-2 focus:outline-primary-500;
401
+ @apply dark:bg-white/5 dark:text-white dark:border-white/10;
402
+ @apply disabled:border-gray-200 disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed;
193
403
  @apply appearance-none bg-right bg-no-repeat;
404
+ background-color: #fff;
194
405
  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='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
195
- background-position: right 0.5rem center;
196
- background-size: 1.5em 1.5em;
406
+ background-position: right 0.75rem center;
407
+ background-size: 1.25em 1.25em;
408
+ border-color: var(--panda-input-border, var(--color-gray-300));
409
+ border-radius: var(--panda-input-radius, var(--radius-xl));
410
+
411
+ &:focus {
412
+ outline-color: var(--panda-input-focus-ring, var(--color-primary-500));
413
+ }
197
414
  }
198
415
 
199
416
  /* Checkbox and radio styling */
200
417
  input[type='checkbox'],
201
418
  input[type='radio'] {
202
- @apply w-4 h-4 text-indigo-600 bg-white border-gray-300 rounded transition-colors duration-200;
203
- @apply focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2;
419
+ @apply w-5 h-5 text-primary-600 bg-white border-gray-300 rounded-md transition-colors duration-200;
420
+ @apply focus:outline-2 focus:outline-offset-2 focus:outline-primary-500;
204
421
  @apply disabled:bg-gray-100 disabled:cursor-not-allowed;
205
422
  }
206
423
 
@@ -208,9 +425,16 @@
208
425
  @apply rounded-full;
209
426
  }
210
427
 
428
+ /* Ensure form controls use primary brand color. Checkbox/radio accent is
429
+ themeable independently of primary-500 via --panda-checkbox-accent
430
+ (falls back to primary-500, today's behaviour, when unset). */
431
+ input, select, textarea {
432
+ accent-color: var(--panda-checkbox-accent, var(--color-primary-500));
433
+ }
434
+
211
435
  /* Label styling */
212
436
  label {
213
- @apply block text-sm font-medium text-gray-700 mb-1;
437
+ @apply block text-xs font-semibold text-gray-500 mb-1;
214
438
  }
215
439
 
216
440
  /* Field wrapper styling */
@@ -222,43 +446,47 @@
222
446
  input.error,
223
447
  textarea.error,
224
448
  select.error {
225
- @apply ring-red-500 focus:ring-red-500;
449
+ @apply outline-error-500 focus:outline-error-500;
226
450
  }
227
451
 
228
452
  .field-error {
229
- @apply text-sm text-red-600 mt-1;
453
+ @apply text-sm text-error-600 mt-1;
230
454
  }
231
455
 
232
456
  /* Button styling */
233
457
  .btn {
234
- @apply inline-flex items-center justify-center px-6 py-3 text-base font-semibold rounded-md transition-colors duration-200;
235
- @apply focus:outline-none focus:ring-2 focus:ring-offset-2;
458
+ @apply inline-flex items-center justify-center px-4 py-2 text-sm font-medium rounded-xl transition-colors duration-200;
459
+ @apply focus-visible:outline-2 focus-visible:outline-offset-2 shadow-sm;
236
460
  @apply disabled:opacity-50 disabled:cursor-not-allowed;
237
461
  }
238
462
 
239
463
  .btn-primary {
240
- @apply bg-mid text-white hover:opacity-90 focus:ring-mid;
464
+ @apply bg-primary-500 text-white hover:bg-primary-600 focus-visible:outline-primary-600;
241
465
  }
242
466
 
243
467
  .btn-secondary {
244
- @apply bg-gray-200 text-gray-900 hover:bg-gray-300 focus:ring-gray-500;
468
+ @apply border border-gray-200 bg-white text-gray-700 hover:bg-gray-50 focus-visible:outline-gray-300;
245
469
  }
246
470
 
247
471
  .btn-danger {
248
- @apply bg-red-600 text-white hover:bg-red-700 focus:ring-red-500;
472
+ @apply border border-error-200 bg-error-50 text-error-600 hover:bg-error-100 focus-visible:outline-error-300;
249
473
  }
250
474
 
251
- a.block-link:after {
252
- position: absolute;
253
- content: '';
254
- inset: 0;
475
+ .btn-success {
476
+ @apply border border-success-200 bg-success-50 text-success-600 hover:bg-success-100 focus-visible:outline-success-300;
255
477
  }
478
+
479
+ /* Custom select dropdown */
480
+ [data-controller="custom-select"] {
481
+ position: relative;
482
+ }
483
+
256
484
  }
257
485
 
258
486
  /* EditorJS content styles */
259
487
  @layer components {
260
488
  .codex-editor__redactor .ce-block .ce-block__content {
261
- @apply text-base font-normal font-sans text-dark leading-[1.6] space-y-[1.6rem];
489
+ @apply text-base font-normal font-sans text-gray-900 leading-[1.6] space-y-[1.6rem];
262
490
 
263
491
  h1.ce-header {
264
492
  @apply text-3xl md:text-4xl font-semibold font-sans leading-[1.2];
@@ -277,7 +505,7 @@
277
505
  @apply leading-[1.6] tracking-wide max-w-[85ch];
278
506
 
279
507
  a {
280
- @apply text-[#1A9597] underline underline-offset-2 hover:text-[#158486] focus:outline-2 focus:outline-offset-2 focus:outline-[#1A9597];
508
+ @apply text-primary-600 underline underline-offset-2 hover:text-primary-700 focus:outline-2 focus:outline-offset-2 focus:outline-primary-600;
281
509
  }
282
510
 
283
511
  strong,
@@ -291,10 +519,10 @@
291
519
  }
292
520
 
293
521
  .cdx-quote {
294
- @apply bg-[#eef0f3] border-l-inactive border-l-8 p-6 mb-4;
522
+ @apply bg-gray-100 border-l-primary-300 border-l-8 p-6 mb-4;
295
523
 
296
524
  .cdx-quote__caption {
297
- @apply block ml-6 mt-2 text-sm text-dark;
525
+ @apply block ml-6 mt-2 text-sm text-gray-600;
298
526
  }
299
527
 
300
528
  .cdx-quote__text {
@@ -302,7 +530,7 @@
302
530
  @apply pl-6;
303
531
 
304
532
  &:before {
305
- @apply -ml-8 mr-2 text-dark text-6xl leading-4 align-text-bottom font-serif;
533
+ @apply -ml-8 mr-2 text-primary-600 text-6xl leading-4 align-text-bottom font-serif;
306
534
  content: open-quote;
307
535
  }
308
536
 
@@ -353,18 +581,18 @@
353
581
  }
354
582
 
355
583
  .cdx-table {
356
- @apply w-full border-collapse border-2 border-dark my-6;
584
+ @apply w-full border-collapse border-2 border-gray-300 my-6;
357
585
 
358
586
  &__head {
359
- @apply font-semibold border-dark border-r-2 p-3 bg-light;
587
+ @apply font-semibold border-gray-300 border-r-2 p-3 bg-gray-100;
360
588
  }
361
589
 
362
590
  &__row {
363
- @apply border-dark border-b-2;
591
+ @apply border-gray-300 border-b-2;
364
592
  }
365
593
 
366
594
  &__cell {
367
- @apply border-dark border-r-2 p-3;
595
+ @apply border-gray-300 border-r-2 p-3;
368
596
  }
369
597
  }
370
598
 
@@ -375,3 +603,57 @@
375
603
  }
376
604
  }
377
605
  }
606
+
607
+ /* Page tree indentation utilities - must be explicitly defined because
608
+ they're used in panda-cms views which aren't scanned by this build */
609
+ @layer utilities {
610
+ .ml-18 {
611
+ margin-left: var(--spacing-18, 4.5rem);
612
+ }
613
+
614
+ /* ButtonComponent action classes - generated dynamically in Ruby, so must be explicitly defined */
615
+ .bg-primary-500 {
616
+ background-color: var(--color-primary-500);
617
+ }
618
+
619
+ .bg-primary-600 {
620
+ background-color: var(--color-primary-600);
621
+ }
622
+
623
+ .hover\:bg-primary-600:hover {
624
+ background-color: var(--color-primary-600);
625
+ }
626
+
627
+ .focus-visible\:outline-primary-600:focus-visible {
628
+ outline-color: var(--color-primary-600);
629
+ }
630
+
631
+ /* Sidebar navigation classes - used in dynamic Ruby string interpolation */
632
+ .space-y-0\.5 > :not(:last-child) {
633
+ margin-bottom: 0.125rem;
634
+ }
635
+
636
+ .pl-6 {
637
+ padding-left: 1.5rem;
638
+ }
639
+
640
+ .pl-8 {
641
+ padding-left: 2rem;
642
+ }
643
+
644
+ .pr-2 {
645
+ padding-right: 0.5rem;
646
+ }
647
+
648
+ .text-white\/90 {
649
+ color: rgb(255 255 255 / 0.9);
650
+ }
651
+
652
+ .border-white\/20 {
653
+ border-color: rgb(255 255 255 / 0.2);
654
+ }
655
+
656
+ .hover\:bg-primary-500\/40:hover {
657
+ background-color: color-mix(in srgb, var(--color-primary-500) 40%, transparent);
658
+ }
659
+ }