/* ============================================================
   RDV-App — Design System
   Variables CSS, reset, typographie, composants
   ============================================================ */

/* ── Variables ──────────────────────────────────────────────── */
:root {
    /* Couleurs primaires — palette "institutionnel doux" (marine + brique) */
    --color-primary: #22406B;
    /* marine profond — actions, liens, états actifs */
    --color-primary-dark: #182F52;
    /* hover/actif sur --color-primary */
    --color-primary-light: #E7ECF2;
    /* fond teinté clair (badges, focus, sections claires) */

    /* Couleur d'accent secondaire — brique, réservée aux CTA à forte intention
       (upsell, bannière finale) : jamais deux fois côte à côte avec --color-primary
       sur un même écran, pour qu'elle garde son effet d'accroche. */
    --color-accent: #B23A2E;
    --color-accent-dark: #8E2E24;
    --color-accent-light: #F5E3E0;

    /* Thème sombre — page de connexion admin (variante marine du thème clair,
       au lieu d'un slate générique déconnecté de l'identité) */
    --color-admin-bg: #f6f4ef;

    /* Couleurs neutres — base chaude (cassé/ivoire) au lieu du gris froid Tailwind
       d'origine, pour rester cohérent avec le fond crème des pages publiques */
    --color-gray-50: #F6F4EF;
    --color-gray-100: #EDEAE1;
    --color-gray-200: #E4E0D4;
    --color-gray-300: #D8D3C4;
    --color-gray-400: #B5B0A0;
    --color-gray-500: #8A887F;
    --color-gray-600: #6B695F;
    --color-gray-700: #4A4842;
    --color-gray-800: #2E2D28;
    --color-gray-900: #22406b;
    /* CORRIGÉ : c'était #0C8259 (un vert, visiblement
                                   un reliquat d'une ancienne palette) alors que
                                   --color-gray-900 est utilisé partout comme la
                                   couleur d'encre des titres — ce bug faisait
                                   apparaître des titres verdâtres incohérents
                                   avec le reste de la charte. */

    /* États — gardés volontairement proches des conventions habituelles
       (succès = vert, alerte = ambre, erreur = rouge, info = bleu) : ce sont
       des couleurs sémantiques, pas des couleurs de marque, donc on ne les
       fait pas dériver de --color-primary/--color-accent. Seule légère
       modification : nuances tirées un peu vers le chaud pour rester en
       harmonie avec les nouveaux gris ivoire. */
    --color-success: #3F7D3B;
    --color-success-light: #E3EEDD;
    --color-warning: #C77A17;
    --color-warning-light: #FBEBD6;
    --color-danger: #DC2626;
    /* rouge franc, volontairement distinct de
                                        --color-accent (#B23A2E, plus brique/mat)
                                        pour ne pas confondre "erreur" et "CTA
                                        premium" à l'oeil */
    --color-danger-light: #FBE7E4;
    --color-info: #3E6690;
    --color-info-light: #E7ECF2;

    /* Typographie */
    --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
    --font-mono: 'JetBrains Mono', 'Fira Code', monospace;

    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;

    --font-normal: 400;
    --font-medium: 500;
    --font-semibold: 600;
    --font-bold: 700;

    /* Espacements */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-8: 2rem;
    --space-10: 2.5rem;
    --space-12: 3rem;
    --space-16: 4rem;

    /* Bordures & radius */
    --radius-sm: 0.25rem;
    --radius-md: 0.5rem;
    --radius-lg: 0.75rem;
    --radius-xl: 1rem;
    --radius-full: 9999px;

    --border-color: var(--color-gray-200);

    /* Ombres */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
    --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

    /* Transitions */
    --transition-fast: 120ms ease;
    --transition-base: 200ms ease;

    /* Layout */
    --sidebar-width: 260px;
    --header-height: 64px;
    --max-width: 1280px;
}

/* ── Reset ──────────────────────────────────────────────────── */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--color-gray-800);
    background: var(--color-gray-50);
    -webkit-font-smoothing: antialiased;
}

img,
svg {
    display: block;
    max-width: 100%;
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    cursor: pointer;
    font: inherit;
    border: none;
    background: none;
}

input,
select,
textarea {
    font: inherit;
}

ul,
ol {
    list-style: none;
}

table {
    border-collapse: collapse;
    width: 100%;
}

/* ── Typographie ────────────────────────────────────────────── */
h1,
h2,
h3,
h4,
h5,
h6 {
    font-weight: var(--font-semibold);
    line-height: 1.25;
    color: var(--color-gray-900);
}

h1 {
    font-size: var(--text-3xl);
}

h2 {
    font-size: var(--text-2xl);
}

h3 {
    font-size: var(--text-xl);
}

h4 {
    font-size: var(--text-lg);
}

p {
    color: var(--color-gray-600);
}

/* ── Boutons ────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
    white-space: nowrap;
    border: 1.5px solid transparent;
    line-height: 1.5;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-primary {
    background: #b23a2e;
    color: #fff;
}

.btn-primary:hover:not(:disabled) {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
}

/* Bouton d'accent — CTA à forte intention (upsell "Passer à Pro", bannière
   finale de la landing) : à utiliser avec parcimonie, jamais à côté d'un
   .btn-primary sur le même écran pour ne pas diluer son effet d'accroche. */
.btn-accent {
    background: var(--color-accent);
    color: #fff;
    border-color: var(--color-accent);
}

.btn-accent:hover:not(:disabled) {
    background: var(--color-accent-dark);
    border-color: var(--color-accent-dark);
}

.btn-secondary {
    background: #fff;
    color: var(--color-gray-700);
    border-color: var(--color-gray-300);
}

.btn-secondary:hover:not(:disabled) {
    background: var(--color-gray-50);
    border-color: var(--color-gray-400);
}

.btn-danger {
    background: var(--color-danger);
    color: #fff;
    border-color: var(--color-danger);
}

.btn-danger:hover:not(:disabled) {
    filter: brightness(0.9);
}

.btn-ghost {
    background: transparent;
    color: var(--color-gray-600);
}

.btn-ghost:hover:not(:disabled) {
    background: var(--color-gray-100);
}

.btn-sm {
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
}

.btn-lg {
    padding: var(--space-3) var(--space-6);
    font-size: var(--text-base);
}

.btn-block {
    width: 100%;
    justify-content: center;
}

.btn-icon {
    padding: var(--space-2);
    aspect-ratio: 1;
}

/* ── Formulaires ────────────────────────────────────────────── */
.form-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

label {
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--color-gray-700);
}

.input,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="color"],
select,
textarea {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    border: 1.5px solid var(--color-gray-300);
    border-radius: var(--radius-md);
    background: #fff;
    color: var(--color-gray-800);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
    appearance: none;
}

.input:focus,
input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-light);
}

.input.is-error {
    border-color: var(--color-danger);
}

textarea {
    resize: vertical;
    min-height: 80px;
}

select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 36px;
}

