@o2vend/theme-cli 1.0.32

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 (116) hide show
  1. package/README.md +425 -0
  2. package/assets/Logo_o2vend.png +0 -0
  3. package/assets/favicon.png +0 -0
  4. package/assets/logo-white.png +0 -0
  5. package/bin/o2vend +42 -0
  6. package/config/widget-map.json +50 -0
  7. package/lib/commands/check.js +201 -0
  8. package/lib/commands/generate.js +33 -0
  9. package/lib/commands/init.js +214 -0
  10. package/lib/commands/optimize.js +216 -0
  11. package/lib/commands/package.js +208 -0
  12. package/lib/commands/serve.js +105 -0
  13. package/lib/commands/validate.js +191 -0
  14. package/lib/lib/api-client.js +357 -0
  15. package/lib/lib/dev-server.js +2618 -0
  16. package/lib/lib/file-watcher.js +80 -0
  17. package/lib/lib/hot-reload.js +106 -0
  18. package/lib/lib/liquid-engine.js +822 -0
  19. package/lib/lib/liquid-filters.js +671 -0
  20. package/lib/lib/mock-api-server.js +989 -0
  21. package/lib/lib/mock-data.js +1468 -0
  22. package/lib/lib/widget-service.js +321 -0
  23. package/package.json +70 -0
  24. package/test-theme/README.md +27 -0
  25. package/test-theme/assets/async-sections.js +446 -0
  26. package/test-theme/assets/cart-drawer.js +463 -0
  27. package/test-theme/assets/cart-manager.js +223 -0
  28. package/test-theme/assets/checkout-price-handler.js +368 -0
  29. package/test-theme/assets/components.css +4629 -0
  30. package/test-theme/assets/delivery-zone.css +299 -0
  31. package/test-theme/assets/delivery-zone.js +396 -0
  32. package/test-theme/assets/logo.png +0 -0
  33. package/test-theme/assets/sections.css +48 -0
  34. package/test-theme/assets/theme.css +3500 -0
  35. package/test-theme/assets/theme.js +3745 -0
  36. package/test-theme/config/settings_data.json +292 -0
  37. package/test-theme/config/settings_schema.json +1050 -0
  38. package/test-theme/layout/theme.liquid +195 -0
  39. package/test-theme/locales/en.default.json +260 -0
  40. package/test-theme/sections/content-fallback.liquid +53 -0
  41. package/test-theme/sections/content.liquid +57 -0
  42. package/test-theme/sections/footer-fallback.liquid +328 -0
  43. package/test-theme/sections/footer.liquid +278 -0
  44. package/test-theme/sections/header-fallback.liquid +1805 -0
  45. package/test-theme/sections/header.liquid +1145 -0
  46. package/test-theme/sections/hero-fallback.liquid +212 -0
  47. package/test-theme/sections/hero.liquid +136 -0
  48. package/test-theme/snippets/account-sidebar.liquid +200 -0
  49. package/test-theme/snippets/add-to-cart-modal.liquid +484 -0
  50. package/test-theme/snippets/breadcrumbs.liquid +134 -0
  51. package/test-theme/snippets/cart-drawer.liquid +467 -0
  52. package/test-theme/snippets/delivery-zone-city-selector.liquid +79 -0
  53. package/test-theme/snippets/delivery-zone-modal.liquid +337 -0
  54. package/test-theme/snippets/delivery-zone-search.liquid +78 -0
  55. package/test-theme/snippets/icon.liquid +105 -0
  56. package/test-theme/snippets/login-modal.liquid +346 -0
  57. package/test-theme/snippets/mega-menu.liquid +812 -0
  58. package/test-theme/snippets/news-thumbnail.liquid +187 -0
  59. package/test-theme/snippets/pagination.liquid +120 -0
  60. package/test-theme/snippets/price.liquid +92 -0
  61. package/test-theme/snippets/product-card-related.liquid +78 -0
  62. package/test-theme/snippets/product-card-simple.liquid +41 -0
  63. package/test-theme/snippets/product-card.liquid +697 -0
  64. package/test-theme/snippets/rating.liquid +85 -0
  65. package/test-theme/snippets/skeleton-collection-grid.liquid +114 -0
  66. package/test-theme/snippets/skeleton-product-card.liquid +124 -0
  67. package/test-theme/snippets/skeleton-product-grid.liquid +34 -0
  68. package/test-theme/snippets/social-sharing.liquid +185 -0
  69. package/test-theme/templates/account/dashboard.liquid +401 -0
  70. package/test-theme/templates/account/loyalty-redemption.liquid +405 -0
  71. package/test-theme/templates/account/loyalty.liquid +588 -0
  72. package/test-theme/templates/account/order-detail.liquid +230 -0
  73. package/test-theme/templates/account/orders.liquid +349 -0
  74. package/test-theme/templates/account/profile.liquid +758 -0
  75. package/test-theme/templates/account/register.liquid +232 -0
  76. package/test-theme/templates/account/return-orders.liquid +348 -0
  77. package/test-theme/templates/account/store-credit.liquid +464 -0
  78. package/test-theme/templates/account/subscriptions.liquid +601 -0
  79. package/test-theme/templates/account/wishlist.liquid +419 -0
  80. package/test-theme/templates/address-book.liquid +1092 -0
  81. package/test-theme/templates/categories.liquid +452 -0
  82. package/test-theme/templates/checkout.liquid +4511 -0
  83. package/test-theme/templates/error.liquid +384 -0
  84. package/test-theme/templates/index.liquid +11 -0
  85. package/test-theme/templates/login.liquid +185 -0
  86. package/test-theme/templates/order-confirmation.liquid +720 -0
  87. package/test-theme/templates/page.liquid +297 -0
  88. package/test-theme/templates/product-detail.liquid +4363 -0
  89. package/test-theme/templates/products.liquid +518 -0
  90. package/test-theme/templates/search.liquid +922 -0
  91. package/test-theme/theme.json.example +19 -0
  92. package/test-theme/widgets/brand-carousel.liquid +676 -0
  93. package/test-theme/widgets/brand.liquid +245 -0
  94. package/test-theme/widgets/carousel.liquid +843 -0
  95. package/test-theme/widgets/category-list-carousel.liquid +656 -0
  96. package/test-theme/widgets/category-list.liquid +340 -0
  97. package/test-theme/widgets/category.liquid +475 -0
  98. package/test-theme/widgets/discount-time.liquid +176 -0
  99. package/test-theme/widgets/footer-menu.liquid +695 -0
  100. package/test-theme/widgets/footer.liquid +179 -0
  101. package/test-theme/widgets/gallery.liquid +271 -0
  102. package/test-theme/widgets/header-menu.liquid +932 -0
  103. package/test-theme/widgets/header.liquid +159 -0
  104. package/test-theme/widgets/html.liquid +214 -0
  105. package/test-theme/widgets/news.liquid +217 -0
  106. package/test-theme/widgets/product-canvas.liquid +235 -0
  107. package/test-theme/widgets/product-carousel.liquid +502 -0
  108. package/test-theme/widgets/product.liquid +45 -0
  109. package/test-theme/widgets/recently-viewed.liquid +26 -0
  110. package/test-theme/widgets/shared/product-grid.liquid +339 -0
  111. package/test-theme/widgets/simple-product.liquid +42 -0
  112. package/test-theme/widgets/single-product.liquid +610 -0
  113. package/test-theme/widgets/spacebar-carousel.liquid +663 -0
  114. package/test-theme/widgets/spacebar.liquid +279 -0
  115. package/test-theme/widgets/splash.liquid +378 -0
  116. package/test-theme/widgets/testimonial-carousel.liquid +709 -0
