kaze 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kaze/commands/install_command.rb +25 -13
  3. data/lib/kaze/commands/installs_hotwire_stack.rb +11 -8
  4. data/lib/kaze/commands/installs_inertia_stacks.rb +34 -24
  5. data/lib/kaze/commands/version_command.rb +6 -0
  6. data/lib/kaze/version.rb +1 -1
  7. data/lib/kaze.rb +1 -3
  8. data/stubs/default/app/forms/auth/login_form.rb +2 -8
  9. data/stubs/default/app/forms/auth/new_password_form.rb +1 -1
  10. data/stubs/default/app/forms/update_profile_information_form.rb +1 -1
  11. data/stubs/default/app/mailers/application_mailer.rb +4 -4
  12. data/stubs/default/app/mailers/user_mailer.rb +1 -1
  13. data/stubs/default/app/models/auth.rb +57 -0
  14. data/stubs/default/app/models/current.rb +1 -1
  15. data/stubs/default/app/validators/current_password_validator.rb +1 -1
  16. data/stubs/default/app/validators/email_validator.rb +1 -1
  17. data/stubs/default/app/validators/lowercase_validator.rb +2 -2
  18. data/stubs/default/app/views/layouts/mailer.html.erb +367 -372
  19. data/stubs/default/app/views/layouts/mailer.text.erb +1 -4
  20. data/stubs/default/app/views/user_mailer/reset_password.html.erb +21 -26
  21. data/stubs/default/config/routes.rb +16 -16
  22. data/stubs/default/db/migrate/20240101000001_create_delayed_jobs.rb +1 -1
  23. data/stubs/default/test/factories/users.rb +7 -0
  24. data/stubs/default/test/integration/auth/authentication_test.rb +43 -0
  25. data/stubs/default/test/integration/auth/password_reset_test.rb +41 -0
  26. data/stubs/default/test/integration/auth/registration_test.rb +21 -0
  27. data/stubs/default/test/integration/password_update_test.rb +28 -0
  28. data/stubs/default/test/integration/profile_test.rb +51 -0
  29. data/stubs/default/test/test_helper.rb +38 -0
  30. data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
  31. data/stubs/hotwire/app/components/dropdown_component.html.erb +17 -18
  32. data/stubs/hotwire/app/components/dropdown_component.rb +7 -7
  33. data/stubs/hotwire/app/components/modal_component.html.erb +55 -59
  34. data/stubs/hotwire/app/components/modal_component.rb +6 -6
  35. data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
  36. data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
  37. data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
  38. data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +12 -9
  39. data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +7 -5
  40. data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +7 -5
  41. data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +7 -5
  42. data/stubs/hotwire/app/controllers/concerns/authenticate.rb +5 -20
  43. data/stubs/hotwire/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
  44. data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +9 -0
  45. data/stubs/hotwire/app/controllers/password_controller.rb +3 -3
  46. data/stubs/hotwire/app/controllers/profile_controller.rb +11 -9
  47. data/stubs/hotwire/app/controllers/welcome_controller.rb +1 -1
  48. data/stubs/hotwire/app/javascript/application.js +3 -3
  49. data/stubs/hotwire/app/views/auth/forgot_password.html.erb +12 -17
  50. data/stubs/hotwire/app/views/auth/login.html.erb +0 -9
  51. data/stubs/hotwire/app/views/auth/register.html.erb +0 -13
  52. data/stubs/hotwire/app/views/auth/reset_password.html.erb +0 -7
  53. data/stubs/hotwire/app/views/dashboard/index.html.erb +9 -10
  54. data/stubs/hotwire/app/views/layouts/_navigation.html.erb +77 -87
  55. data/stubs/hotwire/app/views/layouts/application.html.erb +0 -9
  56. data/stubs/hotwire/app/views/layouts/guest.html.erb +0 -6
  57. data/stubs/hotwire/app/views/profile/edit.html.erb +19 -22
  58. data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +32 -42
  59. data/stubs/hotwire/app/views/profile/partials/_update_password_form.html.erb +42 -55
  60. data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +36 -46
  61. data/stubs/hotwire/app/views/welcome/index.html.erb +34 -46
  62. data/stubs/hotwire/config/importmap.rb +3 -3
  63. data/stubs/hotwire/config/tailwind.config.js +2 -2
  64. data/stubs/inertia-common/app/controllers/application_controller.rb +1 -0
  65. data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +11 -8
  66. data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +5 -3
  67. data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +5 -3
  68. data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +5 -3
  69. data/stubs/inertia-common/app/controllers/concerns/authenticate.rb +5 -20
  70. data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +1 -1
  71. data/stubs/inertia-common/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
  72. data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +9 -0
  73. data/stubs/inertia-common/app/controllers/concerns/verify_csrf_token.rb +4 -4
  74. data/stubs/inertia-common/app/controllers/dashboard_controller.rb +1 -1
  75. data/stubs/inertia-common/app/controllers/password_controller.rb +1 -1
  76. data/stubs/inertia-common/app/controllers/profile_controller.rb +7 -5
  77. data/stubs/inertia-common/app/controllers/welcome_controller.rb +2 -2
  78. data/stubs/inertia-common/bin/vite +6 -6
  79. data/stubs/inertia-common/test/integration/password_update_test.rb +28 -0
  80. data/stubs/inertia-common/test/integration/profile_test.rb +51 -0
  81. data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +13 -9
  82. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +15 -12
  83. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +20 -15
  84. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +119 -87
  85. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +14 -7
  86. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +18 -7
  87. data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +60 -60
  88. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +21 -16
  89. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +20 -15
  90. data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +19 -14
  91. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +22 -16
  92. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +35 -24
  93. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +157 -117
  94. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +15 -15
  95. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -49
  96. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +90 -82
  97. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -115
  98. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +63 -60
  99. data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +23 -17
  100. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +31 -27
  101. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +109 -99
  102. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +121 -113
  103. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +76 -69
  104. data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +87 -63
  105. data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +32 -25
  106. data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +0 -4
  107. data/stubs/inertia-react-ts/config/tailwind.config.js +2 -2
  108. data/stubs/inertia-react-ts/vite.config.ts +2 -5
  109. data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +10 -6
  110. data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +18 -18
  111. data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +5 -5
  112. data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +60 -57
  113. data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +9 -9
  114. data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +7 -7
  115. data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +6 -6
  116. data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +84 -74
  117. data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +12 -12
  118. data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +5 -5
  119. data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +12 -12
  120. data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +13 -13
  121. data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +13 -13
  122. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +168 -136
  123. data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +15 -13
  124. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +56 -49
  125. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +78 -72
  126. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +101 -97
  127. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +71 -68
  128. data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -14
  129. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +34 -30
  130. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +87 -83
  131. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +105 -98
  132. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +69 -59
  133. data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +74 -47
  134. data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +0 -4
  135. data/stubs/inertia-vue-ts/config/tailwind.config.js +2 -2
  136. data/stubs/inertia-vue-ts/vite.config.ts +2 -5
  137. metadata +19 -6
  138. data/stubs/hotwire/bin/vite +0 -27
  139. data/stubs/inertia-common/Procfile.dev +0 -3
  140. /data/stubs/{hotwire → default}/Procfile.dev +0 -0
  141. /data/stubs/hotwire/app/javascript/{alpinejs.js → alpinejs.stub} +0 -0