.form-hint {
    font-size: var(--text-xs);
    color: var(--color-gray-700);
}

.form-error {
    font-size: var(--text-xs);
    color: var(--color-danger);
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.checkbox-group {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.checkbox-group input[type="checkbox"] {
    width: 16px;
    height: 16px;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}

/* ── Cards ──────────────────────────────────────────────────── */
.card {
    background: #fff;
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card-header {
    padding: var(--space-4) var(--space-6);
    border-bottom: 1px solid var(--color-gray-100);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

.card-body {
    padding: var(--space-6);
}

.card-footer {
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--color-gray-100);
    background: var(--color-gray-50);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* ── Alertes ────────────────────────────────────────────────── */
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    border: 1px solid transparent;
}

.alert-success {
    background: var(--color-success-light);
    color: #065F46;
    border-color: #6EE7B7;
}

.alert-error {
    background: var(--color-danger-light);
    color: #991B1B;
    border-color: #FCA5A5;
}

.alert-warning {
    background: var(--color-warning-light);
    color: #92400E;
    border-color: #FCD34D;
}

.alert-info {
    background: var(--color-info-light);
    color: #075985;
    border-color: #7DD3FC;
}

/* ── Badges ─────────────────────────────────────────────────── */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--font-medium);
    border-radius: var(--radius-full);
}

.badge-success {
    background: var(--color-success-light);
    color: #065F46;
}

.badge-danger {
    background: var(--color-danger-light);
    color: #991B1B;
}

.badge-warning {
    background: var(--color-warning-light);
    color: #92400E;
}

.badge-gray {
    background: var(--color-gray-100);
    color: var(--color-gray-600);
}

.badge-primary {
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
}

/* ── Tables ─────────────────────────────────────────────────── */
.table-container {
    overflow-x: auto;
}

.table {
    width: 100%;
    font-size: var(--text-sm);
}

.table thead th {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--color-gray-50);
    border-bottom: 1px solid var(--color-gray-200);
}

.table tbody td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--color-gray-100);
    color: var(--color-gray-700);
    vertical-align: middle;
}

.table tbody tr:last-child td {
    border-bottom: none;
}

.table tbody tr:hover {
    background: var(--color-gray-50);
}

/* ── Layout Dashboard ───────────────────────────────────────── */
.app-layout {
    display: flex;
    min-height: 100vh;
}

/* Sidebar claire par défaut (dashboard utilisateur) : fond ivoire, seul
   l'élément actif reste rempli en marine — remplace l'ancien bloc plein
   sombre, plus lourd visuellement à l'usage quotidien. Le thème sombre
   dédié à l'admin (.sidebar.theme-dark, plus bas) reste inchangé dans son
   principe et override les couleurs ci-dessous là où c'est nécessaire. */
.sidebar {
    width: var(--sidebar-width);
    background: var(--color-gray-50);
    color: var(--color-gray-800);
    border-right: 1px solid var(--color-gray-200);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    overflow-y: auto;
    z-index: 100;
    transition: transform var(--transition-base);
}

.sidebar-logo {
    padding: var(--space-6);
    border-bottom: 1px solid var(--color-gray-200);
}

.sidebar-logo a {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-lg);
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
}

.sidebar-nav {
    flex: 1;
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.nav-section-label {
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    color: var(--color-gray-400);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: var(--space-3) var(--space-3) var(--space-1);
    margin-top: var(--space-2);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    color: var(--color-primary);
    transition: all var(--transition-fast);
}

.nav-link:hover {
    background: #22406b;
    color: #f6f4ef;
}

.nav-link.active {
    background: var(--color-primary);
    color: #fff;
}

.nav-link svg {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}

.sidebar-footer {
    padding: var(--space-4);
    border-top: 1px solid var(--color-gray-200);
}

.main-content {
    margin-left: var(--sidebar-width);
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.topbar {
    min-height: var(--header-height);
    background: #fff;
    border-bottom: 1px solid var(--color-gray-200);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: var(--space-2) var(--space-6);
    position: sticky;
    top: 0;
    z-index: 50;
    gap: var(--space-4);
}

.topbar-title {
    font-size: var(--text-lg);
    font-weight: var(--font-semibold);
    color: var(--color-gray-800);
}

.page-content {
    flex: 1;
    min-width: 0;
    padding: var(--space-8);
    max-width: var(--max-width);
}

/* ── Page publique layout ───────────────────────────────────── */
/* CORRECTION : passage en colonne flex (même principe que .main-content) pour
   pouvoir accueillir un footer de bas de page — voir .public-content
   ci-dessous et public.php. */
.public-layout {
    min-height: 100vh;
    background: var(--color-gray-50);
    display: flex;
    flex-direction: column;
}

/* Enveloppe le contenu réel de chaque page publique (landing, réservation
   /pro/{slug}...) : flex:1 pousse le footer placé après elle en bas du
   viewport sur les pages courtes, comme .page-content côté dashboard/admin. */
.public-content {
    flex: 1;
}

.public-header {
    background: #fff;
    border-bottom: 1px solid var(--color-gray-200);
    padding: var(--space-4) var(--space-6);
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.public-container {
    max-width: 900px;
    margin: 0 auto;
    padding: var(--space-8) var(--space-4);
}

/* ── Stat cards ─────────────────────────────────────────────── */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-4);
}

.stat-card {
    background: #fff;
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.stat-card-label {
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    color: var(--color-gray-700);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.stat-card-value {
    font-size: var(--text-3xl);
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
    line-height: 1;
}

.stat-card-sub {
    font-size: var(--text-sm);
    color: var(--color-gray-800);
}

/* ── Calendrier de réservation public ──────────────────────── */
.booking-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
    align-items: start;
}

@media (max-width: 640px) {
    .booking-grid {
        grid-template-columns: 1fr;
    }
}

.booking-calendar {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--space-1);
}

.calendar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-4);
}

.calendar-nav {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.calendar-day-label {
    text-align: center;
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    color: var(--color-gray-400);
    padding: var(--space-2) 0;
}

.calendar-day {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    cursor: default;
    transition: all var(--transition-fast);
}

.calendar-day.available {
    cursor: pointer;
    color: var(--color-primary);
    font-weight: var(--font-medium);
    background: var(--color-primary-light);
}

.calendar-day.available:hover {
    background: var(--color-primary);
    color: #fff;
}

.calendar-day.selected {
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--font-bold);
}

.calendar-day.today {
    border: 2px solid var(--color-primary);
}

.calendar-day.past,
.calendar-day.unavailable {
    color: var(--color-gray-300);
}

.calendar-day.empty {
    visibility: hidden;
}

/* Créneaux horaires */
.slots-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-2);
}

.slot-btn {
    padding: var(--space-2);
    text-align: center;
    border: 1.5px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
    background: #fff;
    color: var(--color-gray-700);
}

.slot-btn:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.slot-btn.selected {
    background: var(--color-primary);
    color: #fff;
    border-color: var(--color-primary);
}

