create-nymbal-app 0.0.0 → 0.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 (159) hide show
  1. package/bin/create-nymbal-app.mjs +9 -0
  2. package/dist/index.d.ts +37 -0
  3. package/dist/index.js +419 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +41 -7
  6. package/scaffold/project/astro/src/pages/index.astro +57 -0
  7. package/scaffold/templates/astro/README.md +26 -0
  8. package/scaffold/templates/astro/_dot.env.example +6 -0
  9. package/scaffold/templates/astro/_dot.gitignore +16 -0
  10. package/scaffold/templates/astro/_dot.node-version +1 -0
  11. package/scaffold/templates/astro/_dot.npmrc +1 -0
  12. package/scaffold/templates/astro/astro.config.mjs +14 -0
  13. package/scaffold/templates/astro/package.json +59 -0
  14. package/scaffold/templates/astro/src/components/AddressForm.astro +107 -0
  15. package/scaffold/templates/astro/src/components/Breadcrumb.astro +20 -0
  16. package/scaffold/templates/astro/src/components/CategoryNav.astro +27 -0
  17. package/scaffold/templates/astro/src/components/CheckoutSteps.astro +29 -0
  18. package/scaffold/templates/astro/src/components/Footer.astro +108 -0
  19. package/scaffold/templates/astro/src/components/Header.astro +192 -0
  20. package/scaffold/templates/astro/src/components/HeroSection.astro +17 -0
  21. package/scaffold/templates/astro/src/components/ImageGallery.astro +42 -0
  22. package/scaffold/templates/astro/src/components/NewsletterSignup.astro +39 -0
  23. package/scaffold/templates/astro/src/components/OrderSummary.astro +53 -0
  24. package/scaffold/templates/astro/src/components/Pagination.astro +13 -0
  25. package/scaffold/templates/astro/src/components/PriceDisplay.astro +25 -0
  26. package/scaffold/templates/astro/src/components/ProductCard.astro +44 -0
  27. package/scaffold/templates/astro/src/components/RelatedProducts.astro +28 -0
  28. package/scaffold/templates/astro/src/components/ReviewForm.astro +100 -0
  29. package/scaffold/templates/astro/src/components/ReviewList.astro +41 -0
  30. package/scaffold/templates/astro/src/components/SkipNav.astro +3 -0
  31. package/scaffold/templates/astro/src/components/SortDropdown.astro +26 -0
  32. package/scaffold/templates/astro/src/components/StockBadge.astro +32 -0
  33. package/scaffold/templates/astro/src/env.d.ts +2 -0
  34. package/scaffold/templates/astro/src/layouts/AccountLayout.astro +168 -0
  35. package/scaffold/templates/astro/src/layouts/BaseLayout.astro +55 -0
  36. package/scaffold/templates/astro/src/lib/api.ts +89 -0
  37. package/scaffold/templates/astro/src/lib/client.ts +13 -0
  38. package/scaffold/templates/astro/src/lib/format.ts +17 -0
  39. package/scaffold/templates/astro/src/lib/order-status.ts +14 -0
  40. package/scaffold/templates/astro/src/lib/seo.ts +62 -0
  41. package/scaffold/templates/astro/src/pages/404.astro +18 -0
  42. package/scaffold/templates/astro/src/pages/500.astro +17 -0
  43. package/scaffold/templates/astro/src/pages/account/addresses.astro +110 -0
  44. package/scaffold/templates/astro/src/pages/account/index.astro +67 -0
  45. package/scaffold/templates/astro/src/pages/account/login.astro +55 -0
  46. package/scaffold/templates/astro/src/pages/account/orders/[orderNumber].astro +108 -0
  47. package/scaffold/templates/astro/src/pages/account/orders.astro +81 -0
  48. package/scaffold/templates/astro/src/pages/account/profile.astro +131 -0
  49. package/scaffold/templates/astro/src/pages/account/register.astro +94 -0
  50. package/scaffold/templates/astro/src/pages/cart.astro +16 -0
  51. package/scaffold/templates/astro/src/pages/category/[slug].astro +73 -0
  52. package/scaffold/templates/astro/src/pages/checkout.astro +100 -0
  53. package/scaffold/templates/astro/src/pages/fragments/footer.astro +5 -0
  54. package/scaffold/templates/astro/src/pages/fragments/header.astro +5 -0
  55. package/scaffold/templates/astro/src/pages/fragments/nav.astro +9 -0
  56. package/scaffold/templates/astro/src/pages/fragments/product/[slug].astro +14 -0
  57. package/scaffold/templates/astro/src/pages/index.astro +49 -0
  58. package/scaffold/templates/astro/src/pages/order/[orderNumber].astro +127 -0
  59. package/scaffold/templates/astro/src/pages/product/[slug].astro +107 -0
  60. package/scaffold/templates/astro/src/pages/products/index.astro +62 -0
  61. package/scaffold/templates/astro/src/pages/search.astro +37 -0
  62. package/scaffold/templates/astro/src/scripts/account-guard.ts +22 -0
  63. package/scaffold/templates/astro/src/scripts/auth-forms.ts +89 -0
  64. package/scaffold/templates/astro/src/scripts/cart-page.ts +143 -0
  65. package/scaffold/templates/astro/src/scripts/checkout.ts +277 -0
  66. package/scaffold/templates/astro/src/scripts/image-gallery.ts +22 -0
  67. package/scaffold/templates/astro/src/scripts/init-client.ts +16 -0
  68. package/scaffold/templates/astro/src/scripts/order-status.ts +27 -0
  69. package/scaffold/templates/astro/src/scripts/pdp.ts +67 -0
  70. package/scaffold/templates/astro/src/scripts/plp.ts +109 -0
  71. package/scaffold/templates/astro/src/scripts/search.ts +145 -0
  72. package/scaffold/templates/astro/src/styles/global.css +362 -0
  73. package/scaffold/templates/astro/src/styles/pages/account.css +331 -0
  74. package/scaffold/templates/astro/src/styles/pages/cart.css +243 -0
  75. package/scaffold/templates/astro/src/styles/pages/checkout.css +270 -0
  76. package/scaffold/templates/astro/src/styles/pages/confirmation.css +142 -0
  77. package/scaffold/templates/astro/src/styles/pages/error.css +69 -0
  78. package/scaffold/templates/astro/src/styles/pages/home.css +269 -0
  79. package/scaffold/templates/astro/src/styles/pages/pdp.css +272 -0
  80. package/scaffold/templates/astro/src/styles/pages/plp.css +213 -0
  81. package/scaffold/templates/astro/src/styles/pages/search.css +152 -0
  82. package/scaffold/templates/astro/tsconfig.json +3 -0
  83. package/scaffold/templates/nextjs/README.md +26 -0
  84. package/scaffold/templates/nextjs/_dot.env.example +6 -0
  85. package/scaffold/templates/nextjs/_dot.gitignore +17 -0
  86. package/scaffold/templates/nextjs/_dot.node-version +1 -0
  87. package/scaffold/templates/nextjs/_dot.npmrc +1 -0
  88. package/scaffold/templates/nextjs/app/account/addresses/page.tsx +10 -0
  89. package/scaffold/templates/nextjs/app/account/layout.tsx +57 -0
  90. package/scaffold/templates/nextjs/app/account/login/page.tsx +23 -0
  91. package/scaffold/templates/nextjs/app/account/orders/[orderNumber]/page.tsx +192 -0
  92. package/scaffold/templates/nextjs/app/account/orders/page.tsx +123 -0
  93. package/scaffold/templates/nextjs/app/account/page.tsx +59 -0
  94. package/scaffold/templates/nextjs/app/account/profile/page.tsx +10 -0
  95. package/scaffold/templates/nextjs/app/account/register/page.tsx +10 -0
  96. package/scaffold/templates/nextjs/app/cart/page.tsx +10 -0
  97. package/scaffold/templates/nextjs/app/category/[slug]/page.tsx +58 -0
  98. package/scaffold/templates/nextjs/app/checkout/page.tsx +10 -0
  99. package/scaffold/templates/nextjs/app/error.tsx +49 -0
  100. package/scaffold/templates/nextjs/app/globals.css +473 -0
  101. package/scaffold/templates/nextjs/app/layout.tsx +29 -0
  102. package/scaffold/templates/nextjs/app/not-found.tsx +38 -0
  103. package/scaffold/templates/nextjs/app/order/[orderNumber]/page.tsx +127 -0
  104. package/scaffold/templates/nextjs/app/page.tsx +63 -0
  105. package/scaffold/templates/nextjs/app/product/[slug]/page.tsx +111 -0
  106. package/scaffold/templates/nextjs/app/products/page.tsx +40 -0
  107. package/scaffold/templates/nextjs/app/search/page.tsx +24 -0
  108. package/scaffold/templates/nextjs/components/client/AddressManager.tsx +181 -0
  109. package/scaffold/templates/nextjs/components/client/AuthGuard.tsx +55 -0
  110. package/scaffold/templates/nextjs/components/client/CartDrawerToggle.tsx +39 -0
  111. package/scaffold/templates/nextjs/components/client/CartPage.tsx +120 -0
  112. package/scaffold/templates/nextjs/components/client/CheckoutForm.tsx +523 -0
  113. package/scaffold/templates/nextjs/components/client/ImageGallery.tsx +68 -0
  114. package/scaffold/templates/nextjs/components/client/LoginForm.tsx +89 -0
  115. package/scaffold/templates/nextjs/components/client/MiniCartWrapper.tsx +12 -0
  116. package/scaffold/templates/nextjs/components/client/NewsletterSignup.tsx +74 -0
  117. package/scaffold/templates/nextjs/components/client/NymbalSetup.tsx +24 -0
  118. package/scaffold/templates/nextjs/components/client/OrderStatusRefresh.tsx +48 -0
  119. package/scaffold/templates/nextjs/components/client/ProductGrid.tsx +148 -0
  120. package/scaffold/templates/nextjs/components/client/ProductInteractive.tsx +61 -0
  121. package/scaffold/templates/nextjs/components/client/ProfileForm.tsx +112 -0
  122. package/scaffold/templates/nextjs/components/client/RegisterForm.tsx +131 -0
  123. package/scaffold/templates/nextjs/components/client/ReviewForm.tsx +116 -0
  124. package/scaffold/templates/nextjs/components/client/SearchBarWrapper.tsx +27 -0
  125. package/scaffold/templates/nextjs/components/client/SearchResults.tsx +141 -0
  126. package/scaffold/templates/nextjs/components/client/SortDropdown.tsx +35 -0
  127. package/scaffold/templates/nextjs/components/server/Breadcrumb.tsx +36 -0
  128. package/scaffold/templates/nextjs/components/server/CategoryNav.tsx +29 -0
  129. package/scaffold/templates/nextjs/components/server/CheckoutSteps.tsx +60 -0
  130. package/scaffold/templates/nextjs/components/server/Footer.module.css +64 -0
  131. package/scaffold/templates/nextjs/components/server/Footer.tsx +79 -0
  132. package/scaffold/templates/nextjs/components/server/Header.module.css +147 -0
  133. package/scaffold/templates/nextjs/components/server/Header.tsx +102 -0
  134. package/scaffold/templates/nextjs/components/server/HeroSection.tsx +18 -0
  135. package/scaffold/templates/nextjs/components/server/OrderSummary.tsx +79 -0
  136. package/scaffold/templates/nextjs/components/server/PriceDisplay.tsx +31 -0
  137. package/scaffold/templates/nextjs/components/server/ProductCard.tsx +59 -0
  138. package/scaffold/templates/nextjs/components/server/RelatedProducts.tsx +31 -0
  139. package/scaffold/templates/nextjs/components/server/ReviewList.tsx +62 -0
  140. package/scaffold/templates/nextjs/components/server/SkipNav.tsx +7 -0
  141. package/scaffold/templates/nextjs/components/server/StockBadge.tsx +19 -0
  142. package/scaffold/templates/nextjs/lib/api.ts +89 -0
  143. package/scaffold/templates/nextjs/lib/client.ts +23 -0
  144. package/scaffold/templates/nextjs/lib/format.ts +7 -0
  145. package/scaffold/templates/nextjs/lib/order-status.ts +14 -0
  146. package/scaffold/templates/nextjs/lib/seo.ts +73 -0
  147. package/scaffold/templates/nextjs/next.config.mjs +9 -0
  148. package/scaffold/templates/nextjs/package.json +64 -0
  149. package/scaffold/templates/nextjs/styles/pages/account.module.css +377 -0
  150. package/scaffold/templates/nextjs/styles/pages/cart.module.css +240 -0
  151. package/scaffold/templates/nextjs/styles/pages/checkout.module.css +404 -0
  152. package/scaffold/templates/nextjs/styles/pages/confirmation.module.css +237 -0
  153. package/scaffold/templates/nextjs/styles/pages/error.module.css +132 -0
  154. package/scaffold/templates/nextjs/styles/pages/home.module.css +285 -0
  155. package/scaffold/templates/nextjs/styles/pages/pdp.module.css +319 -0
  156. package/scaffold/templates/nextjs/styles/pages/plp.module.css +280 -0
  157. package/scaffold/templates/nextjs/styles/pages/search.module.css +192 -0
  158. package/scaffold/templates/nextjs/tsconfig.json +41 -0
  159. package/README.md +0 -4