@@ -1,376 +1,371 @@
1
1
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
2
  <html xmlns="http://www.w3.org/1999/xhtml">
3
- <head>
4
- <title><%= ENV.fetch("APP_NAME", "Rails") %></title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7
- <meta name="color-scheme" content="light">
8
- <meta name="supported-color-schemes" content="light">
9
- <style>
10
- /* Base */
11
-
12
- body,
13
- body *:not(html):not(style):not(br):not(tr):not(code) {
14
- box-sizing: border-box;
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
16
- 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
17
- position: relative;
18
- }
19
-
20
- body {
21
- -webkit-text-size-adjust: none;
22
- background-color: #ffffff;
23
- color: #718096;
24
- height: 100%;
25
- line-height: 1.4;
26
- margin: 0;
27
- padding: 0;
28
- width: 100% !important;
29
- }
30
-
31
- p,
32
- ul,
33
- ol,
34
- blockquote {
35
- line-height: 1.4;
36
- text-align: left;
37
- }
38
-
39
- a {
40
- color: #3869d4;
41
- }
42
-
43
- a img {
44
- border: none;
45
- }
46
-
47
- /* Typography */
48
-
49
- h1 {
50
- color: #3d4852;
51
- font-size: 18px;
52
- font-weight: bold;
53
- margin-top: 0;
54
- text-align: left;
55
- }
56
-
57
- h2 {
58
- font-size: 16px;
59
- font-weight: bold;
60
- margin-top: 0;
61
- text-align: left;
62
- }
63
-
64
- h3 {
65
- font-size: 14px;
66
- font-weight: bold;
67
- margin-top: 0;
68
- text-align: left;
69
- }
70
-
71
- p {
72
- font-size: 16px;
73
- line-height: 1.5em;
74
- margin-top: 0;
75
- text-align: left;
76
- }
77
-
78
- p.sub {
79
- font-size: 12px;
80
- }
81
-
82
- img {
83
- max-width: 100%;
84
- }
85
-
86
- /* Layout */
87
-
88
- .wrapper {
89
- -premailer-cellpadding: 0;
90
- -premailer-cellspacing: 0;
91
- -premailer-width: 100%;
92
- background-color: #edf2f7;
93
- margin: 0;
94
- padding: 0;
95
- width: 100%;
96
- }
97
-
98
- .content {
99
- -premailer-cellpadding: 0;
100
- -premailer-cellspacing: 0;
101
- -premailer-width: 100%;
102
- margin: 0;
103
- padding: 0;
104
- width: 100%;
105
- }
106
-
107
- /* Header */
108
-
109
- .header {
110
- padding: 25px 0;
111
- text-align: center;
112
- }
113
-
114
- .header a {
115
- color: #3d4852;
116
- font-size: 19px;
117
- font-weight: bold;
118
- text-decoration: none;
119
- }
120
-
121
- /* Logo */
122
-
123
- .logo {
124
- height: 75px;
125
- max-height: 75px;
126
- width: 75px;
127
- }
128
-
129
- /* Body */
130
-
131
- .body {
132
- -premailer-cellpadding: 0;
133
- -premailer-cellspacing: 0;
134
- -premailer-width: 100%;
135
- background-color: #edf2f7;
136
- border-bottom: 1px solid #edf2f7;
137
- border-top: 1px solid #edf2f7;
138
- margin: 0;
139
- padding: 0;
140
- width: 100%;
141
- }
142
-
143
- .inner-body {
144
- -premailer-cellpadding: 0;
145
- -premailer-cellspacing: 0;
146
- -premailer-width: 570px;
147
- background-color: #ffffff;
148
- border-color: #e8e5ef;
149
- border-radius: 2px;
150
- border-width: 1px;
151
- box-shadow: 0 2px 0 rgba(0, 0, 150, 0.025), 2px 4px 0 rgba(0, 0, 150, 0.015);
152
- margin: 0 auto;
153
- padding: 0;
154
- width: 570px;
155
- }
156
-
157
- /* Subcopy */
158
-
159
- .subcopy {
160
- border-top: 1px solid #e8e5ef;
161
- margin-top: 25px;
162
- padding-top: 25px;
163
- }
164
-
165
- .subcopy p {
166
- font-size: 14px;
167
- }
168
-
169
- /* Footer */
170
-
171
- .footer {
172
- -premailer-cellpadding: 0;
173
- -premailer-cellspacing: 0;
174
- -premailer-width: 570px;
175
- margin: 0 auto;
176
- padding: 0;
177
- text-align: center;
178
- width: 570px;
179
- }
180
-
181
- .footer p {
182
- color: #b0adc5;
183
- font-size: 12px;
184
- text-align: center;
185
- }
186
-
187
- .footer a {
188
- color: #b0adc5;
189
- text-decoration: underline;
190
- }
191
-
192
- /* Tables */
193
-
194
- .table table {
195
- -premailer-cellpadding: 0;
196
- -premailer-cellspacing: 0;
197
- -premailer-width: 100%;
198
- margin: 30px auto;
199
- width: 100%;
200
- }
201
-
202
- .table th {
203
- border-bottom: 1px solid #edeff2;
204
- margin: 0;
205
- padding-bottom: 8px;
206
- }
207
-
208
- .table td {
209
- color: #74787e;
210
- font-size: 15px;
211
- line-height: 18px;
212
- margin: 0;
213
- padding: 10px 0;
214
- }
215
-
216
- .content-cell {
217
- max-width: 100vw;
218
- padding: 32px;
219
- }
220
-
221
- /* Buttons */
222
-
223
- .action {
224
- -premailer-cellpadding: 0;
225
- -premailer-cellspacing: 0;
226
- -premailer-width: 100%;
227
- margin: 30px auto;
228
- padding: 0;
229
- text-align: center;
230
- width: 100%;
231
- }
232
-
233
- .button {
234
- -webkit-text-size-adjust: none;
235
- border-radius: 4px;
236
- color: #fff;
237
- display: inline-block;
238
- overflow: hidden;
239
- text-decoration: none;
240
- }
241
-
242
- .button-blue,
243
- .button-primary {
244
- background-color: #2d3748;
245
- border-bottom: 8px solid #2d3748;
246
- border-left: 18px solid #2d3748;
247
- border-right: 18px solid #2d3748;
248
- border-top: 8px solid #2d3748;
249
- }
250
-
251
- .button-green,
252
- .button-success {
253
- background-color: #48bb78;
254
- border-bottom: 8px solid #48bb78;
255
- border-left: 18px solid #48bb78;
256
- border-right: 18px solid #48bb78;
257
- border-top: 8px solid #48bb78;
258
- }
259
-
260
- .button-red,
261
- .button-error {
262
- background-color: #e53e3e;
263
- border-bottom: 8px solid #e53e3e;
264
- border-left: 18px solid #e53e3e;
265
- border-right: 18px solid #e53e3e;
266
- border-top: 8px solid #e53e3e;
267
- }
268
-
269
- /* Panels */
270
-
271
- .panel {
272
- border-left: #2d3748 solid 4px;
273
- margin: 21px 0;
274
- }
275
-
276
- .panel-content {
277
- background-color: #edf2f7;
278
- color: #718096;
279
- padding: 16px;
280
- }
281
-
282
- .panel-content p {
283
- color: #718096;
284
- }
285
-
286
- .panel-item {
287
- padding: 0;
288
- }
289
-
290
- .panel-item p:last-of-type {
291
- margin-bottom: 0;
292
- padding-bottom: 0;
293
- }
294
-
295
- /* Utilities */
296
-
297
- .break-all {
298
- word-break: break-all;
299
- }
300
-
301
- @media only screen and (max-width: 600px) {
302
- .inner-body {
3
+ <head>
4
+ <title><%= ENV.fetch("APP_NAME", "Rails") %></title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7
+ <meta name="color-scheme" content="light">
8
+ <meta name="supported-color-schemes" content="light">
9
+ <style>
10
+ /* Base */
11
+
12
+ body,
13
+ body *:not(html):not(style):not(br):not(tr):not(code) {
14
+ box-sizing: border-box;
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
16
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
17
+ position: relative;
18
+ }
19
+
20
+ body {
21
+ -webkit-text-size-adjust: none;
22
+ background-color: #ffffff;
23
+ color: #718096;
24
+ height: 100%;
25
+ line-height: 1.4;
26
+ margin: 0;
27
+ padding: 0;
303
28
  width: 100% !important;
304
- }
305
-
306
- .footer {
307
- width: 100% !important;
308
- }
309
- }
310
-
311
- @media only screen and (max-width: 500px) {
312
- .button {
313
- width: 100% !important;
314
- }
315
- }
316
- </style>
317
- </head>
318
- <body>
319
-
320
- <table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
321
- <tr>
322
- <td align="center">
323
- <table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
324
- <!-- Header -->
325
- <tr>
326
- <td class="header">
327
- <a href="<%= root_url %>" style="display: inline-block;">
328
- <%= ENV.fetch("APP_NAME", "Rails") %>
329
- </a>
330
- </td>
331
- </tr>
332
-
333
- <!-- Email Body -->
334
- <tr>
335
- <td class="body" width="100%" cellpadding="0" cellspacing="0" style="border: hidden !important;">
336
- <table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
337
- <!-- Body content -->
338
- <tr>
339
- <td class="content-cell">
340
- <%= yield %>
341
-
342
- <!-- Subcopy -->
343
- <% if content_for?(:subcopy) %>
344
- <table class="subcopy" width="100%" cellpadding="0" cellspacing="0" role="presentation">
345
- <tr>
346
- <td>
347
- <%= yield :subcopy %>
348
- </td>
349
- </tr>
350
- </table>
351
- <% end %>
352
-
353
- </td>
354
- </tr>
355
- </table>
356
- </td>
357
- </tr>
358
-
359
- <!-- Footer -->
360
- <tr>
361
- <td>
362
- <table class="footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
363
- <tr>
364
- <td class="content-cell" align="center">
365
- © <%= Time.new.year %> <%= ENV.fetch("APP_NAME", "Rails") %>. All rights reserved.
366
- </td>
367
- </tr>
368
- </table>
369
- </td>
370
- </tr>
371
- </table>
372
- </td>
373
- </tr>
374
- </table>
375
- </body>
29
+ }
30
+
31
+ p,
32
+ ul,
33
+ ol,
34
+ blockquote {
35
+ line-height: 1.4;
36
+ text-align: left;
37
+ }
38
+
39
+ a {
40
+ color: #3869d4;
41
+ }
42
+
43
+ a img {
44
+ border: none;
45
+ }
46
+
47
+ /* Typography */
48
+
49
+ h1 {
50
+ color: #3d4852;
51
+ font-size: 18px;
52
+ font-weight: bold;
53
+ margin-top: 0;
54
+ text-align: left;
55
+ }
56
+
57
+ h2 {
58
+ font-size: 16px;
59
+ font-weight: bold;
60
+ margin-top: 0;
61
+ text-align: left;
62
+ }
63
+
64
+ h3 {
65
+ font-size: 14px;
66
+ font-weight: bold;
67
+ margin-top: 0;
68
+ text-align: left;
69
+ }
70
+
71
+ p {
72
+ font-size: 16px;
73
+ line-height: 1.5em;
74
+ margin-top: 0;
75
+ text-align: left;
76
+ }
77
+
78
+ p.sub {
79
+ font-size: 12px;
80
+ }
81
+
82
+ img {
83
+ max-width: 100%;
84
+ }
85
+
86
+ /* Layout */
87
+
88
+ .wrapper {
89
+ -premailer-cellpadding: 0;
90
+ -premailer-cellspacing: 0;
91
+ -premailer-width: 100%;
92
+ background-color: #edf2f7;
93
+ margin: 0;
94
+ padding: 0;
95
+ width: 100%;
96
+ }
97
+
98
+ .content {
99
+ -premailer-cellpadding: 0;
100
+ -premailer-cellspacing: 0;
101
+ -premailer-width: 100%;
102
+ margin: 0;
103
+ padding: 0;
104
+ width: 100%;
105
+ }
106
+
107
+ /* Header */
108
+
109
+ .header {
110
+ padding: 25px 0;
111
+ text-align: center;
112
+ }
113
+
114
+ .header a {
115
+ color: #3d4852;
116
+ font-size: 19px;
117
+ font-weight: bold;
118
+ text-decoration: none;
119
+ }
120
+
121
+ /* Logo */
122
+
123
+ .logo {
124
+ height: 75px;
125
+ max-height: 75px;
126
+ width: 75px;
127
+ }
128
+
129
+ /* Body */
130
+
131
+ .body {
132
+ -premailer-cellpadding: 0;
133
+ -premailer-cellspacing: 0;
134
+ -premailer-width: 100%;
135
+ background-color: #edf2f7;
136
+ border-bottom: 1px solid #edf2f7;
137
+ border-top: 1px solid #edf2f7;
138
+ margin: 0;
139
+ padding: 0;
140
+ width: 100%;
141
+ }
142
+
143
+ .inner-body {
144
+ -premailer-cellpadding: 0;
145
+ -premailer-cellspacing: 0;
146
+ -premailer-width: 570px;
147
+ background-color: #ffffff;
148
+ border-color: #e8e5ef;
149
+ border-radius: 2px;
150
+ border-width: 1px;
151
+ box-shadow: 0 2px 0 rgba(0, 0, 150, 0.025), 2px 4px 0 rgba(0, 0, 150, 0.015);
152
+ margin: 0 auto;
153
+ padding: 0;
154
+ width: 570px;
155
+ }
156
+
157
+ /* Subcopy */
158
+
159
+ .subcopy {
160
+ border-top: 1px solid #e8e5ef;
161
+ margin-top: 25px;
162
+ padding-top: 25px;
163
+ }
164
+
165
+ .subcopy p {
166
+ font-size: 14px;
167
+ }
168
+
169
+ /* Footer */
170
+
171
+ .footer {
172
+ -premailer-cellpadding: 0;
173
+ -premailer-cellspacing: 0;
174
+ -premailer-width: 570px;
175
+ margin: 0 auto;
176
+ padding: 0;
177
+ text-align: center;
178
+ width: 570px;
179
+ }
180
+
181
+ .footer p {
182
+ color: #b0adc5;
183
+ font-size: 12px;
184
+ text-align: center;
185
+ }
186
+
187
+ .footer a {
188
+ color: #b0adc5;
189
+ text-decoration: underline;
190
+ }
191
+
192
+ /* Tables */
193
+
194
+ .table table {
195
+ -premailer-cellpadding: 0;
196
+ -premailer-cellspacing: 0;
197
+ -premailer-width: 100%;
198
+ margin: 30px auto;
199
+ width: 100%;
200
+ }
201
+
202
+ .table th {
203
+ border-bottom: 1px solid #edeff2;
204
+ margin: 0;
205
+ padding-bottom: 8px;
206
+ }
207
+
208
+ .table td {
209
+ color: #74787e;
210
+ font-size: 15px;
211
+ line-height: 18px;
212
+ margin: 0;
213
+ padding: 10px 0;
214
+ }
215
+
216
+ .content-cell {
217
+ max-width: 100vw;
218
+ padding: 32px;
219
+ }
220
+
221
+ /* Buttons */
222
+
223
+ .action {
224
+ -premailer-cellpadding: 0;
225
+ -premailer-cellspacing: 0;
226
+ -premailer-width: 100%;
227
+ margin: 30px auto;
228
+ padding: 0;
229
+ text-align: center;
230
+ width: 100%;
231
+ }
232
+
233
+ .button {
234
+ -webkit-text-size-adjust: none;
235
+ border-radius: 4px;
236
+ color: #fff;
237
+ display: inline-block;
238
+ overflow: hidden;
239
+ text-decoration: none;
240
+ }
241
+
242
+ .button-blue,
243
+ .button-primary {
244
+ background-color: #2d3748;
245
+ border-bottom: 8px solid #2d3748;
246
+ border-left: 18px solid #2d3748;
247
+ border-right: 18px solid #2d3748;
248
+ border-top: 8px solid #2d3748;
249
+ }
250
+
251
+ .button-green,
252
+ .button-success {
253
+ background-color: #48bb78;
254
+ border-bottom: 8px solid #48bb78;
255
+ border-left: 18px solid #48bb78;
256
+ border-right: 18px solid #48bb78;
257
+ border-top: 8px solid #48bb78;
258
+ }
259
+
260
+ .button-red,
261
+ .button-error {
262
+ background-color: #e53e3e;
263
+ border-bottom: 8px solid #e53e3e;
264
+ border-left: 18px solid #e53e3e;
265
+ border-right: 18px solid #e53e3e;
266
+ border-top: 8px solid #e53e3e;
267
+ }
268
+
269
+ /* Panels */
270
+
271
+ .panel {
272
+ border-left: #2d3748 solid 4px;
273
+ margin: 21px 0;
274
+ }
275
+
276
+ .panel-content {
277
+ background-color: #edf2f7;
278
+ color: #718096;
279
+ padding: 16px;
280
+ }
281
+
282
+ .panel-content p {
283
+ color: #718096;
284
+ }
285
+
286
+ .panel-item {
287
+ padding: 0;
288
+ }
289
+
290
+ .panel-item p:last-of-type {
291
+ margin-bottom: 0;
292
+ padding-bottom: 0;
293
+ }
294
+
295
+ /* Utilities */
296
+
297
+ .break-all {
298
+ word-break: break-all;
299
+ }
300
+
301
+ @media only screen and (max-width: 600px) {
302
+ .inner-body {
303
+ width: 100% !important;
304
+ }
305
+
306
+ .footer {
307
+ width: 100% !important;
308
+ }
309
+ }
310
+
311
+ @media only screen and (max-width: 500px) {
312
+ .button {
313
+ width: 100% !important;
314
+ }
315
+ }
316
+ </style>
317
+ </head>
318
+ <body>
319
+ <table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
320
+ <tr>
321
+ <td align="center">
322
+ <table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
323
+ <!-- Header -->
324
+ <tr>
325
+ <td class="header">
326
+ <a href="<%= root_url %>" style="display: inline-block;">
327
+ <%= ENV.fetch("APP_NAME", "Rails") %>
328
+ </a>
329
+ </td>
330
+ </tr>
331
+ <!-- Email Body -->
332
+ <tr>
333
+ <td class="body" width="100%" cellpadding="0" cellspacing="0" style="border: hidden !important;">
334
+ <table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
335
+ <!-- Body content -->
336
+ <tr>
337
+ <td class="content-cell">
338
+ <%= yield %>
339
+ <!-- Subcopy -->
340
+ <% if content_for?(:subcopy) %>
341
+ <table class="subcopy" width="100%" cellpadding="0" cellspacing="0" role="presentation">
342
+ <tr>
343
+ <td>
344
+ <%= yield :subcopy %>
345
+ </td>
346
+ </tr>
347
+ </table>
348
+ <% end %>
349
+ </td>
350
+ </tr>
351
+ </table>
352
+ </td>
353
+ </tr>
354
+ <!-- Footer -->
355
+ <tr>
356
+ <td>
357
+ <table class="footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
358
+ <tr>
359
+ <td class="content-cell" align="center">
360
+ © <%= Time.new.year %> <%= ENV.fetch("APP_NAME", "Rails") %>. All rights reserved.
361
+ </td>
362
+ </tr>
363
+ </table>
364
+ </td>
365
+ </tr>
366
+ </table>
367
+ </td>
368
+ </tr>
369
+ </table>
370
+ </body>
376
371
  </html>