/* ── Pagination ─────────────────────────────────────────────── */
.pagination {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    justify-content: center;
    margin-top: var(--space-6);
}

.page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    border: 1px solid var(--color-gray-200);
    background: #fff;
    color: var(--color-gray-600);
    transition: all var(--transition-fast);
}

.page-link:hover {
    background: var(--color-gray-100);
}

.page-link.active {
    background: var(--color-primary);
    color: #fff;
    border-color: var(--color-primary);
}

.page-link.disabled {
    opacity: 0.4;
    cursor: not-allowed;
    pointer-events: none;
}

/* ── Modal ──────────────────────────────────────────────────── */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    animation: fadeIn 150ms ease;
}

.modal {
    background: #fff;
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    overflow-y: auto;
    animation: slideUp 200ms ease;
}

.modal-header {
    padding: var(--space-5) var(--space-6);
    border-bottom: 1px solid var(--color-gray-200);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.modal-body {
    padding: var(--space-6);
}

.modal-footer {
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--color-gray-200);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    background: var(--color-gray-50);
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes slideUp {
    from {
        transform: translateY(12px);
        opacity: 0;
    }

    to {
        transform: translateY(0);
        opacity: 1;
    }
}

/* ── Toast notifications ────────────────────────────────────── */
.toast-container {
    position: fixed;
    top: var(--space-4);
    right: var(--space-4);
    z-index: 500;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
    background: var(--color-gray-900);
    color: #fff;
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    box-shadow: var(--shadow-lg);
    max-width: 380px;
    pointer-events: all;
    animation: toastIn 200ms ease;
}

.toast-success {
    background: var(--color-success);
}

.toast-error {
    background: var(--color-danger);
}

.toast-warning {
    background: var(--color-warning);
}

@keyframes toastIn {
    from {
        transform: translateX(100%);
        opacity: 0;
    }

    to {
        transform: translateX(0);
        opacity: 1;
    }
}

/* ── Spinner de chargement ──────────────────────────────────── */
.spinner {
    width: 20px;
    height: 20px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin 600ms linear infinite;
    flex-shrink: 0;
}

.spinner-dark {
    border-color: var(--color-gray-200);
    border-top-color: var(--color-primary);
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* ── Empty state ────────────────────────────────────────────── */
.empty-state {
    text-align: center;
    padding: var(--space-16) var(--space-4);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}

.empty-state-icon {
    width: 56px;
    height: 56px;
    color: var(--color-gray-300);
}

.empty-state h3 {
    color: var(--color-gray-600);
}

.empty-state p {
    font-size: var(--text-sm);
    max-width: 320px;
}

/* ── Pages d'authentification (login, inscription, reset...) ──── */
.auth-layout {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
}

.auth-layout.theme-dark {
    background: var(--color-admin-bg);
}

.auth-box {
    width: 100%;
    max-width: 420px;
}

.auth-box-sm {
    width: 100%;
    max-width: 380px;
}

.auth-box-lg {
    width: 100%;
    max-width: 480px;
}

.auth-logo {
    text-align: center;
    margin-bottom: var(--space-8);
}

.auth-logo-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
}

.auth-logo-text {
    font-size: var(--text-2xl);
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
}

/* CORRECTION : ces variantes .on-dark (texte clair) étaient pensées pour
   l'ancien --color-admin-bg sombre. Ce fond étant désormais clair (même
   crème que le reste de l'admin, voir .sidebar.theme-dark plus bas), ces
   couleurs claires y seraient quasiment invisibles — réajustées pour
   rester lisibles sur fond clair. */
.auth-logo-text.on-dark {
    color: var(--color-gray-900);
}

.auth-tagline {
    margin-top: var(--space-2);
    color: var(--color-gray-700);
    font-size: var(--text-sm);
}

.auth-tagline.on-dark {
    color: var(--color-gray-500);
}

.auth-back-link {
    text-align: center;
    margin-top: var(--space-4);
    font-size: var(--text-sm);
}

.auth-back-link a {
    color: var(--color-gray-500);
}

.auth-back-link.on-dark a {
    color: var(--color-gray-500);
}

/* Remplace l'ancien badge en rouge codé en dur (#EF4444, contraste AA
   insuffisant sur fond blanc pour du petit texte) par --color-danger,
   plus sombre, qui passe le seuil AA (~4,8:1). */
.auth-pill-danger {
    display: inline-flex;
    align-items: center;
    background: var(--color-danger);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 4px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.input-icon-wrapper {
    position: relative;
}

.input-icon-wrapper input {
    padding-right: 44px;
}

.input-icon-btn {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-gray-400);
}

/* Checklist des exigences du mot de passe (auth/register.php,
   auth/reset_password.php) — remplace l'ancienne barre de "force"
   (.strength-track/.strength-bar/.strength-label, retirée : chaque ligne
   correspond désormais explicitement à un critère vérifié côté serveur par
   Validator::rulePassword(), plutôt qu'un score global qui pouvait afficher
   "Fort" sur un mot de passe encore rejeté par le serveur).
   La couleur de chaque <li> est pilotée en JS via style.color (valeur
   réellement dynamique, recalculée à chaque frappe — même convention que le
   reste du code JS de ces pages) ; les règles ci-dessous ne posent que la
   mise en page statique et une couleur neutre par défaut avant la première
   frappe. */
.password-requirements {
    list-style: none;
    padding: 0;
    margin: var(--space-1) 0 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.password-requirements li {
    font-size: var(--text-xs);
    color: var(--color-gray-500);
}

.perks-grid {
    margin-top: var(--space-6);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
    text-align: center;
}

@media (max-width: 480px) {
    .perks-grid {
        grid-template-columns: 1fr;
    }
}

.perk-icon {
    font-size: 1.4rem;
    margin-bottom: var(--space-1);
}

.perk-item {
    font-size: var(--text-sm);
    color: var(--color-gray-500);
}

/* ── Pages de détail (RDV, client, utilisateur) ─────────────────── */
.page-header {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
    flex-wrap: wrap;
}

.page-header-title-group {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* 2 colonnes inégales (ex: 2fr/1fr) ou égales (1fr/1fr), qui repassent
   systématiquement en 1 colonne sur écran étroit — c'est ce qui manquait
   sur les pages de détail utilisateur/RDV/client et sur les disponibilités. */
.layout-2col {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: var(--space-6);
}

.layout-2col-even {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
    align-items: start;
}

/* Filet de sécurité : même piège min-width:auto que .dashboard-main-grid
   ci-dessus, par précaution si une colonne contient un jour un tableau ou
   tout autre contenu intrinsèquement large. */
.layout-2col>*,
.layout-2col-even>* {
    min-width: 0;
}

@media (max-width: 900px) {

    .layout-2col,
    .layout-2col-even {
        grid-template-columns: 1fr;
    }
}

.detail-row {
    display: flex;
    gap: var(--space-4);
    font-size: var(--text-sm);
}

.detail-label {
    color: var(--color-gray-500);
    min-width: 110px;
    flex-shrink: 0;
}

.detail-label-wide {
    min-width: 140px;
}

.stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.stack-sm {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.stack-xs {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* CORRECTION : sans flex-wrap, les deux enfants (ex: formulaire de recherche
   + bouton "Exporter CSV" sur clients.php) restent forcés sur une seule
   ligne — sur un écran étroit, combiné à .search-field-wide (min-width:280px),
   ça dépasse la largeur du viewport et force un scroll horizontal sur toute
   la page. wrap n'a aucun effet tant que tout tient sur une ligne, donc
   aucun changement visuel sur desktop. */
.row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.attachment-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    background: var(--color-gray-50);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
}

.attachment-info {
    flex: 1;
    min-width: 0;
}

.attachment-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.note-bubble {
    margin-top: var(--space-2);
    padding: var(--space-3);
    background: var(--color-gray-50);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
}

.divider {
    border: none;
    border-top: 1px solid var(--color-gray-100);
}

.filter-bar {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
    align-items: flex-end;
}

.field-grow {
    flex: 1;
}

.field-w-sm {
    min-width: 130px;
}

.field-w-md {
    min-width: 150px;
}

.field-w-lg {
    min-width: 180px;
}

.field-w-xl {
    min-width: 200px;
}

.form-row-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
}

@media (max-width: 480px) {
    .form-row-2 {
        grid-template-columns: 1fr;
    }
}

.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-4);
}

/* Aligne le pied de carte (boutons Modifier/Supprimer) sur la même ligne
   d'une carte à l'autre, que la description du service soit présente ou
   non. Les cartes sont déjà étirées à hauteur égale par la grille
   (align-items:stretch, comportement par défaut) ; il manquait juste le
   flex column + flex-grow pour que ce surplus de hauteur pousse le footer
   vers le bas au lieu de laisser un vide sous des boutons "flottants". */
.cards-grid .card {
    display: flex;
    flex-direction: column;
}

.cards-grid .card-body {
    flex: 1 1 auto;
}

.settings-container {
    max-width: 720px;
}

.settings-container-narrow {
    max-width: 640px;
}

/* ── Fieldsets de formulaires (settings, profil…) ────────────── */
/* Remplace les attributs style="border:none;padding:0" répétés sur
   chaque <fieldset> dans settings.php et les autres formulaires admin. */
.fieldset-reset {
    border: none;
    padding: 0;
}

.fieldset-legend {
    font-size: var(--text-base);
    font-weight: var(--font-semibold);
    margin-bottom: var(--space-4);
}

/* ── Formulaire de filtres (liste utilisateurs, RDV, clients…) ── */
/* Remplace le style inline display:flex;gap;flex-wrap;align-items sur le
   <form> de filtres — le même pattern existe sur plusieurs pages liste. */
.filter-form {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
    align-items: flex-end;
}

/* ── Page header avec retour + titre + badges ─────────────────── */
/* Remplace le div inline flex;align-items;gap;margin-bottom des pages
   de détail (user_detail, rdv_detail, client_detail). */
.page-header-back {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}

/* Groupe titre + badges sous le titre (flex col, gap léger) */
.page-header-title-badges {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Ligne de badges sous le titre (flex row, gap) */
.badge-row {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-1);
}

/* ── Ligne d'info détail avec label large (140px) ────────────── */
/* Complète .detail-label (110px) pour les vues qui ont des libellés
   plus longs, comme la fiche utilisateur admin. */
.detail-label-xl {
    min-width: 140px;
    flex-shrink: 0;
}

/* ── Section "page publique" dans user_detail ─────────────────── */
.card-row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* ── Grille stat-card à 3 colonnes fixes (activité user_detail) ── */
/* La classe .stat-grid utilise auto-fit ; cette variante force 3 cols. */
.stat-grid-3 {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
}

@media (max-width: 480px) {
    .stat-grid-3 {
        grid-template-columns: 1fr;
    }
}

/* ── Limite de RDV (texte sous les stat-cards) ────────────────── */
.quota-info {
    margin-top: var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-gray-500);
}

