plutonium 0.34.1 → 0.35.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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium/skill.md +53 -0
  3. data/.claude/skills/{assets → plutonium-assets}/SKILL.md +13 -8
  4. data/.claude/skills/{connect-resource → plutonium-connect-resource}/SKILL.md +1 -1
  5. data/.claude/skills/{controller → plutonium-controller}/SKILL.md +27 -13
  6. data/.claude/skills/{create-resource → plutonium-create-resource}/SKILL.md +1 -1
  7. data/.claude/skills/{definition → plutonium-definition}/SKILL.md +10 -10
  8. data/.claude/skills/{definition-actions → plutonium-definition-actions}/SKILL.md +34 -9
  9. data/.claude/skills/{definition-fields → plutonium-definition-fields}/SKILL.md +38 -10
  10. data/.claude/skills/plutonium-definition-query/SKILL.md +356 -0
  11. data/.claude/skills/{forms → plutonium-forms}/SKILL.md +6 -6
  12. data/.claude/skills/{installation → plutonium-installation}/SKILL.md +9 -9
  13. data/.claude/skills/{interaction → plutonium-interaction}/SKILL.md +20 -19
  14. data/.claude/skills/{model → plutonium-model}/SKILL.md +3 -3
  15. data/.claude/skills/{model-features → plutonium-model-features}/SKILL.md +3 -3
  16. data/.claude/skills/{nested-resources → plutonium-nested-resources}/SKILL.md +5 -5
  17. data/.claude/skills/{package → plutonium-package}/SKILL.md +7 -8
  18. data/.claude/skills/{policy → plutonium-policy}/SKILL.md +26 -4
  19. data/.claude/skills/{portal → plutonium-portal}/SKILL.md +33 -31
  20. data/.claude/skills/{resource → plutonium-resource}/SKILL.md +27 -27
  21. data/.claude/skills/{rodauth → plutonium-rodauth}/SKILL.md +5 -5
  22. data/.claude/skills/plutonium-theming/SKILL.md +424 -0
  23. data/.claude/skills/{views → plutonium-views}/SKILL.md +7 -7
  24. data/CHANGELOG.md +52 -0
  25. data/CLAUDE.md +215 -0
  26. data/CONTRIBUTING.md +72 -18
  27. data/README.md +100 -19
  28. data/app/assets/plutonium.css +1 -11
  29. data/app/assets/plutonium.js +1685 -1146
  30. data/app/assets/plutonium.js.map +4 -4
  31. data/app/assets/plutonium.min.js +70 -70
  32. data/app/assets/plutonium.min.js.map +4 -4
  33. data/app/views/resource/interactive_bulk_action.html.erb +1 -5
  34. data/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
  35. data/app/views/rodauth/_login_form.html.erb +15 -55
  36. data/app/views/rodauth/_login_form_footer.html.erb +2 -2
  37. data/app/views/rodauth/_password_visibility.html.erb +2 -8
  38. data/app/views/rodauth/add_recovery_codes.html.erb +2 -2
  39. data/app/views/rodauth/change_login.html.erb +36 -19
  40. data/app/views/rodauth/change_password.html.erb +34 -10
  41. data/app/views/rodauth/close_account.html.erb +12 -4
  42. data/app/views/rodauth/confirm_password.html.erb +19 -17
  43. data/app/views/rodauth/create_account.html.erb +30 -109
  44. data/app/views/rodauth/email_auth.html.erb +1 -1
  45. data/app/views/rodauth/logout.html.erb +4 -4
  46. data/app/views/rodauth/otp_auth.html.erb +13 -4
  47. data/app/views/rodauth/otp_disable.html.erb +12 -4
  48. data/app/views/rodauth/otp_setup.html.erb +29 -12
  49. data/app/views/rodauth/otp_unlock.html.erb +19 -10
  50. data/app/views/rodauth/otp_unlock_not_available.html.erb +7 -7
  51. data/app/views/rodauth/recovery_auth.html.erb +12 -4
  52. data/app/views/rodauth/recovery_codes.html.erb +12 -4
  53. data/app/views/rodauth/remember.html.erb +7 -7
  54. data/app/views/rodauth/reset_password.html.erb +23 -7
  55. data/app/views/rodauth/reset_password_request.html.erb +14 -10
  56. data/app/views/rodauth/sms_auth.html.erb +13 -4
  57. data/app/views/rodauth/sms_confirm.html.erb +13 -4
  58. data/app/views/rodauth/sms_disable.html.erb +12 -4
  59. data/app/views/rodauth/sms_request.html.erb +1 -1
  60. data/app/views/rodauth/sms_setup.html.erb +23 -7
  61. data/app/views/rodauth/two_factor_auth.html.erb +2 -2
  62. data/app/views/rodauth/two_factor_disable.html.erb +12 -4
  63. data/app/views/rodauth/two_factor_manage.html.erb +7 -7
  64. data/app/views/rodauth/unlock_account.html.erb +13 -5
  65. data/app/views/rodauth/unlock_account_request.html.erb +2 -2
  66. data/app/views/rodauth/verify_account.html.erb +25 -7
  67. data/app/views/rodauth/verify_account_resend.html.erb +14 -10
  68. data/app/views/rodauth/verify_login_change.html.erb +1 -1
  69. data/app/views/rodauth/webauthn_auth.html.erb +1 -1
  70. data/app/views/rodauth/webauthn_remove.html.erb +18 -8
  71. data/app/views/rodauth/webauthn_setup.html.erb +12 -4
  72. data/docs/.vitepress/config.ts +15 -26
  73. data/docs/.vitepress/theme/custom.css +388 -29
  74. data/docs/getting-started/index.md +1 -1
  75. data/docs/getting-started/tutorial/02-first-resource.md +9 -0
  76. data/docs/getting-started/tutorial/06-nested-resources.md +2 -2
  77. data/docs/getting-started/tutorial/07-author-portal.md +191 -0
  78. data/docs/getting-started/tutorial/{07-customizing-ui.md → 08-customizing-ui.md} +7 -7
  79. data/docs/getting-started/tutorial/index.md +5 -2
  80. data/docs/guides/authorization.md +33 -0
  81. data/docs/guides/creating-packages.md +12 -16
  82. data/docs/guides/custom-actions.md +36 -0
  83. data/docs/guides/search-filtering.md +121 -42
  84. data/docs/guides/theming.md +232 -36
  85. data/docs/index.md +203 -57
  86. data/docs/public/og-image.png +0 -0
  87. data/docs/reference/controller/index.md +14 -16
  88. data/docs/reference/definition/actions.md +38 -3
  89. data/docs/reference/definition/fields.md +3 -3
  90. data/docs/reference/definition/index.md +2 -2
  91. data/docs/reference/generators/index.md +0 -1
  92. data/docs/reference/interaction/index.md +14 -10
  93. data/docs/reference/model/index.md +0 -1
  94. data/docs/reference/portal/index.md +13 -27
  95. data/gemfiles/rails_7.gemfile.lock +1 -1
  96. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  97. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  98. data/lib/generators/pu/pkg/portal/portal_generator.rb +0 -2
  99. data/lib/generators/pu/pkg/portal/templates/app/views/package/dashboard/index.html.erb +28 -72
  100. data/lib/plutonium/action/interactive.rb +2 -2
  101. data/lib/plutonium/core/controller.rb +2 -1
  102. data/lib/plutonium/definition/actions.rb +2 -2
  103. data/lib/plutonium/lib/deep_freezer.rb +3 -7
  104. data/lib/plutonium/query/filter.rb +14 -0
  105. data/lib/plutonium/query/filters/association.rb +49 -0
  106. data/lib/plutonium/query/filters/boolean.rb +35 -0
  107. data/lib/plutonium/query/filters/date.rb +97 -0
  108. data/lib/plutonium/query/filters/date_range.rb +58 -0
  109. data/lib/plutonium/query/filters/select.rb +55 -0
  110. data/lib/plutonium/resource/controllers/crud_actions.rb +24 -6
  111. data/lib/plutonium/resource/controllers/interactive_actions.rb +76 -58
  112. data/lib/plutonium/resource/controllers/queryable.rb +4 -2
  113. data/lib/plutonium/resource/query_object.rb +1 -1
  114. data/lib/plutonium/ui/action_button.rb +23 -65
  115. data/lib/plutonium/ui/actions_dropdown.rb +103 -0
  116. data/lib/plutonium/ui/block.rb +1 -1
  117. data/lib/plutonium/ui/breadcrumbs.rb +12 -19
  118. data/lib/plutonium/ui/color_mode_selector.rb +1 -1
  119. data/lib/plutonium/ui/component/kit.rb +6 -0
  120. data/lib/plutonium/ui/component_classes.rb +102 -0
  121. data/lib/plutonium/ui/display/base.rb +15 -0
  122. data/lib/plutonium/ui/display/components/attachment.rb +6 -5
  123. data/lib/plutonium/ui/display/components/boolean.rb +23 -0
  124. data/lib/plutonium/ui/display/components/color.rb +23 -0
  125. data/lib/plutonium/ui/display/resource.rb +1 -1
  126. data/lib/plutonium/ui/display/theme.rb +29 -15
  127. data/lib/plutonium/ui/empty_card.rb +3 -3
  128. data/lib/plutonium/ui/form/base.rb +20 -0
  129. data/lib/plutonium/ui/form/components/key_value_store.rb +11 -11
  130. data/lib/plutonium/ui/form/components/resource_select.rb +31 -0
  131. data/lib/plutonium/ui/form/components/secure_association.rb +1 -2
  132. data/lib/plutonium/ui/form/components/uppy.rb +5 -4
  133. data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +4 -4
  134. data/lib/plutonium/ui/form/interaction.rb +17 -1
  135. data/lib/plutonium/ui/form/query.rb +133 -80
  136. data/lib/plutonium/ui/form/theme.rb +50 -35
  137. data/lib/plutonium/ui/frame_navigator_panel.rb +2 -2
  138. data/lib/plutonium/ui/layout/base.rb +1 -1
  139. data/lib/plutonium/ui/layout/header.rb +4 -7
  140. data/lib/plutonium/ui/layout/rodauth_layout.rb +7 -7
  141. data/lib/plutonium/ui/layout/sidebar.rb +1 -1
  142. data/lib/plutonium/ui/nav_grid_menu.rb +7 -6
  143. data/lib/plutonium/ui/nav_user.rb +9 -8
  144. data/lib/plutonium/ui/page/interactive_action.rb +5 -5
  145. data/lib/plutonium/ui/page_header.rb +29 -10
  146. data/lib/plutonium/ui/panel.rb +4 -4
  147. data/lib/plutonium/ui/sidebar_menu.rb +8 -8
  148. data/lib/plutonium/ui/skeleton_table.rb +7 -8
  149. data/lib/plutonium/ui/tab_list.rb +5 -5
  150. data/lib/plutonium/ui/table/base.rb +3 -0
  151. data/lib/plutonium/ui/table/components/attachment.rb +4 -3
  152. data/lib/plutonium/ui/table/components/bulk_actions_toolbar.rb +82 -0
  153. data/lib/plutonium/ui/table/components/pagy_info.rb +2 -2
  154. data/lib/plutonium/ui/table/components/pagy_pagination.rb +13 -8
  155. data/lib/plutonium/ui/table/components/row_actions_dropdown.rb +101 -0
  156. data/lib/plutonium/ui/table/components/scopes_bar.rb +2 -2
  157. data/lib/plutonium/ui/table/components/selection_column.rb +100 -0
  158. data/lib/plutonium/ui/table/display_theme.rb +6 -6
  159. data/lib/plutonium/ui/table/resource.rb +93 -52
  160. data/lib/plutonium/ui/table/theme.rb +28 -15
  161. data/lib/plutonium/version.rb +1 -1
  162. data/package.json +2 -2
  163. data/plutonium.gemspec +5 -4
  164. data/src/css/components.css +471 -0
  165. data/src/css/intl_tel_input.css +2 -2
  166. data/src/css/plutonium.css +2 -0
  167. data/src/css/tokens.css +149 -0
  168. data/src/js/controllers/bulk_actions_controller.js +109 -0
  169. data/src/js/controllers/filter_panel_controller.js +35 -0
  170. data/src/js/controllers/register_controllers.js +5 -1
  171. data/src/js/controllers/resource_drop_down_controller.js +25 -1
  172. data/src/js/controllers/slim_select_controller.js +6 -2
  173. data/src/js/turbo/turbo_actions.js +1 -1
  174. metadata +52 -39
  175. data/.claude/skills/definition-query/SKILL.md +0 -334
  176. data/docs/concepts/architecture.md +0 -226
  177. data/docs/concepts/auto-detection.md +0 -254
  178. data/docs/concepts/index.md +0 -61
  179. data/docs/concepts/packages-portals.md +0 -304
  180. data/docs/concepts/resources.md +0 -224
  181. data/docs/cookbook/blog.md +0 -411
  182. data/docs/cookbook/index.md +0 -289
  183. data/docs/cookbook/saas.md +0 -481
  184. data/docs/public/CLAUDE.md +0 -578
  185. data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +0 -5
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: portal
2
+ name: plutonium-portal
3
3
  description: Plutonium portals - web interfaces with authentication, entity scoping, and routes
