@salifbiaye/create-boutique 0.1.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.
- package/README.md +1 -0
- package/cli/dist/commands.js +382 -0
- package/cli/dist/create.js +194 -0
- package/cli/dist/docker.js +19 -0
- package/cli/dist/generate.js +322 -0
- package/cli/dist/guide.js +72 -0
- package/cli/dist/index.js +156 -0
- package/cli/dist/paths.js +29 -0
- package/cli/dist/ports.js +54 -0
- package/cli/dist/project.js +119 -0
- package/cli/dist/themes.js +24 -0
- package/docs/fiche-client.en.html +137 -0
- package/docs/fiche-client.html +137 -0
- package/docs/guide-complet.en.html +259 -0
- package/docs/guide-complet.fr.html +259 -0
- package/package.json +51 -0
- package/templates/backend/.dockerignore +9 -0
- package/templates/backend/Dockerfile +30 -0
- package/templates/backend/README.md +78 -0
- package/templates/backend/TEMPLATE_VERSION +1 -0
- package/templates/backend/docker/entrypoint.sh +28 -0
- package/templates/backend/instrumentation.ts +24 -0
- package/templates/backend/medusa-config.ts +114 -0
- package/templates/backend/package-lock.json +16222 -0
- package/templates/backend/package.json +39 -0
- package/templates/backend/src/admin/README.md +33 -0
- package/templates/backend/src/admin/components/image-field.tsx +61 -0
- package/templates/backend/src/admin/i18n/README.md +58 -0
- package/templates/backend/src/admin/i18n/index.ts +8 -0
- package/templates/backend/src/admin/i18n/json/en.json +66 -0
- package/templates/backend/src/admin/i18n/json/fr.json +66 -0
- package/templates/backend/src/admin/lib/client.ts +9 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +286 -0
- package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +113 -0
- package/templates/backend/src/admin/tsconfig.json +24 -0
- package/templates/backend/src/admin/vite-env.d.ts +1 -0
- package/templates/backend/src/admin/widgets/category-image.tsx +56 -0
- package/templates/backend/src/api/README.md +135 -0
- package/templates/backend/src/api/admin/boutique-campaigns/[salesChannelId]/route.ts +30 -0
- package/templates/backend/src/api/admin/boutique-campaigns/route.ts +24 -0
- package/templates/backend/src/api/middlewares.ts +28 -0
- package/templates/backend/src/api/rate-limit.ts +30 -0
- package/templates/backend/src/api/route.ts +6 -0
- package/templates/backend/src/api/store/campaign/route.ts +25 -0
- package/templates/backend/src/api/store/order-lookup/route.ts +74 -0
- package/templates/backend/src/emails/en.json +64 -0
- package/templates/backend/src/emails/fr.json +64 -0
- package/templates/backend/src/jobs/README.md +38 -0
- package/templates/backend/src/lib/emails.ts +94 -0
- package/templates/backend/src/lib/notify.ts +148 -0
- package/templates/backend/src/lib/project.ts +146 -0
- package/templates/backend/src/links/README.md +26 -0
- package/templates/backend/src/links/campaign-sales-channel.ts +9 -0
- package/templates/backend/src/modules/README.md +117 -0
- package/templates/backend/src/modules/campaign/index.ts +9 -0
- package/templates/backend/src/modules/campaign/migrations/.snapshot-boutique-campaign.json +272 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928141440.ts +16 -0
- package/templates/backend/src/modules/campaign/migrations/Migration20260928145243.ts +13 -0
- package/templates/backend/src/modules/campaign/models/campaign.ts +28 -0
- package/templates/backend/src/modules/campaign/service.ts +6 -0
- package/templates/backend/src/modules/campaign/validators.ts +94 -0
- package/templates/backend/src/modules/resend/index.ts +6 -0
- package/templates/backend/src/modules/resend/service.ts +63 -0
- package/templates/backend/src/scripts/README.md +63 -0
- package/templates/backend/src/scripts/campaign-export.ts +15 -0
- package/templates/backend/src/scripts/campaign-import.ts +38 -0
- package/templates/backend/src/scripts/price-report.ts +34 -0
- package/templates/backend/src/scripts/seed.ts +418 -0
- package/templates/backend/src/scripts/storage.ts +63 -0
- package/templates/backend/src/subscribers/README.md +61 -0
- package/templates/backend/src/subscribers/account-emails.ts +27 -0
- package/templates/backend/src/subscribers/fulfillment-emails.ts +42 -0
- package/templates/backend/src/subscribers/order-emails.ts +12 -0
- package/templates/backend/src/subscribers/return-refund-emails.ts +50 -0
- package/templates/backend/src/workflows/README.md +81 -0
- package/templates/backend/src/workflows/steps/upsert-campaign.ts +53 -0
- package/templates/backend/src/workflows/upsert-campaign.ts +30 -0
- package/templates/backend/tsconfig.json +36 -0
- package/templates/storefront/.dockerignore +7 -0
- package/templates/storefront/.github/ISSUE_TEMPLATE/bug-report.yml +71 -0
- package/templates/storefront/.prettierrc +8 -0
- package/templates/storefront/Dockerfile +37 -0
- package/templates/storefront/LICENSE +21 -0
- package/templates/storefront/README.md +127 -0
- package/templates/storefront/locales/en.json +269 -0
- package/templates/storefront/locales/fr.json +269 -0
- package/templates/storefront/next-env.d.ts +7 -0
- package/templates/storefront/next-sitemap.js +19 -0
- package/templates/storefront/next.config.js +29 -0
- package/templates/storefront/package-lock.json +9031 -0
- package/templates/storefront/package.json +49 -0
- package/templates/storefront/postcss.config.js +6 -0
- package/templates/storefront/public/favicon.ico +0 -0
- package/templates/storefront/scripts/sync-design.mjs +30 -0
- package/templates/storefront/src/app/(checkout)/checkout/page.tsx +31 -0
- package/templates/storefront/src/app/(checkout)/layout.tsx +29 -0
- package/templates/storefront/src/app/(checkout)/not-found.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/addresses/page.tsx +34 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/details/[id]/page.tsx +33 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/orders/page.tsx +37 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/page.tsx +22 -0
- package/templates/storefront/src/app/(main)/account/@dashboard/profile/page.tsx +53 -0
- package/templates/storefront/src/app/(main)/account/@login/page.tsx +12 -0
- package/templates/storefront/src/app/(main)/account/layout.tsx +20 -0
- package/templates/storefront/src/app/(main)/account/loading.tsx +9 -0
- package/templates/storefront/src/app/(main)/cart/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/cart/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/cart/page.tsx +21 -0
- package/templates/storefront/src/app/(main)/categories/[...category]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/collections/[handle]/page.tsx +55 -0
- package/templates/storefront/src/app/(main)/layout.tsx +43 -0
- package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/not-found.tsx +21 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/loading.tsx +5 -0
- package/templates/storefront/src/app/(main)/order/[id]/confirmed/page.tsx +23 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/accept/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/decline/page.tsx +42 -0
- package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/page.tsx +35 -0
- package/templates/storefront/src/app/(main)/order/track/page.tsx +32 -0
- package/templates/storefront/src/app/(main)/page.tsx +68 -0
- package/templates/storefront/src/app/(main)/products/[handle]/page.tsx +86 -0
- package/templates/storefront/src/app/(main)/store/page.tsx +28 -0
- package/templates/storefront/src/app/api/health/route.ts +13 -0
- package/templates/storefront/src/app/layout.tsx +42 -0
- package/templates/storefront/src/app/not-found.tsx +21 -0
- package/templates/storefront/src/app/opengraph-image.jpg +0 -0
- package/templates/storefront/src/app/twitter-image.jpg +0 -0
- package/templates/storefront/src/instrumentation-node.ts +18 -0
- package/templates/storefront/src/instrumentation.ts +9 -0
- package/templates/storefront/src/lib/boutique/campaign.ts +116 -0
- package/templates/storefront/src/lib/boutique/config.ts +152 -0
- package/templates/storefront/src/lib/boutique/fonts.ts +29 -0
- package/templates/storefront/src/lib/boutique/i18n-client.tsx +34 -0
- package/templates/storefront/src/lib/boutique/i18n.ts +43 -0
- package/templates/storefront/src/lib/boutique/schema.ts +131 -0
- package/templates/storefront/src/lib/config.ts +39 -0
- package/templates/storefront/src/lib/constants.tsx +75 -0
- package/templates/storefront/src/lib/context/modal-context.tsx +34 -0
- package/templates/storefront/src/lib/data/cart.ts +434 -0
- package/templates/storefront/src/lib/data/categories.ts +49 -0
- package/templates/storefront/src/lib/data/collections.ts +59 -0
- package/templates/storefront/src/lib/data/cookies.ts +103 -0
- package/templates/storefront/src/lib/data/customer.ts +261 -0
- package/templates/storefront/src/lib/data/fulfillment.ts +68 -0
- package/templates/storefront/src/lib/data/onboarding.ts +9 -0
- package/templates/storefront/src/lib/data/order-lookup.ts +34 -0
- package/templates/storefront/src/lib/data/orders.ts +112 -0
- package/templates/storefront/src/lib/data/payment.ts +35 -0
- package/templates/storefront/src/lib/data/products.ts +127 -0
- package/templates/storefront/src/lib/data/regions.ts +70 -0
- package/templates/storefront/src/lib/data/variants.ts +38 -0
- package/templates/storefront/src/lib/hooks/use-in-view.tsx +29 -0
- package/templates/storefront/src/lib/hooks/use-toggle-state.tsx +46 -0
- package/templates/storefront/src/lib/util/compare-addresses.ts +28 -0
- package/templates/storefront/src/lib/util/get-percentage-diff.ts +6 -0
- package/templates/storefront/src/lib/util/get-product-price.ts +79 -0
- package/templates/storefront/src/lib/util/isEmpty.ts +11 -0
- package/templates/storefront/src/lib/util/medusa-error.ts +22 -0
- package/templates/storefront/src/lib/util/money.ts +35 -0
- package/templates/storefront/src/lib/util/product.ts +5 -0
- package/templates/storefront/src/lib/util/repeat.ts +5 -0
- package/templates/storefront/src/lib/util/sort-products.ts +50 -0
- package/templates/storefront/src/modules/account/components/account-info/index.tsx +140 -0
- package/templates/storefront/src/modules/account/components/account-nav/index.tsx +198 -0
- package/templates/storefront/src/modules/account/components/address-book/index.tsx +28 -0
- package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +169 -0
- package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +241 -0
- package/templates/storefront/src/modules/account/components/login/index.tsx +65 -0
- package/templates/storefront/src/modules/account/components/order-card/index.tsx +88 -0
- package/templates/storefront/src/modules/account/components/order-overview/index.tsx +47 -0
- package/templates/storefront/src/modules/account/components/overview/index.tsx +169 -0
- package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +193 -0
- package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
- package/templates/storefront/src/modules/account/components/profile-name/index.tsx +79 -0
- package/templates/storefront/src/modules/account/components/profile-password/index.tsx +72 -0
- package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +74 -0
- package/templates/storefront/src/modules/account/components/register/index.tsx +107 -0
- package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +83 -0
- package/templates/storefront/src/modules/account/templates/account-layout.tsx +43 -0
- package/templates/storefront/src/modules/account/templates/login-template.tsx +27 -0
- package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +75 -0
- package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +25 -0
- package/templates/storefront/src/modules/cart/components/item/index.tsx +144 -0
- package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +27 -0
- package/templates/storefront/src/modules/cart/templates/index.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/items.tsx +58 -0
- package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
- package/templates/storefront/src/modules/cart/templates/summary.tsx +50 -0
- package/templates/storefront/src/modules/categories/templates/index.tsx +94 -0
- package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +117 -0
- package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +186 -0
- package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +114 -0
- package/templates/storefront/src/modules/checkout/components/country-select/index.tsx +50 -0
- package/templates/storefront/src/modules/checkout/components/discount-code/index.tsx +181 -0
- package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
- package/templates/storefront/src/modules/checkout/components/payment/index.tsx +261 -0
- package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +195 -0
- package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +130 -0
- package/templates/storefront/src/modules/checkout/components/payment-test/index.tsx +12 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/index.tsx +42 -0
- package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/review/index.tsx +54 -0
- package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +417 -0
- package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +219 -0
- package/templates/storefront/src/modules/checkout/components/submit-button/index.tsx +32 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-form/index.tsx +38 -0
- package/templates/storefront/src/modules/checkout/templates/checkout-summary/index.tsx +31 -0
- package/templates/storefront/src/modules/collections/templates/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +84 -0
- package/templates/storefront/src/modules/common/components/checkbox/index.tsx +44 -0
- package/templates/storefront/src/modules/common/components/delete-button/index.tsx +42 -0
- package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
- package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +61 -0
- package/templates/storefront/src/modules/common/components/input/index.tsx +79 -0
- package/templates/storefront/src/modules/common/components/interactive-link/index.tsx +33 -0
- package/templates/storefront/src/modules/common/components/line-item-options/index.tsx +26 -0
- package/templates/storefront/src/modules/common/components/line-item-price/index.tsx +63 -0
- package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +62 -0
- package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +29 -0
- package/templates/storefront/src/modules/common/components/modal/index.tsx +118 -0
- package/templates/storefront/src/modules/common/components/native-select/index.tsx +76 -0
- package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -0
- package/templates/storefront/src/modules/common/icons/back.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/bancontact.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/chevron-down.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/eye-off.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/eye.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/fast-delivery.tsx +65 -0
- package/templates/storefront/src/modules/common/icons/ideal.tsx +26 -0
- package/templates/storefront/src/modules/common/icons/map-pin.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/package.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/paypal.tsx +30 -0
- package/templates/storefront/src/modules/common/icons/placeholder-image.tsx +44 -0
- package/templates/storefront/src/modules/common/icons/refresh.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/spinner.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/trash.tsx +51 -0
- package/templates/storefront/src/modules/common/icons/user.tsx +37 -0
- package/templates/storefront/src/modules/common/icons/x.tsx +37 -0
- package/templates/storefront/src/modules/layout/components/cart-mismatch-banner/index.tsx +59 -0
- package/templates/storefront/src/modules/order/components/help/index.tsx +26 -0
- package/templates/storefront/src/modules/order/components/item/index.tsx +57 -0
- package/templates/storefront/src/modules/order/components/items/index.tsx +44 -0
- package/templates/storefront/src/modules/order/components/onboarding-cta/index.tsx +28 -0
- package/templates/storefront/src/modules/order/components/order-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/order-summary/index.tsx +61 -0
- package/templates/storefront/src/modules/order/components/payment-details/index.tsx +64 -0
- package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +74 -0
- package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +83 -0
- package/templates/storefront/src/modules/order/components/transfer-image/index.tsx +275 -0
- package/templates/storefront/src/modules/order/templates/order-completed-template.tsx +53 -0
- package/templates/storefront/src/modules/order/templates/order-details-template.tsx +46 -0
- package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +70 -0
- package/templates/storefront/src/modules/products/templates/index.tsx +118 -0
- package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +285 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-button/index.tsx +5 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-card-details/index.tsx +10 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-cart-totals/index.tsx +30 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-code-form/index.tsx +13 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-line-item/index.tsx +35 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-confirmed-header/index.tsx +14 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-information/index.tsx +36 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-items/index.tsx +43 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-order-summary/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/components/skeleton-product-preview/index.tsx +15 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-cart-page/index.tsx +65 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-order-confirmed/index.tsx +21 -0
- package/templates/storefront/src/modules/skeletons/templates/skeleton-product-grid/index.tsx +23 -0
- package/templates/storefront/src/modules/store/components/pagination/index.tsx +114 -0
- package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +41 -0
- package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +48 -0
- package/templates/storefront/src/modules/store/templates/index.tsx +42 -0
- package/templates/storefront/src/modules/store/templates/paginated-products.tsx +80 -0
- package/templates/storefront/src/modules/ub/button.tsx +41 -0
- package/templates/storefront/src/modules/ub/campaign-blocks.tsx +197 -0
- package/templates/storefront/src/modules/ub/campaign-ended.tsx +28 -0
- package/templates/storefront/src/modules/ub/category-tiles.tsx +41 -0
- package/templates/storefront/src/modules/ub/countdown.tsx +46 -0
- package/templates/storefront/src/modules/ub/footer.tsx +56 -0
- package/templates/storefront/src/modules/ub/icons.tsx +42 -0
- package/templates/storefront/src/modules/ub/nav.tsx +90 -0
- package/templates/storefront/src/modules/ub/pdp/buy-box.tsx +140 -0
- package/templates/storefront/src/modules/ub/pdp/gallery.tsx +40 -0
- package/templates/storefront/src/modules/ub/product-card.tsx +66 -0
- package/templates/storefront/src/modules/ub/top-bar.tsx +20 -0
- package/templates/storefront/src/modules/ub/track-form.tsx +92 -0
- package/templates/storefront/src/proxy.ts +89 -0
- package/templates/storefront/src/styles/globals.css +98 -0
- package/templates/storefront/src/styles/ub/bundle.css +372 -0
- package/templates/storefront/src/styles/ub/fonts.css +17 -0
- package/templates/storefront/src/styles/ub/medusa-ui.css +90 -0
- package/templates/storefront/src/styles/ub/overrides.css +12 -0
- package/templates/storefront/src/styles/ub/tokens.css +9 -0
- package/templates/storefront/src/types/global.ts +24 -0
- package/templates/storefront/src/types/icon.ts +4 -0
- package/templates/storefront/tailwind.config.js +164 -0
- package/templates/storefront/themes/black-friday/campaign.en.json +31 -0
- package/templates/storefront/themes/black-friday/campaign.fr.json +31 -0
- package/templates/storefront/themes/black-friday/theme.json +9 -0
- package/templates/storefront/themes/cyber-monday/campaign.en.json +31 -0
- package/templates/storefront/themes/cyber-monday/campaign.fr.json +31 -0
- package/templates/storefront/themes/cyber-monday/theme.json +9 -0
- package/templates/storefront/themes/halloween/campaign.en.json +31 -0
- package/templates/storefront/themes/halloween/campaign.fr.json +31 -0
- package/templates/storefront/themes/halloween/theme.json +9 -0
- package/templates/storefront/themes/noel/campaign.en.json +31 -0
- package/templates/storefront/themes/noel/campaign.fr.json +31 -0
- package/templates/storefront/themes/noel/theme.json +9 -0
- package/templates/storefront/themes/nouvel-an/campaign.en.json +31 -0
- package/templates/storefront/themes/nouvel-an/campaign.fr.json +31 -0
- package/templates/storefront/themes/nouvel-an/theme.json +9 -0
- package/templates/storefront/themes/thanksgiving/campaign.en.json +31 -0
- package/templates/storefront/themes/thanksgiving/campaign.fr.json +31 -0
- package/templates/storefront/themes/thanksgiving/theme.json +9 -0
- package/templates/storefront/tsconfig.json +53 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deux rôles, sans aucune logique de pays, de langue ni de redirection
|
|
5
|
+
* (la région, la langue et la devise sont fixées par l'instance) :
|
|
6
|
+
* 1. en-têtes de sécurité, dont une CSP avec nonce (Next l'applique à ses scripts) ;
|
|
7
|
+
* 2. identifiant de cache du visiteur (`_medusa_cache_id_<slug>`), qui nomme les
|
|
8
|
+
* tags de cache (panier, client…) que les server actions expirent.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const isDev = process.env.NODE_ENV === "development"
|
|
12
|
+
|
|
13
|
+
function origin(url?: string) {
|
|
14
|
+
try {
|
|
15
|
+
return url ? new URL(url).origin : ""
|
|
16
|
+
} catch {
|
|
17
|
+
return ""
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function contentSecurityPolicy(nonce: string) {
|
|
22
|
+
// Images produits : stockage du projet (S3_FILE_URL) ; à défaut, toute source http(s).
|
|
23
|
+
const files = origin(process.env.S3_FILE_URL) || "http: https:"
|
|
24
|
+
|
|
25
|
+
return [
|
|
26
|
+
"default-src 'self'",
|
|
27
|
+
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://js.stripe.com${isDev ? " 'unsafe-eval'" : ""}`,
|
|
28
|
+
"style-src 'self' 'unsafe-inline'",
|
|
29
|
+
`img-src 'self' data: blob: ${files} https://*.stripe.com`,
|
|
30
|
+
"font-src 'self'",
|
|
31
|
+
`connect-src 'self' https://api.stripe.com https://m.stripe.network https://*.stripe.com${isDev ? " ws:" : ""}`,
|
|
32
|
+
"frame-src https://js.stripe.com https://hooks.stripe.com",
|
|
33
|
+
"frame-ancestors 'none'",
|
|
34
|
+
"form-action 'self'",
|
|
35
|
+
"base-uri 'self'",
|
|
36
|
+
"object-src 'none'",
|
|
37
|
+
].join("; ")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function proxy(request: NextRequest) {
|
|
41
|
+
const nonce = Buffer.from(crypto.randomUUID()).toString("base64")
|
|
42
|
+
const csp = contentSecurityPolicy(nonce)
|
|
43
|
+
|
|
44
|
+
// Next lit la CSP de la requête pour poser le nonce sur ses propres scripts.
|
|
45
|
+
request.headers.set("content-security-policy", csp)
|
|
46
|
+
request.headers.set("x-nonce", nonce)
|
|
47
|
+
|
|
48
|
+
const cacheCookie = `_medusa_cache_id_${process.env.BOUTIQUE}`
|
|
49
|
+
const newCacheId = request.cookies.has(cacheCookie) ? null : crypto.randomUUID()
|
|
50
|
+
if (newCacheId) {
|
|
51
|
+
// Visible dès cette requête par les server components…
|
|
52
|
+
request.cookies.set(cacheCookie, newCacheId)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const response = NextResponse.next({ request: { headers: request.headers } })
|
|
56
|
+
|
|
57
|
+
if (newCacheId) {
|
|
58
|
+
// …et gardé par le navigateur pour les suivantes.
|
|
59
|
+
response.cookies.set(cacheCookie, newCacheId, {
|
|
60
|
+
maxAge: 60 * 60 * 24,
|
|
61
|
+
httpOnly: true,
|
|
62
|
+
sameSite: "strict",
|
|
63
|
+
secure: process.env.NODE_ENV === "production",
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
response.headers.set("Content-Security-Policy", csp)
|
|
68
|
+
response.headers.set("X-Frame-Options", "DENY")
|
|
69
|
+
response.headers.set("X-Content-Type-Options", "nosniff")
|
|
70
|
+
response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin")
|
|
71
|
+
response.headers.set("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=(self \"https://js.stripe.com\")")
|
|
72
|
+
if (request.headers.get("x-forwarded-proto") === "https" || request.nextUrl.protocol === "https:") {
|
|
73
|
+
response.headers.set("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return response
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const config = {
|
|
80
|
+
matcher: [
|
|
81
|
+
{
|
|
82
|
+
source: "/((?!api|_next/static|_next/image|favicon.ico|.*\\..*).*)",
|
|
83
|
+
missing: [
|
|
84
|
+
{ type: "header", key: "next-router-prefetch" },
|
|
85
|
+
{ type: "header", key: "purpose", value: "prefetch" },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
@import "tailwindcss/base";
|
|
2
|
+
@import "tailwindcss/components";
|
|
3
|
+
@import "tailwindcss/utilities";
|
|
4
|
+
|
|
5
|
+
@layer utilities {
|
|
6
|
+
/* Chrome, Safari and Opera */
|
|
7
|
+
.no-scrollbar::-webkit-scrollbar {
|
|
8
|
+
display: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.no-scrollbar::-webkit-scrollbar-track {
|
|
12
|
+
background-color: transparent;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.no-scrollbar {
|
|
16
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
17
|
+
scrollbar-width: none; /* Firefox */
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
input:focus ~ label,
|
|
21
|
+
input:not(:placeholder-shown) ~ label {
|
|
22
|
+
@apply -translate-y-2 text-xsmall-regular;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
input:focus ~ label {
|
|
26
|
+
@apply left-0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
input[type="search"]::-webkit-search-decoration,
|
|
31
|
+
input[type="search"]::-webkit-search-cancel-button,
|
|
32
|
+
input[type="search"]::-webkit-search-results-button,
|
|
33
|
+
input[type="search"]::-webkit-search-results-decoration {
|
|
34
|
+
-webkit-appearance: none;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@layer components {
|
|
39
|
+
.content-container {
|
|
40
|
+
@apply max-w-[1440px] w-full mx-auto px-6;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.contrast-btn {
|
|
44
|
+
@apply px-4 py-2 border border-black rounded-full hover:bg-black hover:text-white transition-colors duration-200 ease-in;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.text-xsmall-regular {
|
|
48
|
+
@apply text-[10px] leading-4 font-normal;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.text-small-regular {
|
|
52
|
+
@apply text-xs leading-5 font-normal;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.text-small-semi {
|
|
56
|
+
@apply text-xs leading-5 font-semibold;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.text-base-regular {
|
|
60
|
+
@apply text-sm leading-6 font-normal;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.text-base-semi {
|
|
64
|
+
@apply text-sm leading-6 font-semibold;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.text-large-regular {
|
|
68
|
+
@apply text-base leading-6 font-normal;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.text-large-semi {
|
|
72
|
+
@apply text-base leading-6 font-semibold;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.text-xl-regular {
|
|
76
|
+
@apply text-2xl leading-[36px] font-normal;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.text-xl-semi {
|
|
80
|
+
@apply text-2xl leading-[36px] font-semibold;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.text-2xl-regular {
|
|
84
|
+
@apply text-[30px] leading-[48px] font-normal;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.text-2xl-semi {
|
|
88
|
+
@apply text-[30px] leading-[48px] font-semibold;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.text-3xl-regular {
|
|
92
|
+
@apply text-[32px] leading-[44px] font-normal;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.text-3xl-semi {
|
|
96
|
+
@apply text-[32px] leading-[44px] font-semibold;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/* COPIE de design/ par scripts/sync-design.mjs — ne pas modifier ici. */
|
|
2
|
+
|
|
3
|
+
/* =====================================================================
|
|
4
|
+
Usine à Boutiques — composants
|
|
5
|
+
1. PRESETS DE THÈME : chaque campagne reprend une référence (police,
|
|
6
|
+
arrondis, forme des boutons, casse des titres, mise en page du hero).
|
|
7
|
+
2. COMPOSANTS : un seul markup, stylé par les tokens + le preset.
|
|
8
|
+
===================================================================== */
|
|
9
|
+
|
|
10
|
+
/* ---------- 1. Presets ---------- */
|
|
11
|
+
:root,[data-theme="halloween"]{ /* Nexora, version sombre */
|
|
12
|
+
--ub-font-head:var(--font-space-grotesk);--ub-font-body:var(--font-inter);
|
|
13
|
+
--ub-head-weight:700;--ub-head-case:uppercase;--ub-head-track:-0.01em;
|
|
14
|
+
--ub-r-card:var(--radius-xl);--ub-r-btn:var(--radius-pill);--ub-r-tile:var(--radius-xl);--ub-r-hero:0px;--ub-r-media:var(--radius-xl);
|
|
15
|
+
}
|
|
16
|
+
[data-theme="thanksgiving"]{ /* NovaTrend */
|
|
17
|
+
--ub-font-head:var(--font-jakarta);--ub-font-body:var(--font-jakarta);
|
|
18
|
+
--ub-head-weight:800;--ub-head-case:none;--ub-head-track:-0.02em;
|
|
19
|
+
--ub-r-card:var(--radius-lg);--ub-r-btn:var(--radius-sm);--ub-r-tile:var(--radius-lg);--ub-r-hero:0px;--ub-r-media:var(--radius-lg);
|
|
20
|
+
}
|
|
21
|
+
[data-theme="black-friday"]{ /* Aeroflow + bloc Flash Sale NovaTrend */
|
|
22
|
+
--ub-font-head:var(--font-oswald);--ub-font-body:var(--font-inter);
|
|
23
|
+
--ub-head-weight:700;--ub-head-case:uppercase;--ub-head-track:0;
|
|
24
|
+
--ub-r-card:var(--radius-md);--ub-r-btn:var(--radius-pill);--ub-r-tile:var(--radius-md);--ub-r-hero:0px;--ub-r-media:var(--radius-md);
|
|
25
|
+
}
|
|
26
|
+
[data-theme="cyber-monday"]{ /* NovaTech */
|
|
27
|
+
--ub-font-head:var(--font-outfit);--ub-font-body:var(--font-outfit);
|
|
28
|
+
--ub-head-weight:600;--ub-head-case:none;--ub-head-track:-0.01em;
|
|
29
|
+
--ub-r-card:var(--radius-lg);--ub-r-btn:var(--radius-md);--ub-r-tile:var(--radius-lg);--ub-r-hero:0px;--ub-r-media:var(--radius-lg);
|
|
30
|
+
}
|
|
31
|
+
[data-theme="noel"]{ /* Crescendo */
|
|
32
|
+
--ub-font-head:var(--font-poppins);--ub-font-body:var(--font-poppins);
|
|
33
|
+
--ub-head-weight:700;--ub-head-case:none;--ub-head-track:-0.02em;
|
|
34
|
+
--ub-r-card:var(--radius-xl);--ub-r-btn:var(--radius-md);--ub-r-tile:var(--radius-xl);--ub-r-hero:var(--radius-2xl);--ub-r-media:var(--radius-xl);
|
|
35
|
+
}
|
|
36
|
+
[data-theme="nouvel-an"]{ /* Nexora, version claire */
|
|
37
|
+
--ub-font-head:var(--font-sora);--ub-font-body:var(--font-inter);
|
|
38
|
+
--ub-head-weight:600;--ub-head-case:uppercase;--ub-head-track:-0.01em;
|
|
39
|
+
--ub-r-card:var(--radius-xl);--ub-r-btn:var(--radius-pill);--ub-r-tile:var(--radius-xl);--ub-r-hero:0px;--ub-r-media:var(--radius-xl);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ---------- 2. Base ---------- */
|
|
43
|
+
.ub{font-family:var(--ub-font-body);color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased;font-size:15px;line-height:24px}
|
|
44
|
+
.ub *{box-sizing:border-box}
|
|
45
|
+
:where(.ub) a{color:inherit;text-decoration:none}
|
|
46
|
+
:where(.ub) h1,:where(.ub) h2,:where(.ub) h3,:where(.ub) p{margin:0}
|
|
47
|
+
.ub :focus-visible{outline:2px solid var(--focus);outline-offset:2px}
|
|
48
|
+
.ub svg{flex:none}
|
|
49
|
+
.ub-wrap{max-width:var(--content-max);margin:0 auto;padding:0 var(--space-6)}
|
|
50
|
+
.ub-section{padding:var(--space-12) 0}
|
|
51
|
+
.ub-head{font-family:var(--ub-font-head);font-weight:var(--ub-head-weight);text-transform:var(--ub-head-case);letter-spacing:var(--ub-head-track)}
|
|
52
|
+
.ub-sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-6)}
|
|
53
|
+
.ub-sec-head h2{font-size:28px;line-height:34px}
|
|
54
|
+
.ub-more{display:inline-flex;align-items:center;gap:6px;font-size:14px;font-weight:600;color:var(--ink)}
|
|
55
|
+
.ub-more svg{width:16px;height:16px}
|
|
56
|
+
|
|
57
|
+
/* Eyebrow : « NEXT-GEN GADGETS » (Nexora), puce « Special Offer » (NovaTech), « TRENDING NOW » (NovaTrend) */
|
|
58
|
+
.ub-eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:12px;line-height:16px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--primary)}
|
|
59
|
+
.ub-eyebrow__dot{width:8px;height:8px;border-radius:var(--radius-pill);background:currentColor}
|
|
60
|
+
[data-theme="cyber-monday"] .ub-eyebrow{letter-spacing:0;text-transform:none;font-size:13px;padding:4px 10px;border-radius:var(--radius-pill);background:var(--accent);color:var(--on-accent)}
|
|
61
|
+
[data-theme="noel"] .ub-eyebrow{letter-spacing:0;text-transform:none;font-size:13px;padding:4px 12px;border-radius:var(--radius-pill);background:var(--tint-2);color:var(--accent)}
|
|
62
|
+
[data-theme="halloween"] .ub-eyebrow,[data-theme="nouvel-an"] .ub-eyebrow{color:var(--accent)}
|
|
63
|
+
[data-theme="black-friday"] .ub-eyebrow{color:var(--primary)}
|
|
64
|
+
|
|
65
|
+
/* Placeholder photo (remplacé par les images produit Medusa) */
|
|
66
|
+
.ub-ph{position:relative;background:var(--surface);display:flex;align-items:center;justify-content:center;color:var(--ink-muted)}
|
|
67
|
+
.ub-ph::before{content:"";width:28px;height:28px;opacity:.5;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Ccircle cx='9' cy='10' r='2'/%3E%3Cpath d='M21 16l-5-5-9 9'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Ccircle cx='9' cy='10' r='2'/%3E%3Cpath d='M21 16l-5-5-9 9'/%3E%3C/svg%3E") center/contain no-repeat}
|
|
68
|
+
|
|
69
|
+
/* ---------- Button ---------- */
|
|
70
|
+
.ub-btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;height:48px;padding:0 24px;border:1px solid transparent;border-radius:var(--ub-r-btn);font:600 15px/20px var(--ub-font-body);cursor:pointer;white-space:nowrap;text-decoration:none}
|
|
71
|
+
.ub-btn svg{width:16px;height:16px}
|
|
72
|
+
.ub-btn--primary{background:var(--primary);color:var(--on-primary)}
|
|
73
|
+
.ub-btn--dark{background:var(--accent);color:var(--on-accent)}
|
|
74
|
+
[data-theme="halloween"] .ub-btn--dark,[data-theme="nouvel-an"] .ub-btn--dark,[data-theme="cyber-monday"] .ub-btn--dark,[data-theme="noel"] .ub-btn--dark{background:var(--ink);color:var(--bg)}
|
|
75
|
+
.ub-btn--ghost{background:transparent;color:var(--ink);border-color:var(--border)}
|
|
76
|
+
.ub-btn--full{width:100%}
|
|
77
|
+
.ub-btn--sm{height:40px;padding:0 16px;font-size:14px}
|
|
78
|
+
/* Nexora : pastille ronde foncée avec flèche au bout du bouton */
|
|
79
|
+
.ub-btn__arrow{display:none}
|
|
80
|
+
[data-theme="halloween"] .ub-btn--primary,[data-theme="nouvel-an"] .ub-btn--primary{padding:0 6px 0 24px;text-transform:uppercase;letter-spacing:.06em;font-size:13px}
|
|
81
|
+
[data-theme="halloween"] .ub-btn--primary .ub-btn__arrow,[data-theme="nouvel-an"] .ub-btn--primary .ub-btn__arrow{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:var(--radius-pill);background:var(--on-primary);color:var(--primary)}
|
|
82
|
+
[data-theme="halloween"] .ub-btn--primary .ub-btn__icon,[data-theme="nouvel-an"] .ub-btn--primary .ub-btn__icon{display:none}
|
|
83
|
+
/* Aeroflow : boutons en capitales */
|
|
84
|
+
[data-theme="black-friday"] .ub-btn{text-transform:uppercase;letter-spacing:.04em}
|
|
85
|
+
|
|
86
|
+
/* ---------- TopBar ---------- */
|
|
87
|
+
.ub-topbar{background:var(--topbar-bg);color:var(--topbar-ink);font-size:13px;line-height:20px;font-weight:500}
|
|
88
|
+
.ub-topbar .ub-wrap{display:flex;justify-content:center;gap:var(--space-8);padding-top:9px;padding-bottom:9px;flex-wrap:wrap}
|
|
89
|
+
.ub-topbar span{display:inline-flex;align-items:center;gap:8px}
|
|
90
|
+
.ub-topbar svg{width:15px;height:15px}
|
|
91
|
+
|
|
92
|
+
/* ---------- Nav ---------- */
|
|
93
|
+
.ub-nav{background:var(--bg);border-bottom:1px solid var(--border)}
|
|
94
|
+
.ub-nav .ub-wrap{display:flex;align-items:center;gap:var(--space-8);height:76px}
|
|
95
|
+
.ub-logo{display:inline-flex;align-items:center;gap:10px;font:700 20px/24px var(--ub-font-head);letter-spacing:var(--ub-head-track);text-transform:var(--ub-head-case)}
|
|
96
|
+
.ub-logo__mark{width:28px;height:28px;border-radius:var(--radius-sm);background:var(--primary)}
|
|
97
|
+
[data-theme="halloween"] .ub-logo__mark,[data-theme="nouvel-an"] .ub-logo__mark{background:var(--accent);border-radius:var(--radius-pill)}
|
|
98
|
+
.ub-nav__links{display:flex;gap:var(--space-6);font-size:14px;font-weight:500;color:var(--ink);margin:0 auto}
|
|
99
|
+
.ub-nav__links a[aria-current]{color:var(--primary);box-shadow:0 2px 0 var(--primary)}
|
|
100
|
+
[data-theme="halloween"] .ub-nav__links a[aria-current],[data-theme="nouvel-an"] .ub-nav__links a[aria-current]{color:var(--ink);box-shadow:none;font-weight:700}
|
|
101
|
+
[data-theme="nouvel-an"] .ub-nav__links a[aria-current]{color:var(--ink)}
|
|
102
|
+
[data-theme="black-friday"] .ub-nav__links{text-transform:uppercase;letter-spacing:.04em;font-weight:600}
|
|
103
|
+
[data-theme="black-friday"] .ub-nav__links a[aria-current]{color:var(--ink);box-shadow:0 2px 0 var(--primary)}
|
|
104
|
+
.ub-search{display:none;align-items:center;justify-content:space-between;width:220px;height:40px;padding:0 14px;border:1px solid var(--border);border-radius:var(--radius-pill);color:var(--ink-muted);font-size:13px}
|
|
105
|
+
.ub-search svg{width:17px;height:17px;color:var(--ink)}
|
|
106
|
+
[data-theme="cyber-monday"] .ub-search{display:flex}
|
|
107
|
+
[data-theme="cyber-monday"] .ub-icon--search{display:none}
|
|
108
|
+
.ub-nav__icons{display:flex;align-items:center;gap:6px}
|
|
109
|
+
.ub-icon{position:relative;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--radius-pill);color:var(--ink);background:transparent;border:0}
|
|
110
|
+
.ub-icon svg{width:21px;height:21px}
|
|
111
|
+
.ub-count{position:absolute;top:2px;right:0;min-width:18px;height:18px;padding:0 5px;border-radius:var(--radius-pill);background:var(--primary);color:var(--on-primary);font:700 11px/18px var(--ub-font-body);text-align:center}
|
|
112
|
+
.ub-nav__cta{display:none}
|
|
113
|
+
[data-theme="halloween"] .ub-nav__cta,[data-theme="nouvel-an"] .ub-nav__cta,[data-theme="noel"] .ub-nav__cta{display:inline-flex}
|
|
114
|
+
[data-theme="noel"] .ub-nav__cta{height:40px;padding:0 18px;font-size:14px}
|
|
115
|
+
[data-theme="halloween"] .ub-icon--fav,[data-theme="nouvel-an"] .ub-icon--fav,[data-theme="noel"] .ub-icon--fav,[data-theme="noel"] .ub-icon--user{display:none}
|
|
116
|
+
|
|
117
|
+
/* ---------- Hero ---------- */
|
|
118
|
+
.ub-hero{background:var(--hero-bg);color:var(--hero-ink);overflow:hidden}
|
|
119
|
+
.ub-hero__in{display:grid;grid-template-columns:1.05fr 1fr;align-items:center;gap:var(--space-12);padding-top:var(--space-16);padding-bottom:var(--space-16)}
|
|
120
|
+
.ub-hero__text{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4)}
|
|
121
|
+
.ub-hero__title{font-size:56px;line-height:60px}
|
|
122
|
+
.ub-hero__title em{font-style:normal;color:var(--primary)}
|
|
123
|
+
[data-theme="halloween"] .ub-hero__title em,[data-theme="nouvel-an"] .ub-hero__title em,[data-theme="noel"] .ub-hero__title em{color:var(--accent)}
|
|
124
|
+
[data-theme="halloween"] .ub-hero__title,[data-theme="nouvel-an"] .ub-hero__title{font-size:68px;line-height:70px}
|
|
125
|
+
.ub-hero__sub{max-width:420px;color:var(--hero-muted);font-size:16px;line-height:26px}
|
|
126
|
+
.ub-hero__actions{display:flex;gap:var(--space-3);flex-wrap:wrap;margin-top:var(--space-2)}
|
|
127
|
+
.ub-hero .ub-btn--ghost{color:var(--hero-ink);border-color:var(--border);background:var(--bg)}
|
|
128
|
+
[data-theme="halloween"] .ub-hero .ub-btn--ghost,[data-theme="nouvel-an"] .ub-hero .ub-btn--ghost{display:none}
|
|
129
|
+
.ub-hero__trust{display:none;gap:var(--space-4);list-style:none;margin:var(--space-4) 0 0;padding:10px 14px;border-radius:var(--radius-lg);background:rgba(255,255,255,.7)}
|
|
130
|
+
.ub-hero__trust li{display:flex;align-items:center;gap:10px;font-size:13px;line-height:18px;font-weight:500}
|
|
131
|
+
.ub-hero__trust svg{width:22px;height:22px;color:var(--primary)}
|
|
132
|
+
.ub-hero__trust small{display:block;color:var(--hero-muted);font-size:11px;font-weight:400}
|
|
133
|
+
[data-theme="noel"] .ub-hero__trust{display:flex}
|
|
134
|
+
.ub-hero__media{position:relative;min-height:400px;display:flex;align-items:center;justify-content:center}
|
|
135
|
+
.ub-hero__blob{position:absolute;width:380px;height:380px;border-radius:var(--radius-pill);background:var(--accent);opacity:.35}
|
|
136
|
+
[data-theme="thanksgiving"] .ub-hero__blob{background:var(--primary);opacity:.9;border-radius:48% 52% 38% 62% / 55% 40% 60% 45%;width:340px;height:300px}
|
|
137
|
+
[data-theme="cyber-monday"] .ub-hero__blob{background:var(--primary);opacity:.1}
|
|
138
|
+
[data-theme="noel"] .ub-hero__blob{background:var(--bg);opacity:.9;width:420px;height:420px}
|
|
139
|
+
[data-theme="nouvel-an"] .ub-hero__blob{opacity:.22;width:420px;height:420px}
|
|
140
|
+
.ub-hero__photo{position:relative;width:74%;aspect-ratio:1/1;border-radius:var(--ub-r-media)}
|
|
141
|
+
.ub-hero__photo.ub-ph{background:transparent;color:var(--hero-muted)}
|
|
142
|
+
.ub-bubble{position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;width:112px;height:112px;border-radius:var(--radius-pill);background:var(--bubble-bg);color:var(--bubble-ink);box-shadow:var(--shadow-pop);font:500 13px/16px var(--ub-font-body);text-align:center;left:4%;bottom:10%}
|
|
143
|
+
.ub-bubble b{font:700 30px/34px var(--ub-font-head)}
|
|
144
|
+
[data-theme="cyber-monday"] .ub-bubble{left:auto;right:14%;top:6%;bottom:auto;width:96px;height:96px}
|
|
145
|
+
[data-theme="cyber-monday"] .ub-bubble b{font-size:18px;line-height:22px}
|
|
146
|
+
[data-theme="halloween"] .ub-bubble,[data-theme="nouvel-an"] .ub-bubble{display:none}
|
|
147
|
+
/* Crescendo : hero dans un grand conteneur arrondi */
|
|
148
|
+
[data-theme="noel"] .ub-hero{background:var(--bg);padding:var(--space-6) var(--space-6) 0}
|
|
149
|
+
[data-theme="noel"] .ub-hero__in{background:var(--hero-bg);border-radius:var(--ub-r-hero);padding:var(--space-12)}
|
|
150
|
+
/* Black Friday : hero noir centré, titre géant */
|
|
151
|
+
[data-theme="black-friday"] .ub-hero__in{grid-template-columns:1fr;text-align:center;padding-top:88px;padding-bottom:88px}
|
|
152
|
+
[data-theme="black-friday"] .ub-hero__text{align-items:center}
|
|
153
|
+
[data-theme="black-friday"] .ub-hero__title{font-size:120px;line-height:112px}
|
|
154
|
+
[data-theme="black-friday"] .ub-hero__title em{display:block;font-size:56px;line-height:64px}
|
|
155
|
+
[data-theme="black-friday"] .ub-hero__sub{max-width:520px}
|
|
156
|
+
[data-theme="black-friday"] .ub-hero__media{display:none}
|
|
157
|
+
[data-theme="black-friday"] .ub-hero .ub-btn--ghost{background:transparent;color:var(--hero-ink);border-color:var(--hero-muted)}
|
|
158
|
+
|
|
159
|
+
/* ---------- Countdown : cases (NovaTech « 16 Days », NovaTrend Flash Sale) ---------- */
|
|
160
|
+
.ub-countdown{display:flex;gap:10px}
|
|
161
|
+
.ub-countdown__c{display:flex;flex-direction:column;align-items:center;justify-content:center;min-width:62px;height:62px;padding:0 6px;border-radius:var(--radius-md);background:var(--bg);color:var(--ink);box-shadow:var(--shadow-card)}
|
|
162
|
+
.ub-countdown__c b{font:700 22px/26px var(--ub-font-head);font-variant-numeric:tabular-nums}
|
|
163
|
+
.ub-countdown__c small{font-size:11px;line-height:14px;color:var(--ink-muted)}
|
|
164
|
+
[data-theme="black-friday"] .ub-countdown__c{background:transparent;color:var(--hero-ink);border:1px solid var(--hero-muted);box-shadow:none}
|
|
165
|
+
[data-theme="black-friday"] .ub-countdown__c small{color:var(--hero-muted)}
|
|
166
|
+
[data-theme="halloween"] .ub-countdown__c{background:var(--surface);color:var(--ink);box-shadow:none;border:1px solid var(--border)}
|
|
167
|
+
.ub-hero__cd{display:none}
|
|
168
|
+
[data-theme="black-friday"] .ub-hero__cd,[data-theme="cyber-monday"] .ub-hero__cd,[data-theme="halloween"] .ub-hero__cd{display:flex}
|
|
169
|
+
|
|
170
|
+
/* ---------- TrustBar ---------- */
|
|
171
|
+
.ub-trust{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-6);padding:var(--space-6) var(--space-8);border-radius:var(--ub-r-card);background:var(--surface);list-style:none;margin:0}
|
|
172
|
+
.ub-trust li{display:flex;align-items:center;gap:14px}
|
|
173
|
+
.ub-trust__ic{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:var(--radius-pill);background:var(--bg);color:var(--primary)}
|
|
174
|
+
.ub-trust__ic svg{width:22px;height:22px}
|
|
175
|
+
.ub-trust b{display:block;font-size:14px;line-height:20px}
|
|
176
|
+
.ub-trust small{display:block;font-size:12px;line-height:18px;color:var(--ink-muted)}
|
|
177
|
+
[data-theme="halloween"] .ub-trust,[data-theme="nouvel-an"] .ub-trust{background:var(--band-bg);color:var(--band-ink)}
|
|
178
|
+
[data-theme="halloween"] .ub-trust small,[data-theme="nouvel-an"] .ub-trust small{color:var(--band-ink);opacity:.8}
|
|
179
|
+
[data-theme="halloween"] .ub-trust__ic,[data-theme="nouvel-an"] .ub-trust__ic{background:transparent;color:var(--primary);border:1px solid rgba(255,255,255,.18)}
|
|
180
|
+
[data-theme="black-friday"] .ub-trust b{text-transform:uppercase;letter-spacing:.04em}
|
|
181
|
+
[data-theme="black-friday"] .ub-trust__ic{color:var(--ink)}
|
|
182
|
+
|
|
183
|
+
/* ---------- Category tiles ---------- */
|
|
184
|
+
.ub-tiles{display:grid;grid-template-columns:repeat(6,1fr);gap:var(--space-3)}
|
|
185
|
+
.ub-tile{position:relative;display:flex;flex-direction:column;overflow:hidden;border-radius:var(--ub-r-tile);background:var(--surface);border:1px solid var(--border);min-height:190px}
|
|
186
|
+
.ub-tile__img{flex:1;min-height:130px}
|
|
187
|
+
.ub-tile__txt{display:flex;flex-direction:column;padding:12px 14px}
|
|
188
|
+
.ub-tile__name{font-weight:600;font-size:14px;line-height:20px}
|
|
189
|
+
.ub-tile__meta{font-size:12px;line-height:16px;color:var(--ink-muted)}
|
|
190
|
+
.ub-tile__ic{display:none}
|
|
191
|
+
.ub-tile__cta{display:none;font-size:12px;font-weight:600;color:var(--primary)}
|
|
192
|
+
/* NovaTech : petites tuiles blanches avec icône + « 24 items » */
|
|
193
|
+
[data-theme="cyber-monday"] .ub-tile{background:var(--bg);box-shadow:var(--shadow-card);align-items:center;text-align:center;min-height:0;padding:22px 8px 14px}
|
|
194
|
+
[data-theme="cyber-monday"] .ub-tile__img{display:none}
|
|
195
|
+
[data-theme="cyber-monday"] .ub-tile__ic{display:flex;width:48px;height:48px;align-items:center;justify-content:center;color:var(--primary)}
|
|
196
|
+
[data-theme="cyber-monday"] .ub-tile__ic svg{width:36px;height:36px}
|
|
197
|
+
[data-theme="cyber-monday"] .ub-tile__txt{padding:8px 0 0;align-items:center}
|
|
198
|
+
/* Crescendo : grandes tuiles pastel, icône en pastille, « Shop Now → », visuel en bas à droite */
|
|
199
|
+
[data-theme="noel"] .ub-tiles{grid-template-columns:repeat(4,1fr);gap:var(--space-6)}
|
|
200
|
+
[data-theme="noel"] .ub-tile:nth-child(n+5){display:none}
|
|
201
|
+
[data-theme="noel"] .ub-tile{border:0;background:var(--tile);min-height:230px;padding:20px}
|
|
202
|
+
[data-theme="noel"] .ub-tile__txt{padding:0}
|
|
203
|
+
[data-theme="noel"] .ub-tile__ic{display:flex;order:-1;width:44px;height:44px;border-radius:var(--radius-pill);background:var(--bg);align-items:center;justify-content:center;color:var(--primary);margin-bottom:12px}
|
|
204
|
+
[data-theme="noel"] .ub-tile__ic svg{width:22px;height:22px}
|
|
205
|
+
[data-theme="noel"] .ub-tile__name{font-size:17px;line-height:24px}
|
|
206
|
+
[data-theme="noel"] .ub-tile__cta{display:block;margin-top:8px}
|
|
207
|
+
[data-theme="noel"] .ub-tile__img{position:absolute;right:14px;bottom:14px;width:44%;min-height:0;aspect-ratio:1;border-radius:var(--radius-pill);background:rgba(255,255,255,.65)}
|
|
208
|
+
/* NovaTrend : tuiles photo, libellé + « Shop Now → » sur bandeau blanc */
|
|
209
|
+
[data-theme="thanksgiving"] .ub-tile{border:0;min-height:210px}
|
|
210
|
+
[data-theme="thanksgiving"] .ub-tile__txt{position:absolute;left:8px;right:8px;bottom:8px;background:var(--bg);border-radius:var(--radius-sm);padding:8px 10px}
|
|
211
|
+
[data-theme="thanksgiving"] .ub-tile__meta{display:none}
|
|
212
|
+
[data-theme="thanksgiving"] .ub-tile__cta{display:block;color:var(--ink-muted);font-weight:500}
|
|
213
|
+
/* Black Friday : tuiles noires, libellé en capitales */
|
|
214
|
+
[data-theme="black-friday"] .ub-tile{background:var(--ink);color:var(--bg);border:0}
|
|
215
|
+
[data-theme="black-friday"] .ub-tile__img{background:rgba(255,255,255,.08);color:var(--hero-muted)}
|
|
216
|
+
[data-theme="black-friday"] .ub-tile__name{text-transform:uppercase;letter-spacing:.04em;font-family:var(--ub-font-head);font-size:17px}
|
|
217
|
+
[data-theme="black-friday"] .ub-tile__meta{color:var(--hero-muted)}
|
|
218
|
+
|
|
219
|
+
/* ---------- Product card ---------- */
|
|
220
|
+
.ub-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-6)}
|
|
221
|
+
.ub-card{position:relative;display:flex;flex-direction:column;border-radius:var(--ub-r-card);background:var(--surface);overflow:hidden}
|
|
222
|
+
[data-theme="noel"] .ub-card,[data-theme="cyber-monday"] .ub-card{background:var(--bg);box-shadow:var(--shadow-card)}
|
|
223
|
+
.ub-card__media{aspect-ratio:1/1}
|
|
224
|
+
[data-theme="noel"] .ub-card__media,[data-theme="cyber-monday"] .ub-card__media{margin:12px 12px 0;border-radius:calc(var(--ub-r-card) - 8px)}
|
|
225
|
+
.ub-badge{position:absolute;top:12px;left:12px;z-index:1;padding:3px 9px;border-radius:var(--radius-sm);font:700 11px/16px var(--ub-font-body);background:var(--ink);color:var(--bg)}
|
|
226
|
+
.ub-badge--sale{background:var(--sale);color:var(--bg)}
|
|
227
|
+
[data-theme="cyber-monday"] .ub-badge{left:auto;right:20px;top:20px;background:var(--primary);color:var(--on-primary)}
|
|
228
|
+
[data-theme="noel"] .ub-badge{border-radius:var(--radius-pill);background:var(--accent);color:var(--on-accent);top:22px;left:22px}
|
|
229
|
+
[data-theme="noel"] .ub-badge--sale{background:var(--sale);color:var(--bg)}
|
|
230
|
+
.ub-card__fav{position:absolute;top:10px;right:10px;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--radius-pill);background:var(--bg);border:0;color:var(--ink)}
|
|
231
|
+
.ub-card__fav svg{width:16px;height:16px}
|
|
232
|
+
[data-theme="cyber-monday"] .ub-card__fav,[data-theme="noel"] .ub-card__fav,[data-theme="halloween"] .ub-card__fav,[data-theme="nouvel-an"] .ub-card__fav{display:none}
|
|
233
|
+
.ub-card__body{display:flex;flex-direction:column;gap:4px;padding:14px 16px 16px}
|
|
234
|
+
.ub-card__cat{display:none;font-size:11px;line-height:16px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted)}
|
|
235
|
+
[data-theme="noel"] .ub-card__cat,[data-theme="black-friday"] .ub-card__cat{display:block}
|
|
236
|
+
.ub-card__name{font:600 15px/22px var(--ub-font-body)}
|
|
237
|
+
[data-theme="noel"] .ub-card__name{font-size:17px;line-height:24px}
|
|
238
|
+
[data-theme="black-friday"] .ub-card__name{text-transform:uppercase;font-family:var(--ub-font-head);font-size:18px;letter-spacing:.02em}
|
|
239
|
+
[data-theme="halloween"] .ub-card__name,[data-theme="nouvel-an"] .ub-card__name{font-weight:500;font-size:14px}
|
|
240
|
+
.ub-rating{display:flex;align-items:center;gap:6px;font-size:12px;line-height:16px;color:var(--ink-muted)}
|
|
241
|
+
.ub-rating__stars{color:var(--star);letter-spacing:1px;font-size:13px}
|
|
242
|
+
[data-theme="halloween"] .ub-card .ub-rating,[data-theme="nouvel-an"] .ub-card .ub-rating{display:none}
|
|
243
|
+
.ub-card__foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px}
|
|
244
|
+
.ub-price{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font-variant-numeric:tabular-nums}
|
|
245
|
+
.ub-price__now{font:700 16px/22px var(--ub-font-body);color:var(--ink)}
|
|
246
|
+
.ub-price__was{font-size:13px;color:var(--ink-muted);text-decoration:line-through}
|
|
247
|
+
.ub-price--sale .ub-price__now{color:var(--sale)}
|
|
248
|
+
.ub-card__cart{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius-pill);border:0;background:var(--ink);color:var(--bg)}
|
|
249
|
+
.ub-card__cart svg{width:17px;height:17px}
|
|
250
|
+
.ub-card__cart .ub-arrow{display:none}
|
|
251
|
+
[data-theme="noel"] .ub-card__cart{background:var(--tint-1);color:var(--primary);width:42px;height:42px}
|
|
252
|
+
[data-theme="cyber-monday"] .ub-card__cart{background:var(--bg);color:var(--ink);border:1px solid var(--border);border-radius:var(--radius-md)}
|
|
253
|
+
[data-theme="halloween"] .ub-card__cart,[data-theme="nouvel-an"] .ub-card__cart{width:28px;height:28px;background:var(--primary);color:var(--on-primary)}
|
|
254
|
+
[data-theme="halloween"] .ub-card__cart .ub-cart-ic,[data-theme="nouvel-an"] .ub-card__cart .ub-cart-ic{display:none}
|
|
255
|
+
[data-theme="halloween"] .ub-card__cart .ub-arrow,[data-theme="nouvel-an"] .ub-card__cart .ub-arrow{display:block;width:14px;height:14px}
|
|
256
|
+
[data-theme="black-friday"] .ub-card__cart{background:var(--primary);color:var(--on-primary)}
|
|
257
|
+
|
|
258
|
+
/* ---------- Promo banner ---------- */
|
|
259
|
+
.ub-promo{position:relative;display:grid;grid-template-columns:1.2fr 1fr;align-items:center;gap:var(--space-8);padding:var(--space-8) var(--space-12);border-radius:var(--ub-r-card);background:var(--band-bg);color:var(--band-ink);overflow:hidden;min-height:260px}
|
|
260
|
+
.ub-promo__text{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4)}
|
|
261
|
+
.ub-promo h2{font-size:36px;line-height:42px}
|
|
262
|
+
.ub-promo .ub-eyebrow{color:inherit;background:transparent;padding:0}
|
|
263
|
+
[data-theme="cyber-monday"] .ub-promo .ub-eyebrow{background:var(--bg);color:var(--primary);padding:4px 10px}
|
|
264
|
+
.ub-promo__media{height:220px;border-radius:var(--ub-r-media);background:rgba(255,255,255,.14);color:inherit}
|
|
265
|
+
[data-theme="cyber-monday"] .ub-promo__media{background:rgba(74,43,214,.08)}
|
|
266
|
+
.ub-promo .ub-btn--primary{background:var(--band-ink);color:var(--band-bg)}
|
|
267
|
+
[data-theme="cyber-monday"] .ub-promo .ub-btn--primary{background:var(--primary);color:var(--on-primary)}
|
|
268
|
+
[data-theme="halloween"] .ub-promo .ub-btn--primary,[data-theme="nouvel-an"] .ub-promo .ub-btn--primary{background:var(--primary);color:var(--on-primary)}
|
|
269
|
+
[data-theme="black-friday"] .ub-promo .ub-countdown__c{border-color:var(--band-ink);color:var(--band-ink)}
|
|
270
|
+
[data-theme="black-friday"] .ub-promo .ub-countdown__c small{color:var(--band-ink)}
|
|
271
|
+
.ub-promo__seal{display:none;width:108px;height:108px;padding:12px;border-radius:var(--radius-pill);background:var(--bg);color:var(--primary);align-items:center;justify-content:center;text-align:center;font:600 15px/19px var(--ub-font-head)}
|
|
272
|
+
[data-theme="noel"] .ub-promo{grid-template-columns:auto 1fr;padding:var(--space-6) var(--space-8);min-height:0}
|
|
273
|
+
[data-theme="noel"] .ub-promo__media,[data-theme="noel"] .ub-promo .ub-countdown{display:none}
|
|
274
|
+
[data-theme="noel"] .ub-promo__seal{display:flex}
|
|
275
|
+
[data-theme="noel"] .ub-promo__text{flex-direction:row;align-items:center;justify-content:space-between;flex-wrap:wrap;width:100%}
|
|
276
|
+
[data-theme="noel"] .ub-promo .ub-eyebrow{display:none}
|
|
277
|
+
|
|
278
|
+
/* ---------- Product detail (Aeroflow) ---------- */
|
|
279
|
+
.ub-pdp{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-12);align-items:start}
|
|
280
|
+
.ub-gallery__main{aspect-ratio:1/1;border-radius:var(--ub-r-media)}
|
|
281
|
+
.ub-gallery__thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-3);margin-top:var(--space-3)}
|
|
282
|
+
.ub-gallery__thumbs .ub-ph{aspect-ratio:1/1;border-radius:var(--radius-md);border:2px solid transparent}
|
|
283
|
+
.ub-gallery__thumbs .ub-ph[aria-current]{border-color:var(--ink)}
|
|
284
|
+
.ub-pdp__info{display:flex;flex-direction:column;gap:var(--space-3)}
|
|
285
|
+
.ub-pdp__title{font-size:40px;line-height:44px}
|
|
286
|
+
.ub-pdp__subtitle{font-size:16px;color:var(--ink-muted)}
|
|
287
|
+
.ub-pdp .ub-rating{display:flex;font-size:13px;color:var(--ink)}
|
|
288
|
+
.ub-pdp__was{font-size:16px;color:var(--ink-muted);text-decoration:line-through;margin-top:var(--space-2)}
|
|
289
|
+
.ub-pdp__price{display:flex;align-items:center;gap:12px}
|
|
290
|
+
.ub-pdp__price b{font:700 36px/40px var(--ub-font-head);color:var(--sale)}
|
|
291
|
+
.ub-save{padding:3px 10px;border-radius:var(--radius-sm);border:1px solid var(--success);color:var(--success);font-size:13px;font-weight:600}
|
|
292
|
+
.ub-pdp__desc{color:var(--ink-muted);max-width:480px}
|
|
293
|
+
.ub-pdp__buy{display:flex;flex-direction:column;gap:10px;margin-top:var(--space-2)}
|
|
294
|
+
.ub-pdp__ship{text-align:center;font-size:13px;color:var(--ink-muted)}
|
|
295
|
+
.ub-pdp__ship svg{width:14px;height:14px;vertical-align:-2px;margin-right:4px}
|
|
296
|
+
.ub-pdp__trust{display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:16px;border-radius:var(--radius-lg);background:var(--surface);font-size:13px;list-style:none;margin:var(--space-2) 0 0}
|
|
297
|
+
.ub-pdp__trust li{display:flex;align-items:center;gap:8px}
|
|
298
|
+
.ub-pdp__trust svg{width:18px;height:18px}
|
|
299
|
+
.ub-options{display:flex;gap:8px;flex-wrap:wrap}
|
|
300
|
+
.ub-opt{min-width:52px;height:40px;padding:0 14px;border-radius:var(--ub-r-btn);border:1px solid var(--border);background:var(--bg);color:var(--ink);font:500 14px/20px var(--ub-font-body)}
|
|
301
|
+
.ub-opt[aria-pressed="true"]{border:2px solid var(--ink)}
|
|
302
|
+
.ub-faq{border-top:1px solid var(--border)}
|
|
303
|
+
.ub-faq details{border-bottom:1px solid var(--border)}
|
|
304
|
+
.ub-faq summary{display:flex;justify-content:space-between;align-items:center;padding:14px 0;cursor:pointer;list-style:none;font-weight:500}
|
|
305
|
+
.ub-faq summary::-webkit-details-marker{display:none}
|
|
306
|
+
.ub-faq summary::after{content:"";width:8px;height:8px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);margin-right:6px}
|
|
307
|
+
.ub-faq details[open] summary::after{transform:rotate(-135deg)}
|
|
308
|
+
.ub-faq p{padding:0 0 14px;color:var(--ink-muted)}
|
|
309
|
+
|
|
310
|
+
/* ---------- Checkout : paiement international (Stripe + PayPal) ---------- */
|
|
311
|
+
.ub-pay{max-width:540px;display:flex;flex-direction:column;gap:var(--space-4)}
|
|
312
|
+
.ub-pay h2{font-size:22px;line-height:28px}
|
|
313
|
+
.ub-express{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
|
|
314
|
+
.ub-express button{height:48px;border-radius:var(--radius-md);border:1px solid var(--ink);background:var(--ink);color:var(--bg);font:600 15px/20px var(--ub-font-body);cursor:pointer}
|
|
315
|
+
.ub-express button.ub-express--light{background:var(--bg);color:var(--ink)}
|
|
316
|
+
.ub-divider{display:flex;align-items:center;gap:12px;color:var(--ink-muted);font-size:13px}
|
|
317
|
+
.ub-divider::before,.ub-divider::after{content:"";flex:1;height:1px;background:var(--border)}
|
|
318
|
+
.ub-methods{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
|
|
319
|
+
.ub-method{border-bottom:1px solid var(--border)}
|
|
320
|
+
.ub-method:last-child{border-bottom:0}
|
|
321
|
+
.ub-method__row{display:flex;align-items:center;gap:12px;padding:16px;cursor:pointer}
|
|
322
|
+
.ub-method__radio{width:18px;height:18px;border-radius:var(--radius-pill);border:1.5px solid var(--ink-muted)}
|
|
323
|
+
.ub-method[aria-checked="true"] .ub-method__radio{border:6px solid var(--ink)}
|
|
324
|
+
.ub-method[aria-checked="true"]{background:var(--surface)}
|
|
325
|
+
.ub-method__name{font-weight:600;flex:1}
|
|
326
|
+
.ub-method__tags{display:flex;gap:6px}
|
|
327
|
+
.ub-tag{padding:2px 8px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg);font-size:11px;font-weight:700;color:var(--ink)}
|
|
328
|
+
.ub-method__body{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:0 16px 16px 46px}
|
|
329
|
+
.ub-field{display:flex;flex-direction:column;gap:6px;font-size:13px;font-weight:500}
|
|
330
|
+
.ub-field--full{grid-column:1/-1}
|
|
331
|
+
.ub-input{height:44px;padding:0 12px;display:flex;align-items:center;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg);color:var(--ink-muted);font-weight:400}
|
|
332
|
+
.ub-method__note{grid-column:1/-1;font-size:12px;color:var(--ink-muted)}
|
|
333
|
+
|
|
334
|
+
/* ---------- Cart drawer ---------- */
|
|
335
|
+
.ub-cart{width:400px;border-radius:var(--ub-r-card);background:var(--bg);border:1px solid var(--border);box-shadow:var(--shadow-pop);overflow:hidden}
|
|
336
|
+
.ub-cart__head{display:flex;justify-content:space-between;align-items:center;padding:18px 20px;border-bottom:1px solid var(--border)}
|
|
337
|
+
.ub-cart__head h2{font-size:20px;line-height:28px}
|
|
338
|
+
.ub-cart__ship{padding:14px 20px;font-size:13px;color:var(--ink-muted);border-bottom:1px solid var(--border)}
|
|
339
|
+
.ub-bar{height:6px;border-radius:var(--radius-pill);background:var(--surface);margin-top:8px;overflow:hidden}
|
|
340
|
+
.ub-bar i{display:block;height:100%;background:var(--primary)}
|
|
341
|
+
.ub-line{display:grid;grid-template-columns:72px 1fr auto;gap:14px;padding:16px 20px;border-bottom:1px solid var(--border)}
|
|
342
|
+
.ub-line .ub-ph{width:72px;height:72px;border-radius:var(--radius-md)}
|
|
343
|
+
.ub-line__name{font-weight:600;font-size:14px;line-height:20px}
|
|
344
|
+
.ub-line__meta{font-size:12px;color:var(--ink-muted)}
|
|
345
|
+
.ub-qty{display:inline-flex;align-items:center;margin-top:8px;border:1px solid var(--border);border-radius:var(--ub-r-btn);height:32px}
|
|
346
|
+
.ub-qty button{width:30px;height:30px;border:0;background:transparent;color:var(--ink)}
|
|
347
|
+
.ub-qty span{min-width:22px;text-align:center;font-size:13px;font-weight:600}
|
|
348
|
+
.ub-cart__foot{padding:18px 20px;display:flex;flex-direction:column;gap:12px}
|
|
349
|
+
.ub-cart__row{display:flex;justify-content:space-between;font-size:14px}
|
|
350
|
+
.ub-cart__row b{font-size:18px}
|
|
351
|
+
|
|
352
|
+
/* ---------- Footer ---------- */
|
|
353
|
+
.ub-footer{margin-top:var(--space-12);background:var(--surface);border-top:1px solid var(--border)}
|
|
354
|
+
[data-theme="halloween"] .ub-footer,[data-theme="nouvel-an"] .ub-footer{background:var(--band-bg);color:var(--band-ink);border:0}
|
|
355
|
+
[data-theme="black-friday"] .ub-footer{background:var(--ink);color:var(--bg);border:0}
|
|
356
|
+
.ub-footer__top{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:var(--space-8);padding:var(--space-12) 0 var(--space-8)}
|
|
357
|
+
.ub-footer p{opacity:.85;font-size:14px;margin-top:10px;max-width:280px}
|
|
358
|
+
.ub-footer h4{margin:0 0 12px;font-size:13px;letter-spacing:.06em;text-transform:uppercase}
|
|
359
|
+
.ub-footer ul{list-style:none;margin:0;padding:0;font-size:14px;line-height:30px;opacity:.85}
|
|
360
|
+
.ub-footer__bot{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:18px 0 28px;border-top:1px solid rgba(127,127,127,.25);font-size:13px;flex-wrap:wrap}
|
|
361
|
+
.ub-pays{display:flex;gap:6px;flex-wrap:wrap}
|
|
362
|
+
.ub-pays span{padding:4px 9px;border-radius:var(--radius-sm);background:#ffffff;color:#111827;border:1px solid rgba(127,127,127,.3);font-size:11px;font-weight:700}
|
|
363
|
+
|
|
364
|
+
@media (max-width:900px){
|
|
365
|
+
.ub-hero__in,.ub-pdp,.ub-promo{grid-template-columns:1fr}
|
|
366
|
+
.ub-hero__title,[data-theme="halloween"] .ub-hero__title,[data-theme="nouvel-an"] .ub-hero__title{font-size:40px;line-height:44px}
|
|
367
|
+
[data-theme="black-friday"] .ub-hero__title{font-size:64px;line-height:64px}
|
|
368
|
+
.ub-grid,.ub-tiles,[data-theme="noel"] .ub-tiles,[data-theme="cyber-monday"] .ub-tiles,.ub-trust{grid-template-columns:repeat(2,1fr)}
|
|
369
|
+
.ub-nav__links,.ub-search{display:none!important}
|
|
370
|
+
.ub-footer__top{grid-template-columns:1fr 1fr}
|
|
371
|
+
.ub-cart{width:100%}
|
|
372
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* Relie les polices next/font (--nf-*) aux variables du design (--font-*, définies dans tokens.css).
|
|
2
|
+
:root:root l'emporte sur le :root de tokens.css sans modifier ce fichier. */
|
|
3
|
+
:root:root {
|
|
4
|
+
--font-inter: var(--nf-inter, Inter), system-ui, sans-serif;
|
|
5
|
+
--font-jakarta: var(--nf-jakarta, "Plus Jakarta Sans"), var(--nf-inter, Inter), sans-serif;
|
|
6
|
+
--font-oswald: var(--nf-oswald, Oswald), "Arial Narrow", sans-serif;
|
|
7
|
+
--font-outfit: var(--nf-outfit, Outfit), var(--nf-inter, Inter), sans-serif;
|
|
8
|
+
--font-poppins: var(--nf-poppins, Poppins), var(--nf-inter, Inter), sans-serif;
|
|
9
|
+
--font-sora: var(--nf-sora, Sora), var(--nf-inter, Inter), sans-serif;
|
|
10
|
+
--font-space-grotesk: var(--nf-space-grotesk, "Space Grotesk"), var(--nf-inter, Inter), sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Le corps de page prend le fond du thème (le starter force du blanc). */
|
|
14
|
+
html,
|
|
15
|
+
body {
|
|
16
|
+
background: var(--bg);
|
|
17
|
+
}
|