/* ── Grilles de champs SMTP (settings.php) ────────────────────── */
/* host (2fr) + port (1fr) */
.smtp-host-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: var(--space-3);
}

/* deux colonnes égales (user/password, from-email/from-name) */
.smtp-pair-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
}

@media (max-width: 480px) {

    .smtp-host-grid,
    .smtp-pair-grid {
        grid-template-columns: 1fr;
    }
}

/* ── Dashboard : grille 2 colonnes pour les blocs stats ──────── */
/* Reprend le style inline display:grid;grid-template-columns:1fr 1fr;gap
   du dashboard. Réutilise .layout-2col-even mais on documente ici que
   c'est l'usage dashboard pour éviter la confusion. */
/* (Pas de nouvelle classe — .layout-2col-even convient déjà.) */

/* ── Ligne de stat (dashboard card-body) ──────────────────────── */
/* Remplace le style inline display:flex;align-items;justify-between;
   font-size répété dans les boucles foreach du dashboard. */
.stat-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: var(--text-sm);
}

/* ── Rendez-vous / Calendrier ────────────────────────────────────── */

/* Le point de couleur d'un service vient de la base (couleur choisie par
   le pro) — seule la couleur reste dynamique/inline, tout le reste
   (taille, forme) est statique et vit ici. */
.color-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.service-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-sm);
}

.calendar-container {
    background: #fff;
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}

/* Surcharge FullCalendar pour correspondre au design system — ne
   s'applique qu'aux pages où FullCalendar est réellement chargé
   (.fc n'existe nulle part ailleurs), donc aucun risque d'effet de bord
   en la centralisant ici plutôt que dans un <style> du template. */
.fc .fc-button {
    font-family: var(--font-sans);
    font-size: var(--text-sm);
    border-radius: var(--radius-md);
    padding: 6px 12px;
    font-weight: var(--font-medium);
}

.fc .fc-button-primary {
    background: var(--color-primary);
    border-color: var(--color-primary);
}

.fc .fc-button-primary:not(:disabled):hover {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
}

.fc .fc-button-primary:not(:disabled).fc-button-active {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
}