4
4
  ---
5
5
 
@@ -244,35 +244,37 @@ end
244
244
 
245
245
  ## Controller Hierarchy
246
246
 
247
+ ### Resource Controllers
248
+
249
+ Portal resource controllers inherit from the feature package's controller:
250
+
247
251
  ```
248
- ::PlutoniumController (app-wide base)
249
-
250
- ::ResourceController (resource handling)
251
-
252
- DashboardPortal::ResourceController (portal base)
252
+ ::PostsController (feature package controller)
253
253
 
254
- DashboardPortal::PostsController (resource-specific)
254
+ DashboardPortal::PostsController (portal-specific)
255
255
  ```
256
256
 
257
- ### Portal Controllers
257
+ Controllers are auto-created if not defined. When accessing `DashboardPortal::PostsController`:
258
+
259
+ 1. If file exists, use it
260
+ 2. Otherwise, dynamically create inheriting from `::PostsController`
261
+ 3. Include `DashboardPortal::Concerns::Controller`
262
+
263
+ ### Non-Resource Controllers
264
+
265
+ For portal pages not tied to a resource (dashboard, settings, etc.), inherit from `PlutoniumController`:
258
266
 
259
267
  ```ruby
260
- # packages/dashboard_portal/app/controllers/dashboard_portal/resource_controller.rb
268
+ # packages/dashboard_portal/app/controllers/dashboard_portal/dashboard_controller.rb
261
269
  module DashboardPortal
262
- class ResourceController < ::ResourceController
263
- include DashboardPortal::Concerns::Controller
270
+ class DashboardController < PlutoniumController
271
+ def index
272
+ # Dashboard home page
273
+ end
264
274
  end
265
275
  end
266
276
  ```
