:root {
    /* ====== COULEUR PRIMAIRE #D00B5E ====== */
    --bs-primary: #D00B5E;
    --bs-primary-rgb: 208, 11, 94;

    /* Teintes de primary (du plus clair au plus foncé) */
    --bs-primary-50: #fce8f0;
    --bs-primary-100: #f9d1e1;
    --bs-primary-200: #f3a3c3;
    --bs-primary-300: #ed75a5;
    --bs-primary-400: #e74787;
    --bs-primary-500: #D00B5E;  /* Couleur principale */
    --bs-primary-600: #a60949;
    --bs-primary-700: #7d0737;
    --bs-primary-800: #530424;
    --bs-primary-900: #2a0212;

    /* Variations Bootstrap de primary */
    --bs-primary-bg-subtle: #fce8f0;
    --bs-primary-border-subtle: #f3a3c3;
    --bs-primary-text-emphasis: #7d0737;

    /* ====== AUTRES COULEURS ADAPTÉES ====== */
    --bs-secondary: #6c757d;
    --bs-secondary-rgb: 108, 117, 125;

    --bs-success: #198754;
    --bs-success-rgb: 25, 135, 84;

    --bs-info: #0dcaf0;
    --bs-info-rgb: 13, 202, 240;

    --bs-warning: #ffc107;
    --bs-warning-rgb: 255, 193, 7;

    --bs-danger: #dc3545;
    --bs-danger-rgb: 220, 53, 69;

    --bs-light: #f8f9fa;
    --bs-light-rgb: 248, 249, 250;

    --bs-dark: #212529;
    --bs-dark-rgb: 33, 37, 41;

    --bs-white: #ffffff;
    --bs-white-rgb: 255, 255, 255;

    /* ====== PERSONNALISATION DES COMPOSANTS ====== */

    /* Liens */
    --bs-link-color: #D00B5E;
    --bs-link-hover-color: #a60949;
    --bs-link-color-rgb: 208, 11, 94;
    --bs-link-hover-color-rgb: 166, 9, 73;

    /* Corps de page */
    --bs-body-bg: #ffffff;
    --bs-body-color: #212529;

    /* Bordures */
    --bs-border-color: #dee2e6;
    --bs-border-radius: 0.375rem;
    --bs-border-radius-sm: 0.25rem;
    --bs-border-radius-lg: 0.5rem;
    --bs-border-radius-xl: 1rem;
    --bs-border-radius-2xl: 2rem;
}

/* ====== BOUTONS PERSONNALISÉS ====== */

/* Bouton primary */
.btn-primary {
    --bs-btn-bg: #D00B5E;
    --bs-btn-border-color: #D00B5E;
    --bs-btn-hover-bg: #a60949;
    --bs-btn-hover-border-color: #a60949;
    --bs-btn-focus-shadow-rgb: 208, 11, 94;
    --bs-btn-active-bg: #7d0737;
    --bs-btn-active-border-color: #7d0737;
    --bs-btn-disabled-bg: #D00B5E;
    --bs-btn-disabled-border-color: #D00B5E;
}

/* Bouton outline primary */
.btn-outline-primary {
    --bs-btn-color: #D00B5E;
    --bs-btn-border-color: #D00B5E;
    --bs-btn-hover-bg: #D00B5E;
    --bs-btn-hover-border-color: #D00B5E;
    --bs-btn-hover-color: #ffffff;
    --bs-btn-focus-shadow-rgb: 208, 11, 94;
    --bs-btn-active-bg: #D00B5E;
    --bs-btn-active-border-color: #D00B5E;
    --bs-btn-active-color: #ffffff;
    --bs-btn-disabled-color: #D00B5E;
    --bs-btn-disabled-border-color: #D00B5E;
}

/* Bouton primary sur blanc - effet moderne */
.btn-primary {
    color: #ffffff;
    font-weight: 600;
    transition: all 0.3s ease;
    box-shadow: 0 2px 4px rgba(208, 11, 94, 0.2);
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(208, 11, 94, 0.3);
}

/* ====== BADGES ====== */
.badge.bg-primary {
    background-color: #D00B5E !important;
}

.badge.text-bg-primary {
    background-color: #D00B5E !important;
    color: #ffffff !important;
}

/* ====== ALERTES ====== */
.alert-primary {
    --bs-alert-bg: #fce8f0;
    --bs-alert-border-color: #f3a3c3;
    --bs-alert-color: #7d0737;
}