.fc-event {
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.fc-toolbar-title {
    font-size: var(--text-xl) !important;
    font-weight: var(--font-semibold);
}

/* Remplace la manipulation directe de .style.opacity/.textDecoration faite
   en JS dans eventDidMount() : on pose une classe sur l'élément, le style
   associé reste défini ici plutôt qu'en JS. */
.fc-event-cancelled {
    opacity: 0.5;
    text-decoration: line-through;
}

/* ── Layout admin / dashboard partagé (sidebar, topbar, badges) ── */
.alert-compact {
    padding: 6px 12px;
    font-size: var(--text-xs);
}

.badge-admin-role {
    display: inline-flex;
    align-items: center;
    background: var(--color-danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 4px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* Sidebar admin — réutilise --color-admin-bg défini plus haut. CORRECTION :
   --color-admin-bg vaut désormais la même couleur crème que le dashboard
   utilisateur (--color-gray-50), et non plus un marine sombre. Les couleurs
   ci-dessous, à l'origine pensées pour du texte clair sur fond sombre, sont
   donc réajustées pour rester lisibles sur ce fond clair — même logique que
   .sidebar (thème par défaut) plus haut. Le badge rouge "ADMIN" à côté du
   logo (voir admin.php) reste le signal visuel distinguant cette sidebar
   de celle du dashboard utilisateur. */
.sidebar.theme-dark {
    background: var(--color-admin-bg);
    border-right-color: var(--color-gray-200);
}

.sidebar.theme-dark .sidebar-logo a {
    color: var(--color-gray-900);
}

.sidebar.theme-dark .sidebar-logo,
.sidebar.theme-dark .sidebar-footer {
    border-color: var(--color-gray-200);
}

.sidebar.theme-dark .nav-section-label {
    color: var(--color-gray-400);
}

.sidebar.theme-dark .nav-link {
    color: var(--color-gray-700);
}

.sidebar.theme-dark .nav-link:hover {
    background: var(--color-primary);
    color: #fff;
}

.sidebar.theme-dark .nav-link.active {
    background: var(--color-primary);
    color: #fff;
}

.impersonation-banner {
    background: var(--color-warning);
    color: #fff;
    padding: 8px 16px;
    text-align: center;
    font-size: var(--text-sm);
    position: sticky;
    top: 0;
    z-index: 999;
}

.impersonation-banner a {
    margin-left: var(--space-4);
    text-decoration: underline;
    color: #fff;
}

.user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--color-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: var(--text-xs);
}

/* Le bouton burger et l'overlay mobile étaient cachés en dur par un style
   inline "display:none" SANS AUCUNE règle pour les réafficher sur mobile —
   le menu burger était donc invisible à toutes les tailles d'écran, y
   compris sur petit écran où il est censé apparaître. Corrigé ci-dessous
   avec la media query manquante (cf. section Responsive). */
.sidebar-toggle {
    display: none;
}

.sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 99;
}

/* ── Pages de statut public (succès / erreur / lien invalide) ──── */
.status-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--space-8);
}

/* cancel_success.php utilisait un padding légèrement différent des 3 autres
   pages de statut (space-6/space-4 au lieu de space-8 partout) — probable
   incohérence d'origine, préservée ici à l'identique plutôt que corrigée
   silencieusement, pour respecter le rendu exact. À harmoniser si tu
   confirmes que c'était involontaire. */
.status-page.padding-tight {
    padding: var(--space-6) var(--space-4);
}

.status-box {
    width: 100%;
    max-width: 400px;
}

.status-box-lg {
    width: 100%;
    max-width: 480px;
}

.status-icon-circle {
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto var(--space-6);
}

.status-icon-circle.size-56 {
    width: 56px;
    height: 56px;
}

.status-icon-circle.size-64 {
    width: 64px;
    height: 64px;
}

.status-icon-circle.mb-tight {
    margin-bottom: var(--space-4);
}

.status-icon-circle.tone-danger {
    background: var(--color-danger-light);
}

.status-icon-circle.tone-warning {
    background: var(--color-warning-light);
}

.status-icon-circle.tone-success {
    background: var(--color-success-light);
}

.status-icon-circle.tone-gray {
    background: var(--color-gray-100);
}

.public-footer {
    text-align: center;
    padding: var(--space-8) var(--space-4);
    font-size: var(--text-xs);
    color: var(--color-gray-400);
}

.public-footer a {
    color: var(--color-primary);
}

.error-code {
    font-weight: var(--font-bold);
    color: var(--color-gray-200);
    line-height: 1;
}

.error-code.size-lg {
    font-size: 6rem;
}

.error-code.size-md {
    font-size: 5rem;
}

.public-business-name {
    font-weight: var(--font-bold);
    font-size: var(--text-lg);
    color: var(--color-gray-900);
}

.public-welcome-message {
    font-size: var(--text-sm);
    color: var(--color-gray-500);
}

.public-logo {
    height: 40px;
    object-fit: contain;
}

.bg-public {
    background: var(--color-gray-50);
}

.min-h-screen {
    min-height: 100vh;
}

.public-topbar {
    background: #fff;
    border-bottom: 1px solid var(--color-gray-200);
    padding: var(--space-4) var(--space-6);
}

.loading-center {
    text-align: center;
}

.service-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--space-3);
}

.detail-label-narrow {
    min-width: 80px;
    flex-shrink: 0;
}

.recap-box {
    background: var(--color-gray-50);
    border-radius: var(--radius-md);
    padding: var(--space-4);
}

.recap-box-primary {
    background: var(--color-primary-light);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
}

/* ── Carte de sélection de service (étape 1 de la réservation) ──── */
.service-card {
    text-align: left;
    border: 2px solid var(--color-gray-200);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    background: #fff;
    cursor: pointer;
    transition: all var(--transition-fast);
}

/* Remplace l'ancienne gestion du survol en JS (mouseenter/mouseleave qui
   modifiaient directement .style.borderColor / .style.boxShadow) : un
   simple :hover CSS fait exactement la même chose, sans JS, et couvre
   aussi la sélection tactile (focus-visible) que mouseenter ne couvre pas. */
.service-card:hover,
.service-card.selected,
.service-card:focus-visible {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
}

.service-card-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}

.service-card-name {
    font-weight: var(--font-semibold);
    font-size: var(--text-base);
    color: var(--color-gray-900);
}

.service-card-desc {
    font-size: var(--text-sm);
    color: var(--color-gray-500);
    margin-bottom: var(--space-3);
}

.service-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.service-card-meta {
    font-size: var(--text-sm);
    color: var(--color-gray-500);
}

.service-card-price {
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
}

.service-color-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* ── Zone d'upload de fichier (réservation) ──────────────────────── */
.upload-dropzone {
    background: var(--color-gray-50);
    border: 1.5px dashed var(--color-gray-300);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    text-align: center;
}

.upload-dropzone-icon {
    margin: 0 auto var(--space-2);
}

.upload-file-input {
    display: none;
}

.upload-label {
    cursor: pointer;
}

