red64-cli 0.1.0 → 0.3.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.
- package/README.md +1 -2
- package/dist/cli/parseArgs.d.ts.map +1 -1
- package/dist/cli/parseArgs.js +5 -0
- package/dist/cli/parseArgs.js.map +1 -1
- package/dist/components/init/CompleteStep.d.ts.map +1 -1
- package/dist/components/init/CompleteStep.js +2 -2
- package/dist/components/init/CompleteStep.js.map +1 -1
- package/dist/components/init/TestCheckStep.d.ts +16 -0
- package/dist/components/init/TestCheckStep.d.ts.map +1 -0
- package/dist/components/init/TestCheckStep.js +120 -0
- package/dist/components/init/TestCheckStep.js.map +1 -0
- package/dist/components/init/index.d.ts +1 -0
- package/dist/components/init/index.d.ts.map +1 -1
- package/dist/components/init/index.js +1 -0
- package/dist/components/init/index.js.map +1 -1
- package/dist/components/init/types.d.ts +9 -0
- package/dist/components/init/types.d.ts.map +1 -1
- package/dist/components/screens/InitScreen.d.ts.map +1 -1
- package/dist/components/screens/InitScreen.js +69 -6
- package/dist/components/screens/InitScreen.js.map +1 -1
- package/dist/components/screens/ListScreen.d.ts.map +1 -1
- package/dist/components/screens/ListScreen.js +28 -3
- package/dist/components/screens/ListScreen.js.map +1 -1
- package/dist/components/screens/StartScreen.d.ts.map +1 -1
- package/dist/components/screens/StartScreen.js +212 -13
- package/dist/components/screens/StartScreen.js.map +1 -1
- package/dist/components/ui/ArtifactsSidebar.d.ts +19 -0
- package/dist/components/ui/ArtifactsSidebar.d.ts.map +1 -0
- package/dist/components/ui/ArtifactsSidebar.js +51 -0
- package/dist/components/ui/ArtifactsSidebar.js.map +1 -0
- package/dist/components/ui/FeatureSidebar.d.ts.map +1 -1
- package/dist/components/ui/FeatureSidebar.js +1 -1
- package/dist/components/ui/FeatureSidebar.js.map +1 -1
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/services/ClaudeErrorDetector.js +3 -3
- package/dist/services/ClaudeErrorDetector.js.map +1 -1
- package/dist/services/ConfigService.d.ts +1 -0
- package/dist/services/ConfigService.d.ts.map +1 -1
- package/dist/services/ConfigService.js.map +1 -1
- package/dist/services/ProjectDetector.d.ts +28 -0
- package/dist/services/ProjectDetector.d.ts.map +1 -0
- package/dist/services/ProjectDetector.js +236 -0
- package/dist/services/ProjectDetector.js.map +1 -0
- package/dist/services/TestRunner.d.ts +46 -0
- package/dist/services/TestRunner.d.ts.map +1 -0
- package/dist/services/TestRunner.js +85 -0
- package/dist/services/TestRunner.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -1
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/framework/.red64/settings/templates/specs/gap-analysis.md +163 -0
- package/framework/agents/claude/.claude/agents/red64/spec-impl.md +131 -2
- package/framework/agents/claude/.claude/agents/red64/validate-gap.md +13 -7
- package/framework/agents/claude/.claude/commands/red64/spec-impl.md +24 -0
- package/framework/agents/claude/.claude/commands/red64/validate-gap.md +4 -0
- package/framework/agents/codex/.codex/agents/red64/spec-impl.md +131 -2
- package/framework/agents/codex/.codex/agents/red64/validate-gap.md +13 -7
- package/framework/agents/codex/.codex/commands/red64/spec-impl.md +24 -0
- package/framework/agents/codex/.codex/commands/red64/validate-gap.md +4 -0
- package/framework/stacks/generic/feedback.md +80 -0
- package/framework/stacks/nextjs/accessibility.md +437 -0
- package/framework/stacks/nextjs/api.md +431 -0
- package/framework/stacks/nextjs/coding-style.md +282 -0
- package/framework/stacks/nextjs/commenting.md +226 -0
- package/framework/stacks/nextjs/components.md +411 -0
- package/framework/stacks/nextjs/conventions.md +333 -0
- package/framework/stacks/nextjs/css.md +310 -0
- package/framework/stacks/nextjs/error-handling.md +442 -0
- package/framework/stacks/nextjs/feedback.md +124 -0
- package/framework/stacks/nextjs/migrations.md +332 -0
- package/framework/stacks/nextjs/models.md +362 -0
- package/framework/stacks/nextjs/queries.md +410 -0
- package/framework/stacks/nextjs/responsive.md +338 -0
- package/framework/stacks/nextjs/tech-stack.md +177 -0
- package/framework/stacks/nextjs/test-writing.md +475 -0
- package/framework/stacks/nextjs/validation.md +467 -0
- package/framework/stacks/python/api.md +468 -0
- package/framework/stacks/python/authentication.md +342 -0
- package/framework/stacks/python/code-quality.md +283 -0
- package/framework/stacks/python/code-refactoring.md +315 -0
- package/framework/stacks/python/coding-style.md +462 -0
- package/framework/stacks/python/conventions.md +399 -0
- package/framework/stacks/python/error-handling.md +512 -0
- package/framework/stacks/python/feedback.md +92 -0
- package/framework/stacks/python/implement-ai-llm.md +468 -0
- package/framework/stacks/python/migrations.md +388 -0
- package/framework/stacks/python/models.md +399 -0
- package/framework/stacks/python/python.md +232 -0
- package/framework/stacks/python/queries.md +451 -0
- package/framework/stacks/python/structure.md +245 -58
- package/framework/stacks/python/tech.md +92 -35
- package/framework/stacks/python/testing.md +380 -0
- package/framework/stacks/python/validation.md +471 -0
- package/framework/stacks/rails/authentication.md +176 -0
- package/framework/stacks/rails/code-quality.md +287 -0
- package/framework/stacks/rails/code-refactoring.md +299 -0
- package/framework/stacks/rails/feedback.md +130 -0
- package/framework/stacks/rails/implement-ai-llm-with-rubyllm.md +342 -0
- package/framework/stacks/rails/rails.md +301 -0
- package/framework/stacks/rails/rails8-best-practices.md +498 -0
- package/framework/stacks/rails/rails8-css.md +573 -0
- package/framework/stacks/rails/structure.md +140 -0
- package/framework/stacks/rails/tech.md +108 -0
- package/framework/stacks/react/code-quality.md +521 -0
- package/framework/stacks/react/components.md +625 -0
- package/framework/stacks/react/data-fetching.md +586 -0
- package/framework/stacks/react/feedback.md +110 -0
- package/framework/stacks/react/forms.md +694 -0
- package/framework/stacks/react/performance.md +640 -0
- package/framework/stacks/react/product.md +22 -9
- package/framework/stacks/react/state-management.md +472 -0
- package/framework/stacks/react/structure.md +351 -44
- package/framework/stacks/react/tech.md +219 -30
- package/framework/stacks/react/testing.md +690 -0
- package/package.json +1 -1
- package/framework/stacks/node/product.md +0 -27
- package/framework/stacks/node/structure.md +0 -82
- package/framework/stacks/node/tech.md +0 -63
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
# Rails 8 CSS Organization & Refactoring Rules
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
1. **Component-First Architecture**: Organize CSS around UI components, not pages
|
|
6
|
+
2. **Maintainability**: Prefer clarity and organization over brevity
|
|
7
|
+
3. **Performance**: Minimize CSS size and optimize for critical rendering path
|
|
8
|
+
4. **Consistency**: Follow established patterns throughout the codebase
|
|
9
|
+
5. **Rails 8 Native**: Leverage Propshaft and modern CSS features
|
|
10
|
+
|
|
11
|
+
## File Structure
|
|
12
|
+
|
|
13
|
+
### Recommended Directory Organization
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
app/assets/stylesheets/
|
|
17
|
+
├── application.css # Main manifest file
|
|
18
|
+
├── base/
|
|
19
|
+
│ ├── reset.css # CSS reset/normalize
|
|
20
|
+
│ ├── typography.css # Font definitions, base typography
|
|
21
|
+
│ ├── variables.css # CSS custom properties (colors, spacing, etc.)
|
|
22
|
+
│ └── utilities.css # Utility classes
|
|
23
|
+
├── layouts/
|
|
24
|
+
│ ├── header.css # Site header styles
|
|
25
|
+
│ ├── footer.css # Site footer styles
|
|
26
|
+
│ ├── sidebar.css # Sidebar styles
|
|
27
|
+
│ └── grid.css # Layout grid systems
|
|
28
|
+
├── components/
|
|
29
|
+
│ ├── buttons.css # Button styles
|
|
30
|
+
│ ├── forms.css # Form elements
|
|
31
|
+
│ ├── cards.css # Card components
|
|
32
|
+
│ ├── modals.css # Modal dialogs
|
|
33
|
+
│ ├── tables.css # Table styles
|
|
34
|
+
│ └── navigation.css # Navigation menus
|
|
35
|
+
├── pages/
|
|
36
|
+
│ ├── home.css # Home page specific styles
|
|
37
|
+
│ ├── dashboard.css # Dashboard specific styles
|
|
38
|
+
│ └── profile.css # Profile page specific styles
|
|
39
|
+
└── vendor/
|
|
40
|
+
└── overrides.css # Third-party library overrides
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Naming Conventions
|
|
44
|
+
|
|
45
|
+
### BEM (Block Element Modifier) - Recommended
|
|
46
|
+
|
|
47
|
+
Use BEM for component-based CSS:
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
/* Block */
|
|
51
|
+
.card { }
|
|
52
|
+
|
|
53
|
+
/* Element */
|
|
54
|
+
.card__header { }
|
|
55
|
+
.card__body { }
|
|
56
|
+
.card__footer { }
|
|
57
|
+
|
|
58
|
+
/* Modifier */
|
|
59
|
+
.card--featured { }
|
|
60
|
+
.card--compact { }
|
|
61
|
+
.card__header--dark { }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Naming Rules
|
|
65
|
+
|
|
66
|
+
1. **Use lowercase with hyphens**: `.user-profile`, not `.userProfile` or `.UserProfile`
|
|
67
|
+
2. **Be descriptive**: `.btn-primary` over `.btn-1`
|
|
68
|
+
3. **Avoid presentational names**: `.alert-danger` over `.red-box`
|
|
69
|
+
4. **Namespace JavaScript hooks**: Use `js-` prefix for JS selectors (`.js-dropdown-toggle`)
|
|
70
|
+
5. **Avoid IDs for styling**: Use classes instead
|
|
71
|
+
|
|
72
|
+
## CSS Custom Properties (Variables)
|
|
73
|
+
|
|
74
|
+
### Define in base/variables.css
|
|
75
|
+
|
|
76
|
+
```css
|
|
77
|
+
:root {
|
|
78
|
+
/* Colors - Semantic naming */
|
|
79
|
+
--color-primary: #007bff;
|
|
80
|
+
--color-secondary: #6c757d;
|
|
81
|
+
--color-success: #28a745;
|
|
82
|
+
--color-danger: #dc3545;
|
|
83
|
+
--color-warning: #ffc107;
|
|
84
|
+
--color-info: #17a2b8;
|
|
85
|
+
|
|
86
|
+
/* Neutral colors */
|
|
87
|
+
--color-gray-100: #f8f9fa;
|
|
88
|
+
--color-gray-200: #e9ecef;
|
|
89
|
+
--color-gray-900: #212529;
|
|
90
|
+
|
|
91
|
+
/* Spacing scale (4px base) */
|
|
92
|
+
--space-1: 0.25rem; /* 4px */
|
|
93
|
+
--space-2: 0.5rem; /* 8px */
|
|
94
|
+
--space-3: 0.75rem; /* 12px */
|
|
95
|
+
--space-4: 1rem; /* 16px */
|
|
96
|
+
--space-6: 1.5rem; /* 24px */
|
|
97
|
+
--space-8: 2rem; /* 32px */
|
|
98
|
+
|
|
99
|
+
/* Typography */
|
|
100
|
+
--font-family-base: system-ui, -apple-system, sans-serif;
|
|
101
|
+
--font-family-mono: 'Courier New', monospace;
|
|
102
|
+
--font-size-sm: 0.875rem;
|
|
103
|
+
--font-size-base: 1rem;
|
|
104
|
+
--font-size-lg: 1.125rem;
|
|
105
|
+
--line-height-base: 1.5;
|
|
106
|
+
|
|
107
|
+
/* Borders */
|
|
108
|
+
--border-radius-sm: 0.25rem;
|
|
109
|
+
--border-radius-base: 0.375rem;
|
|
110
|
+
--border-radius-lg: 0.5rem;
|
|
111
|
+
--border-width: 1px;
|
|
112
|
+
|
|
113
|
+
/* Shadows */
|
|
114
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
115
|
+
--shadow-base: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
116
|
+
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
|
117
|
+
|
|
118
|
+
/* Transitions */
|
|
119
|
+
--transition-fast: 150ms ease-in-out;
|
|
120
|
+
--transition-base: 250ms ease-in-out;
|
|
121
|
+
--transition-slow: 350ms ease-in-out;
|
|
122
|
+
|
|
123
|
+
/* Z-index scale */
|
|
124
|
+
--z-dropdown: 1000;
|
|
125
|
+
--z-sticky: 1020;
|
|
126
|
+
--z-fixed: 1030;
|
|
127
|
+
--z-modal-backdrop: 1040;
|
|
128
|
+
--z-modal: 1050;
|
|
129
|
+
--z-popover: 1060;
|
|
130
|
+
--z-tooltip: 1070;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Component Structure
|
|
135
|
+
|
|
136
|
+
### Template for New Components
|
|
137
|
+
|
|
138
|
+
```css
|
|
139
|
+
/* ============================================
|
|
140
|
+
Component: Button
|
|
141
|
+
Description: Button styles for all button types
|
|
142
|
+
============================================ */
|
|
143
|
+
|
|
144
|
+
/* Base button styles */
|
|
145
|
+
.btn {
|
|
146
|
+
display: inline-block;
|
|
147
|
+
padding: var(--space-2) var(--space-4);
|
|
148
|
+
font-family: var(--font-family-base);
|
|
149
|
+
font-size: var(--font-size-base);
|
|
150
|
+
line-height: var(--line-height-base);
|
|
151
|
+
text-align: center;
|
|
152
|
+
text-decoration: none;
|
|
153
|
+
border: var(--border-width) solid transparent;
|
|
154
|
+
border-radius: var(--border-radius-base);
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
transition: all var(--transition-fast);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Button variants */
|
|
160
|
+
.btn--primary {
|
|
161
|
+
background-color: var(--color-primary);
|
|
162
|
+
color: white;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.btn--primary:hover {
|
|
166
|
+
background-color: color-mix(in srgb, var(--color-primary) 85%, black);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Button sizes */
|
|
170
|
+
.btn--sm {
|
|
171
|
+
padding: var(--space-1) var(--space-3);
|
|
172
|
+
font-size: var(--font-size-sm);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.btn--lg {
|
|
176
|
+
padding: var(--space-3) var(--space-6);
|
|
177
|
+
font-size: var(--font-size-lg);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Button states */
|
|
181
|
+
.btn:disabled,
|
|
182
|
+
.btn--disabled {
|
|
183
|
+
opacity: 0.65;
|
|
184
|
+
cursor: not-allowed;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Refactoring Strategy
|
|
189
|
+
|
|
190
|
+
### Step 1: Audit & Categorize
|
|
191
|
+
|
|
192
|
+
Before refactoring, categorize existing CSS:
|
|
193
|
+
1. **Base styles**: Resets, typography, global styles → `base/`
|
|
194
|
+
2. **Layout styles**: Headers, footers, grids → `layouts/`
|
|
195
|
+
3. **Component styles**: Buttons, forms, cards → `components/`
|
|
196
|
+
4. **Page-specific styles**: Unique to one page → `pages/`
|
|
197
|
+
5. **Utility classes**: Single-purpose helpers → `base/utilities.css`
|
|
198
|
+
|
|
199
|
+
### Step 2: Extract Components
|
|
200
|
+
|
|
201
|
+
Identify repeated patterns and extract into components:
|
|
202
|
+
|
|
203
|
+
```css
|
|
204
|
+
/* BEFORE: Repeated styles */
|
|
205
|
+
.user-card { padding: 16px; border-radius: 8px; }
|
|
206
|
+
.product-card { padding: 16px; border-radius: 8px; }
|
|
207
|
+
.article-card { padding: 16px; border-radius: 8px; }
|
|
208
|
+
|
|
209
|
+
/* AFTER: Component + modifiers */
|
|
210
|
+
.card {
|
|
211
|
+
padding: var(--space-4);
|
|
212
|
+
border-radius: var(--border-radius-lg);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.card--user { /* user-specific styles */ }
|
|
216
|
+
.card--product { /* product-specific styles */ }
|
|
217
|
+
.card--article { /* article-specific styles */ }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Step 3: Eliminate Duplication
|
|
221
|
+
|
|
222
|
+
Use CSS custom properties and shared classes:
|
|
223
|
+
|
|
224
|
+
```css
|
|
225
|
+
/* BEFORE: Duplicated values */
|
|
226
|
+
.header { background: #007bff; }
|
|
227
|
+
.button-primary { background: #007bff; }
|
|
228
|
+
.link-primary { color: #007bff; }
|
|
229
|
+
|
|
230
|
+
/* AFTER: CSS variables */
|
|
231
|
+
:root { --color-primary: #007bff; }
|
|
232
|
+
.header { background: var(--color-primary); }
|
|
233
|
+
.button-primary { background: var(--color-primary); }
|
|
234
|
+
.link-primary { color: var(--color-primary); }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Step 4: Simplify Selectors
|
|
238
|
+
|
|
239
|
+
Replace overly specific selectors:
|
|
240
|
+
|
|
241
|
+
```css
|
|
242
|
+
/* BEFORE: Too specific */
|
|
243
|
+
div.container ul.list li.item a.link { color: blue; }
|
|
244
|
+
|
|
245
|
+
/* AFTER: Simpler, more maintainable */
|
|
246
|
+
.list__link { color: var(--color-primary); }
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Step 5: Remove Dead Code
|
|
250
|
+
|
|
251
|
+
1. Search for unused classes in views
|
|
252
|
+
2. Use tools like PurgeCSS or look for classes not in `app/views/**/*`
|
|
253
|
+
3. Comment out suspicious code first, then remove after testing
|
|
254
|
+
|
|
255
|
+
## Rails 8 Specific Guidelines
|
|
256
|
+
|
|
257
|
+
### Application.css Manifest
|
|
258
|
+
|
|
259
|
+
Use `@import` or native CSS imports (not Sprockets directives):
|
|
260
|
+
|
|
261
|
+
```css
|
|
262
|
+
/* app/assets/stylesheets/application.css */
|
|
263
|
+
|
|
264
|
+
/* Base styles - load first */
|
|
265
|
+
@import "base/variables.css";
|
|
266
|
+
@import "base/reset.css";
|
|
267
|
+
@import "base/typography.css";
|
|
268
|
+
@import "base/utilities.css";
|
|
269
|
+
|
|
270
|
+
/* Layout styles */
|
|
271
|
+
@import "layouts/header.css";
|
|
272
|
+
@import "layouts/footer.css";
|
|
273
|
+
@import "layouts/grid.css";
|
|
274
|
+
|
|
275
|
+
/* Component styles */
|
|
276
|
+
@import "components/buttons.css";
|
|
277
|
+
@import "components/forms.css";
|
|
278
|
+
@import "components/cards.css";
|
|
279
|
+
@import "components/modals.css";
|
|
280
|
+
|
|
281
|
+
/* Page-specific styles */
|
|
282
|
+
@import "pages/home.css";
|
|
283
|
+
@import "pages/dashboard.css";
|
|
284
|
+
|
|
285
|
+
/* Vendor overrides - load last */
|
|
286
|
+
@import "vendor/overrides.css";
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Propshaft Optimization
|
|
290
|
+
|
|
291
|
+
1. Keep files modular for better caching
|
|
292
|
+
2. Use meaningful filenames (Propshaft uses content hashing)
|
|
293
|
+
3. Consider critical CSS extraction for above-the-fold content
|
|
294
|
+
|
|
295
|
+
### Turbo Compatibility
|
|
296
|
+
|
|
297
|
+
Ensure CSS works with Turbo's page transitions:
|
|
298
|
+
|
|
299
|
+
```css
|
|
300
|
+
/* Avoid body classes for page-specific styles */
|
|
301
|
+
/* AVOID: body.dashboard .widget { } */
|
|
302
|
+
|
|
303
|
+
/* PREFER: Scoped classes */
|
|
304
|
+
.dashboard-widget { }
|
|
305
|
+
|
|
306
|
+
/* Or use data attributes on body */
|
|
307
|
+
body[data-controller="dashboards"] .widget { }
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Modern CSS Features to Leverage
|
|
311
|
+
|
|
312
|
+
### Container Queries
|
|
313
|
+
|
|
314
|
+
```css
|
|
315
|
+
.card {
|
|
316
|
+
container-type: inline-size;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@container (min-width: 400px) {
|
|
320
|
+
.card__content {
|
|
321
|
+
display: grid;
|
|
322
|
+
grid-template-columns: 1fr 1fr;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Cascade Layers
|
|
328
|
+
|
|
329
|
+
Organize specificity explicitly:
|
|
330
|
+
|
|
331
|
+
```css
|
|
332
|
+
@layer base, components, utilities, overrides;
|
|
333
|
+
|
|
334
|
+
@layer base {
|
|
335
|
+
/* Base styles */
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
@layer components {
|
|
339
|
+
/* Component styles */
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
@layer utilities {
|
|
343
|
+
/* Utility classes */
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@layer overrides {
|
|
347
|
+
/* High-priority overrides */
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Color Functions
|
|
352
|
+
|
|
353
|
+
```css
|
|
354
|
+
.btn--primary {
|
|
355
|
+
background: var(--color-primary);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.btn--primary:hover {
|
|
359
|
+
/* Darken by mixing with black */
|
|
360
|
+
background: color-mix(in srgb, var(--color-primary) 85%, black);
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Logical Properties
|
|
365
|
+
|
|
366
|
+
Use logical properties for better i18n support:
|
|
367
|
+
|
|
368
|
+
```css
|
|
369
|
+
/* BEFORE: Physical properties */
|
|
370
|
+
.card { margin-left: 1rem; padding-right: 2rem; }
|
|
371
|
+
|
|
372
|
+
/* AFTER: Logical properties */
|
|
373
|
+
.card { margin-inline-start: 1rem; padding-inline-end: 2rem; }
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Utility Classes
|
|
377
|
+
|
|
378
|
+
Keep utilities minimal and semantic:
|
|
379
|
+
|
|
380
|
+
```css
|
|
381
|
+
/* Layout utilities */
|
|
382
|
+
.flex { display: flex; }
|
|
383
|
+
.grid { display: grid; }
|
|
384
|
+
.block { display: block; }
|
|
385
|
+
.hidden { display: none; }
|
|
386
|
+
|
|
387
|
+
/* Spacing utilities - use custom properties */
|
|
388
|
+
.mt-4 { margin-top: var(--space-4); }
|
|
389
|
+
.p-6 { padding: var(--space-6); }
|
|
390
|
+
|
|
391
|
+
/* Text utilities */
|
|
392
|
+
.text-center { text-align: center; }
|
|
393
|
+
.text-sm { font-size: var(--font-size-sm); }
|
|
394
|
+
.font-bold { font-weight: 700; }
|
|
395
|
+
|
|
396
|
+
/* Color utilities */
|
|
397
|
+
.text-primary { color: var(--color-primary); }
|
|
398
|
+
.bg-gray-100 { background-color: var(--color-gray-100); }
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Performance Best Practices
|
|
402
|
+
|
|
403
|
+
1. **Minimize nesting**: Keep selector depth ≤ 3 levels
|
|
404
|
+
2. **Avoid expensive properties**: Be cautious with `box-shadow`, `border-radius` on large elements
|
|
405
|
+
3. **Use `will-change` sparingly**: Only for animated elements
|
|
406
|
+
4. **Prefer `transform` and `opacity`**: For animations (GPU accelerated)
|
|
407
|
+
5. **Remove unused CSS**: Regularly audit and remove dead code
|
|
408
|
+
|
|
409
|
+
## Responsive Design
|
|
410
|
+
|
|
411
|
+
Use mobile-first approach with custom breakpoints:
|
|
412
|
+
|
|
413
|
+
```css
|
|
414
|
+
:root {
|
|
415
|
+
--breakpoint-sm: 640px;
|
|
416
|
+
--breakpoint-md: 768px;
|
|
417
|
+
--breakpoint-lg: 1024px;
|
|
418
|
+
--breakpoint-xl: 1280px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* Mobile first - base styles apply to all sizes */
|
|
422
|
+
.container {
|
|
423
|
+
padding: var(--space-4);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* Tablet and up */
|
|
427
|
+
@media (min-width: 768px) {
|
|
428
|
+
.container {
|
|
429
|
+
padding: var(--space-6);
|
|
430
|
+
max-width: 768px;
|
|
431
|
+
margin-inline: auto;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Desktop and up */
|
|
436
|
+
@media (min-width: 1024px) {
|
|
437
|
+
.container {
|
|
438
|
+
max-width: 1024px;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## Accessibility
|
|
444
|
+
|
|
445
|
+
Ensure CSS supports accessibility:
|
|
446
|
+
|
|
447
|
+
```css
|
|
448
|
+
/* Focus states - always visible */
|
|
449
|
+
.btn:focus-visible {
|
|
450
|
+
outline: 2px solid var(--color-primary);
|
|
451
|
+
outline-offset: 2px;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* Don't remove outlines without replacement */
|
|
455
|
+
/* NEVER: * { outline: none; } */
|
|
456
|
+
|
|
457
|
+
/* Ensure sufficient color contrast */
|
|
458
|
+
.text-muted {
|
|
459
|
+
color: var(--color-gray-600); /* Ensure 4.5:1 contrast ratio */
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* Respect reduced motion preferences */
|
|
463
|
+
@media (prefers-reduced-motion: reduce) {
|
|
464
|
+
* {
|
|
465
|
+
animation-duration: 0.01ms !important;
|
|
466
|
+
animation-iteration-count: 1 !important;
|
|
467
|
+
transition-duration: 0.01ms !important;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* High contrast mode support */
|
|
472
|
+
@media (prefers-contrast: high) {
|
|
473
|
+
.btn {
|
|
474
|
+
border-width: 2px;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Documentation
|
|
480
|
+
|
|
481
|
+
### Component Documentation Template
|
|
482
|
+
|
|
483
|
+
Add comments at the top of each component file:
|
|
484
|
+
|
|
485
|
+
```css
|
|
486
|
+
/**
|
|
487
|
+
* Component: Card
|
|
488
|
+
*
|
|
489
|
+
* Description: Flexible container component used throughout the application
|
|
490
|
+
*
|
|
491
|
+
* Usage:
|
|
492
|
+
* <div class="card card--elevated">
|
|
493
|
+
* <div class="card__header">Title</div>
|
|
494
|
+
* <div class="card__body">Content</div>
|
|
495
|
+
* <div class="card__footer">Footer</div>
|
|
496
|
+
* </div>
|
|
497
|
+
*
|
|
498
|
+
* Modifiers:
|
|
499
|
+
* --elevated: Adds shadow for elevated appearance
|
|
500
|
+
* --compact: Reduces padding for tighter layouts
|
|
501
|
+
* --bordered: Adds border instead of shadow
|
|
502
|
+
*
|
|
503
|
+
* Dependencies: base/variables.css
|
|
504
|
+
*/
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Anti-Patterns to Avoid
|
|
508
|
+
|
|
509
|
+
1. **❌ Inline styles in views**: Keep all styles in CSS files
|
|
510
|
+
2. **❌ !important overuse**: Indicates specificity problems
|
|
511
|
+
3. **❌ Magic numbers**: Use named variables instead of hardcoded values
|
|
512
|
+
4. **❌ Deep nesting**: Keep selectors shallow (max 3 levels)
|
|
513
|
+
5. **❌ Non-semantic class names**: `.red-text` → `.text-danger`
|
|
514
|
+
6. **❌ ID selectors**: Use classes instead
|
|
515
|
+
7. **❌ Element selectors in components**: `.card div` → `.card__content`
|
|
516
|
+
8. **❌ Mixing concerns**: Keep layout, component, and utility styles separate
|
|
517
|
+
|
|
518
|
+
## Code Review Checklist
|
|
519
|
+
|
|
520
|
+
When reviewing CSS changes:
|
|
521
|
+
|
|
522
|
+
- [ ] Uses CSS custom properties for values
|
|
523
|
+
- [ ] Follows established naming conventions (BEM)
|
|
524
|
+
- [ ] Component is in correct directory
|
|
525
|
+
- [ ] No duplication of existing styles
|
|
526
|
+
- [ ] Responsive design implemented (mobile-first)
|
|
527
|
+
- [ ] Accessibility considered (focus states, color contrast)
|
|
528
|
+
- [ ] Works with Turbo page transitions
|
|
529
|
+
- [ ] No overly specific selectors (depth ≤ 3)
|
|
530
|
+
- [ ] Comments added for complex logic
|
|
531
|
+
- [ ] Tested in multiple browsers
|
|
532
|
+
|
|
533
|
+
## Testing Strategy
|
|
534
|
+
|
|
535
|
+
1. **Visual regression testing**: Use tools like Percy or BackstopJS
|
|
536
|
+
2. **Browser testing**: Test in Chrome, Firefox, Safari, Edge
|
|
537
|
+
3. **Device testing**: Test on mobile, tablet, desktop
|
|
538
|
+
4. **Accessibility testing**: Use axe DevTools or WAVE
|
|
539
|
+
5. **Performance testing**: Monitor CSS file sizes and load times
|
|
540
|
+
|
|
541
|
+
## Maintenance
|
|
542
|
+
|
|
543
|
+
1. **Regular audits**: Monthly review for unused CSS
|
|
544
|
+
2. **Documentation updates**: Keep component docs current
|
|
545
|
+
3. **Design token updates**: Centralize changes in variables.css
|
|
546
|
+
4. **Performance monitoring**: Track CSS bundle size
|
|
547
|
+
5. **Team training**: Ensure all developers follow guidelines
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## Quick Reference Commands
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
# Find unused CSS classes (example grep)
|
|
555
|
+
grep -r "class-name" app/views
|
|
556
|
+
|
|
557
|
+
# Find all occurrences of a color value
|
|
558
|
+
grep -r "#007bff" app/assets/stylesheets
|
|
559
|
+
|
|
560
|
+
# Count lines in CSS files
|
|
561
|
+
find app/assets/stylesheets -name "*.css" -exec wc -l {} + | sort -n
|
|
562
|
+
|
|
563
|
+
# List all CSS files
|
|
564
|
+
find app/assets/stylesheets -name "*.css"
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
## Additional Resources
|
|
568
|
+
|
|
569
|
+
- MDN CSS Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS
|
|
570
|
+
- BEM Methodology: https://getbem.com/
|
|
571
|
+
- CSS Guidelines: https://cssguidelin.es/
|
|
572
|
+
- CUBE CSS: https://cube.fyi/
|
|
573
|
+
- Modern CSS Solutions: https://moderncss.dev/
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
## Organization Philosophy
|
|
4
|
+
|
|
5
|
+
Standard Rails conventions with domain-driven extensions. MVC architecture as foundation, with service objects and query objects added as complexity grows.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Directory Patterns
|
|
10
|
+
|
|
11
|
+
### Application Core (`app/`)
|
|
12
|
+
**Purpose**: All application code following Rails conventions
|
|
13
|
+
**Pattern**: Convention over configuration - file location implies behavior
|
|
14
|
+
|
|
15
|
+
| Directory | Purpose | Naming |
|
|
16
|
+
|-----------|---------|--------|
|
|
17
|
+
| `models/` | ActiveRecord models, data + associations | Singular, PascalCase (`Project`, `Source`) |
|
|
18
|
+
| `controllers/` | Request handling, thin actions | Plural + Controller (`ProjectsController`) |
|
|
19
|
+
| `views/` | ERB templates, Turbo Streams | Mirrors controller structure |
|
|
20
|
+
| `jobs/` | Background jobs (Solid Queue) | Descriptive + Job (`CollectContentJob`) |
|
|
21
|
+
| `mailers/` | Email delivery | Descriptive + Mailer (`NotificationMailer`) |
|
|
22
|
+
| `helpers/` | View helpers | Mirrors controller (`ProjectsHelper`) |
|
|
23
|
+
|
|
24
|
+
### JavaScript (`app/javascript/`)
|
|
25
|
+
**Purpose**: Stimulus controllers and application JavaScript
|
|
26
|
+
**Pattern**: Importmap-based ESM, no bundler
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
app/javascript/
|
|
30
|
+
application.js # Entry point, Turbo/Stimulus setup
|
|
31
|
+
controllers/
|
|
32
|
+
application.js # Stimulus application config
|
|
33
|
+
index.js # Controller registration
|
|
34
|
+
*_controller.js # Individual Stimulus controllers
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Extensible Patterns (Add as Needed)
|
|
38
|
+
|
|
39
|
+
**Services** (`app/services/`)
|
|
40
|
+
- Complex business logic spanning multiple models
|
|
41
|
+
- External service integrations (AI providers, Postiz)
|
|
42
|
+
- Named by action: `ContentGenerator`, `SourceCollector`, `IdeaAnalyzer`
|
|
43
|
+
|
|
44
|
+
**Queries** (`app/queries/`)
|
|
45
|
+
- Complex database queries beyond simple scopes
|
|
46
|
+
- Named by domain: `PublishedContentQuery`, `UserSourcesQuery`
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Naming Conventions
|
|
51
|
+
|
|
52
|
+
### Ruby
|
|
53
|
+
- **Models**: Singular, PascalCase (`Project`, `ContentVersion`)
|
|
54
|
+
- **Controllers**: Plural, PascalCase + Controller (`SourcesController`)
|
|
55
|
+
- **Tables**: Plural, snake_case (`projects`, `content_versions`)
|
|
56
|
+
- **Jobs**: Descriptive + Job (`GenerateIdeasJob`)
|
|
57
|
+
- **Services**: Action-oriented (`WorkflowExecutor`, `SourceImporter`)
|
|
58
|
+
|
|
59
|
+
### JavaScript
|
|
60
|
+
- **Stimulus Controllers**: kebab-case + `_controller.js` (`content-editor_controller.js`)
|
|
61
|
+
- **Controller names in HTML**: kebab-case (`data-controller="content-editor"`)
|
|
62
|
+
|
|
63
|
+
### Files
|
|
64
|
+
- **Ruby**: snake_case (`project_workflow.rb`)
|
|
65
|
+
- **Views**: snake_case, match action (`show.html.erb`, `_form.html.erb`)
|
|
66
|
+
- **Partials**: Prefixed with underscore (`_project_card.html.erb`)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Import Organization
|
|
71
|
+
|
|
72
|
+
### Ruby
|
|
73
|
+
```ruby
|
|
74
|
+
# Rails auto-loading handles most requires
|
|
75
|
+
# Explicit requires only for non-autoloaded code
|
|
76
|
+
|
|
77
|
+
# Service usage pattern
|
|
78
|
+
ContentGenerator.new(project: @project).call
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### JavaScript (Importmap)
|
|
82
|
+
```javascript
|
|
83
|
+
// Pinned dependencies from importmap.rb
|
|
84
|
+
import "@hotwired/turbo-rails"
|
|
85
|
+
import "controllers"
|
|
86
|
+
|
|
87
|
+
// Relative imports within app/javascript/
|
|
88
|
+
import { Controller } from "@hotwired/stimulus"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Database Organization
|
|
94
|
+
|
|
95
|
+
Separate SQLite databases for specialized concerns:
|
|
96
|
+
|
|
97
|
+
| Database | Purpose | Schema |
|
|
98
|
+
|----------|---------|--------|
|
|
99
|
+
| Primary | Application data | `db/schema.rb` |
|
|
100
|
+
| Queue | Solid Queue jobs | `db/queue_schema.rb` |
|
|
101
|
+
| Cache | Solid Cache entries | `db/cache_schema.rb` |
|
|
102
|
+
| Cable | Action Cable messages | `db/cable_schema.rb` |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Configuration Patterns
|
|
107
|
+
|
|
108
|
+
### Environment-Specific (`config/environments/`)
|
|
109
|
+
- Development, test, production configurations
|
|
110
|
+
- Inherit from `config/application.rb`
|
|
111
|
+
|
|
112
|
+
### Initializers (`config/initializers/`)
|
|
113
|
+
- Third-party library setup
|
|
114
|
+
- Application-wide configuration
|
|
115
|
+
- Named by concern (`cors.rb`, `ai_client.rb`)
|
|
116
|
+
|
|
117
|
+
### Credentials
|
|
118
|
+
- `config/credentials.yml.enc` for secrets
|
|
119
|
+
- Access via `Rails.application.credentials.dig(:key, :subkey)`
|
|
120
|
+
- Edit with `bin/rails credentials:edit`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Test Organization (`test/`)
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
test/
|
|
128
|
+
models/ # Model unit tests
|
|
129
|
+
controllers/ # Controller tests
|
|
130
|
+
system/ # Browser-based system tests
|
|
131
|
+
integration/ # Request/response tests
|
|
132
|
+
fixtures/ # Test data (YAML)
|
|
133
|
+
test_helper.rb # Common test setup
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Pattern**: Mirror `app/` structure in `test/`
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
_Document patterns, not file trees. New files following patterns should not require updates._
|