create-atsdc-stack 1.1.0 → 1.2.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 (48) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/CLAUDE.md +236 -215
  3. package/CONTRIBUTING.md +342 -342
  4. package/INSTALLATION.md +359 -359
  5. package/LICENSE +201 -201
  6. package/README.md +405 -405
  7. package/app/.env.example +17 -17
  8. package/app/.github/labeler.yml +61 -0
  9. package/app/.github/workflows/browser-tests.yml +101 -0
  10. package/app/.github/workflows/check.yml +24 -0
  11. package/app/.github/workflows/greetings.yml +16 -0
  12. package/app/.github/workflows/label.yml +22 -0
  13. package/app/.github/workflows/stale.yml +27 -0
  14. package/app/.github/workflows/summary.yml +34 -0
  15. package/app/.stylelintrc.json +8 -0
  16. package/app/README.md +251 -251
  17. package/app/astro.config.mjs +83 -83
  18. package/app/drizzle.config.ts +16 -16
  19. package/app/package.json +66 -52
  20. package/app/playwright.config.ts +27 -0
  21. package/app/public/manifest.webmanifest +36 -36
  22. package/app/pwa-assets.config.ts +8 -0
  23. package/app/src/components/Card.astro +36 -36
  24. package/app/src/db/initialize.ts +107 -107
  25. package/app/src/db/schema.ts +72 -72
  26. package/app/src/db/validations.ts +158 -158
  27. package/app/src/layouts/Layout.astro +63 -63
  28. package/app/src/lib/config.ts +36 -36
  29. package/app/src/lib/content-converter.ts +141 -141
  30. package/app/src/lib/dom-utils.ts +230 -230
  31. package/app/src/lib/exa-search.ts +269 -269
  32. package/app/src/pages/api/chat.ts +91 -91
  33. package/app/src/pages/api/posts.ts +350 -350
  34. package/app/src/pages/index.astro +87 -87
  35. package/app/src/styles/components/button.scss +152 -152
  36. package/app/src/styles/components/card.scss +180 -180
  37. package/app/src/styles/components/form.scss +240 -240
  38. package/app/src/styles/global.scss +141 -141
  39. package/app/src/styles/pages/index.scss +80 -80
  40. package/app/src/styles/reset.scss +83 -83
  41. package/app/src/styles/variables/globals.scss +96 -96
  42. package/app/src/styles/variables/mixins.scss +238 -238
  43. package/app/tests/browser.test.nopause.ts +10 -0
  44. package/app/tests/browser.test.ts +13 -0
  45. package/bin/cli.js +1151 -1151
  46. package/package.json +8 -6
  47. package/app/.astro/settings.json +0 -5
  48. package/app/.astro/types.d.ts +0 -1