/* ====== FORMULAIRES ====== */
.form-control:focus,
.form-select:focus {
    border-color: #ed75a5;
    box-shadow: 0 0 0 0.25rem rgba(208, 11, 94, 0.25);
}

.form-check-input:checked {
    background-color: #D00B5E;
    border-color: #D00B5E;
}

.form-check-input:focus {
    box-shadow: 0 0 0 0.25rem rgba(208, 11, 94, 0.25);
}

/* ====== PROGRESS BARS ====== */
.progress-bar {
    background-color: #D00B5E;
}

/* ====== SPINNERS ====== */
.spinner-border.text-primary,
.spinner-grow.text-primary {
    color: #D00B5E !important;
}

/* ====== NAVIGATION ====== */
.nav-link.active,
.navbar-nav .nav-link.active {
    color: #D00B5E !important;
}

.nav-pills .nav-link.active {
    background-color: #D00B5E;
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: #fce8f0;
    color: #D00B5E;
}

.dropdown-item.active {
    background-color: #D00B5E;
    color: #ffffff;
}

/* ====== PAGINATION ====== */
.page-link {
    color: #D00B5E;
}

.page-link:hover {
    color: #a60949;
    background-color: #fce8f0;
}

.page-item.active .page-link {
    background-color: #D00B5E;
    border-color: #D00B5E;
    color: #ffffff;
}

/* ====== CARDS ====== */
.card-primary {
    border-color: #D00B5E;
    border-top: 3px solid #D00B5E;
}

.card-header.bg-primary {
    background-color: #D00B5E !important;
    color: #ffffff;
}

/* ====== TABLES ====== */
.table-primary {
    --bs-table-bg: #fce8f0;
    --bs-table-border-color: #f3a3c3;
    --bs-table-striped-bg: #f9d1e1;
    --bs-table-hover-bg: #f3a3c3;
}

/* ====== MODALS ====== */
.modal-header.bg-primary {
    background-color: #D00B5E !important;
    color: #ffffff;
}

/* ====== CLASSES UTILITAIRES PERSONNALISÉES ====== */
.bg-primary-light {
    background-color: #fce8f0 !important;
}

