@salifbiaye/create-boutique 0.6.0 → 0.7.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 (182) hide show
  1. package/cli/dist/code.js +110 -0
  2. package/cli/dist/commands.js +143 -10
  3. package/cli/dist/create.js +54 -7
  4. package/cli/dist/generate.js +65 -4
  5. package/cli/dist/guide.js +10 -2
  6. package/cli/dist/index.js +20 -7
  7. package/cli/dist/payments.js +150 -0
  8. package/docs/fiche-client.en.html +2 -2
  9. package/docs/fiche-client.html +2 -2
  10. package/docs/guide-complet.fr.html +681 -256
  11. package/docs/guide-images/categories.jpg +0 -0
  12. package/docs/guide-images/clients.jpg +0 -0
  13. package/docs/guide-images/collections.jpg +0 -0
  14. package/docs/guide-images/commande-detail.jpg +0 -0
  15. package/docs/guide-images/commande-expedier.jpg +0 -0
  16. package/docs/guide-images/commande-menu.jpg +0 -0
  17. package/docs/guide-images/commande-paiement.jpg +0 -0
  18. package/docs/guide-images/commandes-liste.jpg +0 -0
  19. package/docs/guide-images/connexion.jpg +0 -0
  20. package/docs/guide-images/groupes-clients.jpg +0 -0
  21. package/docs/guide-images/inventaire.jpg +0 -0
  22. package/docs/guide-images/listes-prix.jpg +0 -0
  23. package/docs/guide-images/menu.jpg +0 -0
  24. package/docs/guide-images/mes-boutiques-fermer.jpg +0 -0
  25. package/docs/guide-images/mes-boutiques-panneau.jpg +0 -0
  26. package/docs/guide-images/mes-boutiques.jpg +0 -0
  27. package/docs/guide-images/parametres-boutique.jpg +0 -0
  28. package/docs/guide-images/parametres-canaux.jpg +0 -0
  29. package/docs/guide-images/parametres-emplacements.jpg +0 -0
  30. package/docs/guide-images/parametres-profil.jpg +0 -0
  31. package/docs/guide-images/parametres-regions.jpg +0 -0
  32. package/docs/guide-images/parametres-utilisateurs.jpg +0 -0
  33. package/docs/guide-images/produit-creer-details.jpg +0 -0
  34. package/docs/guide-images/produit-detail.jpg +0 -0
  35. package/docs/guide-images/produit-variantes-menu.jpg +0 -0
  36. package/docs/guide-images/produit-variantes.jpg +0 -0
  37. package/docs/guide-images/produits-liste.jpg +0 -0
  38. package/docs/guide-images/promotion-details.jpg +0 -0
  39. package/docs/guide-images/promotion-type.jpg +0 -0
  40. package/docs/guide-images/promotions-liste.jpg +0 -0
  41. package/docs/guide-images/site-boutique.jpg +0 -0
  42. package/docs/guide-images/site-fermee.png +0 -0
  43. package/docs/guide-images/vue-ensemble.jpg +0 -0
  44. package/package.json +3 -2
  45. package/templates/backend/medusa-config.ts +31 -25
  46. package/templates/backend/package-lock.json +21 -0
  47. package/templates/backend/package.json +2 -0
  48. package/templates/backend/src/admin/i18n/json/en.json +51 -3
  49. package/templates/backend/src/admin/i18n/json/fr.json +51 -3
  50. package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +2 -0
  51. package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +36 -1
  52. package/templates/backend/src/admin/routes/reviews/page.tsx +259 -0
  53. package/templates/backend/src/api/admin/boutique-campaigns/route.ts +3 -1
  54. package/templates/backend/src/api/admin/boutique-online/[salesChannelId]/route.ts +22 -0
  55. package/templates/backend/src/api/admin/reviews/[id]/route.ts +15 -0
  56. package/templates/backend/src/api/admin/reviews/route.ts +47 -0
  57. package/templates/backend/src/api/middlewares.ts +7 -0
  58. package/templates/backend/src/api/store/campaign/route.ts +5 -1
  59. package/templates/backend/src/api/store/reviews/latest/route.ts +39 -0
  60. package/templates/backend/src/api/store/reviews/order/route.ts +36 -0
  61. package/templates/backend/src/api/store/reviews/route.ts +43 -0
  62. package/templates/backend/src/api/store/reviews/summary/route.ts +28 -0
  63. package/templates/backend/src/emails/en.json +3 -1
  64. package/templates/backend/src/emails/fr.json +3 -1
  65. package/templates/backend/src/lib/email-config.ts +14 -0
  66. package/templates/backend/src/lib/emails.ts +9 -0
  67. package/templates/backend/src/lib/notify.ts +14 -8
  68. package/templates/backend/src/lib/payment-config.ts +66 -0
  69. package/templates/backend/src/lib/project.ts +12 -0
  70. package/templates/backend/src/lib/redirect-payment.ts +264 -0
  71. package/templates/backend/src/lib/review-token.ts +40 -0
  72. package/templates/backend/src/lib/reviews.ts +25 -0
  73. package/templates/backend/src/modules/naboopay/index.ts +6 -0
  74. package/templates/backend/src/modules/naboopay/service.ts +92 -0
  75. package/templates/backend/src/modules/paydunya/index.ts +6 -0
  76. package/templates/backend/src/modules/paydunya/service.ts +89 -0
  77. package/templates/backend/src/modules/paytech/index.ts +6 -0
  78. package/templates/backend/src/modules/paytech/service.ts +114 -0
  79. package/templates/backend/src/modules/product-review/index.ts +8 -0
  80. package/templates/backend/src/modules/product-review/migrations/Migration20261001090000.ts +18 -0
  81. package/templates/backend/src/modules/product-review/models/review.ts +25 -0
  82. package/templates/backend/src/modules/product-review/service.ts +6 -0
  83. package/templates/backend/src/modules/product-review/validators.ts +27 -0
  84. package/templates/backend/src/modules/smtp/index.ts +6 -0
  85. package/templates/backend/src/modules/smtp/service.ts +73 -0
  86. package/templates/backend/src/scripts/seed.ts +52 -36
  87. package/templates/backend/src/subscribers/fulfillment-emails.ts +1 -1
  88. package/templates/backend/src/workflows/reviews.ts +21 -0
  89. package/templates/backend/src/workflows/steps/create-review.ts +52 -0
  90. package/templates/backend/src/workflows/steps/update-review.ts +36 -0
  91. package/templates/storefront/PERSONNALISER.md +134 -0
  92. package/templates/storefront/locales/en.json +198 -11
  93. package/templates/storefront/locales/fr.json +198 -11
  94. package/templates/storefront/public/custom/LISEZMOI.txt +2 -0
  95. package/templates/storefront/src/app/(checkout)/layout.tsx +1 -1
  96. package/templates/storefront/src/app/(main)/layout.tsx +8 -1
  97. package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -7
  98. package/templates/storefront/src/app/(main)/page.tsx +149 -4
  99. package/templates/storefront/src/app/(main)/review/page.tsx +60 -0
  100. package/templates/storefront/src/app/(main)/store/page.tsx +3 -1
  101. package/templates/storefront/src/app/(main)/template.tsx +17 -2
  102. package/templates/storefront/src/app/layout.tsx +13 -1
  103. package/templates/storefront/src/lib/boutique/campaign.ts +5 -1
  104. package/templates/storefront/src/lib/boutique/page-name.ts +25 -0
  105. package/templates/storefront/src/lib/boutique/schema.ts +3 -1
  106. package/templates/storefront/src/lib/constants.tsx +17 -0
  107. package/templates/storefront/src/lib/data/review-actions.ts +28 -0
  108. package/templates/storefront/src/lib/data/reviews.ts +64 -0
  109. package/templates/storefront/src/modules/checkout/components/payment/index.tsx +26 -4
  110. package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +85 -2
  111. package/templates/storefront/src/modules/products/templates/index.tsx +5 -0
  112. package/templates/storefront/src/modules/store/components/shop-search.tsx +85 -0
  113. package/templates/storefront/src/modules/store/templates/index.tsx +16 -8
  114. package/templates/storefront/src/modules/store/templates/paginated-products.tsx +15 -3
  115. package/templates/storefront/src/modules/ub/album.tsx +2 -0
  116. package/templates/storefront/src/modules/ub/arena.tsx +182 -0
  117. package/templates/storefront/src/modules/ub/campaign-blocks.tsx +3 -2
  118. package/templates/storefront/src/modules/ub/campaign-ended.tsx +27 -13
  119. package/templates/storefront/src/modules/ub/cinema.tsx +2 -0
  120. package/templates/storefront/src/modules/ub/cookie-banner.tsx +62 -0
  121. package/templates/storefront/src/modules/ub/gala.tsx +2 -0
  122. package/templates/storefront/src/modules/ub/grimoire.tsx +35 -8
  123. package/templates/storefront/src/modules/ub/harvest.tsx +2 -1
  124. package/templates/storefront/src/modules/ub/hero-image.tsx +14 -0
  125. package/templates/storefront/src/modules/ub/home-kit.ts +45 -0
  126. package/templates/storefront/src/modules/ub/lantern.tsx +244 -0
  127. package/templates/storefront/src/modules/ub/locker.tsx +180 -0
  128. package/templates/storefront/src/modules/ub/mosaic.tsx +189 -0
  129. package/templates/storefront/src/modules/ub/nav.tsx +8 -5
  130. package/templates/storefront/src/modules/ub/review-form.tsx +62 -0
  131. package/templates/storefront/src/modules/ub/reviews.tsx +131 -0
  132. package/templates/storefront/src/modules/ub/riviera.tsx +175 -0
  133. package/templates/storefront/src/modules/ub/souk.tsx +214 -0
  134. package/templates/storefront/src/modules/ub/sunset-checklist.tsx +95 -0
  135. package/templates/storefront/src/modules/ub/sunset.tsx +164 -0
  136. package/templates/storefront/src/modules/ub/tech.tsx +2 -2
  137. package/templates/storefront/src/modules/ub/training.tsx +196 -0
  138. package/templates/storefront/src/proxy.ts +2 -0
  139. package/templates/storefront/src/styles/custom.css +26 -0
  140. package/templates/storefront/src/styles/ub/album.css +1 -1
  141. package/templates/storefront/src/styles/ub/arena.css +120 -0
  142. package/templates/storefront/src/styles/ub/cinema.css +1 -1
  143. package/templates/storefront/src/styles/ub/gala.css +1 -1
  144. package/templates/storefront/src/styles/ub/grimoire.css +23 -7
  145. package/templates/storefront/src/styles/ub/harvest.css +7 -6
  146. package/templates/storefront/src/styles/ub/lantern.css +157 -0
  147. package/templates/storefront/src/styles/ub/locker.css +115 -0
  148. package/templates/storefront/src/styles/ub/media.css +10 -0
  149. package/templates/storefront/src/styles/ub/mosaic.css +118 -0
  150. package/templates/storefront/src/styles/ub/motion.css +0 -3
  151. package/templates/storefront/src/styles/ub/overrides.css +10 -0
  152. package/templates/storefront/src/styles/ub/pages.css +176 -0
  153. package/templates/storefront/src/styles/ub/reviews.css +85 -0
  154. package/templates/storefront/src/styles/ub/riviera.css +103 -0
  155. package/templates/storefront/src/styles/ub/souk.css +144 -0
  156. package/templates/storefront/src/styles/ub/sunset.css +123 -0
  157. package/templates/storefront/src/styles/ub/tech.css +2 -5
  158. package/templates/storefront/src/styles/ub/training.css +120 -0
  159. package/templates/storefront/themes/jeux/campaign.en.json +31 -0
  160. package/templates/storefront/themes/jeux/campaign.fr.json +31 -0
  161. package/templates/storefront/themes/jeux/theme.json +11 -0
  162. package/templates/storefront/themes/jeux-2/campaign.en.json +31 -0
  163. package/templates/storefront/themes/jeux-2/campaign.fr.json +31 -0
  164. package/templates/storefront/themes/jeux-2/theme.json +11 -0
  165. package/templates/storefront/themes/mubarak/campaign.en.json +31 -0
  166. package/templates/storefront/themes/mubarak/campaign.fr.json +31 -0
  167. package/templates/storefront/themes/mubarak/theme.json +11 -0
  168. package/templates/storefront/themes/mubarak-2/campaign.en.json +31 -0
  169. package/templates/storefront/themes/mubarak-2/campaign.fr.json +31 -0
  170. package/templates/storefront/themes/mubarak-2/theme.json +11 -0
  171. package/templates/storefront/themes/sport/campaign.en.json +31 -0
  172. package/templates/storefront/themes/sport/campaign.fr.json +31 -0
  173. package/templates/storefront/themes/sport/theme.json +11 -0
  174. package/templates/storefront/themes/sport-2/campaign.en.json +31 -0
  175. package/templates/storefront/themes/sport-2/campaign.fr.json +31 -0
  176. package/templates/storefront/themes/sport-2/theme.json +11 -0
  177. package/templates/storefront/themes/summer/campaign.en.json +31 -0
  178. package/templates/storefront/themes/summer/campaign.fr.json +31 -0
  179. package/templates/storefront/themes/summer/theme.json +11 -0
  180. package/templates/storefront/themes/summer-2/campaign.en.json +31 -0
  181. package/templates/storefront/themes/summer-2/campaign.fr.json +31 -0
  182. package/templates/storefront/themes/summer-2/theme.json +11 -0