267
277
 
268
- ### Dynamic Controllers
269
-
270
- Controllers are auto-created if not defined. When accessing `DashboardPortal::PostsController`:
271
-
272
- 1. If file exists, use it
273
- 2. Otherwise, dynamically create inheriting from `::PostsController`
274
- 3. Include `DashboardPortal::Concerns::Controller`
275
-
276
278
  ## Portal-Specific Overrides
277
279
 
278
280
  ### Override Definition
@@ -307,13 +309,13 @@ end
307
309
 
308
310
  ```ruby
309
311
  # packages/dashboard_portal/app/controllers/dashboard_portal/posts_controller.rb
310
- module DashboardPortal
311
- class PostsController < ResourceController
312
- private
312
+ class DashboardPortal::PostsController < ::PostsController
313
+ include DashboardPortal::Concerns::Controller
313
314
 
314
- def preferred_action_after_submit
315
- "index"
316
- end
315
+ private
316
+
317
+ def preferred_action_after_submit
318
+ "index"
317
319
  end
318
320
  end
319
321
  ```
@@ -392,9 +394,9 @@ Each portal can:
392
394
 
393
395
  ## Related Skills
394
396
 
395
- - `package` - Package overview (features vs portals)
396
- - `rodauth` - Authentication setup and configuration
397
- - `connect-resource` - Connecting resources to portals
398
- - `policy` - Portal-specific policies
399
- - `definition` - Portal-specific definitions
400
- - `controller` - Portal-specific controllers
397
+ - `plutonium-package` - Package overview (features vs portals)
398
+ - `plutonium-rodauth` - Authentication setup and configuration
399
+ - `plutonium-connect-resource` - Connecting resources to portals
400
+ - `plutonium-policy` - Portal-specific policies
401
+ - `plutonium-definition` - Portal-specific definitions
402
+ - `plutonium-controller` - Portal-specific controllers
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: resource
2
+ name: plutonium-resource
3
3
  description: Overview of Plutonium resources - what they are and how the pieces fit together
