@tutorialkit-rb/cli 0.1.5 → 0.1.8

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. package/dist/index.js +47 -38
  2. package/package.json +1 -1
  3. package/template/.claude/skills/rails-file-management/SKILL.md +211 -0
  4. package/template/.claude/skills/rails-lesson-recipes/SKILL.md +415 -0
  5. package/template/.claude/skills/rails-wasm-author-constraints/SKILL.md +181 -0
  6. package/template/.claude/skills/tutorial-content-structure/SKILL.md +377 -0
  7. package/template/.claude/skills/tutorial-lesson-config/SKILL.md +389 -0
  8. package/template/.claude/skills/tutorial-quickstart/SKILL.md +440 -0
  9. package/template/.github/workflows/deploy.yml +85 -0
  10. package/template/.gitignore +10 -0
  11. package/template/CLAUDE.md +47 -0
  12. package/template/astro.config.ts +12 -0
  13. package/template/bin/build-pack +84 -0
  14. package/template/bin/build-ruby-base +180 -0
  15. package/template/bin/link-local +13 -0
  16. package/template/bin/unlink-local +7 -0
  17. package/template/cors-proxy/README.md +63 -0
  18. package/template/cors-proxy/package-lock.json +1504 -0
  19. package/template/cors-proxy/package.json +12 -0
  20. package/template/cors-proxy/src/index.ts +87 -0
  21. package/template/cors-proxy/wrangler.toml +7 -0
  22. package/template/netlify.toml +9 -0
  23. package/template/package.json +12 -4
  24. package/template/ruby-wasm/Gemfile +6 -0
  25. package/template/ruby-wasm/Gemfile.base +19 -0
  26. package/template/ruby-wasm/Gemfile.base.lock +50 -0
  27. package/template/ruby-wasm/Gemfile.lock +8 -0
  28. package/template/ruby-wasm/bin/pack-gems +368 -0
  29. package/template/ruby-wasm/package.json +6 -0
  30. package/template/src/components/FileManager.tsx +33 -0
  31. package/template/src/components/HeadTags.astro +6 -6
  32. package/template/src/components/HelpDropdown.tsx +1 -1
  33. package/template/src/components/RailsPathLinkHandler.tsx +2 -2
  34. package/template/src/components/ShellConfigurator.tsx +6 -1
  35. package/template/src/content/tutorial/1-getting-started/1-creating-your-first-rails-app/content.md +4 -4
  36. package/template/src/content/tutorial/1-getting-started/2-rails-console/content.md +4 -4
  37. package/template/src/content/tutorial/2-controllers/2-crud-operations/content.md +2 -2
  38. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/.tk-config.json +3 -0
  39. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/controllers/http_demo_controller.rb +65 -0
  40. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/views/http_demo/index.html.erb +172 -0
  41. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/config/routes.rb +8 -0
  42. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/content.md +97 -0
  43. package/template/src/content/tutorial/9-outbound-http/meta.md +4 -0
  44. package/template/src/content/tutorial/meta.md +5 -0
  45. package/template/src/middleware.ts +14 -0
  46. package/template/src/templates/default/lib/boot-progress.js +49 -0
  47. package/template/src/templates/default/lib/http-bridge.js +55 -0
  48. package/template/src/templates/default/lib/patches/http_bridge.rb +167 -0
  49. package/template/src/templates/default/lib/rails.js +52 -5
  50. package/template/src/templates/default/lib/server.js +33 -1
  51. package/template/src/templates/default/package.json +4 -1
  52. package/template/src/templates/default/scripts/rails.js +1 -1
  53. package/template/src/templates/default/scripts/smoke-test.js +349 -0
  54. package/template/src/templates/default/scripts/wasi-loader.mjs +10 -0
  55. package/template/src/templates/default/workspace/_debug_app/.github/dependabot.yml +12 -0
  56. package/template/src/templates/default/workspace/_debug_app/.github/workflows/ci.yml +51 -0
  57. package/template/src/templates/default/workspace/_debug_app/.ruby-version +1 -0
  58. package/template/src/templates/default/workspace/_debug_app/Gemfile +37 -0
  59. package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/application.html.erb +1 -2
  60. package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/manifest.json.erb +2 -2
  61. package/template/src/templates/default/workspace/_debug_app/bin/dev +2 -0
  62. package/template/src/templates/default/workspace/_debug_app/bin/rake +4 -0
  63. package/template/src/templates/default/workspace/_debug_app/bin/setup +34 -0
  64. package/template/src/templates/default/workspace/_debug_app/config/application.rb +30 -0
  65. package/template/src/templates/default/workspace/_debug_app/config/cable.yml +10 -0
  66. package/template/src/templates/default/workspace/_debug_app/config/credentials.yml.enc +1 -0
  67. package/template/src/templates/default/workspace/_debug_app/config/master.key +1 -0
  68. package/template/src/templates/default/workspace/_debug_app/config/routes.rb +14 -0
  69. package/template/src/templates/default/workspace/_debug_app/test/models/.keep +0 -0
  70. package/template/src/templates/default/workspace/_debug_app/test/test_helper.rb +15 -0
  71. package/template/src/templates/default/workspace/_debug_app/tmp/.keep +0 -0
  72. package/template/src/templates/default/workspace/_debug_app/tmp/pids/.keep +0 -0
  73. package/template/src/templates/default/workspace/_debug_app/tmp/storage/.keep +0 -0
  74. package/template/src/templates/default/workspace/_debug_app/vendor/.keep +0 -0
  75. package/template/src/templates/rails-app/workspace/README.md +24 -0
  76. package/template/src/templates/rails-app/workspace/Rakefile +6 -0
  77. package/template/src/templates/rails-app/workspace/app/assets/images/.keep +0 -0
  78. package/template/src/templates/rails-app/workspace/app/assets/stylesheets/application.css +534 -0
  79. package/template/src/templates/rails-app/workspace/app/controllers/application_controller.rb +2 -0
  80. package/template/src/templates/rails-app/workspace/app/helpers/application_helper.rb +2 -0
  81. package/template/src/templates/rails-app/workspace/app/jobs/application_job.rb +7 -0
  82. package/template/src/templates/rails-app/workspace/app/mailers/application_mailer.rb +4 -0
  83. package/template/src/templates/rails-app/workspace/app/models/application_record.rb +3 -0
  84. package/template/src/templates/rails-app/workspace/app/models/concerns/.keep +0 -0
  85. package/template/src/templates/rails-app/workspace/app/views/layouts/application.html.erb +38 -0
  86. package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.html.erb +13 -0
  87. package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.text.erb +1 -0
  88. package/template/src/templates/rails-app/workspace/bin/rails +4 -0
  89. package/template/src/templates/rails-app/workspace/{store/config → config}/application.rb +1 -1
  90. package/template/src/templates/rails-app/workspace/config/boot.rb +3 -0
  91. package/template/src/templates/rails-app/workspace/config/database.yml +32 -0
  92. package/template/src/templates/rails-app/workspace/config/environment.rb +5 -0
  93. package/template/src/templates/rails-app/workspace/config/environments/development.rb +69 -0
  94. package/template/src/templates/rails-app/workspace/config/environments/production.rb +89 -0
  95. package/template/src/templates/rails-app/workspace/config/environments/test.rb +54 -0
  96. package/template/src/templates/rails-app/workspace/config/initializers/assets.rb +7 -0
  97. package/template/src/templates/rails-app/workspace/config/initializers/content_security_policy.rb +25 -0
  98. package/template/src/templates/rails-app/workspace/config/initializers/filter_parameter_logging.rb +8 -0
  99. package/template/src/templates/rails-app/workspace/config/initializers/inflections.rb +16 -0
  100. package/template/src/templates/rails-app/workspace/config/locales/en.yml +31 -0
  101. package/template/src/templates/rails-app/workspace/config/puma.rb +41 -0
  102. package/template/src/templates/rails-app/workspace/{store/config → config}/routes.rb +1 -1
  103. package/template/src/templates/rails-app/workspace/config/storage.yml +34 -0
  104. package/template/src/templates/rails-app/workspace/config.ru +6 -0
  105. package/template/src/templates/rails-app/workspace/db/seeds.rb +9 -0
  106. package/template/src/templates/rails-app/workspace/log/.keep +0 -0
  107. package/template/src/templates/rails-app/workspace/public/400.html +114 -0
  108. package/template/src/templates/rails-app/workspace/public/404.html +114 -0
  109. package/template/src/templates/rails-app/workspace/public/406-unsupported-browser.html +114 -0
  110. package/template/src/templates/rails-app/workspace/public/422.html +114 -0
  111. package/template/src/templates/rails-app/workspace/public/500.html +114 -0
  112. package/template/src/templates/rails-app/workspace/public/icon.png +0 -0
  113. package/template/src/templates/rails-app/workspace/public/icon.svg +3 -0
  114. package/template/src/templates/rails-app/workspace/public/robots.txt +1 -0
  115. package/template/src/templates/rails-app/workspace/script/.keep +0 -0
  116. package/template/src/templates/rails-app/workspace/storage/.keep +0 -0
  117. package/template/src/templates/rails-app/workspace/test/controllers/.keep +0 -0
  118. package/template/src/templates/rails-app/workspace/test/helpers/.keep +0 -0
  119. package/template/src/templates/rails-app/workspace/test/integration/.keep +0 -0
  120. package/template/src/templates/rails-app/workspace/tmp/.keep +0 -0
  121. package/template/src/templates/rails-app/workspace/tmp/cache/.keep +0 -0
  122. package/template/src/templates/rails-app/workspace/tmp/pids/.keep +0 -0
  123. package/template/src/templates/rails-app/workspace/tmp/sockets/.keep +0 -0
  124. package/template/src/templates/rails-app/workspace/tmp/storage/.keep +0 -0
  125. package/template/src/templates/rails-app/workspace/vendor/javascripts/.keep +0 -0
  126. package/template/tsconfig.json +3 -1
  127. package/template/uno.config.ts +17 -0
  128. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/README.md +0 -0
  129. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/Rakefile +0 -0
  130. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/images/.keep +0 -0
  131. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/stylesheets/application.css +0 -0
  132. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/controllers/application_controller.rb +0 -0
  133. /package/template/src/templates/{rails-app/workspace/store/app/models → default/workspace/_debug_app/app/controllers}/concerns/.keep +0 -0
  134. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/helpers/application_helper.rb +0 -0
  135. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/jobs/application_job.rb +0 -0
  136. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/mailers/application_mailer.rb +0 -0
  137. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/models/application_record.rb +0 -0
  138. /package/template/src/templates/{rails-app/workspace/store/log → default/workspace/_debug_app/app/models/concerns}/.keep +0 -0
  139. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.html.erb +0 -0
  140. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.text.erb +0 -0
  141. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/service-worker.js +0 -0
  142. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/bin/rails +0 -0
  143. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/boot.rb +0 -0
  144. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/database.yml +0 -0
  145. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environment.rb +0 -0
  146. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/development.rb +0 -0
  147. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/production.rb +0 -0
  148. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/test.rb +0 -0
  149. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/assets.rb +0 -0
  150. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/content_security_policy.rb +0 -0
  151. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/filter_parameter_logging.rb +0 -0
  152. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/inflections.rb +0 -0
  153. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/locales/en.yml +0 -0
  154. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/puma.rb +0 -0
  155. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/storage.yml +0 -0
  156. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config.ru +0 -0
  157. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/db/seeds.rb +0 -0
  158. /package/template/src/templates/{rails-app/workspace/store/script → default/workspace/_debug_app/lib/tasks}/.keep +0 -0
  159. /package/template/src/templates/{rails-app/workspace/store/storage → default/workspace/_debug_app/log}/.keep +0 -0
  160. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/400.html +0 -0
  161. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/404.html +0 -0
  162. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/406-unsupported-browser.html +0 -0
  163. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/422.html +0 -0
  164. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/500.html +0 -0
  165. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.png +0 -0
  166. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.svg +0 -0
  167. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/robots.txt +0 -0
  168. /package/template/src/templates/{rails-app/workspace/store/test/controllers → default/workspace/_debug_app/script}/.keep +0 -0
  169. /package/template/src/templates/{rails-app/workspace/store/test/helpers → default/workspace/_debug_app/storage}/.keep +0 -0
  170. /package/template/src/templates/{rails-app/workspace/store/test/integration → default/workspace/_debug_app/test/controllers}/.keep +0 -0
  171. /package/template/src/templates/{rails-app/workspace/store/tmp → default/workspace/_debug_app/test/fixtures/files}/.keep +0 -0
  172. /package/template/src/templates/{rails-app/workspace/store/tmp/pids → default/workspace/_debug_app/test/helpers}/.keep +0 -0
  173. /package/template/src/templates/{rails-app/workspace/store/tmp/storage → default/workspace/_debug_app/test/integration}/.keep +0 -0
  174. /package/template/src/templates/{rails-app/workspace/store/vendor/javascripts → default/workspace/_debug_app/test/mailers}/.keep +0 -0
  175. /package/template/src/templates/rails-app/workspace/{store/.ruby-version → .ruby-version} +0 -0
  176. /package/template/src/templates/rails-app/workspace/{store/Gemfile → Gemfile} +0 -0
  177. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/application.js +0 -0
  178. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/application.js +0 -0
  179. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/index.js +0 -0
  180. /package/template/src/templates/rails-app/workspace/{store/bin → bin}/importmap +0 -0
  181. /package/template/src/templates/rails-app/workspace/{store/config → config}/cable.yml +0 -0
  182. /package/template/src/templates/rails-app/workspace/{store/config → config}/credentials.yml.enc +0 -0
  183. /package/template/src/templates/rails-app/workspace/{store/config → config}/importmap.rb +0 -0
  184. /package/template/src/templates/rails-app/workspace/{store/config → config}/master.key +0 -0
  185. /package/template/src/templates/rails-app/workspace/{store/test → test}/test_helper.rb +0 -0