@@ -99,6 +99,74 @@
99
99
  border-color: var(--ink);
100
100
  color: var(--bg);
101
101
  }
102
+ /* Recherche de la page Boutique (modules/store/components/shop-search.tsx) */
103
+ .ub-shopsearch {
104
+ position: relative;
105
+ display: flex;
106
+ align-items: center;
107
+ flex: 1 1 260px;
108
+ max-width: 420px;
109
+ min-height: 44px;
110
+ margin-left: auto;
111
+ padding: 0 12px 0 42px;
112
+ border: 1px solid var(--border);
113
+ border-radius: var(--radius-pill);
114
+ background: var(--surface);
115
+ color: var(--ink);
116
+ transition: border-color 0.15s, box-shadow 0.15s;
117
+ }
118
+ .ub-shopsearch:focus-within {
119
+ border-color: var(--ink);
120
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
121
+ }
122
+ .ub-shopsearch > svg {
123
+ position: absolute;
124
+ left: 15px;
125
+ width: 18px;
126
+ height: 18px;
127
+ fill: none;
128
+ stroke: var(--ink-muted);
129
+ stroke-width: 1.8;
130
+ }
131
+ .ub-shopsearch input {
132
+ flex: 1;
133
+ min-width: 0;
134
+ height: 42px;
135
+ border: 0;
136
+ outline: 0;
137
+ background: transparent;
138
+ color: inherit;
139
+ font: inherit;
140
+ font-size: 15px;
141
+ }
142
+ .ub-shopsearch input::placeholder {
143
+ color: var(--ink-muted);
144
+ }
145
+ .ub-shopsearch input::-webkit-search-cancel-button {
146
+ display: none;
147
+ }
148
+ .ub-shopsearch[aria-busy="true"] > svg {
149
+ stroke: var(--primary);
150
+ }
151
+ .ub-shopsearch__clear {
152
+ display: grid;
153
+ place-items: center;
154
+ width: 28px;
155
+ height: 28px;
156
+ border: 0;
157
+ border-radius: 50%;
158
+ background: var(--tint-1);
159
+ color: var(--ink);
160
+ font-size: 18px;
161
+ line-height: 1;
162
+ cursor: pointer;
163
+ }
164
+ .ub-shop__empty {
165
+ padding: var(--space-16) 0;
166
+ color: var(--ink-muted);
167
+ font-size: 17px;
168
+ text-align: center;
169
+ }
102
170
  .ub-sort {
103
171
  display: inline-flex;
104
172
  padding: 4px;
@@ -283,6 +351,7 @@
283
351
  .ub-contacthero__badge { justify-items: start; text-align: left; }
284
352
  .ub-shop__bar { flex-direction: column; align-items: stretch; }
285
353
  .ub-sort { align-self: flex-start; }
354
+ .ub-shopsearch { max-width: none; margin-left: 0; flex-basis: auto; }
286
355
  .ub-contact__cards { grid-template-columns: minmax(0, 1fr); }
287
356
  .ub-contact__faq { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-top: var(--space-12); }
288
357
  }