@media (max-width: 768px) {
    :root {
        --sidebar-width: 0px;
    }

    .sidebar {
        transform: translateX(-100%);
        width: 260px;
        /* largeur réelle du panneau une fois ouvert (.sidebar.open) —
                          volontairement fixe ici, indépendante de --sidebar-width
                          qui vaut 0px sur cette largeur d'écran (elle ne sert qu'à
                          .main-content ci-dessous, pour ne plus réserver de place
                          à une sidebar qui est repliée par défaut). */
    }

    .sidebar.open {
        transform: translateX(0);
    }

    .main-content {
        margin-left: 0;
    }

    .page-content {
        padding: var(--space-4);
    }

    .topbar {
        padding: var(--space-2) var(--space-4);
    }

    /* CORRECTION : .filter-bar a bien flex-wrap:wrap, mais certaines paires
       de champs (ex: Recherche + Statut sur la page Rendez-vous) totalisent
       une largeur minimale légèrement INFÉRIEURE à celle de l'écran d'après
       le calcul de line-breaking de flex-wrap (basé sur min-width) — le
       navigateur ne les fait donc pas passer à la ligne. Mais le rendu réel
       d'un <select> natif ajoute quelques pixels incompressibles que ce
       calcul ne peut pas anticiper, d'où un léger débordement de quelques
       caractères, trop faible pour se voir dans les indicateurs de débordement
       habituels. Plutôt que d'ajuster des min-width au pixel près (fragile,
       à refaire à chaque nouveau champ), chaque champ de filtre prend
       systématiquement toute la largeur disponible en dessous de 768px :
       aucune ambiguïté de calcul possible, chaque champ est seul sur sa ligne. */
    .filter-bar .form-group {
        flex: 1 1 100%;
        min-width: 0;
    }

    .stat-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    h1 {
        font-size: var(--text-2xl);
    }

    /* Bug corrigé : le bouton était caché à TOUTES les tailles d'écran
       (style inline display:none sans contrepartie). Il ne doit être
       visible que sur mobile, là où la sidebar est repliée par défaut. */
    .sidebar-toggle {
        display: inline-flex;
    }
}

@media (max-width: 400px) {
    .stat-grid {
        grid-template-columns: 1fr;
    }
}

/* ── Utilitaires ────────────────────────────────────────────── */
.text-xs {
    font-size: var(--text-xs);
}

.text-sm {
    font-size: var(--text-sm);
}

.text-base {
    font-size: var(--text-base);
}

.text-lg {
    font-size: var(--text-lg);
}

.text-xl {
    font-size: var(--text-xl);
}

.text-2xl {
    font-size: var(--text-2xl);
}

.text-muted {
    color: var(--color-gray-800);
}

/* Texte légal/CGU dans les formulaires d'inscription : petit, centré,
   interligné légèrement plus aéré que la valeur par défaut (1.6). */
.text-legal {
    font-size: var(--text-sm);
    text-align: center;
    color: var(--color-gray-700);
    line-height: 1.5;
}

.text-gray-400 {
    color: var(--color-gray-400);
}

.text-gray-700 {
    color: var(--color-gray-700);
}

.text-danger {
    color: var(--color-danger);
}

.text-success {
    color: var(--color-success);
}

.font-medium {
    font-weight: var(--font-medium);
}

.font-semibold {
    font-weight: var(--font-semibold);
}

.font-bold {
    font-weight: var(--font-bold);
}

.flex {
    display: flex;
}

.flex-1 {
    flex: 1;
}

.flex-col {
    flex-direction: column;
}

.items-center {
    align-items: center;
}

.justify-between {
    justify-content: space-between;
}

.gap-2 {
    gap: var(--space-2);
}

.gap-3 {
    gap: var(--space-3);
}

.gap-4 {
    gap: var(--space-4);
}

.mt-1 {
    margin-top: var(--space-1);
}

.mt-2 {
    margin-top: var(--space-2);
}

.mt-3 {
    margin-top: var(--space-3);
}

.mt-4 {
    margin-top: var(--space-4);
}

.mt-6 {
    margin-top: var(--space-6);
}

.mt-8 {
    margin-top: var(--space-8);
}

.mb-1 {
    margin-bottom: var(--space-1);
}

.mb-2 {
    margin-bottom: var(--space-2);
}

.mb-3 {
    margin-bottom: var(--space-3);
}

.mb-4 {
    margin-bottom: var(--space-4);
}

.mb-6 {
    margin-bottom: var(--space-6);
}

.ml-1 {
    margin-left: var(--space-1);
}

.w-full {
    width: 100%;
}

.mx-auto {
    margin-left: auto;
    margin-right: auto;
}

.mt-80 {
    margin-top: 80px;
}

.max-w-400 {
    max-width: 400px;
}

.max-w-480 {
    max-width: 480px;
}

.hidden {
    display: none;
}

.text-center {
    text-align: center;
}

.text-left {
    text-align: left;
}

.p-3 {
    padding: var(--space-3);
}

.p-4 {
    padding: var(--space-4);
}

.p-6 {
    padding: var(--space-6);
}

.p-8 {
    padding: var(--space-8);
}

.link-primary {
    color: var(--color-primary);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ══════════════════════════════════════════════════════════════════
   Dashboard pro (tableau de bord utilisateur) — extraction des styles
   inline présents dans index.php, clients.php, client_detail.php,
   services.php, availability.php et settings.php (onglets profil).
   Seules les couleurs réellement dynamiques (couleur de service choisie
   par le pro) restent inline, comme pour le reste de l'application.
   ══════════════════════════════════════════════════════════════════ */

/* ── Utilitaires complémentaires ─────────────────────────────── */
.ml-2 {
    margin-left: var(--space-2);
}

.items-start {
    align-items: flex-start;
}

/* ── Grille principale du dashboard (accueil) : contenu + colonne
   latérale fixe. Repasse en 1 colonne sous 900px, comme .layout-2col. */
.dashboard-main-grid {
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: var(--space-6);
    align-items: start;
}

/* CORRECTION : les éléments de grille CSS ont, comme les éléments flex,
   un min-width:auto implicite — la carte "Prochains rendez-vous" (qui
   contient un tableau large) peut donc forcer cette grille plus large que
   l'écran, même repassée en 1 colonne sous 900px, et même avec le
   min-width:0 déjà posé sur .page-content/.main-content (ça protège la
   colonne flex, pas les enfants directs de CETTE grille). */
.dashboard-main-grid>* {
    min-width: 0;
}

@media (max-width: 900px) {
    .dashboard-main-grid {
        grid-template-columns: 1fr;
    }
}

/* Variante compacte de .empty-state (padding réduit), utilisée dans les
   cartes secondaires (accueil, fiche client) plutôt que sur une page
   entière. */
.empty-state-compact {
    padding: var(--space-10);
}

/* Ligne label/valeur alignée à droite (statistiques, plan, features) */
.stat-line {
    display: flex;
    justify-content: space-between;
    font-size: var(--text-sm);
}

/* Encart "lien de la page publique" (accueil) */
.public-link-box {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--color-gray-50);
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
}