@@ -0,0 +1,534 @@
1
+ /* ============================================
2
+ CSS Custom Properties
3
+ ============================================ */
4
+ :root {
5
+ /* Colors */
6
+ --color-primary: #4f46e5;
7
+ --color-primary-hover: #4338ca;
8
+ --color-primary-light: #eef2ff;
9
+ --color-danger: #dc2626;
10
+ --color-danger-hover: #b91c1c;
11
+ --color-danger-light: #fef2f2;
12
+ --color-success: #16a34a;
13
+ --color-success-light: #f0fdf4;
14
+ --color-warning: #ca8a04;
15
+ --color-warning-light: #fefce8;
16
+ --color-info: #2563eb;
17
+ --color-info-light: #eff6ff;
18
+
19
+ --color-text: #1e293b;
20
+ --color-text-muted: #64748b;
21
+ --color-text-inverse: #ffffff;
22
+
23
+ --color-bg: #f8fafc;
24
+ --color-bg-white: #ffffff;
25
+ --color-border: #e2e8f0;
26
+ --color-border-focus: var(--color-primary);
27
+
28
+ /* Spacing */
29
+ --space-xs: 0.25rem;
30
+ --space-sm: 0.5rem;
31
+ --space-md: 1rem;
32
+ --space-lg: 1.5rem;
33
+ --space-xl: 2rem;
34
+ --space-2xl: 3rem;
35
+
36
+ /* Typography */
37
+ --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
38
+ --font-mono: ui-monospace, "Cascadia Code", "Fira Code", monospace;
39
+ --font-size-sm: 0.875rem;
40
+ --font-size-base: 1rem;
41
+ --font-size-lg: 1.125rem;
42
+ --font-size-xl: 1.25rem;
43
+ --font-size-2xl: 1.5rem;
44
+ --font-size-3xl: 1.875rem;
45
+
46
+ /* Border radius */
47
+ --radius-sm: 0.25rem;
48
+ --radius-md: 0.375rem;
49
+ --radius-lg: 0.5rem;
50
+ --radius-xl: 0.75rem;
51
+
52
+ /* Shadows */
53
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
54
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
55
+ }
56
+
57
+ /* ============================================
58
+ Base Reset & Defaults
59
+ ============================================ */
60
+ *,
61
+ *::before,
62
+ *::after {
63
+ box-sizing: border-box;
64
+ }
65
+
66
+ body {
67
+ margin: 0;
68
+ font-family: var(--font-sans);
69
+ font-size: var(--font-size-base);
70
+ line-height: 1.6;
71
+ color: var(--color-text);
72
+ background-color: var(--color-bg);
73
+ }
74
+
75
+ a {
76
+ color: var(--color-primary);
77
+ text-decoration: none;
78
+ }
79
+
80
+ a:hover {
81
+ text-decoration: underline;
82
+ }
83
+
84
+ h1, h2, h3, h4 {
85
+ margin-top: 0;
86
+ line-height: 1.3;
87
+ }
88
+
89
+ /* ============================================
90
+ Container
91
+ ============================================ */
92
+ .container {
93
+ max-width: 64rem;
94
+ margin: 0 auto;
95
+ padding: 0 var(--space-lg);
96
+ }
97
+
98
+ /* ============================================
99
+ Nav
100
+ ============================================ */
101
+ .nav {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: var(--space-md);
105
+ padding: var(--space-sm) var(--space-lg);
106
+ background-color: var(--color-bg-white);
107
+ border-bottom: 1px solid var(--color-border);
108
+ }
109
+
110
+ .nav__brand {
111
+ font-weight: 700;
112
+ font-size: var(--font-size-lg);
113
+ color: var(--color-text);
114
+ margin-right: auto;
115
+ }
116
+
117
+ .nav__brand:hover {
118
+ text-decoration: none;
119
+ color: var(--color-primary);
120
+ }
121
+
122
+ .nav__link {
123
+ color: var(--color-text-muted);
124
+ font-size: var(--font-size-sm);
125
+ font-weight: 500;
126
+ padding: var(--space-xs) var(--space-sm);
127
+ border-radius: var(--radius-sm);
128
+ transition: color 0.15s;
129
+ }
130
+
131
+ .nav__link:hover {
132
+ color: var(--color-primary);
133
+ text-decoration: none;
134
+ }
135
+
136
+ .nav__user {
137
+ font-size: var(--font-size-sm);
138
+ color: var(--color-text-muted);
139
+ }
140
+
141
+ /* Inline form for logout button in nav */
142
+ .nav form {
143
+ display: inline;
144
+ }
145
+
146
+ .nav form button {
147
+ background: none;
148
+ border: none;
149
+ color: var(--color-text-muted);
150
+ font-size: var(--font-size-sm);
151
+ font-weight: 500;
152
+ cursor: pointer;
153
+ padding: var(--space-xs) var(--space-sm);
154
+ border-radius: var(--radius-sm);
155
+ }
156
+
157
+ .nav form button:hover {
158
+ color: var(--color-danger);
159
+ }
160
+
161
+ /* ============================================
162
+ Alert
163
+ ============================================ */
164
+ .alert {
165
+ padding: var(--space-sm) var(--space-md);
166
+ border-radius: var(--radius-md);
167
+ font-size: var(--font-size-sm);
168
+ margin-bottom: var(--space-md);
169
+ border: 1px solid;
170
+ }
171
+
172
+ .alert--error {
173
+ color: var(--color-danger);
174
+ background-color: var(--color-danger-light);
175
+ border-color: #fecaca;
176
+ }
177
+
178
+ .alert--success {
179
+ color: var(--color-success);
180
+ background-color: var(--color-success-light);
181
+ border-color: #bbf7d0;
182
+ }
183
+
184
+ .alert--info {
185
+ color: var(--color-info);
186
+ background-color: var(--color-info-light);
187
+ border-color: #bfdbfe;
188
+ }
189
+
190
+ .alert--warning {
191
+ color: var(--color-warning);
192
+ background-color: var(--color-warning-light);
193
+ border-color: #fde68a;
194
+ }
195
+
196
+ /* ============================================
197
+ Button
198
+ ============================================ */
199
+ .btn {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ gap: var(--space-xs);
203
+ padding: var(--space-sm) var(--space-md);
204
+ font-size: var(--font-size-sm);
205
+ font-weight: 500;
206
+ font-family: inherit;
207
+ line-height: 1.4;
208
+ border: 1px solid var(--color-border);
209
+ border-radius: var(--radius-md);
210
+ background-color: var(--color-bg-white);
211
+ color: var(--color-text);
212
+ cursor: pointer;
213
+ transition: all 0.15s;
214
+ text-decoration: none;
215
+ }
216
+
217
+ .btn:hover {
218
+ background-color: var(--color-bg);
219
+ text-decoration: none;
220
+ }
221
+
222
+ .btn--primary {
223
+ background-color: var(--color-primary);
224
+ border-color: var(--color-primary);
225
+ color: var(--color-text-inverse);
226
+ }
227
+
228
+ .btn--primary:hover {
229
+ background-color: var(--color-primary-hover);
230
+ border-color: var(--color-primary-hover);
231
+ }
232
+
233
+ .btn--danger {
234
+ background-color: var(--color-danger);
235
+ border-color: var(--color-danger);
236
+ color: var(--color-text-inverse);
237
+ }
238
+
239
+ .btn--danger:hover {
240
+ background-color: var(--color-danger-hover);
241
+ border-color: var(--color-danger-hover);
242
+ }
243
+
244
+ .btn--success {
245
+ background-color: var(--color-success);
246
+ border-color: var(--color-success);
247
+ color: var(--color-text-inverse);
248
+ }
249
+
250
+ .btn--success:hover {
251
+ background-color: #15803d;
252
+ border-color: #15803d;
253
+ }
254
+
255
+ .btn[disabled],
256
+ .btn:disabled {
257
+ opacity: 0.5;
258
+ cursor: not-allowed;
259
+ }
260
+
261
+ .btn[disabled]:hover,
262
+ .btn:disabled:hover {
263
+ background-color: inherit;
264
+ }
265
+
266
+ .btn--success[disabled]:hover,
267
+ .btn--success:disabled:hover {
268
+ background-color: var(--color-success);
269
+ }
270
+
271
+ .btn--small {
272
+ padding: var(--space-xs) var(--space-sm);
273
+ font-size: 0.75rem;
274
+ }
275
+
276
+ .btn--link {
277
+ background: none;
278
+ border: none;
279
+ color: var(--color-primary);
280
+ padding: 0;
281
+ font-weight: 400;
282
+ }
283
+
284
+ .btn--link:hover {
285
+ background: none;
286
+ text-decoration: underline;
287
+ }
288
+
289
+ /* ============================================
290
+ Input / Form Controls
291
+ ============================================ */
292
+ .input {
293
+ display: block;
294
+ width: 100%;
295
+ padding: var(--space-sm) var(--space-md);
296
+ font-size: var(--font-size-base);
297
+ font-family: inherit;
298
+ line-height: 1.5;
299
+ color: var(--color-text);
300
+ background-color: var(--color-bg-white);
301
+ border: 1px solid var(--color-border);
302
+ border-radius: var(--radius-md);
303
+ transition: border-color 0.15s;
304
+ }
305
+
306
+ .input:focus {
307
+ outline: none;
308
+ border-color: var(--color-border-focus);
309
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
310
+ }
311
+
312
+ .input--error {
313
+ border-color: var(--color-danger);
314
+ }
315
+
316
+ .input--error:focus {
317
+ box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);
318
+ }
319
+
320
+ textarea.input {
321
+ min-height: 6rem;
322
+ resize: vertical;
323
+ }
324
+
325
+ select.input {
326
+ appearance: auto;
327
+ }
328
+
329
+ /* ============================================
330
+ Form
331
+ ============================================ */
332
+ .form__group {
333
+ margin-bottom: var(--space-md);
334
+ }
335
+
336
+ .form__label {
337
+ display: block;
338
+ margin-bottom: var(--space-xs);
339
+ font-size: var(--font-size-sm);
340
+ font-weight: 500;
341
+ color: var(--color-text);
342
+ }
343
+
344
+ .form__hint {
345
+ font-size: var(--font-size-sm);
346
+ color: var(--color-text-muted);
347
+ margin-top: var(--space-xs);
348
+ }
349
+
350
+ .form__errors {
351
+ color: var(--color-danger);
352
+ font-size: var(--font-size-sm);
353
+ margin-top: var(--space-xs);
354
+ }
355
+
356
+ .form__actions {
357
+ display: flex;
358
+ gap: var(--space-sm);
359
+ margin-top: var(--space-lg);
360
+ }
361
+
362
+ /* ============================================
363
+ Card
364
+ ============================================ */
365
+ .card {
366
+ background-color: var(--color-bg-white);
367
+ border: 1px solid var(--color-border);
368
+ border-radius: var(--radius-lg);
369
+ box-shadow: var(--shadow-sm);
370
+ }
371
+
372
+ .card__header {
373
+ padding: var(--space-md) var(--space-lg);
374
+ border-bottom: 1px solid var(--color-border);
375
+ }
376
+
377
+ .card__header h1,
378
+ .card__header h2,
379
+ .card__header h3 {
380
+ margin-bottom: 0;
381
+ }
382
+
383
+ .card__body {
384
+ padding: var(--space-lg);
385
+ }
386
+
387
+ .card__footer {
388
+ padding: var(--space-md) var(--space-lg);
389
+ border-top: 1px solid var(--color-border);
390
+ }
391
+
392
+ /* ============================================
393
+ Badge
394
+ ============================================ */
395
+ .badge {
396
+ display: inline-flex;
397
+ align-items: center;
398
+ padding: 0.125rem var(--space-sm);
399
+ font-size: 0.75rem;
400
+ font-weight: 600;
401
+ line-height: 1.4;
402
+ border-radius: 9999px;
403
+ background-color: var(--color-bg);
404
+ color: var(--color-text-muted);
405
+ border: 1px solid var(--color-border);
406
+ }
407
+
408
+ .badge--primary {
409
+ background-color: var(--color-primary-light);
410
+ color: var(--color-primary);
411
+ border-color: transparent;
412
+ }
413
+
414
+ .badge--success {
415
+ background-color: var(--color-success-light);
416
+ color: var(--color-success);
417
+ border-color: transparent;
418
+ }
419
+
420
+ .badge--danger {
421
+ background-color: var(--color-danger-light);
422
+ color: var(--color-danger);
423
+ border-color: transparent;
424
+ }
425
+
426
+ .badge--warning {
427
+ background-color: var(--color-warning-light);
428
+ color: var(--color-warning);
429
+ border-color: transparent;
430
+ }
431
+
432
+ /* ============================================
433
+ Table
434
+ ============================================ */
435
+ .table {
436
+ width: 100%;
437
+ border-collapse: collapse;
438
+ font-size: var(--font-size-sm);
439
+ }
440
+
441
+ .table th,
442
+ .table td {
443
+ padding: var(--space-sm) var(--space-md);
444
+ text-align: left;
445
+ border-bottom: 1px solid var(--color-border);
446
+ }
447
+
448
+ .table th {
449
+ font-weight: 600;
450
+ color: var(--color-text-muted);
451
+ font-size: 0.75rem;
452
+ text-transform: uppercase;
453
+ letter-spacing: 0.05em;
454
+ }
455
+
456
+ .table tr:hover td {
457
+ background-color: var(--color-bg);
458
+ }
459
+
460
+ /* ============================================
461
+ Page Header
462
+ ============================================ */
463
+ .page-header {
464
+ display: flex;
465
+ align-items: center;
466
+ justify-content: space-between;
467
+ margin-bottom: var(--space-lg);
468
+ padding-top: var(--space-lg);
469
+ }
470
+
471
+ .page-header h1 {
472
+ margin-bottom: 0;
473
+ font-size: var(--font-size-2xl);
474
+ }
475
+
476
+ /* ============================================
477
+ Hero (home page)
478
+ ============================================ */
479
+ .hero {
480
+ text-align: center;
481
+ padding: var(--space-2xl) var(--space-lg);
482
+ }
483
+
484
+ .hero__title {
485
+ font-size: var(--font-size-3xl);
486
+ font-weight: 700;
487
+ color: var(--color-text);
488
+ margin-bottom: var(--space-sm);
489
+ }
490
+
491
+ .hero__subtitle {
492
+ font-size: var(--font-size-lg);
493
+ color: var(--color-text-muted);
494
+ margin-bottom: var(--space-xl);
495
+ max-width: 36rem;
496
+ margin-left: auto;
497
+ margin-right: auto;
498
+ }
499
+
500
+ .hero__actions {
501
+ display: flex;
502
+ gap: var(--space-sm);
503
+ justify-content: center;
504
+ }
505
+
506
+ /* ============================================
507
+ Utility
508
+ ============================================ */
509
+ .text-muted {
510
+ color: var(--color-text-muted);
511
+ }
512
+
513
+ .text-sm {
514
+ font-size: var(--font-size-sm);
515
+ }
516
+
517
+ .mt-md {
518
+ margin-top: var(--space-md);
519
+ }
520
+
521
+ .mb-md {
522
+ margin-bottom: var(--space-md);
523
+ }
524
+
525
+ .inline-actions {
526
+ display: flex;
527
+ align-items: center;
528
+ gap: var(--space-sm);
529
+ }
530
+
531
+ /* Inline form (for delete buttons etc.) */
532
+ .inline-actions form {
533
+ display: inline;
534
+ }
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: "from@example.com"
3
+ layout "mailer"
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ primary_abstract_class
3
+ end
@@ -0,0 +1,38 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for(:title) || "Demo App" %></title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="apple-mobile-web-app-capable" content="yes">
7
+ <meta name="mobile-web-app-capable" content="yes">
8
+ <%= csrf_meta_tags %>
9
+ <%= csp_meta_tag %>
10
+
11
+ <%= yield :head %>
12
+
13
+ <link rel="icon" href="/icon.png" type="image/png">
14
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
15
+ <link rel="apple-touch-icon" href="/icon.png">
16
+
17
+ <%# Includes all stylesheet files in app/assets/stylesheets %>
18
+ <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
19
+ <%= javascript_importmap_tags %>
20
+ </head>
21
+
22
+ <body>
23
+ <nav class="nav">
24
+ <%= link_to "Demo App", root_path, class: "nav__brand" %>
25
+ </nav>
26
+
27
+ <main class="container">
28
+ <% if flash[:alert] %>
29
+ <div class="alert alert--error" style="margin-top: var(--space-md)"><%= flash[:alert] %></div>
30
+ <% end %>
31
+ <% if flash[:notice] %>
32
+ <div class="alert alert--success" style="margin-top: var(--space-md)"><%= flash[:notice] %></div>
33
+ <% end %>
34
+
35
+ <%= yield %>
36
+ </main>
37
+ </body>
38
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path("../config/application", __dir__)
3
+ require_relative "../config/boot"
4
+ require "rails/commands"
@@ -6,7 +6,7 @@ require "rails/all"
6
6
  # you've limited to :test, :development, or :production.