.bg-primary-gradient {
    background: linear-gradient(135deg, #D00B5E 0%, #a60949 100%) !important;
    color: #ffffff;
}

.text-primary-light {
    color: #ed75a5 !important;
}

.text-primary-dark {
    color: #7d0737 !important;
}

.border-primary-light {
    border-color: #f3a3c3 !important;
}

/* ====== HOVER EFFECTS SUR FOND BLANC ====== */
.bg-white .btn-primary:hover {
    background-color: #a60949;
    border-color: #a60949;
}

/* Effet glass sur blanc */
.glass-effect {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(208, 11, 94, 0.1);
    box-shadow: 0 4px 6px rgba(208, 11, 94, 0.1);
}

/* Bouton ghost sur fond blanc */
.btn-ghost-primary {
    color: #D00B5E;
    background-color: transparent;
    border: 2px solid #D00B5E;
}

.btn-ghost-primary:hover {
    color: #ffffff;
    background-color: #D00B5E;
    border-color: #D00B5E;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(208, 11, 94, 0.2);
}

.dropdown-menu.store-dropdown-list {
    /* Two classes to outweigh public/css/style.css's `.dropdown-menu.show { min-width: 350px; }`
       (same specificity, but that stylesheet loads first — this one needs to tie, not lose). */
    min-width: 460px;
}

.store-dropdown-list {
    /* Bootstrap's default 0.5rem top/bottom padding on .dropdown-menu left a band of white
       above the beige zip panel (and below the last store). The panel and each store row
       already carry their own padding, so the dropdown itself doesn't need any. */
    padding-top: 0;
    padding-bottom: 0;
    /* The scrollbar itself isn't clipped to a rounded corner by the element that scrolls, so
       scrolling lives on an inner wrapper (.store-dropdown-scroll) instead — this element only
       clips that wrapper to its own (Bootstrap-drawn) rounded corners. */
    overflow: hidden;
}

.store-dropdown-scroll {
    max-height: 70vh;
    overflow-y: auto;
}

.store-zip-panel {
    background-color: #EEE8DE;
    padding: 16px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.store-zip-label {
    display: block;
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: #3A3A3A;
}

/* Smaller variant used by the store confirmation popin — the header dropdown's zip panel keeps
   the larger label above. */
.store-zip-label.store-zip-label-sm {
    font-size: 11px;
}

.store-zip-input {
    flex: 1 1 auto;
    min-width: 0;
    margin-right: 5px;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 8px 14px;
    font-size: 18px;
    letter-spacing: 4px;
    color: var(--bs-primary);
    font-weight: 700;
}

.store-zip-input:focus {
    /* Bootstrap's own `.form-control:focus` (class + pseudo-class) resets `color` and otherwise
       outranks the plain `.store-zip-input` rule above — matching its specificity here instead
       of relying on load order for a color that actually needs to survive focus. */
    color: var(--bs-primary);
}

.store-zip-city {
    /* As wide as the city name needs, up to 70% of the row — not a fixed reservation, so a
       short name doesn't leave the input squeezed for no reason. flex-shrink: 0 (not the 1 that
       `0 1 auto` would give) because — verified live — with shrink enabled the browser still
       shrank this well below its own content width even though the row had plenty of free
       space; max-width: 70% is what actually caps it once a name is genuinely too long to fit
       on one line. */
    flex: 0 0 auto;
    max-width: 70%;
    min-width: 0;
    /* Vertically centered within the row (its parent is align-items-stretch) without making
       this a flex container itself — a flex container gives its own text content an implicit
       min-width: auto, which refuses to shrink below the text's unbroken width and overflows
       instead of wrapping, right through the dropdown's overflow: hidden. */
    align-self: center;
    overflow-wrap: break-word;
    color: #3A3A3A;
    font-size: 14px;
}

.store-zip-city:empty {
    display: none;
}

/* Store shipping mode chips */
.store-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 20px;
    font-size: 11px;
    font-weight: 600;
}


.store-chip i {
    font-size: 12px;
}

.store-chip-lg {
    padding: 6px 14px;
    font-size: 12px;
}

.store-chip-lg i {
    font-size: 14px;
}

.store-chip-success {
    color: #2F7D55;
    background-color: #E4F1E9;
    border: 1px solid rgba(47, 125, 85, 0.28);
}

.store-chip-danger {
    color: #C0294A;
    background-color: #FBE7EC;
    border: 1px solid rgba(192, 41, 74, 0.28);
}

.store-chip-neutral {
    color: #7A7266;
    background-color: #EEE8DE;
}

/* Store confirmation popin — currently selected/default store card */
.confirm-store-card {
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 12px;
    padding: 12px 16px;
}

.confirm-store-image {
    width: 40px;
    height: 40px;
    object-fit: cover;
}

/* Footer's outlined/white button — plain Bootstrap .btn-secondary renders as a solid grey
   button, which doesn't match the popin's design (white, thin border, dark text). */
.btn-modal-ghost {
    background-color: #ffffff;
    color: #1C1C1E;
    border: 1px solid #E1DDD5;
}

.btn-modal-ghost:hover {
    background-color: #F6F4EF;
    color: #1C1C1E;
    border-color: #E1DDD5;
}

/* Store confirmation popin — "Choisir un magasin" radio list */
.store-radio-card {
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    padding: 12px 14px;
    cursor: pointer;
    transition: border-color .12s, box-shadow .12s;
}

.store-radio-card input[type="radio"] {
    accent-color: var(--bs-primary);
}

.store-radio-card:hover {
    border-color: var(--bs-primary);
}

.store-radio-card:has(input:checked) {
    /* :has() rather than a server-rendered "selected" class: the radio's own checked state
       already updates the instant the browser handles the click — a class computed from
       selectedStoreCode would only catch up once a live re-render came back from the server. */
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .15);
}

.store-radio-list {
    max-height: 340px;
    overflow-y: auto;
}

/* Étape "Mode de retrait" — cartes de sélection du mode (retrait en magasin / livraison à
   domicile) */
.pickup-mode-card {
    display: flex;
    align-items: center;
    gap: 12px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    padding: 12px 16px;
    cursor: pointer;
    transition: border-color .12s, box-shadow .12s;
}

.pickup-mode-card input[type="radio"] {
    accent-color: var(--bs-primary);
    margin-left: auto;
}

.pickup-mode-card:hover {
    border-color: var(--bs-primary);
}

.pickup-mode-card:has(input:checked) {
    /* Même choix que .store-radio-card : l'état visuel suit le radio natif, pas une classe
       recalculée côté serveur, pour rester instantané. */
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .15);
}

.pickup-mode-card:has(input:checked) .pickup-mode-icon {
    background-color: var(--bs-primary);
    color: #fff;
}

.pickup-mode-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    flex-shrink: 0;
    border-radius: 10px;
    background-color: #FBE7EC;
    color: var(--bs-primary);
    font-size: 30px;
}