@@ -0,0 +1,384 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{ error.title }} - {{ shop.name }}</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Playfair+Display:wght@600;700;800&display=swap" rel="stylesheet">
10
+ </head>
11
+ <body>
12
+ <div class="error-page">
13
+ <div class="error-container">
14
+ <div class="error-content">
15
+ <div class="error-icon">
16
+ <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
17
+ <circle cx="12" cy="12" r="10"></circle>
18
+ <line x1="12" y1="8" x2="12" y2="12"></line>
19
+ <line x1="12" y1="16" x2="12.01" y2="16"></line>
20
+ </svg>
21
+ </div>
22
+
23
+ <div class="error-header">
24
+ <div class="status-code">{{ error.statusCode }}</div>
25
+ <h1 class="error-title">{{ error.title }}</h1>
26
+ </div>
27
+
28
+ <p class="error-message">{{ error.message }}</p>
29
+
30
+ {% if error.details %}
31
+ <div class="error-details">
32
+ <div class="error-details-header">Technical Details</div>
33
+ <div class="error-details-content">{{ error.details }}</div>
34
+ </div>
35
+ {% endif %}
36
+
37
+ <div class="error-actions">
38
+ <a href="/" class="btn btn-primary">
39
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
40
+ <path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
41
+ <polyline points="9 22 9 12 15 12 15 22"></polyline>
42
+ </svg>
43
+ Back to Home
44
+ </a>
45
+ <button type="button" class="btn btn-secondary" id="retry-button">
46
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
47
+ <polyline points="23 4 23 10 17 10"></polyline>
48
+ <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>
49
+ </svg>
50
+ Try Again
51
+ </button>
52
+ </div>
53
+
54
+ <div class="error-footer">
55
+ <div class="error-meta">
56
+ <div class="error-meta-item">
57
+ <span class="meta-label">Store:</span>
58
+ <span class="meta-value">{{ request.host }}</span>
59
+ </div>
60
+ <div class="error-meta-item">
61
+ <span class="meta-label">Time:</span>
62
+ <span class="meta-value">{{ error.timestamp }}</span>
63
+ </div>
64
+ </div>
65
+ <p class="error-help">If this problem persists, please contact support.</p>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ <style>
72
+ /* CSS Variables - Default Theme Colors */
73
+ :root {
74
+ --color-primary: #000000;
75
+ --color-secondary: #6b7280;
76
+ --color-white: #ffffff;
77
+ --color-gray-50: #f9fafb;
78
+ --color-gray-100: #f3f4f6;
79
+ --color-gray-200: #e5e7eb;
80
+ --color-gray-300: #d1d5db;
81
+ --color-gray-400: #9ca3af;
82
+ --color-gray-500: #6b7280;
83
+ --color-gray-600: #4b5563;
84
+ --color-gray-700: #374151;
85
+ --color-gray-800: #1f2937;
86
+ --color-gray-900: #111827;
87
+ --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
88
+ --font-display: 'Playfair Display', Georgia, serif;
89
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
90
+ --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
91
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
92
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
93
+ }
94
+
95
+ * {
96
+ margin: 0;
97
+ padding: 0;
98
+ box-sizing: border-box;
99
+ }
100
+
101
+ body {
102
+ font-family: var(--font-primary);
103
+ -webkit-font-smoothing: antialiased;
104
+ -moz-osx-font-smoothing: grayscale;
105
+ }
106
+
107
+ .error-page {
108
+ min-height: 100vh;
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ background-color: var(--color-gray-50);
113
+ padding: 2rem 1rem;
114
+ }
115
+
116
+ .error-container {
117
+ max-width: 640px;
118
+ width: 100%;
119
+ }
120
+
121
+ .error-content {
122
+ background-color: var(--color-white);
123
+ border-radius: 0.75rem;
124
+ padding: 3rem 2rem;
125
+ text-align: center;
126
+ box-shadow: var(--shadow-lg);
127
+ border: 1px solid var(--color-gray-200);
128
+ }
129
+
130
+ .error-icon {
131
+ display: flex;
132
+ align-items: center;
133
+ justify-content: center;
134
+ margin-bottom: 2rem;
135
+ color: var(--color-gray-400);
136
+ }
137
+
138
+ .error-icon svg {
139
+ width: 64px;
140
+ height: 64px;
141
+ }
142
+
143
+ .error-header {
144
+ margin-bottom: 1.5rem;
145
+ }
146
+
147
+ .status-code {
148
+ font-family: var(--font-display);
149
+ font-size: 4rem;
150
+ font-weight: 800;
151
+ line-height: 1;
152
+ color: var(--color-gray-900);
153
+ margin-bottom: 1rem;
154
+ letter-spacing: -0.05em;
155
+ }
156
+
157
+ .error-title {
158
+ font-family: var(--font-display);
159
+ font-size: 2rem;
160
+ font-weight: 700;
161
+ line-height: 1.2;
162
+ color: var(--color-gray-900);
163
+ margin-bottom: 0;
164
+ letter-spacing: -0.025em;
165
+ }
166
+
167
+ .error-message {
168
+ font-size: 1.125rem;
169
+ line-height: 1.7;
170
+ color: var(--color-gray-600);
171
+ margin-bottom: 2rem;
172
+ max-width: 480px;
173
+ margin-left: auto;
174
+ margin-right: auto;
175
+ }
176
+
177
+ .error-details {
178
+ background-color: var(--color-gray-50);
179
+ border: 1px solid var(--color-gray-200);
180
+ border-radius: 0.5rem;
181
+ padding: 1.5rem;
182
+ margin-bottom: 2rem;
183
+ text-align: left;
184
+ }
185
+
186
+ .error-details-header {
187
+ font-size: 0.875rem;
188
+ font-weight: 600;
189
+ color: var(--color-gray-900);
190
+ margin-bottom: 0.75rem;
191
+ }
192
+
193
+ .error-details-content {
194
+ font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
195
+ font-size: 0.8125rem;
196
+ color: var(--color-gray-700);
197
+ line-height: 1.6;
198
+ word-break: break-word;
199
+ overflow-wrap: break-word;
200
+ }
201
+
202
+ .error-actions {
203
+ display: flex;
204
+ gap: 1rem;
205
+ justify-content: center;
206
+ margin-bottom: 2.5rem;
207
+ flex-wrap: wrap;
208
+ }
209
+
210
+ .btn {
211
+ display: inline-flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ gap: 0.5rem;
215
+ padding: 0.875rem 1.5rem;
216
+ font-size: 0.9375rem;
217
+ font-weight: 500;
218
+ line-height: 1;
219
+ text-decoration: none;
220
+ border: 1px solid transparent;
221
+ border-radius: 0.375rem;
222
+ cursor: pointer;
223
+ transition: all 150ms ease-in-out;
224
+ white-space: nowrap;
225
+ font-family: var(--font-primary);
226
+ }
227
+
228
+ .btn svg {
229
+ width: 16px;
230
+ height: 16px;
231
+ flex-shrink: 0;
232
+ }
233
+
234
+ .btn-primary {
235
+ background-color: var(--color-primary);
236
+ color: var(--color-white);
237
+ border-color: var(--color-primary);
238
+ }
239
+
240
+ .btn-primary:hover {
241
+ background-color: var(--color-gray-800);
242
+ border-color: var(--color-gray-800);
243
+ }
244
+
245
+ .btn-secondary {
246
+ background-color: var(--color-white);
247
+ color: var(--color-gray-700);
248
+ border-color: var(--color-gray-300);
249
+ }
250
+
251
+ .btn-secondary:hover {
252
+ background-color: var(--color-gray-50);
253
+ border-color: var(--color-gray-400);
254
+ color: var(--color-primary);
255
+ }
256
+
257
+ .error-footer {
258
+ padding-top: 2rem;
259
+ border-top: 1px solid var(--color-gray-200);
260
+ }
261
+
262
+ .error-meta {
263
+ display: flex;
264
+ flex-direction: column;
265
+ gap: 0.5rem;
266
+ margin-bottom: 1rem;
267
+ }
268
+
269
+ .error-meta-item {
270
+ display: flex;
271
+ align-items: center;
272
+ justify-content: center;
273
+ gap: 0.5rem;
274
+ font-size: 0.875rem;
275
+ }
276
+
277
+ .meta-label {
278
+ color: var(--color-gray-500);
279
+ font-weight: 500;
280
+ }
281
+
282
+ .meta-value {
283
+ color: var(--color-gray-700);
284
+ font-weight: 600;
285
+ }
286
+
287
+ .error-help {
288
+ font-size: 0.875rem;
289
+ color: var(--color-gray-500);
290
+ line-height: 1.5;
291
+ }
292
+
293
+ /* Responsive Design */
294
+ @media (max-width: 768px) {
295
+ .error-page {
296
+ padding: 1.5rem 1rem;
297
+ }
298
+
299
+ .error-content {
300
+ padding: 2rem 1.5rem;
301
+ }
302
+
303
+ .error-icon svg {
304
+ width: 48px;
305
+ height: 48px;
306
+ }
307
+
308
+ .status-code {
309
+ font-size: 3rem;
310
+ }
311
+
312
+ .error-title {
313
+ font-size: 1.5rem;
314
+ }
315
+
316
+ .error-message {
317
+ font-size: 1rem;
318
+ }
319
+
320
+ .error-actions {
321
+ flex-direction: column;
322
+ width: 100%;
323
+ }
324
+
325
+ .btn {
326
+ width: 100%;
327
+ padding: 0.875rem 1.25rem;
328
+ }
329
+
330
+ .error-meta {
331
+ gap: 0.75rem;
332
+ }
333
+
334
+ .error-meta-item {
335
+ flex-direction: column;
336
+ gap: 0.25rem;
337
+ }
338
+ }
339
+
340
+ @media (max-width: 480px) {
341
+ .status-code {
342
+ font-size: 2.5rem;
343
+ }
344
+
345
+ .error-title {
346
+ font-size: 1.25rem;
347
+ }
348
+
349
+ .error-details {
350
+ padding: 1rem;
351
+ }
352
+
353
+ .error-details-content {
354
+ font-size: 0.75rem;
355
+ }
356
+ }
357
+ </style>
358
+
359
+ <script>
360
+ // Wait for DOM to be ready
361
+ (function() {
362
+ 'use strict';
363
+
364
+ function initErrorPage() {
365
+ const retryButton = document.getElementById('retry-button');
366
+
367
+ if (retryButton) {
368
+ retryButton.addEventListener('click', function() {
369
+ // Reload the page
370
+ window.location.reload();
371
+ });
372
+ }
373
+ }
374
+
375
+ // Initialize when DOM is ready
376
+ if (document.readyState === 'loading') {
377
+ document.addEventListener('DOMContentLoaded', initErrorPage);
378
+ } else {
379
+ initErrorPage();
380
+ }
381
+ })();
382
+ </script>
383
+ </body>
384
+ </html>
@@ -0,0 +1,11 @@
1
+ {% layout 'layout/theme' %}
2
+ {% comment %}
3
+ O2VEND Default Theme - Homepage Template
4
+ Uses sections for better customization and widget support
5
+ {% endcomment %}
6
+
7
+ <!-- Hero Section -->
8
+ {% section 'sections/hero' %}
9
+
10
+ <!-- Content Section -->
11
+ {% section 'sections/content' %}
@@ -0,0 +1,185 @@
1
+ {% layout 'layout/theme' %}
2
+ {% comment %}
3
+ Customer Login Template
4
+ {% endcomment %}
5
+
6
+ <div class="customer-login">
7
+ <div class="customer-login-container">
8
+ <div class="customer-login-header">
9
+ <h1 class="customer-login-title">Sign In</h1>
10
+ <p class="customer-login-subtitle">Welcome back! Please sign in to your account.</p>
11
+ </div>
12
+
13
+ <div class="customer-login-form-wrapper">
14
+ <form class="customer-login-form" action="/webstoreapi/customer/login" method="post" id="customer-login-form">
15
+ {% if form.errors %}
16
+ <div class="form-errors">
17
+ {% for error in form.errors %}
18
+ <p class="form-error">{{ error }}</p>
19
+ {% endfor %}
20
+ </div>
21
+ {% endif %}
22
+
23
+ <div class="form-group">
24
+ <label for="customer-email" class="form-label">Email</label>
25
+ <input type="email"
26
+ id="customer-email"
27
+ name="email"
28
+ class="form-input"
29
+ placeholder="Enter your email"
30
+ required
31
+ autocomplete="email">
32
+ </div>
33
+
34
+ <div class="form-group">
35
+ <label for="customer-password" class="form-label">Password</label>
36
+ <input type="password"
37
+ id="customer-password"
38
+ name="password"
39
+ class="form-input"
40
+ placeholder="Enter your password"
41
+ required
42
+ autocomplete="current-password">
43
+ </div>
44
+
45
+ <div class="form-group form-group-row">
46
+ <label class="form-checkbox">
47
+ <input type="checkbox" name="remember" id="remember-me">
48
+ <span>Remember me</span>
49
+ </label>
50
+ <a href="/customer/forgot-password" class="form-link">Forgot password?</a>
51
+ </div>
52
+
53
+ <button type="submit" class="btn btn-primary btn-block">Sign In</button>
54
+ </form>
55
+
56
+ <div class="customer-login-footer">
57
+ <p>Don't have an account? <a href="/customer/register">Create one</a></p>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+ <style>
64
+ .customer-login {
65
+ min-height: 60vh;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ padding: 4rem 1rem;
70
+ background: {{ settings.color_background }};
71
+ }
72
+
73
+ .customer-login-container {
74
+ max-width: 400px;
75
+ width: 100%;
76
+ }
77
+
78
+ .customer-login-header {
79
+ text-align: center;
80
+ margin-bottom: 2rem;
81
+ }
82
+
83
+ .customer-login-title {
84
+ font-size: 2rem;
85
+ font-weight: 700;
86
+ margin: 0 0 0.5rem 0;
87
+ color: {{ settings.color_text }};
88
+ }
89
+
90
+ .customer-login-subtitle {
91
+ font-size: 1rem;
92
+ color: {{ settings.color_text_light }};
93
+ margin: 0;
94
+ }
95
+
96
+ .customer-login-form-wrapper {
97
+ background: white;
98
+ padding: 2rem;
99
+ border-radius: 0.5rem;
100
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
101
+ }
102
+
103
+ .form-group {
104
+ margin-bottom: 1.5rem;
105
+ }
106
+
107
+ .form-group-row {
108
+ display: flex;
109
+ justify-content: space-between;
110
+ align-items: center;
111
+ }
112
+
113
+ .form-label {
114
+ display: block;
115
+ margin-bottom: 0.5rem;
116
+ font-weight: 500;
117
+ color: {{ settings.color_text }};
118
+ }
119
+
120
+ .form-input {
121
+ width: 100%;
122
+ padding: 0.75rem 1rem;
123
+ border: 1px solid #d1d5db;
124
+ border-radius: 0.375rem;
125
+ font-size: 1rem;
126
+ transition: border-color 0.2s ease;
127
+ }
128
+
129
+ .form-input:focus {
130
+ outline: none;
131
+ border-color: {{ settings.color_primary }};
132
+ }
133
+
134
+ .form-checkbox {
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 0.5rem;
138
+ cursor: pointer;
139
+ }
140
+
141
+ .form-link {
142
+ color: {{ settings.color_primary }};
143
+ text-decoration: none;
144
+ font-size: 0.875rem;
145
+ }
146
+
147
+ .form-link:hover {
148
+ text-decoration: underline;
149
+ }
150
+
151
+ .form-errors {
152
+ background: #fee2e2;
153
+ border: 1px solid #fecaca;
154
+ border-radius: 0.375rem;
155
+ padding: 1rem;
156
+ margin-bottom: 1.5rem;
157
+ }
158
+
159
+ .form-error {
160
+ color: #991b1b;
161
+ margin: 0;
162
+ font-size: 0.875rem;
163
+ }
164
+
165
+ .btn-block {
166
+ width: 100%;
167
+ }
168
+
169
+ .customer-login-footer {
170
+ text-align: center;
171
+ margin-top: 1.5rem;
172
+ padding-top: 1.5rem;
173
+ border-top: 1px solid #e5e7eb;
174
+ }
175
+
176
+ .customer-login-footer a {
177
+ color: {{ settings.color_primary }};
178
+ text-decoration: none;
179
+ }
180
+
181
+ .customer-login-footer a:hover {
182
+ text-decoration: underline;
183
+ }
184
+ </style>
185
+