@salifbiaye/create-boutique 0.1.5 → 0.2.1

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 (67) hide show
  1. package/cli/dist/commands.js +3 -3
  2. package/cli/dist/create.js +5 -5
  3. package/cli/dist/generate.js +68 -10
  4. package/cli/dist/project.js +2 -0
  5. package/cli/dist/themes.js +5 -1
  6. package/package.json +1 -1
  7. package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +23 -1
  8. package/templates/backend/src/lib/emails.ts +8 -1
  9. package/templates/backend/src/scripts/campaign-import.ts +6 -4
  10. package/templates/backend/src/scripts/seed.ts +15 -3
  11. package/templates/storefront/locales/en.json +33 -1
  12. package/templates/storefront/locales/fr.json +33 -1
  13. package/templates/storefront/package-lock.json +7 -0
  14. package/templates/storefront/package.json +1 -0
  15. package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +3 -9
  16. package/templates/storefront/src/app/(main)/page.tsx +25 -0
  17. package/templates/storefront/src/app/(main)/store/page.tsx +3 -1
  18. package/templates/storefront/src/app/layout.tsx +9 -2
  19. package/templates/storefront/src/lib/boutique/config.ts +1 -0
  20. package/templates/storefront/src/lib/boutique/i18n-client.tsx +10 -2
  21. package/templates/storefront/src/lib/boutique/schema.ts +2 -0
  22. package/templates/storefront/src/modules/account/components/account-nav/index.tsx +50 -177
  23. package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +2 -2
  24. package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +2 -2
  25. package/templates/storefront/src/modules/account/components/overview/index.tsx +98 -143
  26. package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +2 -3
  27. package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +2 -3
  28. package/templates/storefront/src/modules/account/components/register/index.tsx +2 -3
  29. package/templates/storefront/src/modules/account/templates/account-layout.tsx +20 -24
  30. package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +1 -1
  31. package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +2 -2
  32. package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +2 -2
  33. package/templates/storefront/src/modules/common/components/phone-input/index.tsx +110 -0
  34. package/templates/storefront/src/modules/store/templates/index.tsx +82 -17
  35. package/templates/storefront/src/modules/store/templates/paginated-products.tsx +5 -0
  36. package/templates/storefront/src/modules/ub/campaign-blocks.tsx +1 -1
  37. package/templates/storefront/src/modules/ub/contact-page.tsx +78 -0
  38. package/templates/storefront/src/modules/ub/footer.tsx +26 -5
  39. package/templates/storefront/src/modules/ub/mobile-menu.tsx +49 -0
  40. package/templates/storefront/src/modules/ub/nav.tsx +2 -0
  41. package/templates/storefront/src/modules/ub/showcase.tsx +137 -0
  42. package/templates/storefront/src/styles/ub/account.css +199 -0
  43. package/templates/storefront/src/styles/ub/black-friday.css +96 -0
  44. package/templates/storefront/src/styles/ub/forms.css +61 -0
  45. package/templates/storefront/src/styles/ub/medusa-ui.css +18 -1
  46. package/templates/storefront/src/styles/ub/pages.css +382 -0
  47. package/templates/storefront/src/styles/ub/responsive.css +83 -0
  48. package/templates/storefront/src/styles/ub/showcase.css +85 -0
  49. package/templates/storefront/src/styles/ub/variants.css +64 -0
  50. package/templates/storefront/themes/black-friday-2/campaign.en.json +31 -0
  51. package/templates/storefront/themes/black-friday-2/campaign.fr.json +31 -0
  52. package/templates/storefront/themes/black-friday-2/theme.json +10 -0
  53. package/templates/storefront/themes/cyber-monday-2/campaign.en.json +31 -0
  54. package/templates/storefront/themes/cyber-monday-2/campaign.fr.json +31 -0
  55. package/templates/storefront/themes/cyber-monday-2/theme.json +10 -0
  56. package/templates/storefront/themes/halloween-2/campaign.en.json +31 -0
  57. package/templates/storefront/themes/halloween-2/campaign.fr.json +31 -0
  58. package/templates/storefront/themes/halloween-2/theme.json +10 -0
  59. package/templates/storefront/themes/noel-2/campaign.en.json +31 -0
  60. package/templates/storefront/themes/noel-2/campaign.fr.json +31 -0
  61. package/templates/storefront/themes/noel-2/theme.json +10 -0
  62. package/templates/storefront/themes/nouvel-an-2/campaign.en.json +31 -0
  63. package/templates/storefront/themes/nouvel-an-2/campaign.fr.json +31 -0
  64. package/templates/storefront/themes/nouvel-an-2/theme.json +10 -0
  65. package/templates/storefront/themes/thanksgiving-2/campaign.en.json +31 -0
  66. package/templates/storefront/themes/thanksgiving-2/campaign.fr.json +31 -0
  67. package/templates/storefront/themes/thanksgiving-2/theme.json +10 -0