@@ -0,0 +1,237 @@
1
+ /* ── Confirmation Page ─────────────────────────────────────────────── */
2
+
3
+ .page {
4
+ padding-block: var(--nymbal-spacing-xl);
5
+ }
6
+
7
+ .wrapper {
8
+ max-width: 42rem;
9
+ margin-inline: auto;
10
+ }
11
+
12
+ /* ── Success Header ───────────────────────────────────────────────── */
13
+
14
+ .successHeader {
15
+ text-align: center;
16
+ margin-bottom: var(--nymbal-spacing-xl);
17
+ }
18
+
19
+ .checkCircle {
20
+ display: inline-flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ width: 4rem;
24
+ height: 4rem;
25
+ border-radius: 50%;
26
+ background-color: #dcfce7;
27
+ color: var(--nymbal-color-success);
28
+ margin-bottom: var(--nymbal-spacing-md);
29
+ }
30
+
31
+ .checkCircle svg {
32
+ width: 2rem;
33
+ height: 2rem;
34
+ }
35
+
36
+ .successTitle {
37
+ font-size: 1.5rem;
38
+ font-weight: var(--nymbal-font-weight-bold);
39
+ margin-bottom: var(--nymbal-spacing-sm);
40
+ }
41
+
42
+ .successSubtitle {
43
+ font-size: var(--nymbal-font-size-sm);
44
+ color: var(--nymbal-color-text-muted);
45
+ }
46
+
47
+ .orderNumber {
48
+ font-weight: var(--nymbal-font-weight-bold);
49
+ color: var(--nymbal-color-text);
50
+ }
51
+
52
+ /* ── Order Details Card ───────────────────────────────────────────── */
53
+
54
+ .orderCard {
55
+ background: var(--nymbal-color-surface);
56
+ border: 1px solid var(--nymbal-color-border);
57
+ border-radius: var(--nymbal-radius-lg);
58
+ padding: var(--nymbal-spacing-lg);
59
+ margin-bottom: var(--nymbal-spacing-lg);
60
+ }
61
+
62
+ .orderCardTitle {
63
+ font-size: var(--nymbal-font-size-base);
64
+ font-weight: var(--nymbal-font-weight-bold);
65
+ margin-bottom: var(--nymbal-spacing-md);
66
+ }
67
+
68
+ /* ── Line Items ───────────────────────────────────────────────────── */
69
+
70
+ .lineItems {
71
+ display: flex;
72
+ flex-direction: column;
73
+ }
74
+
75
+ .lineItem {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: var(--nymbal-spacing-md);
79
+ padding: var(--nymbal-spacing-sm) 0;
80
+ border-bottom: 1px solid var(--nymbal-color-border);
81
+ }
82
+
83
+ .lineItem:last-child {
84
+ border-bottom: none;
85
+ }
86
+
87
+ .lineItemImage {
88
+ width: 3.5rem;
89
+ height: 3.5rem;
90
+ flex-shrink: 0;
91
+ border-radius: var(--nymbal-radius-md);
92
+ background-color: #f4f4f5;
93
+ overflow: hidden;
94
+ }
95
+
96
+ .lineItemImage img {
97
+ width: 100%;
98
+ height: 100%;
99
+ object-fit: cover;
100
+ }
101
+
102
+ .lineItemInfo {
103
+ flex: 1;
104
+ min-width: 0;
105
+ }
106
+
107
+ .lineItemName {
108
+ font-size: var(--nymbal-font-size-sm);
109
+ font-weight: var(--nymbal-font-weight-medium);
110
+ }
111
+
112
+ .lineItemVariant {
113
+ font-size: var(--nymbal-font-size-xs);
114
+ color: var(--nymbal-color-text-muted);
115
+ }
116
+
117
+ .lineItemQty {
118
+ font-size: var(--nymbal-font-size-xs);
119
+ color: var(--nymbal-color-text-muted);
120
+ }
121
+
122
+ .lineItemPrice {
123
+ font-size: var(--nymbal-font-size-sm);
124
+ font-weight: var(--nymbal-font-weight-medium);
125
+ flex-shrink: 0;
126
+ }
127
+
128
+ /* ── Totals ───────────────────────────────────────────────────────── */
129
+
130
+ .totals {
131
+ margin-top: var(--nymbal-spacing-md);
132
+ padding-top: var(--nymbal-spacing-md);
133
+ border-top: 1px solid var(--nymbal-color-border);
134
+ }
135
+
136
+ .totalRow {
137
+ display: flex;
138
+ justify-content: space-between;
139
+ padding: var(--nymbal-spacing-xs) 0;
140
+ font-size: var(--nymbal-font-size-sm);
141
+ }
142
+
143
+ .totalLabel {
144
+ color: var(--nymbal-color-text-muted);
145
+ }
146
+
147
+ .totalGrand {
148
+ font-weight: var(--nymbal-font-weight-bold);
149
+ font-size: var(--nymbal-font-size-base);
150
+ padding-top: var(--nymbal-spacing-sm);
151
+ border-top: 1px solid var(--nymbal-color-border);
152
+ margin-top: var(--nymbal-spacing-xs);
153
+ }
154
+
155
+ /* ── Address Cards ────────────────────────────────────────────────── */
156
+
157
+ .addressGrid {
158
+ display: grid;
159
+ grid-template-columns: 1fr;
160
+ gap: var(--nymbal-spacing-md);
161
+ }
162
+
163
+ @media (min-width: 640px) {
164
+ .addressGrid {
165
+ grid-template-columns: repeat(2, 1fr);
166
+ }
167
+ }
168
+
169
+ .addressCard {
170
+ padding: var(--nymbal-spacing-md);
171
+ background: #fafafa;
172
+ border-radius: var(--nymbal-radius-md);
173
+ }
174
+
175
+ .addressTitle {
176
+ font-size: var(--nymbal-font-size-xs);
177
+ font-weight: var(--nymbal-font-weight-bold);
178
+ text-transform: uppercase;
179
+ letter-spacing: 0.05em;
180
+ color: var(--nymbal-color-text-muted);
181
+ margin-bottom: var(--nymbal-spacing-sm);
182
+ }
183
+
184
+ .addressText {
185
+ font-size: var(--nymbal-font-size-sm);
186
+ line-height: 1.5;
187
+ color: var(--nymbal-color-text);
188
+ }
189
+
190
+ /* ── Actions ──────────────────────────────────────────────────────── */
191
+
192
+ .actions {
193
+ display: flex;
194
+ gap: var(--nymbal-spacing-md);
195
+ justify-content: center;
196
+ flex-wrap: wrap;
197
+ margin-top: var(--nymbal-spacing-lg);
198
+ }
199
+
200
+ .continueButton {
201
+ padding: 0.75rem 2rem;
202
+ font-size: var(--nymbal-font-size-sm);
203
+ font-weight: var(--nymbal-font-weight-medium);
204
+ color: var(--nymbal-color-text-inverse);
205
+ background-color: var(--nymbal-color-primary);
206
+ border: none;
207
+ border-radius: var(--nymbal-radius-md);
208
+ text-decoration: none;
209
+ cursor: pointer;
210
+ transition: background-color var(--nymbal-transition-fast);
211
+ }
212
+
213
+ .continueButton:hover {
214
+ background-color: var(--nymbal-color-primary-hover);
215
+ text-decoration: none;
216
+ color: var(--nymbal-color-text-inverse);
217
+ }
218
+
219
+ .orderLink {
220
+ padding: 0.75rem 2rem;
221
+ font-size: var(--nymbal-font-size-sm);
222
+ font-weight: var(--nymbal-font-weight-medium);
223
+ color: var(--nymbal-color-text);
224
+ background: none;
225
+ border: 1px solid var(--nymbal-color-border);
226
+ border-radius: var(--nymbal-radius-md);
227
+ text-decoration: none;
228
+ transition: border-color var(--nymbal-transition-fast),
229
+ background-color var(--nymbal-transition-fast);
230
+ }
231
+
232
+ .orderLink:hover {
233
+ border-color: var(--nymbal-color-primary);
234
+ background-color: #f4f4f5;
235
+ text-decoration: none;
236
+ color: var(--nymbal-color-text);
237
+ }
@@ -0,0 +1,132 @@
1
+ /* ── Error Page ────────────────────────────────────────────────────── */
2
+
3
+ .page {
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ min-height: 60vh;
8
+ padding: var(--nymbal-spacing-xl);
9
+ text-align: center;
10
+ }
11
+
12
+ .wrapper {
13
+ max-width: 28rem;
14
+ }
15
+
16
+ /* ── Error Icon ───────────────────────────────────────────────────── */
17
+
18
+ .icon {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ width: 4rem;
23
+ height: 4rem;
24
+ border-radius: 50%;
25
+ background-color: #fef2f2;
26
+ color: var(--nymbal-color-error);
27
+ margin-bottom: var(--nymbal-spacing-md);
28
+ }
29
+
30
+ .icon svg {
31
+ width: 2rem;
32
+ height: 2rem;
33
+ }
34
+
35
+ /* ── Status Code ──────────────────────────────────────────────────── */
36
+
37
+ .statusCode {
38
+ font-size: 4rem;
39
+ font-weight: var(--nymbal-font-weight-bold);
40
+ color: var(--nymbal-color-primary);
41
+ line-height: 1;
42
+ margin-bottom: var(--nymbal-spacing-sm);
43
+ }
44
+
45
+ /* ── Text ─────────────────────────────────────────────────────────── */
46
+
47
+ .title {
48
+ font-size: 1.5rem;
49
+ font-weight: var(--nymbal-font-weight-bold);
50
+ margin-bottom: var(--nymbal-spacing-sm);
51
+ }
52
+
53
+ .message {
54
+ font-size: var(--nymbal-font-size-sm);
55
+ color: var(--nymbal-color-text-muted);
56
+ line-height: 1.6;
57
+ margin-bottom: var(--nymbal-spacing-lg);
58
+ }
59
+
60
+ /* ── Actions ──────────────────────────────────────────────────────── */
61
+
62
+ .actions {
63
+ display: flex;
64
+ gap: var(--nymbal-spacing-md);
65
+ justify-content: center;
66
+ flex-wrap: wrap;
67
+ }
68
+
69
+ .homeLink {
70
+ display: inline-flex;
71
+ align-items: center;
72
+ gap: var(--nymbal-spacing-sm);
73
+ padding: 0.625rem 1.5rem;
74
+ font-size: var(--nymbal-font-size-sm);
75
+ font-weight: var(--nymbal-font-weight-medium);
76
+ color: var(--nymbal-color-text-inverse);
77
+ background-color: var(--nymbal-color-primary);
78
+ border-radius: var(--nymbal-radius-md);
79
+ text-decoration: none;
80
+ transition: background-color var(--nymbal-transition-fast);
81
+ }
82
+
83
+ .homeLink:hover {
84
+ background-color: var(--nymbal-color-primary-hover);
85
+ text-decoration: none;
86
+ color: var(--nymbal-color-text-inverse);
87
+ }
88
+
89
+ .retryButton {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ gap: var(--nymbal-spacing-sm);
93
+ padding: 0.625rem 1.5rem;
94
+ font-size: var(--nymbal-font-size-sm);
95
+ font-weight: var(--nymbal-font-weight-medium);
96
+ color: var(--nymbal-color-text);
97
+ background: none;
98
+ border: 1px solid var(--nymbal-color-border);
99
+ border-radius: var(--nymbal-radius-md);
100
+ cursor: pointer;
101
+ transition: border-color var(--nymbal-transition-fast),
102
+ background-color var(--nymbal-transition-fast);
103
+ }
104
+
105
+ .retryButton:hover {
106
+ border-color: var(--nymbal-color-primary);
107
+ background-color: #f4f4f5;
108
+ }
109
+
110
+ /* ── 404 specific ─────────────────────────────────────────────────── */
111
+
112
+ .notFoundIcon {
113
+ background-color: #f4f4f5;
114
+ color: var(--nymbal-color-text-muted);
115
+ }
116
+
117
+ .searchPrompt {
118
+ margin-top: var(--nymbal-spacing-xl);
119
+ padding-top: var(--nymbal-spacing-lg);
120
+ border-top: 1px solid var(--nymbal-color-border);
121
+ }
122
+
123
+ .searchPromptText {
124
+ font-size: var(--nymbal-font-size-sm);
125
+ color: var(--nymbal-color-text-muted);
126
+ margin-bottom: var(--nymbal-spacing-md);
127
+ }
128
+
129
+ .searchPromptInput {
130
+ max-width: 20rem;
131
+ margin-inline: auto;
132
+ }
@@ -0,0 +1,285 @@
1
+ /* ── Hero ──────────────────────────────────────────────────────────── */
2
+
3
+ .hero {
4
+ position: relative;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ min-height: 28rem;
9
+ padding: var(--nymbal-spacing-xl);
10
+ background-color: var(--nymbal-color-primary);
11
+ color: var(--nymbal-color-text-inverse);
12
+ text-align: center;
13
+ overflow: hidden;
14
+ }
15
+
16
+ .heroContent {
17
+ position: relative;
18
+ z-index: 1;
19
+ max-width: 40rem;
20
+ }
21
+
22
+ .heroTitle {
23
+ font-size: 2rem;
24
+ font-weight: var(--nymbal-font-weight-bold);
25
+ line-height: 1.1;
26
+ margin-bottom: var(--nymbal-spacing-md);
27
+ }
28
+
29
+ .heroSubtitle {
30
+ font-size: var(--nymbal-font-size-lg);
31
+ opacity: 0.85;
32
+ margin-bottom: var(--nymbal-spacing-lg);
33
+ line-height: 1.5;
34
+ }
35
+
36
+ .heroCta {
37
+ display: inline-flex;
38
+ align-items: center;
39
+ gap: var(--nymbal-spacing-sm);
40
+ padding: 0.75rem 2rem;
41
+ font-size: var(--nymbal-font-size-base);
42
+ font-weight: var(--nymbal-font-weight-medium);
43
+ color: var(--nymbal-color-primary);
44
+ background-color: var(--nymbal-color-surface);
45
+ border: none;
46
+ border-radius: var(--nymbal-radius-md);
47
+ cursor: pointer;
48
+ text-decoration: none;
49
+ transition: background-color var(--nymbal-transition-fast),
50
+ transform var(--nymbal-transition-fast);
51
+ }
52
+
53
+ .heroCta:hover {
54
+ background-color: #f4f4f5;
55
+ transform: translateY(-1px);
56
+ text-decoration: none;
57
+ color: var(--nymbal-color-primary);
58
+ }
59
+
60
+ @media (min-width: 640px) {
61
+ .hero {
62
+ min-height: 32rem;
63
+ }
64
+
65
+ .heroTitle {
66
+ font-size: 3rem;
67
+ }
68
+
69
+ .heroSubtitle {
70
+ font-size: var(--nymbal-font-size-xl);
71
+ }
72
+ }
73
+
74
+ @media (min-width: 1024px) {
75
+ .hero {
76
+ min-height: 36rem;
77
+ }
78
+
79
+ .heroTitle {
80
+ font-size: 3.5rem;
81
+ }
82
+ }
83
+
84
+ /* ── Categories Grid ──────────────────────────────────────────────── */
85
+
86
+ .categoriesSection {
87
+ padding-block: var(--nymbal-spacing-xl);
88
+ }
89
+
90
+ .categoriesGrid {
91
+ display: grid;
92
+ grid-template-columns: 1fr;
93
+ gap: var(--nymbal-spacing-md);
94
+ }
95
+
96
+ @media (min-width: 640px) {
97
+ .categoriesGrid {
98
+ grid-template-columns: repeat(2, 1fr);
99
+ }
100
+ }
101
+
102
+ @media (min-width: 1024px) {
103
+ .categoriesGrid {
104
+ grid-template-columns: repeat(3, 1fr);
105
+ }
106
+ }
107
+
108
+ .categoryCard {
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ min-height: 10rem;
113
+ padding: var(--nymbal-spacing-lg);
114
+ background-color: #f9fafb;
115
+ border: 1px solid var(--nymbal-color-border);
116
+ border-radius: var(--nymbal-radius-lg);
117
+ text-decoration: none;
118
+ color: var(--nymbal-color-text);
119
+ font-size: var(--nymbal-font-size-lg);
120
+ font-weight: var(--nymbal-font-weight-medium);
121
+ transition: border-color var(--nymbal-transition-fast),
122
+ box-shadow var(--nymbal-transition-fast),
123
+ transform var(--nymbal-transition-fast);
124
+ }
125
+
126
+ .categoryCard:hover {
127
+ border-color: var(--nymbal-color-accent);
128
+ box-shadow: var(--nymbal-shadow-md);
129
+ transform: translateY(-2px);
130
+ text-decoration: none;
131
+ color: var(--nymbal-color-text);
132
+ }
133
+
134
+ /* ── Featured Products ────────────────────────────────────────────── */
135
+
136
+ .featuredSection {
137
+ padding-block: var(--nymbal-spacing-xl);
138
+ background-color: #fafafa;
139
+ }
140
+
141
+ .featuredHeader {
142
+ display: flex;
143
+ align-items: baseline;
144
+ justify-content: space-between;
145
+ margin-bottom: var(--nymbal-spacing-lg);
146
+ gap: var(--nymbal-spacing-md);
147
+ flex-wrap: wrap;
148
+ }
149
+
150
+ .featuredTitle {
151
+ font-size: 1.5rem;
152
+ font-weight: var(--nymbal-font-weight-bold);
153
+ }
154
+
155
+ .featuredViewAll {
156
+ font-size: var(--nymbal-font-size-sm);
157
+ font-weight: var(--nymbal-font-weight-medium);
158
+ color: var(--nymbal-color-accent);
159
+ text-decoration: none;
160
+ }
161
+
162
+ .featuredViewAll:hover {
163
+ text-decoration: underline;
164
+ }
165
+
166
+ .productCard {
167
+ display: flex;
168
+ flex-direction: column;
169
+ background: var(--nymbal-color-surface);
170
+ border: 1px solid var(--nymbal-color-border);
171
+ border-radius: var(--nymbal-radius-lg);
172
+ overflow: hidden;
173
+ text-decoration: none;
174
+ color: var(--nymbal-color-text);
175
+ transition: box-shadow var(--nymbal-transition-fast),
176
+ transform var(--nymbal-transition-fast);
177
+ }
178
+
179
+ .productCard:hover {
180
+ box-shadow: var(--nymbal-shadow-md);
181
+ transform: translateY(-2px);
182
+ text-decoration: none;
183
+ color: var(--nymbal-color-text);
184
+ }
185
+
186
+ .productImage {
187
+ aspect-ratio: 1;
188
+ background-color: #f4f4f5;
189
+ display: flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ overflow: hidden;
193
+ }
194
+
195
+ .productImage img {
196
+ width: 100%;
197
+ height: 100%;
198
+ object-fit: cover;
199
+ }
200
+
201
+ .productInfo {
202
+ padding: var(--nymbal-spacing-md);
203
+ display: flex;
204
+ flex-direction: column;
205
+ gap: var(--nymbal-spacing-xs);
206
+ }
207
+
208
+ .productName {
209
+ font-size: var(--nymbal-font-size-sm);
210
+ font-weight: var(--nymbal-font-weight-medium);
211
+ line-height: 1.3;
212
+ }
213
+
214
+ .productPrice {
215
+ font-size: var(--nymbal-font-size-sm);
216
+ font-weight: var(--nymbal-font-weight-bold);
217
+ color: var(--nymbal-color-text);
218
+ }
219
+
220
+ /* ── Newsletter ───────────────────────────────────────────────────── */
221
+
222
+ .newsletter {
223
+ padding-block: var(--nymbal-spacing-xl);
224
+ text-align: center;
225
+ }
226
+
227
+ .newsletterInner {
228
+ max-width: 32rem;
229
+ margin-inline: auto;
230
+ }
231
+
232
+ .newsletterTitle {
233
+ font-size: 1.5rem;
234
+ font-weight: var(--nymbal-font-weight-bold);
235
+ margin-bottom: var(--nymbal-spacing-sm);
236
+ }
237
+
238
+ .newsletterText {
239
+ color: var(--nymbal-color-text-muted);
240
+ font-size: var(--nymbal-font-size-sm);
241
+ margin-bottom: var(--nymbal-spacing-lg);
242
+ }
243
+
244
+ .newsletterForm {
245
+ display: flex;
246
+ gap: var(--nymbal-spacing-sm);
247
+ }
248
+
249
+ .newsletterInput {
250
+ flex: 1;
251
+ padding: 0.625rem 0.75rem;
252
+ font-size: var(--nymbal-font-size-sm);
253
+ border: 1px solid var(--nymbal-color-border);
254
+ border-radius: var(--nymbal-radius-md);
255
+ background: var(--nymbal-color-surface);
256
+ }
257
+
258
+ .newsletterInput:focus {
259
+ outline: none;
260
+ border-color: var(--nymbal-color-accent);
261
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
262
+ }
263
+
264
+ .newsletterButton {
265
+ padding: 0.625rem 1.5rem;
266
+ font-size: var(--nymbal-font-size-sm);
267
+ font-weight: var(--nymbal-font-weight-medium);
268
+ color: var(--nymbal-color-text-inverse);
269
+ background-color: var(--nymbal-color-primary);
270
+ border: 1px solid var(--nymbal-color-primary);
271
+ border-radius: var(--nymbal-radius-md);
272
+ cursor: pointer;
273
+ transition: background-color var(--nymbal-transition-fast);
274
+ white-space: nowrap;
275
+ }
276
+
277
+ .newsletterButton:hover {
278
+ background-color: var(--nymbal-color-primary-hover);
279
+ }
280
+
281
+ @media (max-width: 639px) {
282
+ .newsletterForm {
283
+ flex-direction: column;
284
+ }
285
+ }