/* Étape "Mode de retrait" — voile de chargement pendant le changement de mode.
   Masqué par la classe .d-none, que le live component (data-loading) retire le temps de la
   requête : le centrage flex reste donc intact, et le spinner garde sa transform d'animation
   pour lui seul (le centrer par translate le ferait glisser au lieu de tourner). */
.pickup-step-loader {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: 10px;
    background-color: rgba(255, 255, 255, 0.7);
}

/* Étape "Mode de retrait" — panier sous le montant minimum du mode choisi. Carte blanche et
   non rose : elle remplace les créneaux, elle ne les accompagne pas. */
.pickup-minimum-panel {
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    padding: 20px;
}

.pickup-minimum-bar {
    height: 8px;
    border-radius: 50px;
    background-color: #E8E1DA;
    overflow: hidden;
}

.pickup-minimum-bar-fill {
    display: block;
    height: 100%;
    border-radius: 50px;
    background-color: var(--bs-primary);
    transition: width .2s;
}

/* Même barre, en plus fin, dans la carte "Livraison à domicile" (comme l'app mobile) */
.pickup-minimum-bar-sm {
    height: 5px;
}

/* Étape "Mode de retrait" — grille des créneaux proposés par le back */
.pickup-slots-panel {
    background-color: #FDF3F6;
    border-radius: 10px;
    padding: 20px;
}

.pickup-slots-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 700;
    margin-bottom: 16px;
}

.pickup-slots-step {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--bs-primary);
    color: #fff;
    font-size: 13px;
}

.pickup-slot-card {
    display: block;
    height: 100%;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    padding: 12px 14px;
    text-align: center;
    cursor: pointer;
    transition: border-color .12s, box-shadow .12s;
}

.pickup-slot-card:hover {
    border-color: var(--bs-primary);
}

.pickup-slot-card:has(input:checked) {
    /* Comme .store-radio-card / .pickup-mode-card : l'état visuel suit le radio natif, la
       sélection du jour n'a pas besoin d'un aller-retour serveur. */
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .15);
    color: var(--bs-primary);
}

/* Créneau complet : affiché (le client voit que le jour existe) mais non sélectionnable. */
/* Étape "Mode de retrait" — champs des blocs d'adresse, alignés sur la page de création de
   compte : libellé au-dessus, champ blanc arrondi. */
.pickup-slots-panel .form-label {
    font-weight: 700;
    margin-bottom: 6px;
}

.pickup-slots-panel .form-control {
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    padding: 10px 14px;
}

.pickup-slots-panel .form-control:focus {
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .15);
}

.pickup-slots-panel .form-control:disabled {
    /* Identité du bloc facturation : désactivée et non readonly, pour que les valeurs
       postées soient ignorées côté serveur. */
    background-color: #F3F1F0;
    color: var(--bs-secondary-color);
}

.pickup-slots-panel .form-check-input {
    accent-color: var(--bs-primary);
}

/* Checkout — delivery address search (address-search controller) */
.address-search {
    position: relative;
}

.address-search-icon {
    position: absolute;
    top: 50%;
    left: 16px;
    transform: translateY(-50%);
    color: var(--bs-secondary-color);
    pointer-events: none;
}

.pickup-slots-panel .form-control.address-search-input {
    padding-left: 42px;
}

.address-search-results {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 10;
    margin: 0;
    padding: 6px 0;
    list-style: none;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

.address-search-item {
    padding: 8px 14px;
    font-size: 14px;
    cursor: pointer;
}

.address-search-item:hover,
.address-search-item.active {
    background-color: #FDF3F6;
}

.pickup-slot-card-complete,
.pickup-slot-card-complete:hover {
    background-color: #EDE9E6;
    border-color: transparent;
    color: var(--bs-secondary-color);
    cursor: not-allowed;
}

/* Spinner en overlay sur un bouton pendant une action live component (StoreConfirmationModal).
   Centré par flex sur le conteneur, pas par transform sur le spinner lui-même : sinon le
   translate entrerait en conflit avec le transform: rotate() de l'animation du spinner (même
   piège que .pickup-step-loader ci-dessous). */
.btn-loader-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Loader plein écran affiché pendant les changements/chargements de page (voir
   assets/controllers/page-loader-controller.js). Caché par défaut avec opacity/visibility
   plutôt que display:none, pour pouvoir animer son apparition. */
.page-loader-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.7);
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s ease;
}

.page-loader-overlay.is-visible {
    opacity: 1;
    visibility: visible;
}

/* Search results */
mark {
    padding: 0;
    background-color: transparent;
    font-weight: bold;
    color: inherit;
}