@@ -1,240 +1,240 @@
1
- @use '../variables/globals' as *;
2
- @use '../variables/mixins' as *;
3
-
4
- // Form component styles
5
- // Usage (preferred): <input class="form-input" data-state="error" data-size="lg" />
6
- // Usage (alternative): <input class="form-input error lg" />
7
-
8
- .form {
9
- width: 100%;
10
- max-width: 600px;
11
-
12
- &-group {
13
- margin-bottom: $spacing-large;
14
- }
15
-
16
- &-label {
17
- display: block;
18
- margin-bottom: $spacing-extra-small;
19
- font-size: $font-size-small;
20
- font-weight: $font-weight-medium;
21
- color: $text-primary;
22
-
23
- // Use data attributes for required state
24
- &[data-required='true']::after {
25
- content: ' *';
26
- color: $error-color;
27
- }
28
-
29
- // Alternative: class chaining
30
- &.required::after {
31
- content: ' *';
32
- color: $error-color;
33
- }
34
- }
35
-
36
- &-input,
37
- &-textarea,
38
- &-select {
39
- @include input-base;
40
-
41
- // State modifiers using data attributes (preferred)
42
- &[data-state='error'] {
43
- border-color: $error-color;
44
-
45
- &:focus {
46
- box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
47
- }
48
- }
49
-
50
- &[data-state='success'] {
51
- border-color: $success-color;
52
-
53
- &:focus {
54
- box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
55
- }
56
- }
57
-
58
- &[data-state='warning'] {
59
- border-color: $warning-color;
60
-
61
- &:focus {
62
- box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);
63
- }
64
- }
65
-
66
- // Size modifiers using data attributes
67
- &[data-size='small'] {
68
- padding: $spacing-extra-small $spacing-small;
69
- font-size: $font-size-small;
70
- }
71
-
72
- &[data-size='large'] {
73
- padding: $spacing-medium $spacing-large;
74
- font-size: $font-size-large;
75
- }
76
-
77
- // Alternative: class chaining for states
78
- &.error {
79
- border-color: $error-color;
80
-
81
- &:focus {
82
- box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
83
- }
84
- }
85
-
86
- &.success {
87
- border-color: $success-color;
88
-
89
- &:focus {
90
- box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
91
- }
92
- }
93
-
94
- &.warning {
95
- border-color: $warning-color;
96
-
97
- &:focus {
98
- box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);
99
- }
100
- }
101
-
102
- // Size class chaining alternatives
103
- &.small {
104
- padding: $spacing-extra-small $spacing-small;
105
- font-size: $font-size-small;
106
- }
107
-
108
- &.large {
109
- padding: $spacing-medium $spacing-large;
110
- font-size: $font-size-large;
111
- }
112
- }
113
-
114
- &-textarea {
115
- min-height: 120px;
116
- resize: vertical;
117
-
118
- &[data-resize='none'] {
119
- resize: none;
120
- }
121
-
122
- &[data-resize='horizontal'] {
123
- resize: horizontal;
124
- }
125
-
126
- &.no-resize {
127
- resize: none;
128
- }
129
- }
130
-
131
- &-select {
132
- cursor: pointer;
133
- appearance: none;
134
- 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");
135
- background-position: right $spacing-small center;
136
- background-repeat: no-repeat;
137
- background-size: 1.5rem 1.5rem;
138
- padding-right: $spacing-2x-large;
139
- }
140
-
141
- &-helper {
142
- margin-top: $spacing-extra-small;
143
- font-size: $font-size-small;
144
- color: $text-secondary;
145
-
146
- &[data-state='error'] {
147
- color: $error-color;
148
- }
149
-
150
- &[data-state='success'] {
151
- color: $success-color;
152
- }
153
-
154
- &[data-state='warning'] {
155
- color: $warning-color;
156
- }
157
- }
158
-
159
- &-error {
160
- margin-top: $spacing-extra-small;
161
- font-size: $font-size-small;
162
- color: $error-color;
163
- }
164
-
165
- &-checkbox,
166
- &-radio {
167
- display: flex;
168
- align-items: center;
169
- gap: $spacing-small;
170
- margin-bottom: $spacing-small;
171
-
172
- input {
173
- width: 1.125rem;
174
- height: 1.125rem;
175
- cursor: pointer;
176
- accent-color: $primary-color;
177
- }
178
-
179
- label {
180
- cursor: pointer;
181
- font-size: $font-size-base;
182
- color: $text-primary;
183
- }
184
-
185
- &[data-state='disabled'] {
186
- opacity: 0.5;
187
- cursor: not-allowed;
188
-
189
- input,
190
- label {
191
- cursor: not-allowed;
192
- }
193
- }
194
-
195
- // Alternative class chaining
196
- &.disabled {
197
- opacity: 0.5;
198
- cursor: not-allowed;
199
-
200
- input,
201
- label {
202
- cursor: not-allowed;
203
- }
204
- }
205
- }
206
-
207
- &-actions {
208
- @include flex-between;
209
- margin-top: $spacing-extra-large;
210
- gap: $spacing-medium;
211
-
212
- &[data-layout='stack'] {
213
- flex-direction: column;
214
-
215
- button {
216
- width: 100%;
217
- }
218
- }
219
-
220
- &[data-align='center'] {
221
- justify-content: center;
222
- }
223
-
224
- &[data-align='start'] {
225
- justify-content: flex-start;
226
- }
227
-
228
- &[data-align='end'] {
229
- justify-content: flex-end;
230
- }
231
-
232
- @media (max-width: $breakpoint-tablet) {
233
- flex-direction: column;
234
-
235
- button {
236
- width: 100%;
237
- }
238
- }
239
- }
240
- }
1
+ @use '../variables/globals' as *;
2
+ @use '../variables/mixins' as *;
3
+
4
+ // Form component styles
5
+ // Usage (preferred): <input class="form-input" data-state="error" data-size="lg" />
6
+ // Usage (alternative): <input class="form-input error lg" />
7
+
8
+ .form {
9
+ width: 100%;
10
+ max-width: 600px;
11
+
12
+ &-group {
13
+ margin-bottom: $spacing-large;
14
+ }
15
+
16
+ &-label {
17
+ display: block;
18
+ margin-bottom: $spacing-extra-small;
19
+ font-size: $font-size-small;
20
+ font-weight: $font-weight-medium;
21
+ color: $text-primary;
22
+
23
+ // Use data attributes for required state
24
+ &[data-required='true']::after {
25
+ content: ' *';
26
+ color: $error-color;
27
+ }
28
+
29
+ // Alternative: class chaining
30
+ &.required::after {
31
+ content: ' *';
32
+ color: $error-color;
33
+ }
34
+ }
35
+
36
+ &-input,
37
+ &-textarea,
38
+ &-select {
39
+ @include input-base;
40
+
41
+ // State modifiers using data attributes (preferred)
42
+ &[data-state='error'] {
43
+ border-color: $error-color;
44
+
45
+ &:focus {
46
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
47
+ }
48
+ }
49
+
50
+ &[data-state='success'] {
51
+ border-color: $success-color;
52
+
53
+ &:focus {
54
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
55
+ }
56
+ }
57
+
58
+ &[data-state='warning'] {
59
+ border-color: $warning-color;
60
+
61
+ &:focus {
62
+ box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);
63
+ }
64
+ }
65
+
66
+ // Size modifiers using data attributes
67
+ &[data-size='small'] {
68
+ padding: $spacing-extra-small $spacing-small;
69
+ font-size: $font-size-small;
70
+ }
71
+
72
+ &[data-size='large'] {
73
+ padding: $spacing-medium $spacing-large;
74
+ font-size: $font-size-large;
75
+ }
76
+
77
+ // Alternative: class chaining for states
78
+ &.error {
79
+ border-color: $error-color;
80
+
81
+ &:focus {
82
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
83
+ }
84
+ }
85
+
86
+ &.success {
87
+ border-color: $success-color;
88
+
89
+ &:focus {
90
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
91
+ }
92
+ }
93
+
94
+ &.warning {
95
+ border-color: $warning-color;
96
+
97
+ &:focus {
98
+ box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1);
99
+ }
100
+ }
101
+
102
+ // Size class chaining alternatives
103
+ &.small {
104
+ padding: $spacing-extra-small $spacing-small;
105
+ font-size: $font-size-small;
106
+ }
107
+
108
+ &.large {
109
+ padding: $spacing-medium $spacing-large;
110
+ font-size: $font-size-large;
111
+ }
112
+ }
113
+
114
+ &-textarea {
115
+ min-height: 120px;
116
+ resize: vertical;
117
+
118
+ &[data-resize='none'] {
119
+ resize: none;
120
+ }
121
+
122
+ &[data-resize='horizontal'] {
123
+ resize: horizontal;
124
+ }
125
+
126
+ &.no-resize {
127
+ resize: none;
128
+ }
129
+ }
130
+
131
+ &-select {
132
+ cursor: pointer;
133
+ appearance: none;
134
+ 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");
135
+ background-position: right $spacing-small center;
136
+ background-repeat: no-repeat;
137
+ background-size: 1.5rem 1.5rem;
138
+ padding-right: $spacing-2x-large;
139
+ }
140
+
141
+ &-helper {
142
+ margin-top: $spacing-extra-small;
143
+ font-size: $font-size-small;
144
+ color: $text-secondary;
145
+
146
+ &[data-state='error'] {
147
+ color: $error-color;
148
+ }
149
+
150
+ &[data-state='success'] {
151
+ color: $success-color;
152
+ }
153
+
154
+ &[data-state='warning'] {
155
+ color: $warning-color;
156
+ }
157
+ }
158
+
159
+ &-error {
160
+ margin-top: $spacing-extra-small;
161
+ font-size: $font-size-small;
162
+ color: $error-color;
163
+ }
164
+
165
+ &-checkbox,
166
+ &-radio {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: $spacing-small;
170
+ margin-bottom: $spacing-small;
171
+
172
+ input {
173
+ width: 1.125rem;
174
+ height: 1.125rem;
175
+ cursor: pointer;
176
+ accent-color: $primary-color;
177
+ }
178
+
179
+ label {
180
+ cursor: pointer;
181
+ font-size: $font-size-base;
182
+ color: $text-primary;
183
+ }
184
+
185
+ &[data-state='disabled'] {
186
+ opacity: 0.5;
187
+ cursor: not-allowed;
188
+
189
+ input,
190
+ label {
191
+ cursor: not-allowed;
192
+ }
193
+ }
194
+
195
+ // Alternative class chaining
196
+ &.disabled {
197
+ opacity: 0.5;
198
+ cursor: not-allowed;
199
+
200
+ input,
201
+ label {
202
+ cursor: not-allowed;
203
+ }
204
+ }
205
+ }
206
+
207
+ &-actions {
208
+ @include flex-between;
209
+ margin-top: $spacing-extra-large;
210
+ gap: $spacing-medium;
211
+
212
+ &[data-layout='stack'] {
213
+ flex-direction: column;
214
+
215
+ button {
216
+ width: 100%;
217
+ }
218
+ }
219
+
220
+ &[data-align='center'] {
221
+ justify-content: center;
222
+ }
223
+
224
+ &[data-align='start'] {
225
+ justify-content: flex-start;
226
+ }
227
+
228
+ &[data-align='end'] {
229
+ justify-content: flex-end;
230
+ }
231
+
232
+ @media (max-width: $breakpoint-tablet) {
233
+ flex-direction: column;
234
+
235
+ button {
236
+ width: 100%;
237
+ }
238
+ }
239
+ }
240
+ }