.public-link-text {
    font-size: var(--text-xs);
    color: var(--color-gray-600);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Champ de recherche large (liste clients) */
.search-field-wide {
    min-width: 280px;
}

/* ── Paramètres (onglets profil / réservation / apparence / mot de passe) ── */
/* CORRECTION : sans overflow-x, 4 onglets ("Profil", "Réservation",
   "Apparence", "Mot de passe") ne tiennent pas sur une largeur d'écran
   étroite — le dernier onglet est tronqué/inaccessible et force un scroll
   horizontal sur TOUTE la page. Même motif que .table-container plus haut :
   le scroll reste contenu à la barre elle-même. flex-shrink:0 sur
   .settings-tab (ci-dessous) empêche les onglets de s'écraser au lieu de
   défiler. */
.settings-tabs-bar {
    display: flex;
    gap: 0;
    border-bottom: 2px solid var(--color-gray-200);
    margin-bottom: var(--space-6);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.settings-tab {
    border-radius: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    padding: var(--space-2) var(--space-4);
    flex-shrink: 0;
    white-space: nowrap;
}

.settings-tab.active {
    border-bottom-color: var(--color-primary);
    color: var(--color-primary);
    font-weight: var(--font-semibold);
}

/* Remplace la bascule d'affichage pilotée en JS via style.display sur
   chaque panneau d'onglet. */
.tab-panel {
    display: none;
}

.tab-panel.active {
    display: block;
}

.form-row-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: var(--space-3);
}

@media (max-width: 640px) {
    .form-row-3 {
        grid-template-columns: 1fr;
    }
}

/* Variante de .form-row-2 (gap space-3) avec un gap plus large (space-4),
   utilisée pour la grille des 2 couleurs de marque dans Paramètres. */
.form-row-2-lg {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
}

@media (max-width: 480px) {
    .form-row-2-lg {
        grid-template-columns: 1fr;
    }
}

.fieldset-box {
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    padding: var(--space-4);
}

.fieldset-box-legend {
    font-size: var(--text-sm);
    font-weight: var(--font-semibold);
    padding: 0 var(--space-2);
}

.slug-prefix {
    font-size: var(--text-sm);
    color: var(--color-gray-500);
    white-space: nowrap;
}

/* Partagé entre Paramètres (couleurs de marque) et Services (couleur du
   service) : le carré de sélection de couleur natif <input type="color">.
   CORRECTION : qualifié en "input.color-swatch-input" (et non simplement
   ".color-swatch-input") pour égaler la spécificité du sélecteur générique
   "input[type=\"color\"]" plus haut (une combinaison élément+attribut est
   plus spécifique qu'une seule classe) ; à spécificité égale, c'est l'ordre
   dans la feuille de style qui tranche, et cette règle est bien après.
   Sans ce correctif, le carré de couleur héritait de "width:100%" et
   écrasait le champ hexadécimal juste à côté. */
input.color-swatch-input {
    width: 48px;
    height: 38px;
    padding: 2px;
    cursor: pointer;
    flex-shrink: 0;
}

.color-hex-input {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
}

.logo-preview {
    height: 48px;
    object-fit: contain;
    margin-bottom: var(--space-2);
}

.file-input-sm {
    font-size: var(--text-sm);
}

/* ── Disponibilités ───────────────────────────────────────────── */
.avail-day-label {
    font-weight: var(--font-semibold);
    font-size: var(--text-sm);
    min-width: 90px;
}

.slot-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.slot-time-input {
    width: 110px;
}

.slot-empty {
    font-size: var(--text-sm);
    color: var(--color-gray-800);
}

/* Champs heure début/fin de l'exception : masqués par défaut (cas
   "Fermé (journée)"), affichés en grille 2 colonnes sinon. Remplace la
   double manipulation JS de style.display + style.gridTemplateColumns. */
.exception-time-fields {
    display: none;
    gap: var(--space-3);
}

.exception-time-fields.visible {
    display: grid;
    grid-template-columns: 1fr 1fr;
}

/* ── Services (gestion admin, différent de .service-card qui sert à la
   sélection d'un service par le client sur la page de réservation
   publique — noms distincts volontairement pour ne pas les confondre) ── */
.admin-service-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
}

.admin-service-name-group {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1;
    min-width: 0;
}

.admin-service-color-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex-shrink: 0;
}

.admin-service-title {
    font-size: var(--text-base);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.admin-service-desc {
    font-size: var(--text-sm);
    color: var(--color-gray-800);
    margin-top: var(--space-2);
}

.admin-service-meta {
    display: flex;
    gap: var(--space-4);
    margin-top: var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-gray-600);
}

.form-row-name-color {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--space-3);
    align-items: end;
}

.upload-section-divider {
    border-top: 1px solid var(--color-gray-200);
    padding-top: var(--space-4);
}

.file-instruction-group {
    margin-top: var(--space-3);
}

.label-normal {
    font-weight: normal;
}

/* ── Déconnexion en formulaire POST (au lieu d'un lien <a> en GET) ──
   Les liens "Déconnexion" de admin.php et dashboard.php sont désormais des
   <button type="submit"> dans un <form>, pour appliquer la même politique
   CSRF que le reste des actions de changement d'état de session (voir
   AdminController::stopImpersonation()). .nav-link-button ne touche qu'aux
   propriétés par défaut du navigateur sur <button> (fond, bordure, police,
   alignement du texte) — le reste (flex, couleur, padding, icône) vient
   toujours de .nav-link, déjà appliquée conjointement sur le même élément. */
button.nav-link-button {
    background: none;
    border: none;
    font: inherit;
    text-align: left;
    width: 100%;
    cursor: pointer;
}

/* ══════════════════════════════════════════════════════════════════
   Page d'accueil publique (landing) — templates/public/accueil.php
   Ajout pur (aucune règle existante modifiée) : présentation de la
   plateforme + tarifs, avant le formulaire de connexion qui reste sur
   /auth/connexion. Namespacé .landing-* pour ne rien croiser avec les
   classes déjà utilisées par la page de réservation publique
   (/pro/{slug}), qui partage le même layout templates/layouts/public.php.
   ══════════════════════════════════════════════════════════════════ */

/* ── Barre de navigation ──────────────────────────────────────── */
.landing-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-6) var(--space-6) 0;
}

.landing-nav-logo {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-semibold);
    font-size: var(--text-lg);
    color: var(--color-gray-900);
}

/* ── Hero ──────────────────────────────────────────────────────── */
.landing-hero {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-16) var(--space-6);
    display: grid;
    grid-template-columns: 1fr 420px;
    gap: var(--space-16);
    align-items: center;
}

@media (max-width: 900px) {
    .landing-hero {
        grid-template-columns: 1fr;
        padding: var(--space-10) var(--space-6);
        gap: var(--space-10);
        text-align: center;
    }
}

.landing-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
    font-size: var(--text-base);
    font-weight: var(--font-medium);
    margin-bottom: var(--space-4);
}

.landing-hero h1 {
    font-size: 2.75rem;
    line-height: 1.15;
    letter-spacing: -0.02em;
    margin-bottom: var(--space-5);
}

@media (max-width: 640px) {
    .landing-hero h1 {
        font-size: var(--text-3xl);
    }
}

.landing-hero-sub {
    font-size: var(--text-lg);
    color: var(--color-gray-600);
    max-width: 44ch;
    margin-bottom: var(--space-8);
}

@media (max-width: 900px) {
    .landing-hero-sub {
        max-width: none;
        margin-left: auto;
        margin-right: auto;
    }
}

.landing-hero-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