4
4
  ---
5
5
 
@@ -49,7 +49,7 @@ This generates:
49
49
  - `app/controllers/posts_controller.rb` - Controller (empty, inherits CRUD)
50
50
  - Migration file
51
51
 
52
- See `create-resource` skill for full generator options.
52
+ See `plutonium-create-resource` skill for full generator options.
53
53
 
54
54
  ### From Existing Models
55
55
 
@@ -99,7 +99,7 @@ This:
99
99
  - Creates portal-specific controller
100
100
  - Creates portal-specific policy with attribute permissions
101
101
 
102
- See `connect-resource` skill for details.
102
+ See `plutonium-connect-resource` skill for details.
103
103
 
104
104
  ## Layer Responsibilities
105
105
 
@@ -122,14 +122,14 @@ The model handles:
122
122
  - Business logic scopes
123
123
  - Callbacks
124
124
 
125
- **Skills:** `model`, `model-features`
125
+ **Skills:** `plutonium-model`, `plutonium-model-features`
126
126
 
127
127
  ### Definition (UI Layer)
128
128
 
129
129
  ```ruby
130
130
  class PostDefinition < ResourceDefinition
131
131
  # Override auto-detected field types
132
- input :content, as: :rich_text
132
+ input :content, as: :markdown
133
133
 
134
134
  # Add filters and scopes
135
135
  filter :published, with: Plutonium::Query::Filters::Boolean
@@ -147,7 +147,7 @@ The definition handles:
147
147
  - Search, filters, scopes, sorting
148
148
  - Actions (interactive operations)
149
149
 
150
- **Skills:** `definition`, `definition-fields`, `definition-actions`, `definition-query`
150
+ **Skills:** `plutonium-definition`, `plutonium-definition-fields`, `plutonium-definition-actions`, `plutonium-definition-query`
151
151
 
152
152
  ### Policy (Authorization Layer)
153
153
 
@@ -188,7 +188,7 @@ The policy handles:
188
188
  - Resource scoping (what records user can see)
189
189
  - Attribute permissions (read/write access per field)
190
190
 
191
- **Skill:** `policy`
191
+ **Skill:** `plutonium-policy`
192
192
 
193
193
  ### Controller (Request Layer)
194
194
 
@@ -216,7 +216,7 @@ The controller handles:
216
216
  - Custom parameter processing
217
217
  - Non-standard authorization flows
218
218
 
219
- **Skill:** `controller`
219
+ **Skill:** `plutonium-controller`
220
220
 
221
221
  ## Auto-Detection
222
222
 
@@ -260,22 +260,22 @@ end
260
260
 
261
261
  ## Related Skills
262
262
 
263
- - `model` - Model structure and organization
264
- - `model-features` - has_cents, associations, scopes, routes
265
- - `definition` - Definition overview and structure
266
- - `definition-fields` - Fields, inputs, displays, columns
267
- - `definition-actions` - Actions and interactions
268
- - `interaction` - Writing interaction classes
269
- - `definition-query` - Search, filters, scopes, sorting
270
- - `policy` - Authorization and permissions
271
- - `controller` - Controller customization
272
- - `views` - Custom pages, displays, tables using Phlex
273
- - `forms` - Custom form templates and field builders
274
- - `assets` - TailwindCSS and component theming
275
- - `package` - Feature and portal packages
276
- - `portal` - Portal configuration and entity scoping
277
- - `nested-resources` - Parent/child routes and scoping
278
- - `installation` - Setting up Plutonium
279
- - `rodauth` - Authentication setup
280
- - `create-resource` - Scaffold generator details
281
- - `connect-resource` - Portal connection details
263
+ - `plutonium-model` - Model structure and organization
264
+ - `plutonium-model-features` - has_cents, associations, scopes, routes
265
+ - `plutonium-definition` - Definition overview and structure
266
+ - `plutonium-definition-fields` - Fields, inputs, displays, columns
267
+ - `plutonium-definition-actions` - Actions and interactions
268
+ - `plutonium-interaction` - Writing interaction classes
269
+ - `plutonium-definition-query` - Search, filters, scopes, sorting
270
+ - `plutonium-policy` - Authorization and permissions
271
+ - `plutonium-controller` - Controller customization
272
+ - `plutonium-views` - Custom pages, displays, tables using Phlex
273
+ - `plutonium-forms` - Custom form templates and field builders
274
+ - `plutonium-assets` - TailwindCSS and component theming
275
+ - `plutonium-package` - Feature and portal packages
276
+ - `plutonium-portal` - Portal configuration and entity scoping
277
+ - `plutonium-nested-resources` - Parent/child routes and scoping
278
+ - `plutonium-installation` - Setting up Plutonium
279
+ - `plutonium-rodauth` - Authentication setup
280
+ - `plutonium-create-resource` - Scaffold generator details
281
+ - `plutonium-connect-resource` - Portal connection details
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: rodauth
2
+ name: plutonium-rodauth
3
3
  description: Plutonium Rodauth integration - authentication setup, account types, and configuration
4
4
  ---
5
5
 
@@ -165,7 +165,7 @@ Including `Plutonium::Auth::Rodauth(:name)` adds:
165
165
  |--------|-------------|
166
166
  | `current_user` | The authenticated account |
167
167
  | `logout_url` | URL to logout |
168
- | `rodauth` | Access to Rodauth instance |
168
+ | `plutonium-rodauth` | Access to Rodauth instance |
169
169
 
170
170
  ## Generated Files
171
171
 
@@ -447,6 +447,6 @@ User.create!(
447
447
 
448
448
  ## Related Skills
449
449
 
450
- - `installation` - Initial Plutonium setup
451
- - `portal` - Portal configuration
452
- - `policy` - Authorization after authentication
450
+ - `plutonium-installation` - Initial Plutonium setup
451
+ - `plutonium-portal` - Portal configuration
452
+ - `plutonium-policy` - Authorization after authentication
@@ -0,0 +1,424 @@
1
+ ---
2
+ name: plutonium-theming
3
+ description: Plutonium design token system - CSS custom properties, component classes, and consistent styling patterns
4
+ ---
5
+
6
+ # Plutonium Design Token System
7
+
8
+ Plutonium uses a comprehensive CSS design token system for consistent, themeable UI components. This system provides CSS custom properties and reusable component classes that automatically support light and dark modes.
9
+
10
+ ## CSS Design Tokens
11
+
12
+ Design tokens are defined in `src/css/tokens.css` and provide the foundation for all UI styling.
13
+
14
+ ### Surface & Background Colors
15
+
16
+ ```css
17
+ /* Light mode */
18
+ --pu-body: #f8fafc; /* Page background */
19
+ --pu-surface: #ffffff; /* Main surface (cards, panels) */
20
+ --pu-surface-alt: #f1f5f9; /* Alternate surface (headers) */
21
+ --pu-surface-raised: #ffffff; /* Elevated elements */
22
+ --pu-surface-overlay: rgba(255, 255, 255, 0.95);
23
+
24
+ /* Dark mode (.dark class) */
25
+ --pu-body: #0f172a;
26
+ --pu-surface: #1e293b;
27
+ --pu-surface-alt: #0f172a;
28
+ --pu-surface-raised: #334155;
29
+ --pu-surface-overlay: rgba(30, 41, 59, 0.95);
30
+ ```
31
+
32
+ ### Text Colors
33
+
34
+ ```css
35
+ /* Light mode */
36
+ --pu-text: #0f172a; /* Primary text */
37
+ --pu-text-muted: #64748b; /* Secondary text */
38
+ --pu-text-subtle: #94a3b8; /* Tertiary/disabled text */
39
+
40
+ /* Dark mode */
41
+ --pu-text: #f8fafc;
42
+ --pu-text-muted: #94a3b8;
43
+ --pu-text-subtle: #64748b;
44
+ ```
45
+
46
+ ### Border Colors
47
+
48
+ ```css
49
+ /* Light mode */
50
+ --pu-border: #e2e8f0; /* Standard borders */
51
+ --pu-border-muted: #f1f5f9; /* Subtle borders */
52
+ --pu-border-strong: #cbd5e1; /* Emphasized borders */
53
+
54
+ /* Dark mode */
55
+ --pu-border: #334155;
56
+ --pu-border-muted: #1e293b;
57
+ --pu-border-strong: #475569;
58
+ ```
59
+
60
+ ### Form Tokens
61
+
62
+ ```css
63
+ --pu-input-bg: #ffffff; /* Input background */
64
+ --pu-input-border: #e2e8f0; /* Input border */
65
+ --pu-input-focus-ring: theme(colors.primary.500);
66
+ --pu-input-placeholder: #94a3b8; /* Placeholder text */
67
+ ```
68
+
69
+ ### Card Tokens
70
+
71
+ ```css
72
+ --pu-card-bg: #ffffff;
73
+ --pu-card-border: #e2e8f0;
74
+ ```
75
+
76
+ ### Shadow System
77
+
78
+ ```css
79
+ --pu-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.03), 0 1px 3px 0 rgb(0 0 0 / 0.05);
80
+ --pu-shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.04), 0 4px 6px -1px rgb(0 0 0 / 0.06);
81
+ --pu-shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.03), 0 10px 15px -3px rgb(0 0 0 / 0.08);
82
+ ```
83
+
84
+ ### Border Radius
85
+
86
+ ```css
87
+ --pu-radius-sm: 0.375rem; /* 6px */
88
+ --pu-radius-md: 0.5rem; /* 8px */
89
+ --pu-radius-lg: 0.75rem; /* 12px */
90
+ --pu-radius-xl: 1rem; /* 16px */
91
+ --pu-radius-full: 9999px; /* Fully rounded */
92
+ ```
93
+
94
+ ### Spacing
95
+
96
+ ```css
97
+ --pu-space-xs: 0.25rem; /* 4px */
98
+ --pu-space-sm: 0.5rem; /* 8px */
99
+ --pu-space-md: 1rem; /* 16px */
100
+ --pu-space-lg: 1.5rem; /* 24px */
101
+ --pu-space-xl: 2rem; /* 32px */
102
+ ```
103
+
104
+ ### Transitions
105
+
106
+ ```css
107
+ --pu-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
108
+ --pu-transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1);
109
+ --pu-transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
110
+ ```
111
+
112
+ ## Component Classes
113
+
114
+ Component classes are defined in `src/css/components.css` and provide ready-to-use styled components.
115
+
116
+ ### Buttons
117
+
118
+ Base class with size variants:
119
+
120
+ ```css
121
+ .pu-btn /* Base button styles */
122
+ .pu-btn-md /* Medium size (default) */
123
+ .pu-btn-sm /* Small size */
124
+ .pu-btn-xs /* Extra small size */
125
+ ```
126
+
127
+ Solid variants (with hover lift animation):
128
+
129
+ ```css
130
+ .pu-btn-primary /* Primary action */
131
+ .pu-btn-secondary /* Secondary action */
132
+ .pu-btn-danger /* Destructive action */
133
+ .pu-btn-success /* Success action */
134
+ .pu-btn-warning /* Warning action */
135
+ .pu-btn-info /* Informational action */
136
+ .pu-btn-accent /* Accent action */
137
+ ```
138
+
139
+ Other variants:
140
+
141
+ ```css
142
+ .pu-btn-ghost /* Minimal, text-like */
143
+ .pu-btn-outline /* Bordered, transparent background */
144
+ ```
145
+
146
+ Soft variants (tinted backgrounds for secondary contexts):
147
+
148
+ ```css
149
+ .pu-btn-soft-primary
150
+ .pu-btn-soft-danger
151
+ .pu-btn-soft-success
152
+ .pu-btn-soft-warning
153
+ .pu-btn-soft-info
154
+ .pu-btn-soft-secondary
155
+ .pu-btn-soft-accent
156
+ ```
157
+
158
+ Usage:
159
+
160
+ ```erb
161
+ <%= form.submit "Save", class: "pu-btn pu-btn-md pu-btn-primary" %>
162
+ <%= form.submit "Delete", class: "pu-btn pu-btn-md pu-btn-danger" %>
163
+ <%= form.submit "Disable", class: "pu-btn pu-btn-md pu-btn-warning" %>
164
+ ```
165
+
166
+ ### Form Inputs
167
+
168
+ ```css
169
+ .pu-input /* Base input styles */
170
+ .pu-input-invalid /* Error state */
171
+ .pu-input-valid /* Valid state */
172
+ ```
173
+
174
+ Usage:
175
+
176
+ ```erb
177
+ <%= form.text_field :name, class: "pu-input #{errors? ? 'pu-input-invalid' : ''}" %>
178
+ ```
179
+
180
+ ### Labels & Text
181
+
182
+ ```css
183
+ .pu-label /* Form labels */
184
+ .pu-label-required /* Adds red asterisk after label */
185
+ .pu-hint /* Helper text below inputs */
186
+ .pu-error /* Error messages */
187
+ ```
188
+
189
+ Usage:
190
+
191
+ ```erb
192
+ <%= form.label :email, class: "pu-label" %>
193
+ <span class="pu-error">Email is required</span>
194
+ ```
195
+
196
+ ### Checkboxes
197
+
198
+ ```css
199
+ .pu-checkbox /* Styled checkbox/radio */
200
+ ```
201
+
202
+ Usage:
203
+
204
+ ```erb
205
+ <%= form.check_box :remember_me, class: "pu-checkbox" %>
206
+ ```
207
+
208
+ ### Cards
209
+
210
+ ```css
211
+ .pu-card /* Card container with border, shadow, radius */
212
+ .pu-card-body /* Card content padding */
213
+ ```
214
+
215
+ ### Panels
216
+
217
+ ```css
218
+ .pu-panel-header /* Panel header with background */
219
+ .pu-panel-title /* Panel title text */
220
+ .pu-panel-description /* Panel description text */
221
+ ```
222
+
223
+ ### Tables
224
+
225
+ ```css
226
+ .pu-table-wrapper /* Scrollable container with card styling */
227
+ .pu-table /* Base table styles */
228
+ .pu-table-header /* Header row */
229
+ .pu-table-header-cell /* Header cell */
230
+ .pu-table-body-row /* Body row with hover */
231
+ .pu-table-body-row-selected /* Selected row */
232
+ .pu-table-body-cell /* Body cell */
233
+ .pu-selection-cell /* Checkbox column */
234
+ ```
235
+
236
+ ### Toolbar
237
+
238
+ ```css
239
+ .pu-toolbar /* Toolbar container with gradient */
240
+ .pu-toolbar-text /* Toolbar text */
241
+ .pu-toolbar-actions /* Toolbar action buttons */
242
+ ```
243
+
244
+ ### Empty State
245
+
246
+ ```css
247
+ .pu-empty-state /* Centered container */
248
+ .pu-empty-state-icon /* Icon styling */
249
+ .pu-empty-state-title /* Title text */
250
+ .pu-empty-state-description /* Description text */
251
+ ```
252
+
253
+ ## Ruby Component Classes
254
+
255
+ The `Plutonium::UI::ComponentClasses` module provides Ruby constants for consistent class usage.
256
+
257
+ Location: `lib/plutonium/ui/component_classes.rb`
258
+
259
+ ### Button Classes
260
+
261
+ ```ruby
262
+ ComponentClasses::Button::BASE # "pu-btn"
263
+ ComponentClasses::Button::SIZE_DEFAULT # "pu-btn-md"
264
+ ComponentClasses::Button::SIZE_SM # "pu-btn-sm"
265
+ ComponentClasses::Button::SIZE_XS # "pu-btn-xs"
266
+
267
+ ComponentClasses::Button::VARIANTS[:primary] # "pu-btn-primary"
268
+ ComponentClasses::Button::VARIANTS[:danger] # "pu-btn-danger"
269
+ ComponentClasses::Button::SOFT_VARIANTS[:primary] # "pu-btn-soft-primary"
270
+
271
+ # Helper method
272
+ ComponentClasses::Button.classes(variant: :primary, size: :default, soft: false)
273
+ # => "pu-btn pu-btn-md pu-btn-primary"
274
+ ```
275
+
276
+ ### Form Classes
277
+
278
+ ```ruby
279
+ ComponentClasses::Form::INPUT # "pu-input"
280
+ ComponentClasses::Form::INPUT_INVALID # "pu-input pu-input-invalid"
281
+ ComponentClasses::Form::INPUT_VALID # "pu-input pu-input-valid"
282
+ ComponentClasses::Form::LABEL # "pu-label"
283
+ ComponentClasses::Form::HINT # "pu-hint"
284
+ ComponentClasses::Form::ERROR # "pu-error"
285
+ ComponentClasses::Form::BUTTON # "pu-btn pu-btn-md pu-btn-primary"
286
+ ```
287
+
288
+ ### Table Classes
289
+
290
+ ```ruby
291
+ ComponentClasses::Table::WRAPPER # "pu-table-wrapper"
292
+ ComponentClasses::Table::BASE # "pu-table"
293
+ ComponentClasses::Table::HEADER # "pu-table-header"
294
+ ComponentClasses::Table::HEADER_CELL # "pu-table-header-cell"
295
+ ComponentClasses::Table::BODY_ROW # "pu-table-body-row"
296
+ ComponentClasses::Table::BODY_ROW_SELECTED # "pu-table-body-row-selected"
297
+ ComponentClasses::Table::BODY_CELL # "pu-table-body-cell"
298
+ ComponentClasses::Table::CHECKBOX # "pu-checkbox"
299
+ ```
300
+
301
+ ### Card Classes
302
+
303
+ ```ruby
304
+ ComponentClasses::Card::BASE # "pu-card"
305
+ ComponentClasses::Card::BODY # "pu-card-body"
306
+ ComponentClasses::Card::HEADER # "pu-panel-header"
307
+ ComponentClasses::Card::TITLE # "pu-panel-title"
308
+ ComponentClasses::Card::DESCRIPTION # "pu-panel-description"
309
+ ```
310
+
311
+ ## Using Tokens in Templates
312
+
313
+ ### ERB Templates
314
+
315
+ ```erb
316
+ <%# Text colors %>
317
+ <h1 class="text-[var(--pu-text)]">Title</h1>
318
+ <p class="text-[var(--pu-text-muted)]">Description</p>
319
+
320
+ <%# Surfaces %>
321
+ <div class="bg-[var(--pu-surface)] border border-[var(--pu-border)] rounded-[var(--pu-radius-lg)]">
322
+ Content
323
+ </div>
324
+
325
+ <%# With shadows %>
326
+ <div class="bg-[var(--pu-card-bg)]" style="box-shadow: var(--pu-shadow-md)">
327
+ Card content
328
+ </div>
329
+
330
+ <%# Form fields %>
331
+ <%= form.label :name, class: "pu-label" %>
332
+ <%= form.text_field :name, class: "pu-input" %>
333
+ <span class="pu-error">Error message</span>
334
+
335
+ <%# Buttons %>
336
+ <%= form.submit "Save", class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
337
+ ```
338
+
339
+ ### Phlex Components
340
+
341
+ ```ruby
342
+ class MyComponent < Plutonium::UI::Component::Base
343
+ def view_template
344
+ div(class: "bg-[var(--pu-surface)] border border-[var(--pu-border)] rounded-[var(--pu-radius-lg)]",
345
+ style: "box-shadow: var(--pu-shadow-md)") {
346
+ h2(class: "text-lg font-semibold text-[var(--pu-text)]") { "Title" }
347
+ p(class: "text-[var(--pu-text-muted)]") { "Description" }
348
+ }
349
+ end
350
+ end
351
+ ```
352
+
353
+ ## Link Styling Patterns
354
+
355
+ Plutonium uses consistent link styling patterns:
356
+
357
+ ```erb
358
+ <%# Primary links %>
359
+ <%= link_to "Link", path, class: "font-medium text-secondary-600 dark:text-secondary-400 hover:underline transition-colors" %>
360
+
361
+ <%# Muted links %>
362
+ <%= link_to "Link", path, class: "text-[var(--pu-text-muted)] hover:text-primary-600 transition-colors" %>
363
+ ```
364
+
365
+ ## Dark Mode
366
+
367
+ All tokens automatically switch values when the `.dark` class is present on `<html>`:
368
+
369
+ ```html
370
+ <!-- Light mode -->
371
+ <html>
372
+ <body class="bg-[var(--pu-body)]">...</body>
373
+ </html>
374
+
375
+ <!-- Dark mode -->
376
+ <html class="dark">
377
+ <body class="bg-[var(--pu-body)]">...</body>
378
+ </html>
379
+ ```
380
+
381
+ No additional classes needed - tokens handle the switch automatically.
382
+
383
+ ## Customizing Tokens
384
+
385
+ Override tokens in your application CSS:
386
+
387
+ ```css
388
+ /* app/assets/stylesheets/application.tailwind.css */
389
+ @import "gem:plutonium/src/css/plutonium.css";
390
+ @import "tailwindcss";
391
+
392
+ :root {
393
+ /* Override light mode tokens */
394
+ --pu-surface: #fafafa;
395
+ --pu-border: #d1d5db;
396
+ }
397
+
398
+ .dark {
399
+ /* Override dark mode tokens */
400
+ --pu-surface: #111827;
401
+ --pu-border: #374151;
402
+ }
403
+ ```
404
+
405
+ ## Migration from Hardcoded Classes
406
+
407
+ When updating views to use the design token system:
408
+
409
+ | Old Pattern | New Pattern |
410
+ |-------------|-------------|
411
+ | `text-gray-900 dark:text-white` | `text-[var(--pu-text)]` |
412
+ | `text-gray-500 dark:text-gray-400` | `text-[var(--pu-text-muted)]` |
413
+ | `bg-gray-50 dark:bg-gray-700` | `bg-[var(--pu-surface)]` |
414
+ | `border-gray-300 dark:border-gray-600` | `border-[var(--pu-border)]` |
415
+ | `bg-gray-50 border ... (long input class)` | `pu-input` |
416
+ | `block mb-2 text-sm font-semibold ...` | `pu-label` |
417
+ | `text-red-600 dark:text-red-400` | `pu-error` |
418
+ | `(long button class)` | `pu-btn pu-btn-md pu-btn-primary` |
419
+
420
+ ## Related Skills
421
+
422
+ - `plutonium-assets` - TailwindCSS configuration and asset setup
423
+ - `plutonium-forms` - Form component customization
424
+ - `plutonium-views` - View and layout customization
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: views
2
+ name: plutonium-views
3
3
  description: Customizing Plutonium views - pages, forms, displays, tables, and layouts using Phlex
4
4
  ---
5
5
 
@@ -555,9 +555,9 @@ end
555
555
 
556
556
  ## Related Skills
557
557
 
558
- - `forms` - Custom form templates and field builders
559
- - `assets` - TailwindCSS and component theming
560
- - `definition-fields` - Field/input/display configuration
561
- - `definition-actions` - Action buttons and interactions
562
- - `controller` - Presentation hooks (`present_parent?`, etc.)
563
- - `portal` - Portal-specific customization
558
+ - `plutonium-forms` - Custom form templates and field builders
559
+ - `plutonium-assets` - TailwindCSS and component theming
560
+ - `plutonium-definition-fields` - Field/input/display configuration
561
+ - `plutonium-definition-actions` - Action buttons and interactions
562
+ - `plutonium-controller` - Presentation hooks (`present_parent?`, etc.)
563
+ - `plutonium-portal` - Portal-specific customization