7
7
  Bundler.require(*Rails.groups)
8
8
 
9
- module Store
9
+ module DemoApp
10
10
  class Application < Rails::Application
11
11
  # Initialize configuration defaults for originally generated Rails version.
12
12
  config.load_defaults 8.0
@@ -0,0 +1,3 @@
1
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2
+
3
+ require "bundler/setup" # Set up gems listed in the Gemfile.
@@ -0,0 +1,32 @@
1
+ default: &default
2
+ adapter: pglite
3
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
4
+ timeout: 5000
5
+
6
+ development:
7
+ <<: *default
8
+ database: store_development
9
+
10
+ # Warning: The database defined as "test" will be erased and
11
+ # re-generated from your development database when you run "rake".
12
+ # Do not set this db to the same as development or production.
13
+ test:
14
+ <<: *default
15
+ database: store_test
16
+
17
+ production:
18
+ primary:
19
+ <<: *default
20
+ # database: path/to/persistent/storage/production.sqlite3
21
+ cache:
22
+ <<: *default
23
+ # database: path/to/persistent/storage/production_cache.sqlite3
24
+ migrations_paths: db/cache_migrate
25
+ queue:
26
+ <<: *default
27
+ # database: path/to/persistent/storage/production_queue.sqlite3
28
+ migrations_paths: db/queue_migrate
29
+ cable:
30
+ <<: *default
31
+ # database: path/to/persistent/storage/production_cable.sqlite3
32
+ migrations_paths: db/cable_migrate
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require_relative "application"
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!