@nextsparkjs/theme-productivity 0.1.0-beta.1

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 (57) hide show
  1. package/README.md +76 -0
  2. package/about.md +123 -0
  3. package/components/CardDetailModal.tsx +318 -0
  4. package/components/KanbanBoard.tsx +612 -0
  5. package/components/KanbanCard.tsx +218 -0
  6. package/components/KanbanColumn.tsx +264 -0
  7. package/components/SortableList.tsx +46 -0
  8. package/components/index.ts +4 -0
  9. package/config/app.config.ts +172 -0
  10. package/config/billing.config.ts +187 -0
  11. package/config/dashboard.config.ts +357 -0
  12. package/config/dev.config.ts +55 -0
  13. package/config/features.config.ts +256 -0
  14. package/config/flows.config.ts +484 -0
  15. package/config/permissions.config.ts +167 -0
  16. package/config/theme.config.ts +106 -0
  17. package/entities/boards/boards.config.ts +61 -0
  18. package/entities/boards/boards.fields.ts +154 -0
  19. package/entities/boards/boards.service.ts +256 -0
  20. package/entities/boards/boards.types.ts +57 -0
  21. package/entities/boards/messages/en.json +80 -0
  22. package/entities/boards/messages/es.json +80 -0
  23. package/entities/boards/migrations/001_boards_table.sql +83 -0
  24. package/entities/cards/cards.config.ts +61 -0
  25. package/entities/cards/cards.fields.ts +242 -0
  26. package/entities/cards/cards.service.ts +336 -0
  27. package/entities/cards/cards.types.ts +79 -0
  28. package/entities/cards/messages/en.json +114 -0
  29. package/entities/cards/messages/es.json +114 -0
  30. package/entities/cards/migrations/020_cards_table.sql +92 -0
  31. package/entities/lists/lists.config.ts +61 -0
  32. package/entities/lists/lists.fields.ts +105 -0
  33. package/entities/lists/lists.service.ts +252 -0
  34. package/entities/lists/lists.types.ts +55 -0
  35. package/entities/lists/messages/en.json +60 -0
  36. package/entities/lists/messages/es.json +60 -0
  37. package/entities/lists/migrations/010_lists_table.sql +79 -0
  38. package/lib/selectors.ts +206 -0
  39. package/messages/en.json +79 -0
  40. package/messages/es.json +79 -0
  41. package/migrations/999_theme_sample_data.sql +922 -0
  42. package/migrations/999a_initial_sample_data.sql +377 -0
  43. package/migrations/999b_abundant_sample_data.sql +346 -0
  44. package/package.json +17 -0
  45. package/permissions-matrix.md +122 -0
  46. package/styles/components.css +460 -0
  47. package/styles/globals.css +560 -0
  48. package/templates/dashboard/(main)/boards/[id]/[cardId]/page.tsx +238 -0
  49. package/templates/dashboard/(main)/boards/[id]/edit/page.tsx +390 -0
  50. package/templates/dashboard/(main)/boards/[id]/page.tsx +236 -0
  51. package/templates/dashboard/(main)/boards/create/page.tsx +236 -0
  52. package/templates/dashboard/(main)/boards/page.tsx +335 -0
  53. package/templates/dashboard/(main)/layout.tsx +32 -0
  54. package/templates/dashboard/(main)/page.tsx +592 -0
  55. package/templates/shared/ProductivityMobileNav.tsx +410 -0
  56. package/templates/shared/ProductivitySidebar.tsx +538 -0
  57. package/templates/shared/ProductivityTopBar.tsx +317 -0
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Productivity Theme - Component Styles
3
+ *
4
+ * Specific component overrides for the productivity app.
5
+ */
6
+
7
+ /* ============================================================================
8
+ Board Card (Board Preview in Dashboard)
9
+ ============================================================================ */
10
+
11
+ .board-preview-card {
12
+ position: relative;
13
+ overflow: hidden;
14
+ border-radius: var(--radius);
15
+ aspect-ratio: 16 / 9;
16
+ cursor: pointer;
17
+ transition: transform var(--transition-normal), box-shadow var(--transition-normal);
18
+ }
19
+
20
+ .board-preview-card:hover {
21
+ transform: translateY(-2px);
22
+ box-shadow: var(--card-shadow-hover);
23
+ }
24
+
25
+ .board-preview-card::before {
26
+ content: '';
27
+ position: absolute;
28
+ inset: 0;
29
+ background: linear-gradient(to bottom, transparent 50%, rgba(0, 0, 0, 0.6) 100%);
30
+ z-index: 1;
31
+ }
32
+
33
+ .board-preview-content {
34
+ position: absolute;
35
+ bottom: 0;
36
+ left: 0;
37
+ right: 0;
38
+ padding: 1rem;
39
+ z-index: 2;
40
+ color: white;
41
+ }
42
+
43
+ .board-preview-title {
44
+ font-weight: 600;
45
+ font-size: 1rem;
46
+ margin-bottom: 0.25rem;
47
+ }
48
+
49
+ .board-preview-meta {
50
+ font-size: 0.75rem;
51
+ opacity: 0.8;
52
+ }
53
+
54
+ /* ============================================================================
55
+ Quick Add Card
56
+ ============================================================================ */
57
+
58
+ .quick-add-card {
59
+ padding: 0.5rem;
60
+ margin-top: 0.5rem;
61
+ }
62
+
63
+ .quick-add-textarea {
64
+ width: 100%;
65
+ min-height: 60px;
66
+ padding: 0.5rem;
67
+ border: 1px solid hsl(var(--border));
68
+ border-radius: var(--radius-sm);
69
+ font-size: 0.875rem;
70
+ resize: none;
71
+ background: hsl(var(--background));
72
+ transition: border-color var(--transition-fast);
73
+ }
74
+
75
+ .quick-add-textarea:focus {
76
+ outline: none;
77
+ border-color: hsl(var(--primary));
78
+ }
79
+
80
+ .quick-add-actions {
81
+ display: flex;
82
+ align-items: center;
83
+ gap: 0.5rem;
84
+ margin-top: 0.5rem;
85
+ }
86
+
87
+ /* ============================================================================
88
+ Card Detail Modal
89
+ ============================================================================ */
90
+
91
+ .card-detail-modal {
92
+ max-width: 768px;
93
+ width: 100%;
94
+ }
95
+
96
+ .card-detail-header {
97
+ padding: 1.5rem;
98
+ border-bottom: 1px solid hsl(var(--border));
99
+ }
100
+
101
+ .card-detail-title {
102
+ font-size: 1.25rem;
103
+ font-weight: 600;
104
+ margin-bottom: 0.5rem;
105
+ }
106
+
107
+ .card-detail-breadcrumb {
108
+ font-size: 0.75rem;
109
+ color: hsl(var(--muted-foreground));
110
+ }
111
+
112
+ .card-detail-body {
113
+ display: grid;
114
+ grid-template-columns: 1fr 240px;
115
+ gap: 1.5rem;
116
+ padding: 1.5rem;
117
+ }
118
+
119
+ .card-detail-main {
120
+ min-width: 0;
121
+ }
122
+
123
+ .card-detail-sidebar {
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: 1rem;
127
+ }
128
+
129
+ .card-detail-section {
130
+ margin-bottom: 1.5rem;
131
+ }
132
+
133
+ .card-detail-section-title {
134
+ font-size: 0.75rem;
135
+ font-weight: 600;
136
+ text-transform: uppercase;
137
+ letter-spacing: 0.05em;
138
+ color: hsl(var(--muted-foreground));
139
+ margin-bottom: 0.75rem;
140
+ }
141
+
142
+ @media (max-width: 640px) {
143
+ .card-detail-body {
144
+ grid-template-columns: 1fr;
145
+ }
146
+
147
+ .card-detail-sidebar {
148
+ order: -1;
149
+ flex-direction: row;
150
+ flex-wrap: wrap;
151
+ }
152
+ }
153
+
154
+ /* ============================================================================
155
+ Sidebar Action Button
156
+ ============================================================================ */
157
+
158
+ .sidebar-action {
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 0.5rem;
162
+ width: 100%;
163
+ padding: 0.5rem 0.75rem;
164
+ font-size: 0.875rem;
165
+ font-weight: 500;
166
+ color: hsl(var(--foreground));
167
+ background: hsl(var(--muted) / 0.5);
168
+ border: none;
169
+ border-radius: var(--radius-sm);
170
+ cursor: pointer;
171
+ transition: background var(--transition-fast);
172
+ }
173
+
174
+ .sidebar-action:hover {
175
+ background: hsl(var(--muted));
176
+ }
177
+
178
+ .sidebar-action-icon {
179
+ width: 1rem;
180
+ height: 1rem;
181
+ color: hsl(var(--muted-foreground));
182
+ }
183
+
184
+ /* ============================================================================
185
+ Member Selector
186
+ ============================================================================ */
187
+
188
+ .member-selector {
189
+ display: flex;
190
+ flex-direction: column;
191
+ gap: 0.25rem;
192
+ }
193
+
194
+ .member-option {
195
+ display: flex;
196
+ align-items: center;
197
+ gap: 0.75rem;
198
+ padding: 0.5rem;
199
+ border-radius: var(--radius-sm);
200
+ cursor: pointer;
201
+ transition: background var(--transition-fast);
202
+ }
203
+
204
+ .member-option:hover {
205
+ background: hsl(var(--muted) / 0.5);
206
+ }
207
+
208
+ .member-option.selected {
209
+ background: hsl(var(--primary) / 0.1);
210
+ }
211
+
212
+ .member-avatar {
213
+ width: 2rem;
214
+ height: 2rem;
215
+ border-radius: 9999px;
216
+ object-fit: cover;
217
+ }
218
+
219
+ .member-info {
220
+ flex: 1;
221
+ min-width: 0;
222
+ }
223
+
224
+ .member-name {
225
+ font-size: 0.875rem;
226
+ font-weight: 500;
227
+ color: hsl(var(--foreground));
228
+ }
229
+
230
+ .member-role {
231
+ font-size: 0.75rem;
232
+ color: hsl(var(--muted-foreground));
233
+ }
234
+
235
+ /* ============================================================================
236
+ Label Selector
237
+ ============================================================================ */
238
+
239
+ .label-selector {
240
+ display: flex;
241
+ flex-wrap: wrap;
242
+ gap: 0.5rem;
243
+ }
244
+
245
+ .label-option {
246
+ padding: 0.25rem 0.75rem;
247
+ border-radius: 9999px;
248
+ font-size: 0.75rem;
249
+ font-weight: 500;
250
+ cursor: pointer;
251
+ opacity: 0.6;
252
+ transition: opacity var(--transition-fast), transform var(--transition-fast);
253
+ }
254
+
255
+ .label-option:hover {
256
+ opacity: 0.8;
257
+ }
258
+
259
+ .label-option.selected {
260
+ opacity: 1;
261
+ transform: scale(1.05);
262
+ }
263
+
264
+ /* ============================================================================
265
+ Calendar View
266
+ ============================================================================ */
267
+
268
+ .calendar-card {
269
+ background: hsl(var(--card));
270
+ border: 1px solid hsl(var(--border));
271
+ border-radius: var(--radius-sm);
272
+ padding: 0.375rem 0.5rem;
273
+ font-size: 0.75rem;
274
+ cursor: pointer;
275
+ transition: background var(--transition-fast);
276
+ }
277
+
278
+ .calendar-card:hover {
279
+ background: hsl(var(--muted) / 0.5);
280
+ }
281
+
282
+ .calendar-card.overdue {
283
+ border-left: 3px solid var(--label-urgent);
284
+ }
285
+
286
+ .calendar-card.due-today {
287
+ border-left: 3px solid var(--label-important);
288
+ }
289
+
290
+ /* ============================================================================
291
+ Empty State
292
+ ============================================================================ */
293
+
294
+ .productivity-empty-state {
295
+ display: flex;
296
+ flex-direction: column;
297
+ align-items: center;
298
+ justify-content: center;
299
+ padding: 3rem 1.5rem;
300
+ text-align: center;
301
+ }
302
+
303
+ .productivity-empty-icon {
304
+ width: 4rem;
305
+ height: 4rem;
306
+ margin-bottom: 1rem;
307
+ color: hsl(var(--muted-foreground) / 0.5);
308
+ }
309
+
310
+ .productivity-empty-title {
311
+ font-size: 1.125rem;
312
+ font-weight: 600;
313
+ color: hsl(var(--foreground));
314
+ margin-bottom: 0.5rem;
315
+ }
316
+
317
+ .productivity-empty-description {
318
+ font-size: 0.875rem;
319
+ color: hsl(var(--muted-foreground));
320
+ max-width: 20rem;
321
+ margin-bottom: 1.5rem;
322
+ }
323
+
324
+ /* ============================================================================
325
+ Statistics Cards
326
+ ============================================================================ */
327
+
328
+ .stat-card {
329
+ background: hsl(var(--card));
330
+ border: 1px solid hsl(var(--border));
331
+ border-radius: var(--radius);
332
+ padding: 1.25rem;
333
+ display: flex;
334
+ flex-direction: column;
335
+ }
336
+
337
+ .stat-label {
338
+ font-size: 0.75rem;
339
+ font-weight: 500;
340
+ color: hsl(var(--muted-foreground));
341
+ text-transform: uppercase;
342
+ letter-spacing: 0.05em;
343
+ margin-bottom: 0.5rem;
344
+ }
345
+
346
+ .stat-value {
347
+ font-size: 2rem;
348
+ font-weight: 700;
349
+ color: hsl(var(--foreground));
350
+ line-height: 1;
351
+ }
352
+
353
+ .stat-trend {
354
+ font-size: 0.75rem;
355
+ margin-top: 0.5rem;
356
+ }
357
+
358
+ .stat-trend.positive {
359
+ color: var(--board-green);
360
+ }
361
+
362
+ .stat-trend.negative {
363
+ color: var(--label-urgent);
364
+ }
365
+
366
+ /* ============================================================================
367
+ Activity Feed
368
+ ============================================================================ */
369
+
370
+ .activity-item {
371
+ display: flex;
372
+ gap: 0.75rem;
373
+ padding: 0.75rem 0;
374
+ border-bottom: 1px solid hsl(var(--border) / 0.5);
375
+ }
376
+
377
+ .activity-item:last-child {
378
+ border-bottom: none;
379
+ }
380
+
381
+ .activity-avatar {
382
+ width: 2rem;
383
+ height: 2rem;
384
+ border-radius: 9999px;
385
+ flex-shrink: 0;
386
+ }
387
+
388
+ .activity-content {
389
+ flex: 1;
390
+ min-width: 0;
391
+ }
392
+
393
+ .activity-text {
394
+ font-size: 0.875rem;
395
+ color: hsl(var(--foreground));
396
+ }
397
+
398
+ .activity-text strong {
399
+ font-weight: 600;
400
+ }
401
+
402
+ .activity-time {
403
+ font-size: 0.75rem;
404
+ color: hsl(var(--muted-foreground));
405
+ margin-top: 0.125rem;
406
+ }
407
+
408
+ /* ============================================================================
409
+ Drag and Drop States
410
+ ============================================================================ */
411
+
412
+ .is-dragging-over {
413
+ background: hsl(var(--primary) / 0.05);
414
+ }
415
+
416
+ .drag-handle {
417
+ cursor: grab;
418
+ opacity: 0;
419
+ transition: opacity var(--transition-fast);
420
+ }
421
+
422
+ .card-item:hover .drag-handle,
423
+ .list-header:hover .drag-handle {
424
+ opacity: 1;
425
+ }
426
+
427
+ .drag-handle:active {
428
+ cursor: grabbing;
429
+ }
430
+
431
+ /* ============================================================================
432
+ Role Badges
433
+ ============================================================================ */
434
+
435
+ .role-badge {
436
+ display: inline-flex;
437
+ align-items: center;
438
+ padding: 0.125rem 0.5rem;
439
+ border-radius: var(--radius-sm);
440
+ font-size: 0.675rem;
441
+ font-weight: 600;
442
+ text-transform: uppercase;
443
+ letter-spacing: 0.025em;
444
+ }
445
+
446
+ .role-badge.owner {
447
+ background: hsl(var(--primary) / 0.1);
448
+ color: hsl(var(--primary));
449
+ }
450
+
451
+ .role-badge.member {
452
+ background: hsl(var(--muted));
453
+ color: hsl(var(--muted-foreground));
454
+ }
455
+
456
+ .role-badge.viewer {
457
+ background: hsl(var(--muted) / 0.5);
458
+ color: hsl(var(--muted-foreground));
459
+ }
460
+