@@ -380,3 +449,110 @@
380
449
  .ub-footwrap { padding: 0 var(--space-2); }
381
450
  .ub-footcta, .ub-footwrap .ub-footer { border-radius: var(--radius-xl); }
382
451
  }
452
+
453
+ /* ---------- Boutique fermée (admin → Campagnes → Hors ligne) : couleurs de la page, pas du hero ---------- */
454
+ .ub-closed { background: var(--surface); color: var(--ink); border-bottom: 1px solid var(--border); }
455
+ .ub-closed__in { display: grid; justify-items: center; gap: 18px; min-height: 58vh; align-content: center; padding-top: 72px; padding-bottom: 72px; text-align: center; }
456
+ .ub-closed__icon { display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%; background: var(--bg); color: var(--primary); box-shadow: var(--shadow-card, 0 10px 30px -18px rgb(0 0 0 / 0.4)); }
457
+ .ub-closed__title { margin: 0; color: var(--ink); font-size: clamp(30px, 4vw, 48px); line-height: 1.1; }
458
+ .ub-closed__text { max-width: 34em; margin: 0; color: var(--ink-muted); font-size: 17px; line-height: 26px; }
459
+ .ub-closed__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 6px; }
460
+ /* Site fermé : plus d'appel à acheter (bouton du menu, bannière du pied de page) */
461
+ body:has(.ub-closed) .ub-nav__cta,
462
+ body:has(.ub-closed) .ub-footcta { display: none; }
463
+
464
+ /* Le champ est dans un conteneur qui porte déjà l'anneau de focus : pas de second cadre sur le texte */
465
+ .ub-shopsearch input:focus,
466
+ .ub-shopsearch input:focus-visible,
467
+ .ub-search input:focus,
468
+ .ub-search input:focus-visible {
469
+ outline: none;
470
+ box-shadow: none;
471
+ }
472
+ .ub-search:focus-within {
473
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
474
+ }
475
+
476
+ /* ---------- Bandeau cookies (modules/ub/cookie-banner.tsx) : variables du thème, discret, n'empêche pas de naviguer ---------- */
477
+ .ub-cookies {
478
+ position: fixed;
479
+ z-index: 60;
480
+ left: 20px;
481
+ bottom: 20px;
482
+ display: grid;
483
+ gap: 14px;
484
+ width: min(420px, calc(100vw - 40px));
485
+ padding: 18px 20px;
486
+ border: 1px solid var(--border);
487
+ border-top: 3px solid var(--primary);
488
+ border-radius: var(--ub-r-card, 14px);
489
+ background: var(--surface);
490
+ color: var(--ink);
491
+ box-shadow: 0 24px 60px -20px rgb(0 0 0 / 0.45);
492
+ font-family: var(--ub-font-body, inherit);
493
+ animation: ub-cookies-in 0.35s ease-out both;
494
+ }
495
+ .ub-cookies__title {
496
+ display: block;
497
+ margin-bottom: 4px;
498
+ font-family: var(--ub-font-head, inherit);
499
+ font-size: 16px;
500
+ }
501
+ .ub-cookies p {
502
+ margin: 0;
503
+ color: var(--ink-muted);
504
+ font-size: 14px;
505
+ line-height: 21px;
506
+ }
507
+ .ub-cookies p a {
508
+ color: var(--ink);
509
+ text-decoration: underline;
510
+ text-underline-offset: 3px;
511
+ }
512
+ .ub-cookies__actions {
513
+ display: flex;
514
+ justify-content: flex-end;
515
+ gap: 10px;
516
+ }
517
+ .ub-cookies__btn {
518
+ min-height: 42px;
519
+ padding: 0 20px;
520
+ border: 0;
521
+ border-radius: var(--ub-r-btn, 999px);
522
+ background: var(--primary);
523
+ color: var(--on-primary);
524
+ font-weight: 600;
525
+ font-size: 14px;
526
+ cursor: pointer;
527
+ }
528
+ .ub-cookies__btn--ghost {
529
+ background: transparent;
530
+ color: var(--ink);
531
+ box-shadow: inset 0 0 0 1px var(--border);
532
+ }
533
+ .ub-cookies__btn:focus-visible {
534
+ outline: 2px solid var(--focus, var(--primary));
535
+ outline-offset: 2px;
536
+ }
537
+ @keyframes ub-cookies-in {
538
+ from { opacity: 0; transform: translateY(12px); }
539
+ }
540
+ @media (prefers-reduced-motion: reduce) {
541
+ .ub-cookies { animation: none; }
542
+ }
543
+ @media (max-width: 600px) {
544
+ .ub-cookies { left: 12px; right: 12px; bottom: 12px; width: auto; }
545
+ .ub-cookies__btn { flex: 1; }
546
+ }
547
+
548
+ /* ---------- Pages légales (app/(main)/legal/[page]) : lisibles, sommaire, sections ---------- */
549
+ .ub-legal .ub-wrap { max-width: 780px; }
550
+ .ub-legal__title { margin: 0 0 6px; font-size: clamp(30px, 4vw, 40px); line-height: 1.15; }
551
+ .ub-legal__updated { margin: 0 0 var(--space-8); color: var(--ink-muted); font-size: 14px; }
552
+ .ub-legal__toc { margin-bottom: var(--space-8); padding: 18px 22px; border: 1px solid var(--border); border-radius: var(--ub-r-card, 12px); background: var(--surface); }
553
+ .ub-legal__toc ol { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 24px; margin: 0; padding-left: 20px; }
554
+ .ub-legal__toc a { color: var(--ink); font-size: 15px; text-decoration: none; }
555
+ .ub-legal__toc a:hover { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }
556
+ .ub-legal__sec { padding: 22px 0; border-top: 1px solid var(--border); scroll-margin-top: 90px; }
557
+ .ub-legal__sec h2 { margin: 0 0 8px; font-family: var(--ub-font-head, inherit); font-size: 20px; line-height: 1.3; }
558
+ .ub-legal__sec p { margin: 0; color: var(--ink-muted); font-size: 16px; line-height: 1.7; }
@@ -0,0 +1,85 @@
1
+ /* Avis clients (modules/ub/reviews.tsx, review-form.tsx, app/(main)/review) : variables du thème, s'accorde à chaque boutique. */
2
+
3
+ .ub-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
4
+
5
+ /* Étoiles : la dernière peut être remplie en partie (moyenne) */
6
+ .ub-stars { display: inline-flex; gap: 2px; vertical-align: middle; }
7
+ .ub-stars__one { position: relative; display: inline-block; width: var(--s, 16px); height: var(--s, 16px); background: color-mix(in srgb, var(--ink-muted) 35%, transparent); -webkit-mask: var(--ub-star-shape) center / contain no-repeat; mask: var(--ub-star-shape) center / contain no-repeat; }
8
+ .ub-stars__one > span { position: absolute; inset: 0 auto 0 0; background: var(--star, #f5b400); }
9
+ :root { --ub-star-shape: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.5l2.9 6.1 6.6.8-4.9 4.6 1.3 6.6L12 17.3l-5.9 3.3 1.3-6.6-4.9-4.6 6.6-.8z'/%3E%3C/svg%3E"); }
10
+
11
+ /* ---------- Fiche produit ---------- */
12
+ .ub-reviews { scroll-margin-top: 90px; }
13
+ .ub-reviews__title { margin: 0 0 var(--space-8); font-size: clamp(26px, 3vw, 36px); }
14
+ .ub-reviews__empty { max-width: 40em; margin: 0; padding: 24px; border: 1px dashed var(--border); border-radius: var(--ub-r-card, 12px); color: var(--ink-muted); }
15
+ .ub-reviews__grid { display: grid; grid-template-columns: minmax(240px, 300px) minmax(0, 1fr); gap: var(--space-12); align-items: start; }
16
+ .ub-reviews__summary { position: sticky; top: 100px; display: grid; gap: 10px; padding: 24px; border: 1px solid var(--border); border-radius: var(--ub-r-card, 12px); background: var(--surface); }
17
+ .ub-reviews__avg { margin: 0; line-height: 1; }
18
+ .ub-reviews__avg b { font: 700 48px/1 var(--ub-font-head, inherit); color: var(--ink); }
19
+ .ub-reviews__avg span { color: var(--ink-muted); font-size: 18px; }
20
+ .ub-reviews__count { margin: 0; color: var(--ink-muted); font-size: 14px; }
21
+ .ub-reviews__bars { display: grid; gap: 6px; margin: 6px 0 0; padding: 0; list-style: none; font-size: 13px; color: var(--ink-muted); }
22
+ .ub-reviews__bars li { display: grid; grid-template-columns: 30px 1fr 24px; align-items: center; gap: 8px; }
23
+ .ub-reviews__bar { height: 6px; overflow: hidden; border-radius: 999px; background: color-mix(in srgb, var(--ink-muted) 18%, transparent); }
24
+ .ub-reviews__bar i { display: block; height: 100%; border-radius: inherit; background: var(--star, #f5b400); }
25
+ .ub-reviews__how { margin: 8px 0 0; padding-top: 12px; border-top: 1px solid var(--border); color: var(--ink-muted); font-size: 13px; line-height: 1.5; }
26
+ .ub-reviews__list { display: grid; gap: 14px; margin: 0; padding: 0; list-style: none; }
27
+ .ub-review { padding: 20px 22px; border: 1px solid var(--border); border-radius: var(--ub-r-card, 12px); background: var(--surface); }
28
+ .ub-review__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
29
+ .ub-review__verified { display: inline-flex; align-items: center; gap: 6px; color: var(--success, #149e5f); font-size: 12px; font-weight: 600; }
30
+ .ub-review__verified::before { content: "✓"; display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--success, #149e5f); color: #fff; font-size: 10px; }
31
+ .ub-review__title { margin: 10px 0 0; font-weight: 700; color: var(--ink); }
32
+ .ub-review__text { margin: 6px 0 0; color: var(--ink); line-height: 1.6; white-space: pre-line; }
33
+ .ub-review__by { margin: 10px 0 0; color: var(--ink-muted); font-size: 13px; }
34
+
35
+ /* ---------- Accueil : derniers avis ---------- */
36
+ .ub-homereviews__head { display: grid; justify-items: center; gap: 6px; margin-bottom: var(--space-8); text-align: center; }
37
+ .ub-homereviews__head .ub-head { margin: 0; font-size: clamp(26px, 3.2vw, 40px); }
38
+ .ub-homereviews__kicker { margin: 0; color: var(--primary); font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; }
39
+ .ub-homereviews__list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin: 0; padding: 0; list-style: none; }
40
+ .ub-quote { display: flex; flex-direction: column; gap: 12px; height: 100%; margin: 0; padding: 24px; border: 1px solid var(--border); border-radius: var(--ub-r-card, 14px); background: var(--surface); }
41
+ .ub-quote blockquote { flex: 1; margin: 0; }
42
+ .ub-quote blockquote b { display: block; margin-bottom: 6px; color: var(--ink); }
43
+ .ub-quote blockquote p { margin: 0; color: var(--ink); line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
44
+ .ub-quote blockquote::before { content: "“"; display: block; height: 28px; color: var(--primary); font: 700 48px/1 Georgia, serif; }
45
+ .ub-quote__product { display: flex; align-items: center; gap: 12px; padding-top: 14px; border-top: 1px solid var(--border); color: var(--ink); }
46
+ .ub-quote__img { flex: none; width: 44px; height: 44px; overflow: hidden; border-radius: var(--ub-r-media, 8px); background: var(--tint-1); }
47
+ .ub-quote__img img { width: 100%; height: 100%; object-fit: cover; }
48
+ .ub-quote__product span:last-child { display: grid; min-width: 0; }
49
+ .ub-quote__product b { font-size: 14px; }
50
+ .ub-quote__product small { overflow: hidden; color: var(--ink-muted); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
51
+
52
+ /* ---------- Page « Laisser un avis » ---------- */
53
+ .ub-reviewpage .ub-wrap { max-width: 760px; }
54
+ .ub-reviewpage__title { margin: 0 0 8px; font-size: clamp(28px, 4vw, 40px); }
55
+ .ub-reviewpage__lead { margin: 0 0 var(--space-8); color: var(--ink-muted); font-size: 16px; line-height: 1.6; }
56
+ .ub-reviewpage__list { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }
57
+ .ub-reviewpage__item { padding: 22px; border: 1px solid var(--border); border-radius: var(--ub-r-card, 14px); background: var(--surface); }
58
+ .ub-reviewpage__product { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; color: var(--ink); }
59
+ .ub-reviewpage__img { flex: none; width: 60px; height: 60px; overflow: hidden; border-radius: var(--ub-r-media, 10px); background: var(--tint-1); }
60
+ .ub-reviewpage__img img { width: 100%; height: 100%; object-fit: cover; }
61
+
62
+ .ub-rform { display: grid; gap: 14px; }
63
+ .ub-rform__stars { display: flex; align-items: center; gap: 4px; margin: 0; padding: 0; border: 0; }
64
+ .ub-rform__stars legend { margin-bottom: 6px; color: var(--ink); font-size: 14px; font-weight: 600; }
65
+ .ub-rform__stars label { position: relative; cursor: pointer; color: color-mix(in srgb, var(--ink-muted) 45%, transparent); font-size: 34px; line-height: 1; transition: transform 0.12s, color 0.12s; }
66
+ .ub-rform__stars label.is-on { color: var(--star, #f5b400); }
67
+ .ub-rform__stars label:hover { transform: scale(1.12); }
68
+ .ub-rform__stars input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
69
+ .ub-rform__stars label:focus-within { outline: 2px solid var(--focus, var(--primary)); outline-offset: 2px; border-radius: 6px; }
70
+ .ub-rform__hint { margin-left: 10px; color: var(--ink-muted); font-size: 14px; }
71
+ .ub-rform__field { display: grid; gap: 6px; color: var(--ink); font-size: 14px; font-weight: 600; }
72
+ .ub-rform__field small { color: var(--ink-muted); font-weight: 400; }
73
+ .ub-rform__field input, .ub-rform__field textarea { width: 100%; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--ub-r-btn-input, 10px); background: var(--bg); color: var(--ink); font: inherit; font-weight: 400; }
74
+ .ub-rform__field input:focus, .ub-rform__field textarea:focus { outline: 2px solid color-mix(in srgb, var(--primary) 40%, transparent); outline-offset: 0; border-color: var(--primary); }
75
+ .ub-rform__btn { display: inline-flex; align-items: center; justify-content: center; justify-self: start; min-height: 48px; padding: 0 24px; border: 0; border-radius: var(--ub-r-btn, 999px); background: var(--primary); color: var(--on-primary); font-weight: 700; cursor: pointer; }
76
+ .ub-rform__btn:disabled { opacity: 0.5; cursor: not-allowed; }
77
+ .ub-rform__error { margin: 0; color: var(--sale, #dc2626); font-size: 14px; }
78
+ .ub-rform__done { margin: 0; padding: 14px 16px; border-radius: var(--ub-r-card, 10px); background: color-mix(in srgb, var(--success, #149e5f) 12%, transparent); color: var(--ink); }
79
+
80
+ @media (max-width: 900px) {
81
+ .ub-reviews__grid { grid-template-columns: 1fr; gap: var(--space-8); }
82
+ .ub-reviews__summary { position: static; }
83
+ .ub-homereviews__list { grid-auto-flow: column; grid-template-columns: none; grid-auto-columns: min(82%, 320px); overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 8px; }
84
+ .ub-homereviews__list > li { scroll-snap-align: start; }
85
+ }
@@ -0,0 +1,103 @@
1
+ /* Accueil « Riviera » (Summer) — modules/ub/riviera.tsx. Élégance d'été : gris perle, vert bouteille, laiton ; typo à empattements.
2
+ Jetons valables sur tout le site (fiche produit, panier, checkout, compte). */
3
+
4
+ [data-variant="summer"] {
5
+ --bg: #f1efeb; --surface: #e8e5df; --tint-1: #e4e0d8; --tint-2: #e9ece6; --tint-3: #ece6dc; --tint-4: #e3e7e4;
6
+ --ink: #16181a; --ink-muted: #5d6360; --border: #d9d5cd;
7
+ --primary: #1f3a30; --on-primary: #f4f1ea; --accent: #a8864a; --on-accent: #16181a;
8
+ --sale: #9a3b2e; --star: #a8864a; --success: #2f6b4f;
9
+ --hero-bg: #efeeeb; --hero-ink: #16181a; --hero-muted: #55595a;
10
+ --band-bg: #1f3a30; --band-ink: #f4f1ea; --bubble-bg: #1f3a30; --bubble-ink: #f4f1ea;
11
+ --topbar-bg: #1f3a30; --topbar-ink: #efe7d6; --focus: #a8864a;
12
+ --shadow-card: 0 18px 40px -28px rgb(22 24 26 / 0.45);
13
+ --ub-font-head: var(--font-serif); --ub-font-body: var(--font-jakarta);
14
+ --ub-head-weight: 500; --ub-head-case: none; --ub-head-track: -0.01em;
15
+ --ub-r-card: 2px; --ub-r-btn: 999px; --ub-r-tile: 2px; --ub-r-hero: 0px; --ub-r-media: 2px;
16
+ --rv-green: #1f3a30; --rv-brass: #a8864a;
17
+ color-scheme: light;
18
+ }
19
+ [data-variant="summer"] .ub-nav { background: var(--bg); border-bottom: 1px solid var(--border); }
20
+ [data-variant="summer"] .ub-nav__cta { background: var(--rv-green); color: #f4f1ea; }
21
+ [data-variant="summer"] .ub-footwrap { --foot-bg: var(--rv-green); --foot-ink: #efe7d6; --cta-bg: #e8e5df; --cta-ink: #16181a; }
22
+ [data-variant="summer"] .ub-card { background: transparent; box-shadow: none; }
23
+ [data-variant="summer"] .ub-badge { background: var(--rv-green); color: #f4f1ea; }
24
+
25
+ .ub-rv-kicker { margin: 0; color: var(--rv-brass); font: 600 12px/16px var(--ub-font-body); letter-spacing: 0.32em; text-transform: uppercase; }
26
+ .ub-rv-h2 { margin: 8px 0 0; font: 500 clamp(30px, 3.6vw, 50px) / 1.08 var(--font-serif); letter-spacing: -0.01em; }
27
+ .ub-rv-sub { max-width: 32em; margin: 0; color: var(--hero-muted); font-size: 17px; line-height: 28px; }
28
+ .ub-rv-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 30px; border-radius: 999px; font: 600 14px/18px var(--ub-font-body); letter-spacing: 0.08em; text-transform: uppercase; transition: background 0.2s, transform 0.2s; }
29
+ .ub-rv-btn--solid { background: var(--rv-green); color: #f4f1ea; }
30
+ .ub-rv-btn--solid:hover { transform: translateY(-2px); }
31
+ .ub-rv-btn--light { background: #f4f1ea; color: var(--rv-green); }
32
+ .ub-rv-link { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 600; border-bottom: 1px solid currentColor; padding-bottom: 2px; }
33
+ .ub-rv-link svg { width: 16px; height: 16px; }
34
+ .ub-rv-price { display: inline-flex; gap: 8px; align-items: baseline; font-weight: 600; }
35
+ .ub-rv-price s { color: var(--ink-muted); font-weight: 400; font-size: 0.9em; }
36
+
37
+ /* ---------- Hero éditorial ---------- */
38
+ .ub-rv-hero { position: relative; isolation: isolate; overflow: hidden; background: var(--hero-bg); color: var(--hero-ink); }
39
+ .ub-rv-hero__in { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; min-height: clamp(600px, 50vw, 780px); padding-top: var(--space-12); padding-bottom: var(--space-12); }
40
+ .ub-rv-hero__text { display: grid; justify-items: start; gap: 22px; align-self: center; padding-bottom: 40px; }
41
+ .ub-rv-title { margin: 0; font: 500 clamp(46px, 5.6vw, 86px) / 1.02 var(--font-serif); letter-spacing: -0.02em; text-wrap: balance; }
42
+ .ub-rv-title em { font-style: italic; color: var(--rv-green); }
43
+ .ub-rv-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; }
44
+ .ub-rv-note { margin: 0; padding-left: 14px; border-left: 2px solid var(--rv-brass); color: var(--hero-muted); font-size: 14px; }
45
+ .ub-rv-note b { color: var(--ink); font: 500 22px/1 var(--font-serif); }
46
+ /* Visuel en fond : moitié droite, fondu vers la gauche et fusionné avec le fond (multiply : le gris du studio disparaît) */
47
+ .ub-rv-hero .ub-rv-hero__bg { left: 38%; mix-blend-mode: multiply; -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 34%); mask-image: linear-gradient(90deg, transparent 0%, #000 34%); }
48
+ .ub-rv-hero .ub-rv-hero__bg:has(.ub-fade.is-loaded) { background: none; }
49
+ @media (max-width: 900px) {
50
+ .ub-rv-hero .ub-rv-hero__in { grid-template-columns: 1fr; min-height: 0; padding-top: 360px; padding-bottom: 40px; }
51
+ .ub-rv-hero .ub-rv-hero__bg { left: 0; bottom: auto; height: 420px; -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent); mask-image: linear-gradient(180deg, #000 55%, transparent); }
52
+ }
53
+
54
+ /* ---------- Sections ---------- */
55
+ .ub-rv-section { padding-top: var(--space-16); }
56
+ .ub-riviera > :last-child { padding-bottom: var(--space-16); }
57
+ .ub-rv-head { display: grid; gap: 4px; margin-bottom: var(--space-8); }
58
+ .ub-rv-head--row { display: flex; align-items: end; justify-content: space-between; gap: var(--space-6); }
59
+
60
+ /* Lookbook : une grande image, deux petites empilées */
61
+ .ub-rv-looks { display: grid; grid-template-columns: 1.25fr 1fr; grid-template-rows: 1fr 1fr; gap: 20px; }
62
+ .ub-rv-look { position: relative; display: grid; overflow: hidden; color: var(--ink); }
63
+ .ub-rv-look--1 { grid-row: span 2; }
64
+ .ub-rv-look__img { display: block; overflow: hidden; background: var(--surface); aspect-ratio: 4 / 5; }
65
+ .ub-rv-look--2 .ub-rv-look__img, .ub-rv-look--3 .ub-rv-look__img { aspect-ratio: 16 / 9; }
66
+ .ub-rv-look__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s cubic-bezier(0.2, 0.7, 0.2, 1); }
67
+ .ub-rv-look:hover .ub-rv-look__img img { transform: scale(1.03); }
68
+ .ub-rv-look__cap { display: grid; gap: 2px; padding: 12px 0 0; }
69
+ .ub-rv-look__cap small { color: var(--rv-brass); font-size: 11px; letter-spacing: 0.3em; text-transform: uppercase; }
70
+ .ub-rv-look__cap b { font: 500 20px/1.25 var(--font-serif); }
71
+
72
+ /* Couleurs de la saison : rail horizontal, pastille de couleur sous chaque pièce */
73
+ .ub-rv-colours { margin-top: var(--space-16); padding: var(--space-16) 0; background: var(--surface); }
74
+ .ub-rv-rail { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(200px, 1fr); gap: 20px; margin: 0; padding: 0 0 8px; list-style: none; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; }
75
+ .ub-rv-rail > li { scroll-snap-align: start; }
76
+ @media (min-width: 1100px) { .ub-rv-rail { grid-auto-columns: calc((100% - 60px) / 4); } }
77
+ .ub-rv-piece { display: grid; gap: 8px; color: var(--ink); }
78
+ .ub-rv-piece__img { display: block; aspect-ratio: 3 / 4; overflow: hidden; background: var(--bg); }
79
+ .ub-rv-piece__img img { width: 100%; height: 100%; object-fit: cover; }
80
+ .ub-rv-piece__swatch { width: 28px; height: 28px; margin-top: 4px; border-radius: 50%; box-shadow: 0 0 0 1px var(--border), inset 0 0 0 3px var(--surface); }
81
+ .ub-rv-piece__name { font-weight: 600; font-size: 15px; }
82
+
83
+ /* Sur-mesure : bloc vert, étapes numérotées */
84
+ .ub-rv-tailor { display: grid; grid-template-columns: 1.1fr 1fr; gap: 40px; padding: clamp(32px, 5vw, 64px); background: var(--rv-green); color: #f4f1ea; }
85
+ .ub-rv-tailor .ub-rv-h2 { color: #f4f1ea; }
86
+ .ub-rv-tailor .ub-rv-sub { color: #cfd8d2; }
87
+ .ub-rv-tailor__text { display: grid; justify-items: start; gap: 18px; }
88
+ .ub-rv-cd .ub-countdown__c { background: rgb(255 255 255 / 0.08); color: #f4f1ea; box-shadow: none; border: 1px solid rgb(255 255 255 / 0.2); }
89
+ .ub-rv-cd .ub-countdown__c small { color: #cfd8d2; }
90
+ .ub-rv-steps { display: grid; align-content: center; gap: 0; margin: 0; padding: 0; list-style: none; }
91
+ .ub-rv-steps li { display: grid; grid-template-columns: 64px 1fr; gap: 16px; align-items: center; padding: 20px 0; border-bottom: 1px solid rgb(255 255 255 / 0.18); }
92
+ .ub-rv-steps__n { font: 500 38px/1 var(--font-serif); color: var(--rv-brass); }
93
+ .ub-rv-steps b { display: block; font-size: 17px; }
94
+ .ub-rv-steps small { color: #cfd8d2; font-size: 14px; }
95
+
96
+ @media (max-width: 900px) {
97
+ .ub-rv-hero__in { grid-template-columns: 1fr; gap: 0; padding-top: var(--space-8); }
98
+ .ub-rv-hero__text { padding-bottom: var(--space-6); }
99
+ .ub-rv-looks { grid-template-columns: 1fr 1fr; grid-template-rows: auto; }
100
+ .ub-rv-look--1 { grid-column: span 2; grid-row: auto; }
101
+ .ub-rv-tailor { grid-template-columns: 1fr; }
102
+ .ub-rv-head--row { flex-direction: column; align-items: start; }
103
+ }
@@ -0,0 +1,144 @@
1
+ /* Accueil « Souk » (Mubarak · Sable) — modules/ub/souk.tsx. Crème, sable, terre cuite, safran, indigo ; treillis, auvents, cachet de cire. */
2
+
3
+ [data-variant="mubarak-2"] {
4
+ --bg: #fbf6ee; --surface: #ffffff; --tint-1: #f6ead9; --tint-2: #f3e3cf; --tint-3: #efe1d0; --tint-4: #f7eee2;
5
+ --ink: #2a1a10; --ink-muted: #7a6554; --border: #eadccb;
6
+ --primary: #8a3b1e; --on-primary: #fff8ef; --accent: #c8841f; --on-accent: #2a1a10;
7
+ --sale: #a8431f; --star: #c8841f; --success: #3f7a57;
8
+ --hero-bg: #fbf6ee; --hero-ink: #2a1a10; --hero-muted: #6b5645;
9
+ --band-bg: #8a3b1e; --band-ink: #fff8ef; --bubble-bg: #8a3b1e; --bubble-ink: #fff8ef;
10
+ --topbar-bg: #5a2a17; --topbar-ink: #f6e3c4; --focus: #c8841f;
11
+ --shadow-card: 0 20px 40px -26px rgb(90 42 23 / 0.45);
12
+ --ub-font-head: var(--font-poppins); --ub-font-body: var(--font-inter);
13
+ --ub-head-weight: 600; --ub-head-case: none; --ub-head-track: -0.01em;
14
+ --ub-r-card: 16px; --ub-r-btn: 999px; --ub-r-tile: 16px; --ub-r-hero: 0px; --ub-r-media: 12px;
15
+ --sk-terra: #a8431f; --sk-brown: #5a2a17; --sk-saffron: #d99a22; --sk-indigo: #2c3e74; --sk-teal: #1f6b66; --sk-sand: #e9d4b4;
16
+ color-scheme: light;
17
+ }
18
+ [data-variant="mubarak-2"] .ub-nav { background: rgb(251 246 238 / 0.95); border-bottom: 1px solid var(--border); }
19
+ [data-variant="mubarak-2"] .ub-nav__cta { background: var(--sk-terra); color: #fff8ef; }
20
+ [data-variant="mubarak-2"] .ub-footwrap { --foot-bg: #5a2a17; --foot-ink: #f6e3c4; --cta-bg: var(--sk-saffron); --cta-ink: #2a1a10; }
21
+
22
+ /* ---------- Éléments communs ---------- */
23
+ .ub-sk-lattice { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; color: rgb(168 67 31 / 0.07); pointer-events: none; }
24
+ .ub-sk-kicker { margin: 0; color: var(--sk-terra); font: 600 12px/16px var(--font-inter); letter-spacing: 0.28em; text-transform: uppercase; }
25
+ .ub-sk-h2 { margin: 8px 0 0; font: 600 clamp(30px, 3.6vw, 50px) / 1.1 var(--font-poppins); letter-spacing: -0.02em; color: var(--ink); }
26
+ .ub-sk-sub { max-width: 34em; margin: 0; color: var(--hero-muted); font-size: 17px; line-height: 28px; }
27
+ .ub-sk-btn { display: inline-flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 28px; border-radius: 999px; background: var(--sk-terra); color: #fff8ef; font: 600 15px/18px var(--font-poppins); box-shadow: 0 12px 26px -14px rgb(168 67 31 / 0.8); transition: transform 0.2s, background-color 0.2s; }
28
+ .ub-sk-btn:hover { transform: translateY(-2px); background: var(--sk-brown); }
29
+ .ub-sk-btn svg { width: 18px; height: 18px; }
30
+ .ub-sk-btn--ghost { background: transparent; color: var(--sk-brown); box-shadow: inset 0 0 0 1.5px var(--sk-brown); }
31
+ .ub-sk-btn--ghost:hover { background: var(--sk-brown); color: #fff8ef; }
32
+ .ub-sk-price { display: inline-flex; align-items: baseline; gap: 8px; }
33
+ .ub-sk-price b { font: 600 17px/1 var(--font-poppins); color: var(--sk-terra); }
34
+ .ub-sk-price s { color: var(--ink-muted); font-size: 13px; }
35
+
36
+ /* ---------- Hero ---------- */
37
+ .ub-sk-hero { position: relative; isolation: isolate; overflow: hidden; background: var(--hero-bg); color: var(--hero-ink); }
38
+ .ub-sk-hero__in { display: grid; align-items: center; min-height: clamp(660px, 52vw, 840px); padding-top: var(--space-12); padding-bottom: var(--space-12); }
39
+ .ub-sk-hero__text { display: grid; justify-items: start; gap: 22px; max-width: min(640px, 56%); }
40
+ .ub-sk-title { margin: 0; font: 600 clamp(46px, 5.2vw, 84px) / 1.04 var(--font-poppins); letter-spacing: -0.035em; text-wrap: balance; }
41
+ .ub-sk-title__hl { position: relative; z-index: 0; color: var(--sk-terra); white-space: nowrap; }
42
+ /* Trait de pinceau safran sous le mot mis en avant */
43
+ .ub-sk-title__hl::after { content: ""; position: absolute; z-index: -1; left: -3%; right: -3%; bottom: 0.08em; height: 0.26em; border-radius: 0.2em 0.5em 0.3em 0.6em; background: var(--sk-saffron); opacity: 0.45; transform: rotate(-1.5deg); }
44
+ .ub-sk-actions { display: flex; flex-wrap: wrap; gap: 12px; }
45
+ .ub-sk-perks { display: flex; flex-wrap: wrap; gap: 22px; margin: 4px 0 0; padding: 0; list-style: none; color: var(--hero-muted); font-size: 14px; }
46
+ .ub-sk-perks li { display: inline-flex; align-items: center; gap: 8px; }
47
+ .ub-sk-perks svg { width: 20px; height: 20px; color: var(--sk-terra); }
48
+ /* Visuel (843 × 1264) : bord droit et bas du hero, toute la hauteur ; côté gauche et haut fondus (masque sur l'image seule) */
49
+ .ub-sk-visual { position: absolute; top: 0; right: 0; bottom: 0; height: 100%; aspect-ratio: 843 / 1264; max-width: 50%; margin: 0; }
50
+ .ub-sk-visual img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: right bottom; mix-blend-mode: multiply;
51
+ -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 42%), linear-gradient(180deg, transparent 0%, #000 12%); -webkit-mask-composite: source-in;
52
+ mask-image: linear-gradient(90deg, transparent 0%, #000 42%), linear-gradient(180deg, transparent 0%, #000 12%); mask-composite: intersect; }
53
+ .ub-sk-hero .ub-wrap { position: relative; z-index: 1; }
54
+ /* Cachet de cire (remise) */
55
+ .ub-sk-seal { position: absolute; top: 30%; left: 4%; z-index: 2; display: grid; place-items: center; align-content: center; width: 124px; height: 124px; margin: 0; color: #fbe9cf; text-align: center;
56
+ background: radial-gradient(circle at 35% 30%, #c65a32 0%, #9c3a1b 55%, #6e2410 100%);
57
+ clip-path: polygon(50% 0, 60% 4%, 70% 2%, 77% 9%, 87% 11%, 90% 21%, 98% 28%, 96% 38%, 100% 48%, 96% 58%, 98% 68%, 91% 75%, 88% 86%, 78% 89%, 70% 97%, 60% 95%, 50% 100%, 40% 96%, 30% 98%, 23% 91%, 13% 88%, 10% 78%, 2% 71%, 4% 61%, 0 51%, 4% 41%, 2% 31%, 9% 24%, 12% 13%, 22% 10%, 30% 3%, 40% 5%);
58
+ filter: drop-shadow(0 12px 18px rgb(90 42 23 / 0.45)); transform: rotate(-8deg); }
59
+ .ub-sk-seal::before { content: ""; position: absolute; inset: 14px; border: 1.5px solid rgb(251 233 207 / 0.45); border-radius: 50%; }
60
+ .ub-sk-seal small { font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; }
61
+ .ub-sk-seal b { font: 700 32px/1 var(--font-poppins); }
62
+
63
+ /* ---------- Sections ---------- */
64
+ .ub-sk-section { padding-top: var(--space-24); }
65
+ .ub-souk > :last-child { padding-bottom: var(--space-24); }
66
+ .ub-sk-head { display: grid; justify-items: center; gap: 6px; margin-bottom: var(--space-12); text-align: center; }
67
+
68
+ /* Vitrine : bande sable à treillis, grand produit + quatre pièces, arcs outrepassés liserés de terre cuite */
69
+ .ub-sk-vitrine { position: relative; isolation: isolate; margin-top: 0; padding-bottom: var(--space-16); background: linear-gradient(180deg, #fbf6ee 0%, #f4e7d4 45%, #f8efe2 100%); }
70
+ .ub-sk-vitrine .ub-sk-lattice { color: rgb(168 67 31 / 0.06); }
71
+ .ub-sk-head--row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: end; gap: 16px; text-align: left; }
72
+ .ub-sk-more { display: inline-flex; align-items: center; gap: 8px; padding-bottom: 4px; border-bottom: 1.5px solid currentColor; color: var(--sk-terra); font: 600 15px/1 var(--font-poppins); }
73
+ .ub-sk-more svg { width: 16px; height: 16px; }
74
+ /* Le comptoir : fenêtre en arc outrepassé (produit choisi) + liste */
75
+ .ub-sk-counter { display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); align-items: center; gap: clamp(28px, 5vw, 72px); }
76
+ .ub-sk-counter__stage { position: relative; width: min(100%, 440px); justify-self: center; aspect-ratio: 4 / 5; }
77
+ .ub-sk-view { position: absolute; inset: 0; display: block; opacity: 0; visibility: hidden; color: var(--ink); transition: opacity 0.4s, visibility 0.4s; }
78
+ .ub-sk-counter:has(#ub-sk-pick-0:checked) .ub-sk-view[data-i="0"],
79
+ .ub-sk-counter:has(#ub-sk-pick-1:checked) .ub-sk-view[data-i="1"],
80
+ .ub-sk-counter:has(#ub-sk-pick-2:checked) .ub-sk-view[data-i="2"],
81
+ .ub-sk-counter:has(#ub-sk-pick-3:checked) .ub-sk-view[data-i="3"],
82
+ .ub-sk-counter:has(#ub-sk-pick-4:checked) .ub-sk-view[data-i="4"],
83
+ .ub-sk-counter:has(#ub-sk-pick-5:checked) .ub-sk-view[data-i="5"] { opacity: 1; visibility: visible; }
84
+ .ub-sk-view__img { position: absolute; inset: 0; overflow: hidden; border-radius: 50% 50% 14px 14px / 36% 36% 14px 14px; background: var(--tint-1);
85
+ box-shadow: 0 0 0 1px rgb(168 67 31 / 0.4), 0 0 0 9px #f8efe2, 0 0 0 10px rgb(168 67 31 / 0.25), 0 40px 70px -40px rgb(90 42 23 / 0.6); }
86
+ .ub-sk-view__img img { width: 100%; height: 100%; object-fit: cover; }
87
+ .ub-sk-view__cap { position: absolute; left: 14px; right: 14px; bottom: 14px; display: grid; justify-items: start; gap: 6px; padding: 16px 18px; border-radius: 12px; background: rgb(255 250 242 / 0.94); box-shadow: 0 12px 24px -16px rgb(42 26 16 / 0.5); }
88
+ .ub-sk-view__off { padding: 4px 10px; border-radius: 999px; background: var(--sk-terra); color: #fff8ef; font: 600 12px/1 var(--font-poppins); }
89
+ .ub-sk-view__name { font: 600 20px/1.2 var(--font-poppins); letter-spacing: -0.01em; }
90
+ .ub-sk-view__go { display: inline-flex; align-items: center; gap: 6px; color: var(--sk-terra); font: 600 14px/1 var(--font-poppins); }
91
+ .ub-sk-view__go svg { width: 15px; height: 15px; }
92
+ .ub-sk-counter__list { display: grid; margin: 0; padding: 0; list-style: none; border-top: 1px solid rgb(168 67 31 / 0.18); }
93
+ .ub-sk-counter__list li { border-bottom: 1px solid rgb(168 67 31 / 0.18); }
94
+ .ub-sk-pick { position: absolute; opacity: 0; pointer-events: none; }
95
+ .ub-sk-row { position: relative; display: grid; grid-template-columns: 58px minmax(0, 1fr) auto auto; align-items: center; gap: 16px; padding: 12px 14px; border-radius: 12px; cursor: pointer; transition: background-color 0.2s; }
96
+ .ub-sk-row:hover { background: rgb(255 255 255 / 0.6); }
97
+ .ub-sk-pick:checked + .ub-sk-row { background: #fff; box-shadow: 0 10px 24px -18px rgb(90 42 23 / 0.6); }
98
+ .ub-sk-pick:checked + .ub-sk-row::before { content: ""; position: absolute; left: -2px; top: 18%; bottom: 18%; width: 3px; border-radius: 3px; background: var(--sk-terra); }
99
+ .ub-sk-pick:focus-visible + .ub-sk-row { outline: 2px solid var(--focus); outline-offset: 2px; }
100
+ .ub-sk-row__img { display: block; width: 58px; height: 58px; overflow: hidden; border-radius: 50% 50% 8px 8px / 40% 40% 8px 8px; background: var(--tint-1); }
101
+ .ub-sk-row__img img { width: 100%; height: 100%; object-fit: cover; }
102
+ .ub-sk-row__name { font: 500 16px/1.3 var(--font-poppins); }
103
+ .ub-sk-row__off { padding: 3px 9px; border-radius: 999px; background: rgb(168 67 31 / 0.1); color: var(--sk-terra); font: 600 12px/1 var(--font-poppins); }
104
+ .ub-sk-row__price { color: var(--ink); font: 600 16px/1 var(--font-poppins); white-space: nowrap; }
105
+
106
+ /* Pour qui ? : portes en arc */
107
+ .ub-sk-who { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
108
+ .ub-sk-door { display: grid; place-items: center; align-content: end; gap: 8px; min-height: 180px; padding: 22px; border-radius: 999px 999px 16px 16px / 70% 70% 16px 16px; background: var(--a1); color: #fff8ef; font: 600 18px/1.2 var(--font-poppins); text-align: center; transition: transform 0.2s; }
109
+ .ub-sk-door:hover { transform: translateY(-4px); }
110
+ .ub-sk-door svg { width: 18px; height: 18px; }
111
+
112
+ /* Carte de vœux en enveloppe */
113
+ .ub-sk-letter { position: relative; max-width: 920px; margin: 0 auto; padding: 100px 26px 26px; border-radius: 18px; background: linear-gradient(180deg, #c98e5b, #a8431f); box-shadow: 0 40px 80px -40px rgb(90 42 23 / 0.6); }
114
+ .ub-sk-letter__flap { position: absolute; z-index: 2; left: 0; right: 0; top: 0; height: 140px; border-radius: 18px 18px 0 0; background: linear-gradient(180deg, #b86a3a, #9c3a1b); clip-path: polygon(0 0, 100% 0, 50% 100%); }
115
+ .ub-sk-letter__card { position: relative; isolation: isolate; z-index: 1; display: grid; justify-items: center; gap: 16px; overflow: hidden; padding: 90px 24px clamp(40px, 6vw, 70px); border-radius: 12px; background: #fffaf2; text-align: center; box-shadow: 0 -10px 30px -20px rgb(0 0 0 / 0.5); }
116
+ .ub-sk-letter__card .ub-sk-lattice { color: rgb(168 67 31 / 0.06); }
117
+ .ub-sk-cd .ub-countdown__c { background: #fff; color: var(--ink); box-shadow: inset 0 0 0 1px var(--border); }
118
+ .ub-sk-cd .ub-countdown__c b { color: var(--sk-terra); }
119
+ .ub-sk-sign { margin: 6px 0 0; font: italic 500 18px/1.3 var(--font-poppins); color: var(--sk-brown); }
120
+ .ub-sk-letter__seal { position: absolute; z-index: 3; top: 104px; left: 50%; display: grid; place-items: center; width: 70px; height: 70px; margin-left: -35px; border-radius: 50%;
121
+ background: radial-gradient(circle at 35% 30%, #d06a3e, #8a2e14 70%); box-shadow: 0 10px 18px rgb(90 42 23 / 0.45); }
122
+ .ub-sk-letter__seal svg { width: 30px; height: 32px; fill: #f6d9b0; }
123
+
124
+ @media (max-width: 1024px) {
125
+ .ub-sk-counter { grid-template-columns: 1fr; }
126
+ .ub-sk-counter__stage { width: min(100%, 380px); }
127
+ }
128
+ @media (max-width: 900px) {
129
+ .ub-sk-visual { position: relative; top: auto; height: 380px; max-width: none; width: 100%; aspect-ratio: auto; }
130
+ .ub-sk-visual img { object-position: right top; -webkit-mask-image: linear-gradient(180deg, #000 60%, transparent); mask-image: linear-gradient(180deg, #000 60%, transparent); }
131
+ .ub-sk-hero .ub-sk-hero__in { min-height: 0; margin-top: -60px; padding-top: 0; padding-bottom: 48px; }
132
+ .ub-sk-hero__text { max-width: none; }
133
+ .ub-sk-seal { top: 24%; left: 8%; width: 100px; height: 100px; }
134
+ .ub-sk-seal b { font-size: 26px; }
135
+ }
136
+ @media (max-width: 600px) {
137
+ .ub-sk-title { font-size: 42px; }
138
+ .ub-sk-row { grid-template-columns: 50px minmax(0, 1fr) auto; gap: 12px; }
139
+ .ub-sk-row__img { width: 50px; height: 50px; }
140
+ .ub-sk-row__off { display: none; }
141
+ .ub-sk-section { padding-top: var(--space-16); }
142
+ .ub-souk > :last-child { padding-bottom: var(--space-16); }
143
+ .ub-sk-letter { padding: 100px 12px 12px; }
144
+ }