@@ -0,0 +1,137 @@
1
+ import Link from "next/link"
2
+ import { t } from "@lib/boutique/i18n"
3
+ import { getProductPrice } from "@lib/util/get-product-price"
4
+ import { HttpTypes } from "@medusajs/types"
5
+ import { Icon } from "./icons"
6
+
7
+ type P = HttpTypes.StoreProduct
8
+ const imageOf = (p: P) => p.thumbnail ?? p.images?.[0]?.url ?? undefined
9
+ const priceOf = (p: P) => {
10
+ const { cheapestPrice: price } = getProductPrice({ product: p })
11
+ return { price, onSale: price?.price_type === "sale" }
12
+ }
13
+
14
+ /**
15
+ * « Offres phares » en accordéon : les cartes repliées montrent le nom à la verticale ; au survol ou au focus
16
+ * (clavier, toucher) une carte s'ouvre en grand avec photo, prix et remise. CSS seul, aucun JavaScript.
17
+ */
18
+ export function DealsFold({ products, title }: { products: P[]; title: string }) {
19
+ const items = products.slice(0, 5)
20
+ if (items.length < 3) return null
21
+
22
+ return (
23
+ <section className="ub-section">
24
+ <div className="ub-wrap">
25
+ <h2 className="ub-head ub-fold__title">{title}</h2>
26
+ <ul className="ub-fold">
27
+ {items.map((p, i) => {
28
+ const { price, onSale } = priceOf(p)
29
+ const image = imageOf(p)
30
+ return (
31
+ <li key={p.id} className="ub-fold__item">
32
+ <Link href={`/products/${p.handle}`} className="ub-fold__link" aria-label={t("card.view", { name: p.title ?? "" })}>
33
+ {image ? (
34
+ // eslint-disable-next-line @next/next/no-img-element
35
+ <img className="ub-fold__img" src={image} alt="" loading="lazy" />
36
+ ) : (
37
+ <span className="ub-fold__img ub-ph" />
38
+ )}
39
+ <span className="ub-fold__label">
40
+ <span className="ub-fold__num">{String(i + 1).padStart(2, "0")}</span>
41
+ {p.title}
42
+ </span>
43
+ <span className="ub-fold__body">
44
+ {onSale && price?.percentage_diff && <b className="ub-fold__off">-{price.percentage_diff}%</b>}
45
+ <span className="ub-fold__name">{p.title}</span>
46
+ {price && (
47
+ <span className="ub-fold__price">
48
+ {price.calculated_price}
49
+ {onSale && <s>{price.original_price}</s>}
50
+ </span>
51
+ )}
52
+ <span className="ub-fold__go" aria-hidden>
53
+ <Icon name="arrowUpRight" />
54
+ </span>
55
+ </span>
56
+ </Link>
57
+ </li>
58
+ )
59
+ })}
60
+ </ul>
61
+ </div>
62
+ </section>
63
+ )
64
+ }
65
+
66
+ /**
67
+ * Grande carte sombre : visuel du produit choisi à gauche, liste d'offres à droite (onglets radio + :has(),
68
+ * sans JavaScript). La première offre est sélectionnée par défaut.
69
+ */
70
+ export function DealsSpotlight({ products, eyebrow, title }: { products: P[]; eyebrow?: string; title: string }) {
71
+ const items = products.slice(0, 4)
72
+ if (items.length < 2) return null
73
+
74
+ return (
75
+ <section className="ub-section">
76
+ <div className="ub-wrap">
77
+ <div className="ub-spot">
78
+ <div className="ub-spot__head">
79
+ {eyebrow && (
80
+ <span className="ub-eyebrow">
81
+ <span className="ub-eyebrow__dot" />
82
+ {eyebrow}
83
+ </span>
84
+ )}
85
+ <h2 className="ub-head ub-spot__title">{title}</h2>
86
+ </div>
87
+ <div className="ub-spot__grid">
88
+ <div className="ub-spot__stage">
89
+ {items.map((p, i) => {
90
+ const image = imageOf(p)
91
+ return (
92
+ <div key={p.id} className="ub-spot__media" data-i={i}>
93
+ {image ? (
94
+ // eslint-disable-next-line @next/next/no-img-element
95
+ <img src={image} alt={p.title ?? ""} loading="lazy" />
96
+ ) : (
97
+ <span className="ub-ph" />
98
+ )}
99
+ </div>
100
+ )
101
+ })}
102
+ </div>
103
+ <div className="ub-spot__list" role="radiogroup" aria-label={title}>
104
+ {items.map((p, i) => {
105
+ const { price, onSale } = priceOf(p)
106
+ return (
107
+ <div key={p.id} className="ub-spot__item" data-i={i}>
108
+ <input type="radio" name="ub-spot" id={`ub-spot-${i}`} defaultChecked={i === 0} className="ub-spot__radio" />
109
+ <label htmlFor={`ub-spot-${i}`} className="ub-spot__label">
110
+ <span className="ub-spot__num">{String(i + 1).padStart(2, "0")}</span>
111
+ <span className="ub-spot__name">{p.title}</span>
112
+ {onSale && price?.percentage_diff && <b className="ub-spot__off">-{price.percentage_diff}%</b>}
113
+ </label>
114
+ <div className="ub-spot__more">
115
+ {p.description && <p>{p.description}</p>}
116
+ <div className="ub-spot__buy">
117
+ {price && (
118
+ <span className="ub-spot__price">
119
+ {price.calculated_price}
120
+ {onSale && <s>{price.original_price}</s>}
121
+ </span>
122
+ )}
123
+ <Link href={`/products/${p.handle}`} className="ub-spot__cta">
124
+ {t("card.viewShort")} <Icon name="arrowRight" />
125
+ </Link>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ )
130
+ })}
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </section>
136
+ )
137
+ }
@@ -0,0 +1,199 @@
1
+ /* Espace client : menu latéral, tableau de bord, formulaires de connexion. Tokens du thème uniquement. */
2
+ .ub-account { padding-top: var(--space-12); padding-bottom: var(--space-12); }
3
+ .ub-account__grid { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: var(--space-8); align-items: start; }
4
+ .ub-account__solo { display: grid; justify-items: center; }
5
+ .ub-account__solo .ub-account__main {
6
+ width: 100%;
7
+ max-width: 480px;
8
+ padding: clamp(24px, 4vw, 40px);
9
+ background: var(--surface);
10
+ border: 1px solid var(--border);
11
+ border-radius: var(--ub-r-card);
12
+ }
13
+ .ub-account__main { min-width: 0; }
14
+
15
+ /* ---------- Menu latéral ---------- */
16
+ .ub-accnav { position: sticky; top: 96px; display: grid; gap: var(--space-4); }
17
+ .ub-accnav__me {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: var(--space-3);
21
+ padding: var(--space-4);
22
+ background: var(--surface);
23
+ border: 1px solid var(--border);
24
+ border-radius: var(--ub-r-card);
25
+ }
26
+ .ub-accnav__avatar {
27
+ flex: none;
28
+ display: grid;
29
+ place-items: center;
30
+ width: 48px;
31
+ height: 48px;
32
+ border-radius: 50%;
33
+ background: var(--primary);
34
+ color: var(--on-primary);
35
+ font-family: var(--ub-font-head);
36
+ font-weight: 700;
37
+ font-size: 17px;
38
+ letter-spacing: 0.02em;
39
+ }
40
+ .ub-accnav__who { display: grid; min-width: 0; }
41
+ .ub-accnav__who b { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
42
+ .ub-accnav__who small { font-size: 12px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
43
+ .ub-accnav__list {
44
+ display: grid;
45
+ gap: 4px;
46
+ margin: 0;
47
+ padding: var(--space-2);
48
+ list-style: none;
49
+ background: var(--surface);
50
+ border: 1px solid var(--border);
51
+ border-radius: var(--ub-r-card);
52
+ }
53
+ .ub-accnav__link {
54
+ position: relative;
55
+ display: flex;
56
+ align-items: center;
57
+ gap: var(--space-3);
58
+ width: 100%;
59
+ padding: 11px 12px;
60
+ border-radius: calc(var(--ub-r-card) * 0.6);
61
+ font-size: 15px;
62
+ font-weight: 500;
63
+ color: var(--ink-muted);
64
+ text-align: left;
65
+ transition: background 0.15s, color 0.15s;
66
+ }
67
+ .ub-accnav__link:hover { background: var(--tint-1); color: var(--ink); }
68
+ .ub-accnav__link[aria-current="page"] { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--ink); font-weight: 700; }
69
+ .ub-accnav__link[aria-current="page"] .ub-accnav__ic { color: var(--primary); }
70
+ .ub-accnav__ic { display: inline-grid; place-items: center; width: 20px; height: 20px; }
71
+ .ub-accnav__ic svg { width: 20px; height: 20px; }
72
+ .ub-accnav__logout { margin-top: 4px; border-top: 1px solid var(--border); border-radius: 0 0 calc(var(--ub-r-card) * 0.6) calc(var(--ub-r-card) * 0.6); }
73
+ .ub-accnav__logout:hover { color: var(--sale); }
74
+
75
+ /* ---------- Tableau de bord ---------- */
76
+ .ub-acc { display: grid; gap: var(--space-6); }
77
+ .ub-acc__hello {
78
+ position: relative;
79
+ overflow: hidden;
80
+ display: flex;
81
+ align-items: flex-end;
82
+ justify-content: space-between;
83
+ gap: var(--space-4);
84
+ flex-wrap: wrap;
85
+ padding: clamp(24px, 4vw, 40px);
86
+ background: var(--hero-bg);
87
+ color: var(--hero-ink);
88
+ border-radius: var(--ub-r-card);
89
+ }
90
+ .ub-acc__hello::before {
91
+ content: "";
92
+ position: absolute;
93
+ right: -80px;
94
+ top: -120px;
95
+ width: 320px;
96
+ aspect-ratio: 1;
97
+ border-radius: 50%;
98
+ background: radial-gradient(circle, color-mix(in srgb, var(--primary) 35%, transparent), transparent 65%);
99
+ pointer-events: none;
100
+ }
101
+ .ub-acc__hello h1 { position: relative; font-size: clamp(28px, 3.4vw, 42px); line-height: 1.05; }
102
+ .ub-acc__hello p { position: relative; margin-top: 8px !important; font-size: 14px; color: var(--hero-muted); }
103
+ .ub-acc__hello p b { color: var(--hero-ink); }
104
+ .ub-acc__shop {
105
+ position: relative;
106
+ display: inline-flex;
107
+ align-items: center;
108
+ gap: 6px;
109
+ padding: 10px 18px;
110
+ border-radius: var(--ub-r-btn);
111
+ background: var(--primary);
112
+ color: var(--on-primary);
113
+ font-size: 14px;
114
+ font-weight: 700;
115
+ }
116
+ .ub-acc__shop svg, .ub-acc__more svg, .ub-acc__order > svg { width: 16px; height: 16px; }
117
+ .ub-acc__stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
118
+ .ub-acc__stat {
119
+ display: grid;
120
+ gap: 4px;
121
+ padding: var(--space-6);
122
+ background: var(--surface);
123
+ border: 1px solid var(--border);
124
+ border-radius: var(--ub-r-card);
125
+ transition: transform 0.2s, border-color 0.2s;
126
+ }
127
+ .ub-acc__stat:hover { transform: translateY(-2px); border-color: var(--primary); }
128
+ .ub-acc__stat b { margin-top: var(--space-3); font-family: var(--ub-font-head); font-size: 36px; line-height: 1; }
129
+ .ub-acc__stat small { font-size: 13px; color: var(--ink-muted); }
130
+ .ub-acc__ic {
131
+ display: inline-grid;
132
+ place-items: center;
133
+ width: 40px;
134
+ height: 40px;
135
+ border-radius: 12px;
136
+ background: color-mix(in srgb, var(--primary) 16%, transparent);
137
+ color: var(--primary);
138
+ }
139
+ .ub-acc__ic svg { width: 20px; height: 20px; }
140
+ .ub-acc__progress { display: grid; gap: 8px; font-size: 13px; color: var(--ink-muted); }
141
+ .ub-acc__progress i { display: block; height: 6px; border-radius: 99px; background: var(--tint-1); overflow: hidden; }
142
+ .ub-acc__progress i::before { content: ""; display: block; width: var(--p); height: 100%; background: var(--primary); border-radius: inherit; }
143
+ .ub-acc__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-4); }
144
+ .ub-acc__head h2 { font-size: 22px; }
145
+ .ub-acc__more { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: var(--primary); }
146
+ .ub-acc__orders { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
147
+ .ub-acc__order {
148
+ display: grid;
149
+ grid-template-columns: auto 1fr auto auto;
150
+ align-items: center;
151
+ gap: var(--space-4);
152
+ padding: var(--space-4);
153
+ background: var(--surface);
154
+ border: 1px solid var(--border);
155
+ border-radius: var(--ub-r-card);
156
+ transition: border-color 0.15s;
157
+ }
158
+ .ub-acc__order:hover { border-color: var(--primary); }
159
+ .ub-acc__order span:nth-child(2) { display: grid; }
160
+ .ub-acc__order small { font-size: 13px; color: var(--ink-muted); }
161
+ .ub-acc__amount { font-weight: 700; }
162
+ .ub-acc__empty {
163
+ display: grid;
164
+ justify-items: center;
165
+ gap: var(--space-3);
166
+ padding: var(--space-12) var(--space-6);
167
+ text-align: center;
168
+ background: var(--surface);
169
+ border: 1px dashed var(--border);
170
+ border-radius: var(--ub-r-card);
171
+ }
172
+
173
+ /* ---------- Aide ---------- */
174
+ .ub-account__help {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ gap: var(--space-6);
179
+ flex-wrap: wrap;
180
+ margin-top: var(--space-12);
181
+ padding: var(--space-6) var(--space-8);
182
+ background: var(--surface);
183
+ border: 1px solid var(--border);
184
+ border-radius: var(--ub-r-card);
185
+ }
186
+ .ub-account__help h3 { font-size: 22px; }
187
+ .ub-account__help p { margin-top: 4px !important; color: var(--ink-muted); font-size: 14px; }
188
+
189
+ @media (max-width: 900px) {
190
+ .ub-account__grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
191
+ .ub-accnav { position: static; }
192
+ .ub-accnav__list { display: flex; overflow-x: auto; scrollbar-width: none; }
193
+ .ub-accnav__list li { flex: none; }
194
+ .ub-accnav__link { white-space: nowrap; }
195
+ .ub-accnav__logout { margin-top: 0; border-top: 0; }
196
+ .ub-acc__stats { grid-template-columns: minmax(0, 1fr); }
197
+ .ub-acc__order { grid-template-columns: auto 1fr auto; }
198
+ .ub-acc__order > svg { display: none; }
199
+ }
@@ -0,0 +1,96 @@
1
+ /* Black Friday (thème de base, clair) : jaune / noir / blanc. Sections volontairement différentes de la variante
2
+ « Blackout » (black-friday-2, sombre) : grille bento au lieu de l'accordéon, carte jaune, bandeau « ruban de chantier ».
3
+ :not([data-variant]) : la variante halloween-2 emprunte la mise en page black-friday et ne doit pas hériter de ceci. */
4
+ [data-theme="black-friday"]:not([data-variant]) {
5
+ --bg: #ffffff; --surface: #f6f6f3; --tint-1: #fff6c2; --tint-2: #f4f4f2; --tint-3: #fde8e8; --tint-4: #f1f1ee;
6
+ --ink: #0a0a0a; --ink-muted: #525252; --border: #e6e6e1;
7
+ --primary: #ffd400; --on-primary: #0a0a0a; --accent: #0a0a0a; --on-accent: #ffd400;
8
+ --sale: #e11d48; --star: #f59e0b; --success: #15803d;
9
+ --hero-bg: #0a0a0a; --hero-ink: #ffffff; --hero-muted: #a3a3a3;
10
+ --band-bg: #ffd400; --band-ink: #0a0a0a; --bubble-bg: #ffd400; --bubble-ink: #0a0a0a;
11
+ --topbar-bg: #0a0a0a; --topbar-ink: #ffd400; --focus: #2563eb;
12
+ }
13
+ :root:not([data-variant])[data-theme="black-friday"] .ub-hero__title em { color: var(--primary); font-style: normal; }
14
+
15
+ /* ---------- Cartes produit : blanches, fine bordure, contour noir au survol ---------- */
16
+ [data-theme="black-friday"]:not([data-variant]) .ub-card { border: 1px solid var(--border); box-shadow: none; transition: transform 0.2s, border-color 0.2s; }
17
+ [data-theme="black-friday"]:not([data-variant]) .ub-card:hover { transform: translateY(-3px); border-color: var(--ink); }
18
+ [data-theme="black-friday"]:not([data-variant]) .ub-badge--sale { background: var(--primary); color: #0a0a0a; }
19
+
20
+ /* ---------- Offres phares : grille bento (toutes les cartes ouvertes) ---------- */
21
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold {
22
+ display: grid;
23
+ grid-template-columns: 2fr 1fr 1fr;
24
+ grid-template-rows: 1fr 1fr;
25
+ height: clamp(460px, 48vw, 640px);
26
+ }
27
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item { flex: none !important; }
28
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item:first-child { grid-row: span 2; }
29
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__link { border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); }
30
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__link::after { display: none; }
31
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__img { opacity: 1 !important; transform: none !important; }
32
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item:hover .ub-fold__img { transform: scale(1.04) !important; }
33
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__label { display: none; }
34
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__body {
35
+ opacity: 1 !important;
36
+ transform: none !important;
37
+ left: 12px;
38
+ right: 12px;
39
+ bottom: 12px;
40
+ padding: 12px 64px 12px 14px;
41
+ background: var(--bg);
42
+ color: var(--ink);
43
+ border-radius: var(--radius-md);
44
+ box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
45
+ }
46
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__name { font-size: clamp(16px, 1.6vw, 22px); }
47
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item:first-child .ub-fold__name { font-size: clamp(22px, 2.6vw, 34px); }
48
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__price { font-size: 17px; }
49
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__price s { opacity: 0.5; }
50
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__off { position: absolute; top: -14px; left: 14px; background: var(--sale); color: #fff; }
51
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__go { right: 12px; bottom: 50%; transform: translateY(50%); width: 40px; height: 40px; background: var(--primary); color: #0a0a0a; backdrop-filter: none; }
52
+
53
+ /* ---------- Carte d'offres : jaune, zone visuelle noire ---------- */
54
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot { background: var(--primary); color: #0a0a0a; }
55
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot::before { background: radial-gradient(circle, rgb(255 255 255 / 0.45), transparent 65%); }
56
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot .ub-eyebrow { color: #0a0a0a; }
57
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__stage { background: #0a0a0a; box-shadow: 18px 18px 0 rgb(0 0 0 / 0.9); border-radius: var(--radius-md); }
58
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__item { border-bottom-color: rgb(0 0 0 / 0.15); }
59
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__item::before { background: #0a0a0a; width: 4px; }
60
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__item:has(.ub-spot__radio:checked) { background: rgb(255 255 255 / 0.45); }
61
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__num,
62
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__off { color: #0a0a0a; }
63
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__off { background: rgb(0 0 0 / 0.1); }
64
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__more p { color: rgb(10 10 10 / 0.72); }
65
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__cta { background: #0a0a0a; color: var(--primary); }
66
+
67
+ /* ---------- Bandeau CTA « ruban de chantier » + pied de page clair ---------- */
68
+ [data-theme="black-friday"]:not([data-variant]) .ub-footwrap { --cta-bg: #0a0a0a; --cta-ink: #ffffff; --foot-bg: var(--surface); --foot-ink: var(--ink); }
69
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta { background: #0a0a0a; border-radius: var(--radius-md); padding-top: clamp(64px, 8vw, 104px); padding-bottom: clamp(64px, 8vw, 104px); }
70
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta__shape { display: none; }
71
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta::before,
72
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta::after {
73
+ content: "";
74
+ position: absolute;
75
+ left: 0;
76
+ right: 0;
77
+ height: 16px;
78
+ background: repeating-linear-gradient(-45deg, var(--primary) 0 18px, #0a0a0a 18px 36px);
79
+ }
80
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta::before { top: 0; }
81
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta::after { bottom: 0; }
82
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta__title em { color: var(--primary); text-decoration: none; }
83
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta__eyebrow { background: var(--primary); color: #0a0a0a; }
84
+ [data-theme="black-friday"]:not([data-variant]) .ub-footcta .ub-footcta__btn { background: var(--primary); color: #0a0a0a; border-color: var(--primary); }
85
+ [data-theme="black-friday"]:not([data-variant]) .ub-footwrap .ub-footer { border: 1px solid var(--border); border-radius: var(--radius-md); }
86
+ [data-theme="black-friday"]:not([data-variant]) .ub-footwrap .ub-footer .ub-logo__mark { background: var(--primary); }
87
+ [data-theme="black-friday"]:not([data-variant]) .ub-footwrap .ub-pays span { background: var(--bg); }
88
+
89
+ @media (max-width: 900px) {
90
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold { grid-template-columns: 1fr 1fr; grid-template-rows: none; grid-auto-rows: 220px; height: auto; flex-direction: row; }
91
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item { height: auto !important; }
92
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item:first-child { grid-column: span 2; grid-row: span 1; }
93
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__body { padding-right: 52px; }
94
+ [data-theme="black-friday"]:not([data-variant]) .ub-fold__item:not(:first-child) .ub-fold__price s { display: none; }
95
+ [data-theme="black-friday"]:not([data-variant]) .ub-spot__stage { box-shadow: 10px 10px 0 rgb(0 0 0 / 0.9); }
96
+ }
@@ -0,0 +1,61 @@
1
+ /* Téléphone avec indicatif pays (modules/common/components/phone-input). Même hauteur et mêmes couleurs
2
+ que les autres champs (variables Medusa UI rebranchées sur le thème dans medusa-ui.css). */
3
+ .ub-phone { display: flex; gap: 8px; width: 100%; }
4
+ .ub-phone__country {
5
+ position: relative;
6
+ flex: none;
7
+ display: flex;
8
+ align-items: center;
9
+ height: 44px;
10
+ padding: 0 32px 0 14px;
11
+ border: 1px solid var(--border-base);
12
+ border-radius: 0.375rem;
13
+ background: var(--bg-field);
14
+ font-size: 14px;
15
+ font-weight: 600;
16
+ white-space: nowrap;
17
+ cursor: pointer;
18
+ }
19
+ .ub-phone__country::after {
20
+ content: "";
21
+ position: absolute;
22
+ right: 12px;
23
+ top: 50%;
24
+ width: 7px;
25
+ height: 7px;
26
+ border-right: 1.5px solid currentColor;
27
+ border-bottom: 1.5px solid currentColor;
28
+ transform: translateY(-70%) rotate(45deg);
29
+ opacity: 0.6;
30
+ }
31
+ .ub-phone__country:hover { background: var(--bg-field-hover); }
32
+ .ub-phone__country:focus-within { box-shadow: var(--borders-interactive-with-active); }
33
+ .ub-phone__country select { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }
34
+ .ub-phone__flag { pointer-events: none; }
35
+ .ub-phone__field { position: relative; z-index: 0; flex: 1; min-width: 0; font-size: 14px; }
36
+ .ub-phone__field input {
37
+ display: block;
38
+ width: 100%;
39
+ height: 44px;
40
+ padding: 16px 16px 4px;
41
+ border: 1px solid var(--border-base);
42
+ border-radius: 0.375rem;
43
+ background: var(--bg-field);
44
+ color: inherit;
45
+ outline: none;
46
+ }
47
+ .ub-phone__field input:hover { background: var(--bg-field-hover); }
48
+ .ub-phone__field input:focus { box-shadow: var(--borders-interactive-with-active); }
49
+ .ub-phone__field label {
50
+ position: absolute;
51
+ top: 12px;
52
+ left: 0;
53
+ z-index: 1;
54
+ margin: 0 12px;
55
+ padding: 0 4px;
56
+ color: var(--fg-subtle);
57
+ transform-origin: 0 0;
58
+ transition: transform 0.3s, font-size 0.3s;
59
+ pointer-events: none;
60
+ }
61
+ .ub-phone[data-invalid] .ub-phone__field input { border-color: var(--sale); }
@@ -91,9 +91,26 @@ html[data-theme] {
91
91
 
92
92
  /* Couleurs Tailwind écrites en dur dans le starter (compte, panier, checkout, squelettes de chargement) :
93
93
  ramenées aux tokens du thème, sinon un thème sombre affiche des blocs blancs au texte illisible. */
94
- .ub :is(.bg-white, .bg-gray-50, .bg-neutral-50) {
94
+ /* bg-white = conteneurs de page du starter (étapes du checkout, résumé, code promo) sans marge intérieure :
95
+ transparents (en surface grise, leur contenu collé aux bords paraissait coupé). Menus déroulants : surface. */
96
+ .ub .bg-white {
97
+ background-color: transparent;
98
+ }
99
+ .ub .bg-white:is(.absolute, .fixed),
100
+ .ub :is(.bg-gray-50, .bg-neutral-50) {
95
101
  background-color: var(--surface);
96
102
  }
103
+ /* Sélecteur de quantité (IconBadge de Medusa UI, fond blanc imposé) et listes déroulantes natives */
104
+ .ub .ub-qty {
105
+ background: var(--bg-field) !important;
106
+ border-color: var(--border-base) !important;
107
+ color: var(--ink) !important;
108
+ border-radius: var(--ub-r-btn);
109
+ }
110
+ .ub select option {
111
+ background: var(--surface);
112
+ color: var(--ink);
113
+ }
97
114
  .ub :is(.bg-gray-100, .bg-neutral-100) {
98
115
  background-color: var(--tint-1);
99
116
  }