@media (max-width: 900px) {
    .landing-hero-actions {
        justify-content: center;
        flex-wrap: wrap;
    }
}

/* Aperçu du calendrier — élément signature : montre le produit plutôt
   qu'une illustration décorative générique. */
.landing-mock {
    background: #fff;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
    padding: var(--space-5);
    transform: rotate(-1.5deg);
}

.landing-mock-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-4);
}

.landing-mock-header-title {
    font-size: var(--text-sm);
    font-weight: var(--font-semibold);
    color: var(--color-gray-900);
}

.landing-mock-header-name {
    font-size: var(--text-xs);
    color: var(--color-gray-500);
}

.landing-mock-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--space-1);
    margin-bottom: var(--space-4);
}

.landing-mock-day-label {
    font-size: var(--text-xs);
    color: var(--color-gray-400);
    text-align: center;
    padding-bottom: var(--space-1);
}

.landing-mock-day {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-xs);
    color: var(--color-gray-600);
    border-radius: var(--radius-md);
}

.landing-mock-day.is-booked {
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--font-semibold);
}

.landing-mock-slot {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    background: var(--color-gray-50);
    border: 1px solid var(--color-gray-200);
    border-radius: var(--radius-md);
    padding: var(--space-3);
}

.landing-mock-slot-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-primary);
    flex-shrink: 0;
}

.landing-mock-slot-time {
    font-size: var(--text-sm);
    font-weight: var(--font-semibold);
    color: var(--color-gray-900);
    white-space: nowrap;
}

.landing-mock-slot-title {
    font-size: var(--text-sm);
    color: var(--color-gray-600);
}

/* ── Sections génériques (fonctionnalités, tarifs) ───────────────── */
.landing-section {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-16) var(--space-6);
}

.landing-section-header {
    text-align: center;
    max-width: 56ch;
    margin: 0 auto var(--space-10);
}

.landing-section-header h2 {
    font-size: var(--text-2xl);
    margin-bottom: var(--space-2);
}

.landing-section-header p {
    font-size: var(--text-base);
}

/* ── Fonctionnalités ──────────────────────────────────────────── */
.landing-features-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-6);
}

@media (max-width: 900px) {
    .landing-features-grid {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 560px) {
    .landing-features-grid {
        grid-template-columns: 1fr;
    }
}

.landing-feature-card {
    background: #fff;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
}

.landing-feature-icon {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background: #fbebd6;
    color: #c77a17;
    margin-bottom: var(--space-4);
}

.landing-feature-card h3 {
    font-size: var(--text-base);
    margin-bottom: var(--space-2);
}

.landing-feature-card p {
    font-size: var(--text-sm);
}

/* ── Tarifs ───────────────────────────────────────────────────── */
.landing-pricing-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
    max-width: 900px;
    margin: 0 auto;
}

@media (max-width: 640px) {
    .landing-pricing-grid {
        grid-template-columns: 1fr;
    }
}

.landing-pricing-card {
    position: relative;
    background: #fff;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-xl);
    padding: var(--space-8);
    display: flex;
    flex-direction: column;
}

.landing-pricing-card.is-highlighted {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-lg);
}

.landing-pricing-badge {
    position: absolute;
    top: -13px;
    left: var(--space-6);
    background: #b23a2e;
    color: #fff;
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
}

.landing-pricing-name {
    font-size: var(--text-lg);
    font-weight: var(--font-semibold);
    color: var(--color-gray-900);
    margin-bottom: var(--space-1);
}

.landing-pricing-tagline {
    font-size: var(--text-sm);
    color: var(--color-gray-700);
    margin-bottom: var(--space-5);
}

.landing-price {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    margin-bottom: var(--space-6);
    min-height: 5.5rem;
}

.landing-price-amount {
    font-size: 2.5rem;
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
    letter-spacing: -0.02em;
}

.landing-price-amount2 {
    font-size: 2.0rem;
    font-weight: var(--font-bold);
    color: var(--color-gray-900);
    letter-spacing: -0.02em;
}

.landing-price-period {
    font-size: var(--text-sm);
    color: var(--color-gray-600);
}

.landing-pricing-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-8);
    flex: 1;
}

.landing-pricing-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-gray-700);
}

.landing-pricing-item svg {
    flex-shrink: 0;
    margin-top: 3px;
    color: var(--color-success);
}

.landing-price {
    margin-bottom: var(--space-6);
    min-height: 6.8rem;
}

.landing-price-line {
    display: flex;
    align-items: baseline;
    gap: .35rem;
}

.landing-price-separator {
    font-size: .85rem;
    color: var(--color-gray-500);
    line-height: 1;
    margin: .15rem 0;
}

.landing-price-placeholder {
    height: 2.3rem;
}

/* ── CTA de pied de page ─────────────────────────────────────── */
.landing-footer-cta {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-16) var(--space-6) var(--space-16);
    text-align: center;
    background: var(--color-gray-900);
    border-radius: var(--radius-xl);
    margin-bottom: var(--space-16);
}

.landing-footer-cta h2 {
    color: #fff;
    margin-bottom: var(--space-3);
}

.landing-footer-cta p {
    color: var(--color-gray-400);
    margin-bottom: var(--space-6);
}

.footer {
    border-top: 1px solid var(--color-gray-200);
    padding: var(--space-6) 0;
}

.footer-page {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 var(--space-8);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--color-gray-700);
    line-height: 1.6;
}

/* ── Footer : liens légaux ──────────────────────────────────── */
.footer-page a {
    color: var(--color-gray-600);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.footer-page a:hover {
    color: var(--color-primary);
}

/* ── Pages légales (mentions, confidentialité, CGU/CGV) ──────── */
.legal-page {
    max-width: 72ch;
    margin: 0 auto;
    padding: var(--space-16) var(--space-6);
}

.legal-back-link {
    display: inline-block;
    font-size: var(--text-sm);
    color: var(--color-gray-600);
    margin-bottom: var(--space-6);
}

.legal-back-link:hover {
    color: var(--color-primary);
}

.legal-page h1 {
    margin-bottom: var(--space-8);
}

.legal-section {
    margin-bottom: var(--space-8);
}

.legal-section h2 {
    margin-bottom: var(--space-3);
}

.legal-section p {
    margin-bottom: var(--space-3);
}

.legal-section p:last-child {
    margin-bottom: 0;
}

.legal-section ul {
    list-style: disc;
    padding-left: var(--space-6);
    margin-bottom: var(--space-3);
}

.legal-section li {
    color: var(--color-gray-600);
    font-size: var(--text-base);
    margin-bottom: var(--space-2);
}

.legal-section a {
    color: var(--color-primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.legal-section a:hover {
    color: var(--color-primary-dark);
}

section.landing-hero .landing-mock-image {
    border-radius: 12px !important;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08) !important;
    transform: rotate(2.5deg) !important;
    max-width: 100% !important;
    height: auto !important;
    display: block !important;
}

.intro {
    font-weight: var(--font-bold);
}