/* ==========================================================================
   HEALTECHPOS — feuille de style principale
   Poppins, interface SaaS/POS, responsive, optimisée tactile.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');

:root {
    --brand-900: #0b1b3a;
    --brand-800: #12244d;
    --brand-700: #1a3163;
    --brand-600: #23407f;
    --brand-500: #2f56a5;
    --accent:    #f59e0b;

    --success: #16a34a;
    --danger:  #dc2626;
    --warning: #d97706;
    --info:    #0891b2;

    --bg:         #f4f6fb;
    --surface:    #ffffff;
    --surface-2:  #f8fafc;
    --border:     #e2e8f0;
    --text:       #0f172a;
    --text-muted: #64748b;

    --radius:    12px;
    --radius-sm: 8px;
    --shadow:    0 1px 2px rgba(15, 23, 42, .06), 0 8px 24px rgba(15, 23, 42, .06);
    --shadow-lg: 0 20px 50px rgba(15, 23, 42, .18);

    --sidebar-width: 262px;
    --topbar-height: 64px;

    --font: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

/* ---------------------------------------------------------------- Icônes ---
   Jeu SVG intégré (app/Support/Icons.php). Les icônes héritent de la couleur
   du texte et s'alignent optiquement avec la ligne de base. */

.icon {
    width: 20px; height: 20px;
    flex: 0 0 auto;
    display: inline-block;
    vertical-align: -.22em;
}
.icon--sm { width: 16px; height: 16px; }
.icon--lg { width: 24px; height: 24px; }
.icon--xl { width: 30px; height: 30px; }

html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--brand-600); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0 0 .5rem; font-weight: 600; line-height: 1.25; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

/* ------------------------------------------------------------------ Layout */

.layout { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-width);
    flex: 0 0 var(--sidebar-width);
    background: linear-gradient(180deg, var(--brand-900), var(--brand-800));
    color: #cbd5e1;
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    transition: transform .25s ease;
}

/* En-tête de la barre : bandeau blanc cassé qui porte le logo « système ». */
.sidebar__brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .35rem;
    padding: 1rem 1.25rem;
    background: #f4f5f7;
    border-bottom: 1px solid var(--border);
}

/* Logo « système » : marque-mot recolorée en bleu nuit, posée sur le blanc. */
.sidebar__logo {
    display: block;
    width: auto; height: auto;
    max-width: 100%; max-height: 42px;
    object-fit: contain;
}

.sidebar__title { color: var(--brand-900); font-weight: 600; font-size: .98rem; letter-spacing: .02em; }
.sidebar__subtitle { font-size: .7rem; color: var(--text-muted); }

.sidebar__nav { padding: .9rem .75rem; overflow-y: auto; flex: 1; }
.sidebar__section { padding: 1rem .6rem .35rem; font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: #64748b; }

.sidebar__link {
    display: flex; align-items: center; gap: .7rem;
    padding: .62rem .75rem;
    border-radius: var(--radius-sm);
    color: #cbd5e1;
    font-weight: 400;
    margin-bottom: 2px;
    transition: background .15s ease, color .15s ease;
}
.sidebar__link:hover { background: rgba(255, 255, 255, .07); color: #fff; text-decoration: none; }
.sidebar__link.is-active { background: var(--brand-600); color: #fff; font-weight: 500; }
.sidebar__link .icon { opacity: .85; }
.sidebar__link.is-active .icon { opacity: 1; }

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

.topbar {
    height: var(--topbar-height);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 1.35rem;
    position: sticky; top: 0; z-index: 30;
}

.topbar__left { display: flex; align-items: center; gap: .9rem; min-width: 0; }
.topbar__title { font-weight: 600; font-size: 1.05rem; }
.topbar__right { display: flex; align-items: center; gap: .8rem; }

.topbar__clock { font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: .85rem; }

.avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--brand-600); color: #fff;
    display: grid; place-items: center; font-weight: 600; font-size: .82rem;
}

.user-menu { position: relative; }
.user-menu__button { display: flex; align-items: center; gap: .6rem; background: none; border: 0; cursor: pointer; font-family: inherit; color: inherit; }
.user-menu__name { font-weight: 500; font-size: .86rem; line-height: 1.1; }
.user-menu__role { font-size: .72rem; color: var(--text-muted); }
.user-menu__dropdown {
    position: absolute; right: 0; top: calc(100% + 10px);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-lg);
    min-width: 208px; padding: .4rem; display: none;
}
.user-menu__dropdown.is-open { display: block; }
.user-menu__item { display: block; padding: .55rem .7rem; border-radius: var(--radius-sm); color: var(--text); font-size: .86rem; }
.user-menu__item:hover { background: var(--surface-2); text-decoration: none; }

/* Bascule de langue dans le menu utilisateur. */
.user-menu__langs { display: flex; gap: .3rem; padding: .35rem .4rem; margin: .25rem 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.user-menu__lang {
    flex: 1; padding: .4rem .3rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text-muted); font: inherit; font-size: .78rem; font-weight: 600; cursor: pointer;
}
.user-menu__lang:hover { background: var(--surface-2); color: var(--text); }
.user-menu__lang.is-active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; cursor: default; }

.content { padding: 1.4rem; flex: 1; }
.page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.15rem; flex-wrap: wrap; }
.page-header p { margin: .15rem 0 0; color: var(--text-muted); font-size: .87rem; }

/* ------------------------------------------------------------------- Cards */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.card__header { padding: 1rem 1.15rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: .8rem; flex-wrap: wrap; }
.card__title { font-weight: 600; font-size: .98rem; }
.card__body { padding: 1.15rem; }
.card__footer { padding: .85rem 1.15rem; border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius); }

.grid { display: grid; gap: 1rem; }
.grid--stats { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.stat { display: flex; align-items: center; gap: .95rem; padding: 1.1rem 1.15rem; }
.stat__icon { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; background: #eef2ff; color: var(--brand-600); }
.stat__icon .icon { width: 22px; height: 22px; vertical-align: 0; }
.stat__value { font-size: 1.5rem; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat__label { color: var(--text-muted); font-size: .8rem; }

/* Compteur sur lequel il y a quelque chose à faire : « À vérifier » ouvre la
   liste des chambres dont le temps est écoulé. Les autres ne sont que des
   chiffres — un faux bouton ferait perdre du temps à l'essayer. */
.stat--action { cursor: pointer; transition: box-shadow .15s ease, transform .12s ease; }
.stat--action:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.stat--action:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .stat--action { transition: none; }
    .stat--action:hover { transform: none; }
}

/* ------------------------------------------------------------------ Tables */

.table-wrapper { overflow-x: auto; }

.table { width: 100%; border-collapse: collapse; font-size: .87rem; }
.table th, .table td { padding: .72rem .9rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table th { background: var(--surface-2); font-weight: 600; font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); white-space: nowrap; }
.table tbody tr:hover { background: #fafcff; }
.table td.actions { white-space: nowrap; text-align: right; }
.table .empty { text-align: center; color: var(--text-muted); padding: 2.2rem 1rem; }

/* ----------------------------------------------------------------- Buttons */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
    padding: .55rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-family: inherit; font-size: .86rem; font-weight: 500;
    cursor: pointer; white-space: nowrap;
    transition: background .15s ease, border-color .15s ease, opacity .15s ease;
    min-height: 40px;
}
.btn:hover { text-decoration: none; }
.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn--primary { background: var(--brand-600); color: #fff; }
.btn--primary:hover { background: var(--brand-700); }
.btn--secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn--secondary:hover { background: var(--surface-2); }
.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { filter: brightness(.93); }
.btn--ghost { background: transparent; color: var(--text-muted); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }
.btn--sm { padding: .35rem .65rem; font-size: .8rem; min-height: 32px; }
.btn--block { width: 100%; }

/* ------------------------------------------------------------------- Forms */

.form-group { margin-bottom: 1rem; }
.form-row { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.label { display: block; font-size: .82rem; font-weight: 500; margin-bottom: .35rem; }
.label .req { color: var(--danger); }

.input, .select, .textarea {
    width: 100%;
    padding: .58rem .75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: inherit; font-size: .88rem;
    background: var(--surface); color: var(--text);
    min-height: 40px;
}
.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--brand-500);
    box-shadow: 0 0 0 3px rgba(47, 86, 165, .12);
}
.input.is-invalid, .select.is-invalid { border-color: var(--danger); }
.field-error { color: var(--danger); font-size: .76rem; margin-top: .25rem; display: block; }
.help { color: var(--text-muted); font-size: .78rem; margin-top: .25rem; }

/* Champ date en français (jj/mm/aaaa) — le <input type=date> natif garde le
   format de la langue du navigateur ; on saisit dans un champ texte français
   posé devant, et un bouton ouvre le calendrier natif (resté caché). */
.datefr { position: relative; display: block; }
.datefr .datefr__text { width: 100%; padding-right: 2.1rem; letter-spacing: .02em; }
.datefr__native {
    position: absolute; right: .6rem; bottom: 0;
    width: 1px; height: 1px; min-height: 0; padding: 0; margin: 0;
    border: 0; opacity: 0; pointer-events: none;
}
.datefr__pick {
    position: absolute; top: 0; right: 0; height: 100%; width: 2rem;
    display: grid; place-items: center; padding: 0;
    border: 0; background: none; cursor: pointer; color: var(--text-muted);
}
.datefr__pick:hover { color: var(--brand-500); }
.datefr__pick svg { width: 15px; height: 15px; }

.ojx__day .datefr { width: 10.5rem; }
.ojx__range { display: flex; gap: .6rem; }
@media (max-width: 560px) { .ojx__range { flex-wrap: wrap; } .ojx__range .ojx__day { flex: 1 1 8rem; } .ojx__range .datefr { width: 100%; } }
.xp__range-field .datefr { width: 160px; }
.xph__field .datefr { min-width: 150px; }

.checkbox, .radio { display: flex; align-items: flex-start; gap: .55rem; font-size: .86rem; cursor: pointer; padding: .2rem 0; }
.checkbox input, .radio input { margin-top: .22rem; width: 16px; height: 16px; cursor: pointer; }

.toolbar { display: flex; gap: .7rem; flex-wrap: wrap; align-items: center; }
.toolbar .input, .toolbar .select { width: auto; min-width: 180px; }

/* ------------------------------------------------------------------ Badges */

.badge {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .2rem .6rem; border-radius: 999px;
    font-size: .73rem; font-weight: 500;
    background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border);
}
.badge--success { background: #dcfce7; color: #166534; border-color: #bbf7d0; }
.badge--danger  { background: #fee2e2; color: #991b1b; border-color: #fecaca; }
.badge--warning { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.badge--info    { background: #e0f2fe; color: #075985; border-color: #bae6fd; }
.badge--brand   { background: #e0e7ff; color: #3730a3; border-color: #c7d2fe; }

/* ------------------------------------------------------------------ Modals */

.modal-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, .55);
    display: none; align-items: flex-start; justify-content: center;
    padding: 3vh 1rem; z-index: 60; overflow-y: auto;
}
.modal-backdrop.is-open { display: flex; }

.modal {
    background: var(--surface); border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    width: 100%; max-width: 620px; margin: auto;
    animation: modal-in .18s ease;
}
.modal--lg { max-width: 940px; }
.modal--sm { max-width: 430px; }

@keyframes modal-in { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

.modal__header { padding: 1.05rem 1.25rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.modal__title { font-weight: 600; font-size: 1.02rem; }
.modal__close { background: none; border: 0; font-size: 1.35rem; line-height: 1; cursor: pointer; color: var(--text-muted); padding: 0 .25rem; }
.modal__body { padding: 1.25rem; max-height: 68vh; overflow-y: auto; }
.modal__footer { padding: .95rem 1.25rem; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: .6rem; background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius); }

/* ------------------------------------------------------------------ Toasts */

.toast-container { position: fixed; top: 1rem; right: 1rem; z-index: 90; display: flex; flex-direction: column; gap: .6rem; max-width: 380px; }

.toast {
    background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--brand-600);
    border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
    padding: .8rem 1rem; display: flex; gap: .7rem; align-items: flex-start;
    animation: toast-in .2s ease;
}
.toast--success { border-left-color: var(--success); }
.toast--error   { border-left-color: var(--danger); }
.toast--warning { border-left-color: var(--warning); }
.toast__title { font-weight: 600; font-size: .87rem; }
.toast__message { font-size: .82rem; color: var(--text-muted); }
.toast__close { margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--text-muted); font-size: 1.1rem; line-height: 1; }

@keyframes toast-in { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }

/* -------------------------------------------------------------- Pagination */

.pagination { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.pagination__info { color: var(--text-muted); font-size: .82rem; }
.pagination__pages { display: flex; gap: .3rem; }
.pagination__page {
    min-width: 36px; height: 36px; padding: 0 .5rem;
    border: 1px solid var(--border); background: var(--surface);
    border-radius: var(--radius-sm); cursor: pointer; font-family: inherit; font-size: .84rem;
}
.pagination__page.is-active { background: var(--brand-600); color: #fff; border-color: var(--brand-600); }
.pagination__page:disabled { opacity: .45; cursor: not-allowed; }

/* --------------------------------------------------------------- Connexion */

.auth {
    min-height: 100vh;
    display: grid; grid-template-columns: 1.05fr .95fr;
    background: var(--bg);
}
.auth__side {
    background: linear-gradient(150deg, var(--brand-900), var(--brand-600) 65%, var(--brand-500));
    color: #fff; padding: 3rem; display: flex; flex-direction: column; justify-content: space-between;
}
.auth__side h1 { font-size: 2.05rem; color: #fff; }
.auth__side p { color: #cbd5e1; max-width: 44ch; }
.auth__features { list-style: none; padding: 0; margin: 1.6rem 0 0; display: grid; gap: .6rem; }
.auth__features li { display: flex; gap: .6rem; align-items: center; color: #e2e8f0; font-size: .9rem; }

.auth__panel { display: grid; place-items: center; padding: 2rem; }
.auth__form { width: 100%; max-width: 390px; }
.auth__logo { width: 54px; height: 54px; border-radius: 14px; background: linear-gradient(135deg, var(--accent), #f97316); display: grid; place-items: center; font-weight: 700; color: var(--brand-900); font-size: 1.15rem; margin-bottom: 1.1rem; }

.alert { padding: .8rem 1rem; border-radius: var(--radius-sm); font-size: .85rem; margin-bottom: 1rem; display: none; }
.alert.is-visible { display: block; }
.alert--error { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
.alert--warning { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
.alert--info { background: #e0f2fe; color: #075985; border: 1px solid #bae6fd; }

/* ------------------------------------------------------------------ Divers */

.muted { color: var(--text-muted); }
.text-right { text-align: right; }
.text-center { text-align: center; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: .5rem; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.flex { display: flex; } .flex-between { display: flex; align-items: center; justify-content: space-between; gap: .8rem; }
.gap-1 { gap: .5rem; } .gap-2 { gap: 1rem; }
.hidden { display: none !important; }

/* Interrupteur segmenté (bascule entre deux vues d'une même page). */
.seg {
    display: inline-flex; gap: 2px; margin-bottom: 1.15rem;
    padding: 3px; border-radius: 999px; background: var(--surface-2);
}
.seg__btn {
    min-height: 34px; padding: .3rem 1rem;
    border: 0; border-radius: 999px; background: none;
    color: var(--text-muted); cursor: pointer;
    font-family: inherit; font-size: .84rem; font-weight: 600;
}
.seg__btn.is-active { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.seg__btn:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

/* Visible des seuls lecteurs d'écran : sert d'étiquette aux champs dont le
   libellé est porté par le contexte visuel. */
.sr-only {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0;
}

/* ------------------------------------------- POS : barre des départements ---
   Premier niveau, au-dessus des catégories : Bar, Restaurant, Chambre… Plus
   sobre que les pastilles de catégorie qu'elle range — c'est elle qui les
   range, pas l'inverse. */

.pos__dept-tabs {
    display: flex; flex-wrap: wrap; gap: .3rem;
    margin-bottom: .6rem; padding-bottom: .6rem;
    border-bottom: 1px solid var(--border);
}
.pos__dept-tab {
    min-height: 40px; padding: .45rem 1.1rem;
    border: 0; border-radius: 10px;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit; font-size: .86rem; font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.pos__dept-tab:hover { background: var(--surface-2); color: var(--text); }
.pos__dept-tab.is-active { background: var(--brand-600); color: #fff; }
.pos__dept-tab:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .pos__dept-tab { transition: none; }
}

/* -------------------------------------------- POS : barre des catégories ---
   Les catégories du catalogue sur une ligne, « Tous » en tête. Elles viennent
   de la base, pas du code : ce que l'encadrement crée apparaît ici. Cibles
   hautes (44 px) : l'écran est tactile et le caissier va vite. */

.pos__filters {
    display: flex; flex-wrap: wrap; gap: .4rem;
    margin-bottom: .6rem;
}
.pos__filter {
    min-height: 44px; padding: .5rem 1rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text-muted);
    font-family: inherit; font-size: .88rem; font-weight: 500;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.pos__filter:hover { border-color: var(--brand-500); color: var(--text); }
.pos__filter.is-active {
    background: var(--brand-600); border-color: var(--brand-600); color: #fff;
}
.pos__filter:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

/* Étiquette de catégorie sur la vignette produit, quand « Tous » est actif. */
.pos__product-dept {
    font-size: .66rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
    .pos__filter { transition: none; }
}

/* ------------------------------------------------ POS : tickets ouverts ---
   Groupés par serveuse, du plus récent au plus ancien. Chaque ticket est une
   tuile entièrement cliquable : au comptoir on vise avec le doigt, pas avec
   la souris sur un petit bouton en bout de ligne. */

/* ------------------------------------ POS : tableau des tickets ouverts ---
   Une colonne par serveuse, comme un tableau de service. On balaie la salle
   du regard au lieu de dérouler une liste : les colonnes glissent
   horizontalement, chacune défile verticalement si elle déborde. */

.board {
    display: flex; gap: .75rem;
    overflow-x: auto; overflow-y: hidden;
    padding: .2rem .2rem 1rem;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
}

.board__col {
    flex: 0 0 268px;
    display: flex; flex-direction: column;
    max-height: 58vh;
    scroll-snap-align: start;

    /* Chaque colonne se pose l'une après l'autre : le mouvement dit dans
       quel ordre lire, sans forcer l'attention. */
    animation: board-in .32s ease both;
    animation-delay: calc(var(--rang, 0) * 45ms);
}

@keyframes board-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* Teintes : une par serveuse, stable puisqu'elle vient de son nom. */
.board__col { --who: var(--brand-600); --who-soft: var(--surface-2); }

.board__col--0 { --who: #6d28d9; --who-soft: #f5f3ff; }
.board__col--1 { --who: #1d4ed8; --who-soft: #eff6ff; }
.board__col--2 { --who: #0e7490; --who-soft: #ecfeff; }
.board__col--3 { --who: #be123c; --who-soft: #fff1f2; }
.board__col--4 { --who: #15803d; --who-soft: #f0fdf4; }
.board__col--5 { --who: #b45309; --who-soft: #fffbeb; }
.board__col--6 { --who: #4338ca; --who-soft: #eef2ff; }
.board__col--7 { --who: #9d174d; --who-soft: #fdf2f8; }

/* Les tickets sans serveuse ne sont pas une personne : gris à part. */
.board__col--none { --who: #475569; --who-soft: #f1f5f9; }

.board__head {
    display: flex; align-items: center; gap: .55rem;
    padding: .6rem .7rem;
    border-radius: 14px 14px 0 0;
    background: var(--who-soft);
    border-bottom: 3px solid var(--who);
}
.board__avatar {
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 34px; height: 34px; border-radius: 50%;
    background: var(--who); color: #fff;
    font-size: .78rem; font-weight: 700; letter-spacing: .02em;
}
.board__who { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.board__name {
    font-size: .86rem; font-weight: 700; color: var(--who);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.board__count { font-size: .7rem; color: var(--text-muted); }
.board__sum {
    font-size: .88rem; font-weight: 700; color: var(--who);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

.board__list {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column; gap: .45rem;
    padding: .55rem;
    overflow-y: auto;
    background: var(--surface-2);
    border-radius: 0 0 14px 14px;
    scrollbar-width: thin;
}

/* Carte de ticket : la table en tête, le montant en gros, la référence et
   l'ancienneté en pied. L'ancienneté est ce qui trahit un ticket oublié. */
.tcard {
    display: flex; flex-direction: column; gap: .3rem;
    padding: .7rem .75rem;
    border: 0; border-left: 3px solid var(--who);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .07);
    font-family: inherit; text-align: left; cursor: pointer;
    transition: transform .14s ease, box-shadow .18s ease;
    animation: board-in .3s ease both;
    animation-delay: calc(var(--index, 0) * 35ms + 120ms);
}
.tcard:hover { transform: translateY(-2px); box-shadow: 0 10px 18px -10px rgba(15, 23, 42, .45); }
.tcard:active { transform: translateY(0); }
.tcard:focus-visible { outline: 2px solid var(--who); outline-offset: 2px; }

.tcard__top { display: flex; align-items: baseline; justify-content: space-between; gap: .4rem; }
.tcard__table {
    font-size: .86rem; font-weight: 600; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tcard__clock {
    flex: 0 0 auto;
    padding: .08rem .4rem; border-radius: 6px;
    background: var(--who-soft); color: var(--who);
    font-size: .7rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.tcard__total {
    font-size: 1.32rem; font-weight: 700; line-height: 1.05;
    font-variant-numeric: tabular-nums;
}
.tcard__foot {
    display: flex; align-items: baseline; justify-content: space-between; gap: .4rem;
    font-size: .68rem; color: var(--text-muted);
}
.tcard__ref { font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
    .board__col { flex-basis: 82vw; }
}

@media (prefers-reduced-motion: reduce) {
    .board { scroll-behavior: auto; }
    .board__col, .card { animation: none; }
    .card { transition: none; }
    .card:hover { transform: none; }
}

/* ------------------------------------------- POS : monnaie à rendre ---
   Le chiffre que le caissier annonce au client. Il est calculé à chaque
   frappe et reste affiché : personne ne doit poser une soustraction de tête
   pendant qu'on attend devant lui. */

.pos__tender-quick { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }
.pos__tender {
    min-height: 40px; padding: .45rem .85rem;
    border: 1px solid var(--border); border-radius: 999px;
    background: var(--surface); color: var(--text);
    font-family: inherit; font-size: .82rem; font-weight: 500;
    cursor: pointer; font-variant-numeric: tabular-nums;
}
.pos__tender:hover { border-color: var(--success); background: #ecfdf5; color: #15803d; }
.pos__tender:focus-visible { outline: 2px solid var(--success); outline-offset: 2px; }

.pos__change {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; margin-top: .7rem;
    padding: .75rem 1rem;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.pos__change-label {
    font-size: .78rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-muted);
}
.pos__change-value {
    font-size: 1.75rem; font-weight: 700; line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

/* Rendu dû : c'est l'information utile, elle doit sauter aux yeux. */
.pos__change.is-due {
    background: #ecfdf5; border-color: var(--success);
}
.pos__change.is-due .pos__change-label,
.pos__change.is-due .pos__change-value { color: #15803d; }

/* Le client n'a pas donné assez : on le dit avant de valider. */
.pos__change.is-short {
    background: #fef3c7; border-color: var(--warning);
}
.pos__change.is-short .pos__change-label,
.pos__change.is-short .pos__change-value { color: #92400e; }

/* ---------------------------------------------------- Formules de séjour ---
   Transposition de l'affiche d'accueil : fond ambre, bandeau sombre, prix en
   très gros, devise en pastille rouge. Le blanc sur #292524 donne 14:1, la
   pastille rouge 5,9:1 : les gros chiffres restent lisibles de loin, ce qui
   est le point de cette présentation. */

.tariffs {
    background: linear-gradient(180deg, #f59e0b 0%, #f59e0b 42%, #fbbf24 100%);
    border-radius: var(--radius);
    padding: 1.15rem;
    box-shadow: var(--shadow);
}
.tariffs__head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
    margin-bottom: .9rem;
}
.tariffs__eyebrow {
    display: block;
    color: #7c2d12; font-size: .72rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .14em;
}
.tariffs__title {
    margin: 0;
    color: #fff; font-size: 1.9rem; font-weight: 700; line-height: 1.05;
    text-shadow: 0 1px 0 rgba(120, 53, 15, .35);
}
.tariffs__title em { font-style: normal; color: #431407; }
.tariffs__head .muted { color: #7c2d12; font-size: .78rem; }

.tariffs__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: .7rem;
}

.tariff {
    position: relative;
    display: flex; flex-direction: column; gap: .15rem;
    padding: 1rem 1.05rem 1.05rem;
    border-radius: 14px;
    background: #292524;
    color: #fff;
    border-top: 3px solid var(--tariff-tone, #f59e0b);
}
.tariff__price {
    font-size: 2.05rem; font-weight: 700; line-height: 1;
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.tariff__currency {
    position: absolute; top: .75rem; right: .8rem;
    display: inline-grid; place-items: center;
    min-width: 34px; height: 34px; padding: 0 .3rem;
    border-radius: 50%;
    background: #be123c; color: #fff;
    font-size: .64rem; font-weight: 700; letter-spacing: .04em;
}
.tariff__name {
    margin-top: .3rem;
    color: var(--tariff-tone, #fbbf24);
    font-size: 1.02rem; font-weight: 700; font-style: italic;
    text-transform: uppercase; letter-spacing: .01em;
}
.tariff__duration { color: #d6d3d1; font-size: .76rem; }
.tariff__includes {
    list-style: none; margin: .45rem 0 0; padding: 0;
    display: flex; flex-direction: column; gap: .12rem;
}
.tariff__includes li {
    color: #e7e5e4; font-size: .76rem;
    display: flex; align-items: center; gap: .35rem;
}
.tariff__includes .icon { width: 13px; height: 13px; color: var(--tariff-tone, #fbbf24); }
.tariff__edit {
    position: absolute; right: .55rem; bottom: .55rem;
    background: none; border: 0; padding: .25rem;
    color: #a8a29e; cursor: pointer; line-height: 0;
    border-radius: 6px;
}
.tariff__edit:hover { color: #fff; background: rgba(255, 255, 255, .12); }
.tariff__edit:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }

/* Carte cliquable : même dessin, mais c'est un bouton — le curseur, le focus
   et le retour au clic doivent le dire. */
.tariff--action {
    width: 100%; text-align: left;
    font-family: inherit;
    cursor: pointer;
    transition: transform .14s ease, box-shadow .18s ease;
}
.tariff--action:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 20px -12px rgba(0, 0, 0, .55);
}
.tariff--action:active { transform: translateY(0); }
.tariff--action:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.tariff--action.is-chosen {
    box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--tariff-tone, #f59e0b);
}

/* ------------------------------------------- Vente chambre : les formules ---
   Une carte par formule : prix en gros, ce qu'elle comprend, et le nombre de
   chambres réellement libres. Un tarif affiché sans dire s'il reste une
   chambre à vendre fait perdre le temps qu'il prétend gagner. */

.plans {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(216px, 1fr));
    gap: .8rem; padding: 1rem;
}

.plan {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: .3rem;
    padding: .95rem .9rem .8rem;
    border: 1px solid var(--border); border-radius: 14px;
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
    font-family: inherit; text-align: left; cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.plan:hover { border-color: var(--tone, var(--brand-600)); box-shadow: var(--shadow); transform: translateY(-2px); }
.plan:focus-visible { outline: 2px solid var(--tone, var(--brand-600)); outline-offset: 2px; }

/* Bandeau de couleur : la formule se reconnaît avant d'être lue. */
.plan__band {
    position: absolute; inset: 0 0 auto 0; height: 5px;
    background: var(--tone, #f59e0b);
}

.plan.is-chosen {
    border-color: var(--tone, var(--brand-600));
    box-shadow: 0 0 0 2px var(--tone, var(--brand-600));
}

/* Plus une chambre à vendre : la carte le dit et ne se clique plus. */
.plan[disabled] { opacity: .55; cursor: not-allowed; }
.plan[disabled]:hover { transform: none; box-shadow: 0 1px 2px rgba(15, 23, 42, .05); border-color: var(--border); }

.plan__head { display: flex; flex-direction: column; gap: .05rem; margin-top: .25rem; }
.plan__name { font-size: .98rem; font-weight: 700; line-height: 1.2; }
.plan__duration {
    font-size: .7rem; font-weight: 600; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .06em;
}
.plan__price {
    font-size: 1.9rem; font-weight: 700; line-height: 1;
    font-variant-numeric: tabular-nums; color: var(--tone, var(--text));
}
.plan__price small { font-size: .68rem; font-weight: 700; margin-left: .25rem; color: var(--text-muted); }
.plan__desc { font-size: .78rem; color: var(--text-muted); line-height: 1.35; }

.plan__includes { list-style: none; margin: .2rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .18rem; }
.plan__includes li { display: flex; align-items: center; gap: .35rem; font-size: .76rem; color: var(--text); }
.plan__includes .icon { color: var(--success); flex: 0 0 auto; }

.plan__foot { margin-top: auto; padding-top: .55rem; }
.plan__state { font-size: .74rem; font-weight: 600; }
.plan__state--ok { color: var(--success); }
.plan__state--none { color: var(--danger); }
.plan__state--extend { color: var(--info); }

/* ------------------------------------------- Vente chambre : les chambres ---
   Toutes les chambres sont montrées, y compris celles qu'on ne peut pas
   vendre : le caissier doit pouvoir répondre « la 3 se libère dans vingt
   minutes » sans changer d'écran. */

.rooms-board {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
    gap: .6rem; margin-top: .4rem;
}

.rtile {
    --tone: var(--text-muted);
    display: flex; flex-direction: column; gap: .12rem;
    min-height: 108px; padding: .75rem .8rem;
    border: 1px solid var(--border);
    border-left: 4px solid var(--tone);
    border-radius: 12px;
    background: var(--surface);
    font-family: inherit; text-align: left; cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.rtile:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
.rtile:focus-visible { outline: 2px solid var(--tone); outline-offset: 2px; }

/* Un état, une couleur, la même partout dans l'application. */
.rtile--free     { --tone: #15803d; }
.rtile--occupied { --tone: #be123c; }
.rtile--reserved { --tone: #b45309; }
.rtile--to_inspect { --tone: #b45309; }
.rtile--cleaning { --tone: #0e7490; }
.rtile--out      { --tone: #475569; }

/* Vignette : elle occupe toute la largeur de la pastille, débordant du
   retrait interne pour toucher les bords. Sans photo, un aplat de la couleur
   d'état porte le numéro — une grille où seules certaines pastilles ont une
   image se lirait comme un gabarit cassé. */
.rtile__photo {
    display: block; width: auto; height: 88px;
    margin: -.75rem -.8rem .5rem;
    object-fit: cover;
    border-radius: 11px 11px 0 0;
    background: var(--surface-2);
}
.rtile__photo--flat {
    display: grid; place-items: center;
    background: var(--tone); color: #fff;
    font-size: 1.6rem; font-weight: 700; letter-spacing: .02em;
}

.rtile__top { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }
.rtile__number { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rtile__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--tone); flex: 0 0 auto; }
.rtile__type {
    font-size: .7rem; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rtile__state { font-size: .82rem; font-weight: 600; color: var(--tone); }
.rtile__free { font-size: .72rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.rtile__guest {
    font-size: .7rem; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Chambre qu'on ne peut pas vendre : montrée, et consultable. On la choisit
   pour lire ses tarifs et l'heure à laquelle elle se libère — les formules
   s'ouvrent alors grisées. Interdire le clic obligerait le caissier à changer
   d'écran pour répondre « la 2 se libère dans une heure ». */
.rtile.is-blocked { background: var(--surface-2); }
.rtile.is-blocked:hover { transform: none; }

/* Chambre retenue : c'est elle qu'on est en train de vendre. Le cerclage la
   sort de la grille sans changer sa couleur d'état — on doit continuer à lire
   qu'elle est libre, ou à remettre en état. */
.rtile.is-chosen {
    box-shadow: 0 0 0 2px var(--tone), 0 10px 20px -14px rgba(15, 23, 42, .8);
}

/* L'heure de libération est passée : ce n'est plus une attente, c'est un
   retard, et c'est au comptoir de le savoir. */
.rtile.is-overdue .rtile__free { color: var(--danger); font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
    .tariff--action, .plan, .rtile { transition: none; }
    .tariff--action:hover, .plan:hover, .rtile:hover { transform: none; }
}

.tariff.is-inactive { opacity: .55; }
.tariff.is-inactive .tariff__name::after { content: " — inactive"; font-size: .7rem; }

@media (max-width: 560px) {
    .tariffs__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tariff__price { font-size: 1.6rem; }
    .tariffs__title { font-size: 1.5rem; }
}

/* ------------------------------------------------------ Panneau de filtres ---
   Replié par défaut, ouvert par le bouton « Filtres » de l'en-tête. Le compte
   de critères actifs reste visible même panneau fermé. */

.filters {
    padding: 1rem 1.15rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.filters__actions {
    display: flex; align-items: center; justify-content: flex-end;
    gap: .6rem; margin-top: .9rem;
    flex-wrap: wrap;
}
.filters__actions .muted { margin-right: auto; font-size: .82rem; }

.btn__badge {
    display: inline-grid; place-items: center;
    min-width: 18px; height: 18px; padding: 0 5px;
    margin-left: .1rem;
    border-radius: 9px;
    background: var(--brand-600); color: #fff;
    font-size: .68rem; font-weight: 600; line-height: 1;
}
.btn--primary .btn__badge { background: rgba(255, 255, 255, .28); }
.nowrap { white-space: nowrap; }
.mono { font-family: 'Consolas', 'Menlo', monospace; font-size: .82rem; }

.permission-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }

/* =========================================================================
   CATALOGUE
   Deux colonnes : à gauche ce qui structure le catalogue — catégories et
   suppléments —, à droite les produits en vignettes. La composition ressemble
   à la vente : ce qu'on voit ici est ce que le caissier verra.
   ========================================================================== */

.catalog {
    display: grid;
    grid-template-columns: 288px minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}
.catalog__rail { min-width: 0; display: flex; flex-direction: column; gap: .9rem; }
.catalog__main { min-width: 0; }

/* Chaque bloc de la colonne de gauche a sa propre barre de défilement —
   la liste des catégories ne pousse plus la page. */
.catalog__rail .rail { overflow-y: auto; overscroll-behavior: contain; }
.catalog__rail .card:first-child .rail { max-height: 52vh; }
.catalog__rail .card:last-child  .rail { max-height: 34vh; }

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

/* Grand écran : la colonne de gauche suit le défilement de la page. */
@media (min-width: 1001px) {
    .catalog__rail {
        position: sticky;
        top: calc(var(--topbar-height) + 1.4rem);
    }
}

/* Carte repliable : l'en-tête entier est le bouton de dépliage, le corps ne
   s'affiche qu'une fois ouverte (fermée par défaut). */
.card--fold > .rail { display: none; }
.card--fold.is-open > .rail { display: flex; }
.card__fold-head {
    display: flex; align-items: center; gap: .5rem;
    width: 100%; padding: 1rem 1.15rem;
    border: 0; border-bottom: 1px solid transparent; background: none;
    cursor: pointer; font-family: inherit; text-align: left; color: inherit;
}
.card--fold.is-open .card__fold-head { border-bottom-color: var(--border); }
.card__fold-head > span { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.card__fold-head .card__title { display: block; }
.card--fold.is-open .card__fold-head .rail__chevron { transform: rotate(90deg); }
.card__fold-head:hover .card__title { color: var(--brand-600); }

/* Colonne de gauche : une liste de lignes cliquables, pas un tableau. */
.rail { display: flex; flex-direction: column; padding: .35rem; }
.rail__empty { padding: .9rem; color: var(--text-muted); font-size: .84rem; }

/* Arborescence : un département dépliable, puis ses catégories en retrait.
   Fermé par défaut — le corps ne s'affiche qu'une fois le groupe ouvert. */
.rail__group { display: flex; flex-direction: column; }
.rail__group + .rail__group { margin-top: .35rem; border-top: 1px solid var(--border); padding-top: .35rem; }

.rail__group-body { display: none; flex-direction: column; }
.rail__group.is-open .rail__group-body { display: flex; }

.rail__chevron { flex: 0 0 auto; transition: transform .15s ease; color: var(--text-muted); }
.rail__group.is-open .rail__chevron { transform: rotate(90deg); }
.rail__item--head.is-active .rail__chevron { color: #fff; }

/* En-tête « libellé » : tout le bandeau est le bouton de dépliage. */
.rail__group-head {
    display: flex; align-items: center; gap: .35rem;
    width: 100%; padding: .5rem .6rem;
    border: 0; background: none; cursor: pointer;
    font-family: inherit; font-size: .7rem; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted);
    text-align: left;
}
.rail__group-head span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__group-head:hover { background: var(--surface-2); border-radius: 10px; }

/* En-tête « fourre-tout » : petit chevron à gauche, le nom reste un filtre. */
.rail__toggle {
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 26px; height: 32px; margin-left: .1rem;
    border: 0; background: none; cursor: pointer; color: inherit;
}
.rail__head-btn .rail__name {
    font-size: .72rem; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-muted);
}
.rail__item--head.is-active .rail__name { color: #fff; }

.rail__group-body .rail__item .rail__pick { padding-left: 1.5rem; }
.rail__group-body .rail__item.is-active .rail__pick {
    padding-left: calc(1.5rem - 3px); border-left: 3px solid #fff;
}

.rail__item {
    display: flex; align-items: center; gap: .4rem;
    border-radius: 10px;
    transition: background .14s ease;
}
.rail__item:hover { background: var(--surface-2); }
.rail__item.is-active { background: var(--brand-600); }
.rail__item.is-active .rail__name,
.rail__item.is-active .rail__detail,
.rail__item.is-active .rail__count { color: #fff; }
.rail__item.is-active .rail__count { background: rgba(255, 255, 255, .2); }

.rail__pick {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; gap: .1rem;
    padding: .55rem .6rem;
    border: 0; background: none; cursor: pointer;
    font-family: inherit; text-align: left;
}
.rail__pick--static { cursor: default; }
.rail__pick:focus-visible { outline: 2px solid var(--brand-600); outline-offset: -2px; border-radius: 10px; }

.rail__name {
    font-size: .88rem; font-weight: 600; color: var(--text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail__detail {
    font-size: .72rem; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail__count {
    flex: 0 0 auto;
    min-width: 26px; padding: .1rem .4rem;
    border-radius: 999px; background: var(--surface-2);
    color: var(--text-muted); font-size: .72rem; font-weight: 700;
    text-align: center; font-variant-numeric: tabular-nums;
}
.rail__edit {
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 32px; height: 32px; margin-right: .25rem;
    border: 0; border-radius: 8px; background: none;
    color: var(--text-muted); cursor: pointer;
}
.rail__edit:hover { background: var(--surface); color: var(--brand-600); }
.rail__item.is-active .rail__edit { color: #fff; }
.rail__item.is-active .rail__edit:hover { background: rgba(255, 255, 255, .18); color: #fff; }
.rail__edit:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 1px; }

/* Grille de produits : mêmes proportions que les vignettes du comptoir. */
.pgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
    gap: .75rem;
    padding: .9rem;
}

.pcard {
    display: flex; flex-direction: column;
    border: 1px solid var(--border); border-radius: 14px;
    background: var(--surface); overflow: hidden;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
    transition: box-shadow .16s ease, transform .12s ease, border-color .16s ease;
}
.pcard:hover { border-color: var(--brand-500); box-shadow: var(--shadow); transform: translateY(-2px); }

/* Produit hors service : atténué, jamais caché — c'est souvent celui qu'on
   vient réactiver. */
.pcard.is-off { opacity: .62; }

.pcard__media {
    width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
    background: var(--surface-2);
}
.pcard__media--flat {
    position: relative;
    display: grid; place-items: center;
    background: var(--tile, #e2e8f0);
    color: #fff; font-size: 2.2rem; font-weight: 700;
}

/* L'absence d'image est dite, pas seulement suggérée : c'est ce qui se
   remarque le moins et se corrige le plus vite. */
.pcard__noimage {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: .18rem 0;
    background: rgba(15, 23, 42, .45);
    color: #fff; font-size: .62rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .07em; text-align: center;
}

.pcard__body { display: flex; flex-direction: column; gap: .12rem; padding: .7rem .75rem .55rem; }
.pcard__cat {
    font-size: .64rem; font-weight: 700; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .07em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pcard__name { font-size: .92rem; font-weight: 600; line-height: 1.25; }
.pcard__sku { font-size: .68rem; color: var(--text-muted); }
.pcard__price {
    margin-top: .3rem;
    font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.pcard__currency { font-size: .72rem; font-weight: 600; color: var(--text-muted); }
.pcard__tags { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .35rem; }
.pcard__tags:empty { display: none; }

.pcard__actions {
    display: flex; gap: .35rem; margin-top: auto;
    padding: .55rem .6rem;
    border-top: 1px solid var(--border); background: var(--surface-2);
}
.pcard__actions .btn { flex: 1; }

@media (prefers-reduced-motion: reduce) {
    .pcard, .rail__item { transition: none; }
    .pcard:hover { transform: none; }
}

/* ------------------------------------------------------ Image d'un produit ---
   L'aperçu est de la taille de la vignette du poste de vente : ce qu'on voit
   ici est ce que le caissier verra, cadrage compris. */

.uploader { display: flex; align-items: flex-start; gap: .9rem; }
.uploader__preview {
    flex: 0 0 auto;
    display: grid; place-items: center; overflow: hidden;
    width: 104px; height: 104px;
    border: 1px dashed var(--border); border-radius: 12px;
    background: var(--surface-2);
}
.uploader__preview img { width: 100%; height: 100%; object-fit: cover; }
.uploader__empty { font-size: .72rem; color: var(--text-muted); text-align: center; padding: 0 .4rem; }
.uploader__actions { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .35rem; align-items: flex-start; }

/* Vignette dans une liste : elle dit sans détour quels produits n'ont pas
   encore d'image. */
.cell-media { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.thumb {
    flex: 0 0 auto;
    width: 38px; height: 38px; border-radius: 9px; object-fit: cover;
    background: var(--surface-2);
}
.thumb--empty {
    display: grid; place-items: center;
    color: var(--text-muted); font-weight: 700; font-size: .95rem;
}
.permission-module { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.permission-module__header { background: var(--surface-2); padding: .55rem .8rem; font-weight: 600; font-size: .8rem; display: flex; justify-content: space-between; align-items: center; }
.permission-module__body { padding: .6rem .8rem; display: grid; gap: .15rem; }

/* -------------------------------------------------------- Plan d'occupation */

.rack th, .rack td { padding: .4rem .35rem; text-align: center; }
.rack__room { text-align: left !important; white-space: nowrap; min-width: 130px; position: sticky; left: 0; background: var(--surface); z-index: 1; }
.rack__date { font-size: .68rem; line-height: 1.15; min-width: 42px; }
.rack__cell { height: 34px; min-width: 42px; border-radius: 4px; }
.rack__cell--free     { background: #f8fafc; }
.rack__cell--booked   { background: #bfdbfe; }
.rack__cell--occupied { background: #86efac; }
.rack__legend { display: flex; gap: 1.2rem; padding: .8rem 1rem; font-size: .78rem; color: var(--text-muted); flex-wrap: wrap; }
.rack__swatch { display: inline-block; width: 14px; height: 14px; border-radius: 3px; vertical-align: -2px; margin-right: .3rem; border: 1px solid var(--border); }

/* ------------------------------------------------------------ Sélecteur client */

.picker { position: relative; }
.picker__results {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 20;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg); max-height: 260px; overflow-y: auto; display: none;
}
.picker__results.is-open { display: block; }
.picker__item { padding: .55rem .75rem; cursor: pointer; font-size: .86rem; }
.picker__item:hover { background: var(--surface-2); }
.picker__selected { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .6rem .75rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); }

.room-option { display: flex; align-items: center; gap: .7rem; padding: .5rem .65rem; border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: .4rem; }
.room-option input { width: 18px; height: 18px; }
.room-option__rate { margin-left: auto; display: flex; align-items: center; gap: .4rem; }
.room-option__rate .input { width: 110px; min-height: 34px; padding: .3rem .5rem; }

/* ============================================================================
   TABLEAU DE BORD — poste de commande
   Direction « Data-Dense Dashboard » sur trame Bento : fond sombre, tuiles de
   tailles inégales, chiffres en chasse tabulaire, couleurs d'état toujours
   doublées d'un libellé. Tout est portée par .dash : le reste de l'application
   conserve son identité claire.
   ========================================================================= */

/* Les briques dash__* servent aussi à la carte de comparaison de la page
   Rapports : le jeu de jetons est partagé, sinon les couleurs y seraient
   indéfinies et le texte perdrait son contraste. */
.dash, .cmp-card {
    --d-bg:        #ffffff;
    --d-tile:      #ffffff;
    --d-tile-2:    #f1f5f9;
    --d-line:      #e2e8f0;
    --d-text:      #0f172a;
    --d-muted:     #64748b;   /* 4.8:1 sur fond blanc */
    --d-accent:    #2563eb;
    --d-ok:        #15803d;
    --d-warn:      #b45309;
    --d-danger:    #be123c;
    --d-violet:    #7c3aed;

    color: var(--d-text);
}

.dash {
    background: var(--d-bg);
    border-radius: 20px;
    padding: 1.1rem;
    margin: -.3rem 0 0;
}

/* ------------------------------------------------------- Accès rapide */

/* Points de vente : rectangles pleins, angles vifs, une couleur par domaine.
   Le texte est blanc sur des fonds vérifiés à 4,5:1 minimum. */

.dash__stamp-row { display: flex; justify-content: flex-end; margin-bottom: .5rem; }

.dash__quick {
    display: flex; flex-wrap: wrap;
    gap: .55rem;
    margin-bottom: 1.1rem;
}

.dash__quick-item {
    position: relative;
    /* Le montant du jour s'ajoute au nom : la carte s'élargit un peu, mais
       elle doit surtout rester sur une seule rangée. Elle s'étire donc pour
       remplir la ligne et se resserre quand la place manque, sans descendre
       sous la largeur où un chiffre se couperait. */
    flex: 1 1 168px;
    max-width: 260px;
    display: flex; flex-direction: row; align-items: center;
    gap: .6rem;
    padding: .7rem .8rem;
    min-height: 70px;
    overflow: hidden;
    border-radius: 10px;
    border: 0;
    color: #fff;
    background: var(--q-tone);     /* couleur pleine, sans dégradé */
    box-shadow: 0 1px 2px rgba(15, 23, 42, .10);
    transition: transform .14s ease, box-shadow .18s ease, filter .18s ease;
}

/* Liseré clair à gauche : rappelle la couleur sans alourdir la carte. */
.dash__quick-item::before {
    content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
    background: rgba(255, 255, 255, .45);
}
/* Icône filigrane : décorative, masquée aux lecteurs d'écran. */
.dash__quick-ghost {
    position: absolute; right: -14px; bottom: -18px;
    line-height: 0; opacity: .17; pointer-events: none;
    transition: transform .25s ease, opacity .25s ease;
}
.dash__quick-ghost .icon { width: 82px; height: 82px; color: #fff; }

.dash__quick-badge {
    position: relative; z-index: 1;
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px;
    background: rgba(255, 255, 255, .20);
    border-radius: 4px;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28);
}
.dash__quick-badge .icon { color: #fff; }
/* Le chevron sort du flux : il ne fait qu'indiquer qu'on peut cliquer, et la
   carte entière est déjà un lien. Lui laisser une colonne prenait la place du
   nom — « Chambres » s'y coupait en « Chamb… ». */
.dash__quick-go {
    position: absolute; right: .5rem; top: 50%;
    transform: translateY(-50%);
    z-index: 1; opacity: .45;
    transition: transform .18s ease, opacity .18s ease;
}

/* Le nom et le chiffre s'empilent : la carte reste une porte, mais elle dit
   aussi ce qui s'est passé derrière. */
.dash__quick-text {
    position: relative; z-index: 1;
    display: flex; flex-direction: column; gap: .1rem;
    min-width: 0; flex: 1;
    padding-right: 1.1rem;   /* la place du chevron, qui flotte au-dessus */
}
.dash__quick-label {
    font-size: .96rem; font-weight: 600; line-height: 1.15; letter-spacing: .01em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Le montant, en blanc translucide : lisible sans voler la vedette au nom du
   point de vente, qui reste ce qu'on vise du doigt. */
.dash__quick-figure {
    font-size: .82rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: rgba(255, 255, 255, .88);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.dash__quick-item:hover {
    text-decoration: none;
    transform: translateY(-2px);
    filter: brightness(1.06);
    box-shadow: 0 10px 18px -10px var(--q-tone);
}
.dash__quick-item:hover .dash__quick-ghost { transform: translate(-4px, -4px) scale(1.06); opacity: .24; }
.dash__quick-item:hover .dash__quick-go { opacity: 1; transform: translate(3px, -50%); }
.dash__quick-item:active { transform: translateY(0); }
.dash__quick-item:focus-visible { outline: 3px solid var(--d-text); outline-offset: 2px; }

.dash__quick-item--bar    { --q-tone: #6d28d9; }
.dash__quick-item--room   { --q-tone: #1d4ed8; }
.dash__quick-item--pool   { --q-tone: #0e7490; }
.dash__quick-item--casino { --q-tone: #be123c; }
.dash__quick-item--rental { --q-tone: #15803d; }

@media (prefers-reduced-motion: reduce) {
    .dash__quick-item, .dash__quick-ghost, .dash__quick-go { transition: none; }
    .dash__quick-item:hover { transform: none; }
    .dash__quick-item:hover .dash__quick-ghost { transform: none; }
    .dash__quick-item:hover .dash__quick-go { transform: none; }
}

.dash__stamp {
    display: inline-flex; align-items: center; gap: .4rem;
    color: var(--d-muted); font-size: .8rem;
}

/* ------------------------------------------------------- Trame Bento */

.dash__grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: .75rem;
}

.dash__tile {
    background: var(--d-tile);
    border: 1px solid var(--d-line);
    border-radius: 18px;
    padding: 1.05rem 1.15rem;
    display: flex; flex-direction: column; gap: .5rem;
    min-width: 0;
    position: relative;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 18px rgba(15, 23, 42, .05);
}

.dash__tile--hero    { grid-column: span 7; grid-row: span 2; }
.dash__tile--ring    { grid-column: span 5; }
.dash__tile--cash    { grid-column: span 5; }
.dash__tile--kpi     { grid-column: span 3; gap: .3rem; }
.dash__tile--bars    { grid-column: span 5; }
.dash__tile--methods { grid-column: span 4; }
.dash__tile--feed    { grid-column: span 3; }
.dash__tile--net     { grid-column: span 12; }

.dash__tile-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: .6rem;
}
.dash__tile-title {
    font-size: .78rem; font-weight: 500; letter-spacing: .07em;
    text-transform: uppercase; color: var(--d-muted);
}
.dash__link { color: var(--d-accent); font-size: .78rem; }
.dash__link:hover { text-decoration: underline; }
.dash__muted { color: var(--d-muted); font-size: .82rem; }
.dash__empty { color: var(--d-muted); font-size: .85rem; margin: .4rem 0; }

/* --------------------------------------------------------- Chiffres */

.dash__figure { display: flex; align-items: baseline; gap: .5rem; margin-top: .2rem; }
.dash__figure-value {
    font-size: 2.9rem; font-weight: 600; line-height: 1;
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.dash__figure-value.is-negative { color: var(--d-danger); }
.dash__figure-unit { color: var(--d-muted); font-size: .95rem; }
.dash__figure--sm .dash__figure-value { font-size: 1.7rem; }

.dash__delta-row { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.dash__delta {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .2rem .6rem; border-radius: 999px;
    font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums;
}
.dash__delta--up   { background: #dcfce7; color: var(--d-ok); }
.dash__delta--down { background: #ffe4e6; color: var(--d-danger); }
.dash__delta--flat { background: var(--d-tile-2); color: var(--d-muted); }

.dash__spark { width: 100%; height: 92px; margin-top: auto; display: block; }
.dash__caption { color: var(--d-muted); font-size: .74rem; }

/* --------------------------------- Comparaison de CA (page Rapports)
   La carte réutilise les briques du tableau de bord (chiffre, écart, encadrés,
   barre de répartition) : un seul jeu de styles pour un seul concept. */

.cmp {
    display: grid;
    grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
    gap: 1.2rem;
    align-items: start;
    margin-bottom: 1rem;
}
.cmp__main { display: flex; flex-direction: column; gap: .45rem; }
.cmp .dash__takings { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-top: 0; }

/* Courbe de tendance du CA dans la carte de comparaison. */
.cmp__spark { margin-top: .4rem; }
.cmp__spark svg { width: 100%; height: 64px; display: block; }

/* Graphique du rapport détaillé — juste sous l'en-tête de la carte, avant le tableau. */
.rep-chart { padding: 1rem 1.15rem 1.15rem; border-bottom: 1px solid var(--border); }
.rep-chart__head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; margin-bottom: .8rem; }
.rep-chart__title { font-size: .82rem; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--text-muted); }
.rep-chart__sub { font-size: .74rem; color: var(--text-muted); }

@media (max-width: 860px) {
    .cmp { grid-template-columns: 1fr; gap: .9rem; }
}

/* ------------------------------------- Sélecteur de période du CA */

.dash__periods {
    display: inline-flex; align-self: flex-start;
    padding: 3px; gap: 2px;
    background: var(--d-tile-2);
    border: 1px solid var(--d-line);
    border-radius: 10px;
}
.dash__period {
    min-height: 32px; padding: .3rem .8rem;
    border: 0; border-radius: 7px;
    background: transparent;
    color: var(--d-muted);
    font-family: inherit; font-size: .82rem; font-weight: 500;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.dash__period:hover { color: var(--d-text); background: rgba(15, 23, 42, .05); }
.dash__period.is-active {
    background: var(--d-tile);
    color: var(--d-text);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .10);
}
.dash__period:focus-visible { outline: 2px solid var(--d-accent); outline-offset: 1px; }

/* ------------------------------------- Encaissé / commandes du jour */

.dash__takings {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .55rem; margin-top: .35rem;
}
.dash__take {
    display: flex; flex-direction: column; gap: .18rem;
    padding: .6rem .75rem;
    background: var(--d-tile-2);
    border: 1px solid var(--d-line);
    border-radius: 10px;
}
.dash__take-label {
    display: inline-flex; align-items: center; gap: .35rem;
    color: var(--d-muted); font-size: .74rem;
    text-transform: uppercase; letter-spacing: .06em;
}
.dash__take-label .icon { color: var(--d-muted); }
.dash__take-value {
    font-size: 1.28rem; font-weight: 600; line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.dash__take-value small {
    font-size: .74rem; font-weight: 400; color: var(--d-muted);
    margin-left: .3rem; letter-spacing: 0;
}

/* -------------------------- Répartition des entrées (barre empilée) */

.dash__split { display: flex; flex-direction: column; gap: .45rem; margin-top: .55rem; }
.dash__split-title {
    font-size: .74rem; font-weight: 500; letter-spacing: .06em;
    text-transform: uppercase; color: var(--d-muted);
}
.dash__split-bar {
    display: flex; width: 100%; height: 14px;
    border-radius: 7px; overflow: hidden;
    background: var(--d-tile-2);
}
.dash__split-seg { display: block; height: 100%; min-width: 2px; }
.dash__split-seg + .dash__split-seg { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .55); }

.dash__split-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: .18rem; }
.dash__split-item {
    display: grid;
    grid-template-columns: 10px minmax(0, 1fr) auto auto;
    align-items: center; gap: .5rem;
    font-size: .8rem;
}
/* Sans permission financière la colonne des montants disparaît : la grille
   se referme sur trois colonnes au lieu de laisser un trou. */
.dash__split-item--nomoney { grid-template-columns: 10px minmax(0, 1fr) auto; }
.dash__split-dot { width: 10px; height: 10px; border-radius: 3px; }
.dash__split-name { color: var(--d-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash__split-amount { color: var(--d-text); font-variant-numeric: tabular-nums; font-weight: 500; }
.dash__split-share {
    color: var(--d-muted); font-variant-numeric: tabular-nums;
    min-width: 3.4rem; text-align: right;
}

/* ----------------------------------------------------------- Anneau */

.dash__ring-wrap { position: relative; display: grid; place-items: center; flex: 1; min-height: 132px; }
.dash__ring { width: 132px; height: 132px; transform: rotate(-90deg); }

/* L'anneau cède la place à la liste des chambres : il résume, elle détaille. */
.dash__ring-wrap--sm { flex: 0 0 auto; min-height: 0; margin: .2rem 0 .1rem; }
.dash__ring-wrap--sm .dash__ring { width: 96px; height: 96px; }
.dash__ring-wrap--sm .dash__ring-figure { font-size: 1.35rem; }

/* --------------------------------------------- Chambres en direct (tuile) ---
   Une ligne par chambre : pastille d'état, numéro, état, chronomètre. Le
   chronomètre est en chasse fixe, sinon la ligne tremble à chaque seconde. */

.dash__live {
    display: inline-flex; align-items: center; gap: .35rem;
    color: var(--d-muted); font-size: .72rem;
    text-transform: uppercase; letter-spacing: .06em;
}
.dash__live-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--d-ok);
    animation: pulse 2.4s ease-in-out infinite;
}
.is-stale .dash__live-dot { background: var(--d-danger); animation: none; }
.is-stale .dash__live { color: var(--d-danger); }

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}

.rooms {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: 2px;
    max-height: 216px; overflow-y: auto;
}
.rooms__item {
    display: grid;
    grid-template-columns: 8px 4.2rem minmax(0, 1fr) auto;
    align-items: center; gap: .55rem;
    padding: .42rem .5rem;
    border-radius: 8px;
    font-size: .82rem;
}
.rooms__item:nth-child(odd) { background: var(--d-tile-2); }

.rooms__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--d-muted); }
.rooms__number { font-weight: 600; font-variant-numeric: tabular-nums; }
.rooms__state { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rooms__state small { color: var(--d-muted); margin-left: .35rem; }
.rooms__timer {
    font-variant-numeric: tabular-nums;
    font-size: .82rem; color: var(--d-muted);
    min-width: 4.6rem; text-align: right;
}

/* Une couleur ne suffit jamais : l'état est aussi écrit en toutes lettres. */
.rooms__item--free     .rooms__dot { background: var(--d-ok); }
.rooms__item--free     .rooms__timer { color: var(--d-ok); }
.rooms__item--occupied .rooms__dot { background: var(--d-accent); }
.rooms__item--cleaning .rooms__dot { background: var(--d-warn); }
.rooms__item--reserved .rooms__dot { background: var(--d-violet); }
.rooms__item--out      .rooms__dot { background: var(--d-danger); }
.rooms__item--out      .rooms__state { color: var(--d-danger); }

/* Départ dépassé : le décompte est devenu un retard. */
.rooms__item.is-late .rooms__timer,
.rooms__item.is-overdue .rooms__timer { color: var(--d-danger); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
    .dash__live-dot { animation: none; }
}
.dash__ring-track { fill: none; stroke: var(--d-tile-2); stroke-width: 9; }
.dash__ring-value {
    fill: none; stroke: var(--d-accent); stroke-width: 9; stroke-linecap: round;
    transition: stroke-dasharray .5s ease;
}
.dash__ring-center { position: absolute; text-align: center; display: grid; gap: .1rem; }
.dash__ring-figure {
    font-size: 1.9rem; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1;
}
.dash__ring-figure small { font-size: .9rem; color: var(--d-muted); margin-left: .1rem; }

/* ------------------------------------------------------------ Caisse */

.dash__tile--cash.is-open    { border-left: 3px solid var(--d-ok); }
.dash__tile--cash.is-closed  { border-left: 3px solid var(--d-warn); }
.dash__state { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.dash__pill {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .25rem .65rem; border-radius: 999px;
    font-size: .78rem; font-weight: 600;
}
.dash__pill--ok   { background: #dcfce7; color: var(--d-ok); }
.dash__pill--warn { background: #fef3c7; color: var(--d-warn); }

.dash__actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: auto; padding-top: .6rem; }
.dash__btn {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .5rem .85rem; min-height: 44px;
    border-radius: 10px; border: 1px solid var(--d-line);
    background: var(--d-tile-2); color: var(--d-text);
    font-size: .85rem; font-weight: 500;
    transition: background .18s ease, border-color .18s ease;
}
.dash__btn:hover { text-decoration: none; border-color: var(--d-accent); background: #e8eefc; }
.dash__btn:focus-visible { outline: 2px solid var(--d-accent); outline-offset: 2px; }
.dash__btn--primary { background: var(--d-accent); border-color: var(--d-accent); color: #fff; }
.dash__btn--primary:hover { background: #1d4ed8; border-color: #1d4ed8; }

/* -------------------------------------------------------------- KPI */

.dash__tile--kpi { align-items: flex-start; }
.dash__kpi-icon {
    width: 38px; height: 38px; border-radius: 11px;
    display: grid; place-items: center; margin-bottom: .15rem;
}
.dash__kpi-icon--info    { background: #dbeafe; color: var(--d-accent); }
.dash__kpi-icon--warn    { background: #fef3c7; color: var(--d-warn); }
.dash__kpi-icon--ok      { background: #dcfce7; color: var(--d-ok); }
.dash__kpi-icon--neutral { background: #ede9fe; color: var(--d-violet); }
.dash__kpi-value {
    font-size: 2rem; font-weight: 600; line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ Barres */

.dash__bars { list-style: none; margin: .3rem 0 0; padding: 0; display: grid; gap: .65rem; }
.dash__bar { display: grid; grid-template-columns: 1fr 2fr auto; align-items: center; gap: .6rem; }
.dash__bar-label { font-size: .84rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash__bar-track { height: 8px; border-radius: 999px; background: var(--d-tile-2); overflow: hidden; }
.dash__bar-fill {
    display: block; height: 100%; border-radius: 999px;
    background: linear-gradient(90deg, var(--d-accent), var(--d-violet));
}
.dash__bar-value { font-size: .82rem; font-variant-numeric: tabular-nums; color: var(--d-muted); }

/* ------------------------------------------------- Moyens de paiement */

.dash__legend { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .4rem; }
.dash__legend li { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: .55rem; }
.dash__legend-label { font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash__legend-value { font-size: .82rem; font-variant-numeric: tabular-nums; }
.dash__legend-share { font-size: .76rem; color: var(--d-muted); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }

.dash__dot { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }
.dash__dot--0 { background: var(--d-accent); }
.dash__dot--1 { background: var(--d-violet); }
.dash__dot--2 { background: var(--d-ok); }
.dash__dot--3 { background: var(--d-warn); }

.dash__stack { display: flex; height: 10px; border-radius: 999px; overflow: hidden; margin-top: auto; }
.dash__stack-part { display: block; height: 100%; }

/* ------------------------------------------------------------ Journal */

.dash__feed { list-style: none; margin: .3rem 0 0; padding: 0; display: grid; gap: .55rem; }
.dash__feed li { display: grid; grid-template-columns: auto 1fr; gap: .6rem; align-items: start; }
.dash__feed-time { font-size: .76rem; color: var(--d-muted); font-variant-numeric: tabular-nums; padding-top: .1rem; }
.dash__feed-body { display: grid; gap: .1rem; min-width: 0; }
.dash__feed-action { font-size: .78rem; font-weight: 600; color: var(--d-accent); letter-spacing: .02em; }
.dash__feed-body .dash__muted {
    font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ------------------------------------------------------------ Détail */

.dash__breakdown { list-style: none; margin: .4rem 0 0; padding: 0; display: grid; gap: .35rem; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.dash__breakdown li {
    display: flex; justify-content: space-between; gap: .6rem;
    padding: .5rem .7rem; border-radius: 10px; background: var(--d-tile-2);
    font-size: .83rem;
}
.dash__breakdown li span:last-child { font-variant-numeric: tabular-nums; font-weight: 600; }

/* -------------------------------------------------------- Adaptatif */

@media (max-width: 1200px) {
    .dash__tile--hero    { grid-column: span 12; grid-row: span 1; }
    .dash__tile--ring,
    .dash__tile--cash    { grid-column: span 6; }
    .dash__tile--bars,
    .dash__tile--methods { grid-column: span 6; }
    .dash__tile--feed    { grid-column: span 12; }
}

@media (max-width: 760px) {
    .dash { padding: .8rem; border-radius: 16px; }
    .dash__grid { gap: .6rem; }
    .dash__quick { gap: .5rem; }
    .dash__quick-item { flex: 1 1 calc(50% - .25rem); min-height: 78px; }
    .dash__quick-ghost .icon { width: 70px; height: 70px; }
    .dash__tile { padding: .9rem 1rem; }
    .dash__tile--ring, .dash__tile--cash,
    .dash__tile--bars, .dash__tile--methods { grid-column: span 12; }
    .dash__tile--kpi { grid-column: span 6; }
    .dash__figure-value { font-size: 2.2rem; }
    .dash__bar { grid-template-columns: 1fr auto; }
    .dash__bar-track { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .dash__quick-item, .dash__ring-value { transition: none; }
    .dash__quick-item:hover { transform: none; }
}

@media print {
    .dash { background: #fff; color: #000; padding: 0; }
    .dash__tile { background: #fff; border-color: #ccc; }
    .dash__quick { display: none; }
}

/* ==================================================== Accès rapide caissier */

.launcher-head { display: flex; justify-content: flex-end; margin-bottom: .9rem; }

.launcher-session {
    display: flex; align-items: center; gap: .7rem;
    padding: .6rem .9rem; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface);
    font-size: .84rem; color: var(--text); min-height: 46px;
}
.launcher-session:hover { text-decoration: none; border-color: var(--brand-500); }
.launcher-session__meta { display: block; color: var(--text-muted); font-size: .78rem; }
.launcher-session--open { border-left: 4px solid var(--success); }
.launcher-session--open .icon { color: var(--success); }
.launcher-session--closed { border-left: 4px solid var(--warning); }
.launcher-session--closed .icon { color: var(--warning); }

.launcher {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: .75rem;
}

/* Cartes rectangulaires : icône et titre sur la même ligne, hauteur contenue. */
.launcher__card {
    display: flex; flex-direction: row; align-items: center;
    gap: .85rem;
    padding: .85rem 1rem;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow);
    color: var(--text);
    min-height: 74px;
    position: relative;
    overflow: hidden;
    transition: transform .1s ease, box-shadow .15s ease, border-color .15s ease;
}
.launcher__card::after {
    content: ''; position: absolute; inset: 0 auto 0 0; width: 4px;
    background: var(--launcher-tone, var(--brand-600));
}
.launcher__card:hover {
    text-decoration: none;
    border-color: var(--launcher-tone, var(--brand-500));
    box-shadow: 0 10px 28px rgba(15, 23, 42, .12);
    transform: translateY(-2px);
}
.launcher__card:active { transform: translateY(0); }

.launcher__icon {
    width: 44px; height: 44px; border-radius: 12px;
    display: grid; place-items: center; flex: 0 0 auto;
    background: var(--launcher-bg, #eef2ff);
    color: var(--launcher-tone, var(--brand-600));
}
.launcher__icon .icon { width: 23px; height: 23px; vertical-align: 0; }

.launcher__label {
    font-size: 1.08rem; font-weight: 600; line-height: 1.2;
    letter-spacing: .01em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Une couleur par domaine : le caissier reconnaît sa carte sans lire. */
.launcher__card--bar     { --launcher-tone: #7c3aed; --launcher-bg: #f5f3ff; }
.launcher__card--room    { --launcher-tone: #2563eb; --launcher-bg: #eff6ff; }
.launcher__card--pool    { --launcher-tone: #0891b2; --launcher-bg: #ecfeff; }
.launcher__card--casino  { --launcher-tone: #be123c; --launcher-bg: #fff1f2; }
.launcher__card--rental  { --launcher-tone: #15803d; --launcher-bg: #f0fdf4; }
.launcher__card--expense { --launcher-tone: #ea580c; --launcher-bg: #fff7ed; }

@media (max-width: 640px) {
    .launcher { grid-template-columns: 1fr; gap: .6rem; }
    .launcher__card { min-height: 66px; padding: .75rem .9rem; }
    .launcher__icon { width: 40px; height: 40px; }
    .launcher__icon .icon { width: 21px; height: 21px; }
    .launcher__label { font-size: 1.02rem; }
}

/* ================================================================== POS ==== */

/* ==========================================================================
   POSTE DE VENTE
   Plein écran, deux volets qui défilent séparément : le catalogue à gauche,
   le ticket à droite, toujours visible. La page elle-même ne défile jamais —
   c'est ce qui distingue un poste de caisse d'un site web.
   ========================================================================== */

.pos {
    --pos-ticket: 272px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--pos-ticket);
    gap: .9rem;
    /* Exactement la hauteur laissée par la barre du haut et le retrait du
       conteneur (.9rem + 1.2rem) : le volet du ticket, qui déborde de ce
       retrait, arrive alors pile au bas de la fenêtre. */
    height: calc(100vh - var(--topbar-height) - 2.1rem);
    min-height: 520px;
}

.pos__catalog {
    display: flex; flex-direction: column; gap: .7rem;
    min-width: 0; min-height: 0;
}

/* Barre de commande : navigation, recherche, table, tickets ouverts. */
.pos__bar { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }

.pos__nav {
    display: grid; place-items: center;
    width: 44px; height: 44px; flex: 0 0 auto;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text-muted); cursor: pointer;
}
.pos__nav:hover { color: var(--brand-600); border-color: var(--brand-500); }
.pos__nav:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

.pos__search {
    flex: 1 1 240px; min-width: 0;
    display: flex; align-items: center; gap: .5rem;
    height: 44px; padding: 0 .85rem;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface);
}
.pos__search .icon { color: var(--text-muted); }
.pos__search input {
    flex: 1; min-width: 0; height: 100%;
    border: 0; outline: 0; background: none;
    font-family: inherit; font-size: .92rem; color: var(--text);
}
.pos__search:focus-within { border-color: var(--brand-600); box-shadow: 0 0 0 3px rgba(35, 64, 127, .12); }

.pos__table { flex: 0 0 auto; width: auto; min-width: 150px; height: 44px; }

/* ------------------------------------------------- POS : onglet Chambre ---
   Le comptoir de chambre prend la place du catalogue, dans la même colonne et
   sans repousser le ticket. Son allure est propre au poste de vente : au
   comptoir on choisit d'un geste, on ne lit pas une fiche.

   Les formules glissent sur un rail horizontal — quatre aujourd'hui, huit
   demain, la ligne ne se casse jamais. Les chambres, elles, s'étalent en
   pastilles larges, l'état lisible à un mètre. */

.pos__rooms {
    flex: 1; min-height: 0;
    overflow-y: auto; padding: .15rem .35rem .8rem 0;
    /* Le défilement reste actif — souris, tactile, clavier — seule la barre
       disparaît : sur cet onglet, elle n'apporte rien que le caissier lise. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.pos__rooms::-webkit-scrollbar { display: none; }

/* En-tête collant : en descendant vers les chambres, on garde sous les yeux
   la formule retenue et le nombre de chambres vendables. Un léger dégradé la
   distingue du reste du comptoir — c'est la première chose que l'œil trouve
   en arrivant sur l'onglet. */
.pos__rooms-head {
    position: sticky; top: 0; z-index: 2;
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin-bottom: .85rem; padding: .7rem .9rem;
    border-radius: 0;
    border: 1px solid rgba(35, 64, 127, .08);
    background:
        linear-gradient(135deg, rgba(35, 64, 127, .05), rgba(35, 64, 127, 0) 60%),
        var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 10px 26px -20px rgba(15, 23, 42, .35);
}

.pos__rooms-title { display: flex; align-items: center; gap: .65rem; min-width: 0; }
.pos__rooms-badge {
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 38px; height: 38px;
    border-radius: 11px;
    background: linear-gradient(155deg, var(--brand-600), var(--brand-800));
    color: #fff;
    box-shadow: 0 6px 14px -8px rgba(35, 64, 127, .65);
}

/* Le compteur devient une pastille : un chiffre qui compte se lit mieux posé
   que perdu dans du texte courant. */
.pos__rooms-count {
    padding: .22rem .65rem; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--border);
    color: var(--text-muted); font-size: .74rem; font-weight: 600;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Étape 2 : une fois la chambre choisie, les formules s'ouvrent dans un
   panneau à part — pas au fil de la page. Le distinguer de la grille du
   dessus dit d'un coup d'œil qu'on est passé à l'étape suivante, et l'entrée
   lui est propre : un « dépli », pas le fondu des pastilles de chambre. */
.pos__rooms-step {
    position: relative;
    margin-top: 1.1rem; padding: .9rem 1rem 1rem;
    border-radius: 0;
    border: 1px solid rgba(35, 64, 127, .1);
    background: linear-gradient(180deg, rgba(35, 64, 127, .045), rgba(35, 64, 127, 0) 70%), var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 14px 30px -22px rgba(15, 23, 42, .45);
    animation: step-open .28s cubic-bezier(.2, .8, .3, 1) both;
}
.pos__rooms-step::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
    background: linear-gradient(90deg, var(--brand-600), var(--accent));
}
.pos__rooms-step .label { font-weight: 700; color: var(--brand-700); }

@keyframes step-open {
    from { opacity: 0; transform: translateY(-6px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .pos__rooms-step { animation: none; }
}

/* --------------------------------------------------------------- Folios ---
   Une carte par chambre plutôt qu'un tableau : au comptoir on cherche « la
   3 », pas une ligne. Le numéro de chambre porte donc la carte, le solde s'y
   lit en gros, et les deux gestes possibles sont au même endroit. */

.folios {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
    gap: .7rem;
}

.fcard {
    --ton: var(--text-muted);
    --ton-wash: rgba(100, 116, 139, .07);
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: .35rem;
    padding: .85rem .9rem .8rem;
    border-radius: 16px;
    border: 1px solid rgba(15, 23, 42, .05);
    background: linear-gradient(165deg, var(--ton-wash), rgba(0, 0, 0, 0) 65%), var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 10px 20px -18px rgba(15, 23, 42, .4);
    transition: box-shadow .15s ease, transform .12s ease;
    animation: rooms-in .28s ease both;
    animation-delay: calc(var(--rang, 0) * 35ms);
}
.fcard:hover { box-shadow: 0 14px 26px -16px rgba(15, 23, 42, .5); transform: translateY(-1px); }

/* Bandeau haut : l'état se voit avant d'être lu, et s'estompe vers la
   droite plutôt que de s'arrêter net — le même principe que les pastilles
   de chambre juste au-dessus, pour que les deux cartes se lisent comme un
   seul système. */
.fcard::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
    background: linear-gradient(90deg, var(--ton), transparent);
}

.fcard--due     { --ton: #b45309; --ton-wash: rgba(180, 83, 9, .08); }    /* une note court    */
.fcard--pending { --ton: #0e7490; --ton-wash: rgba(14, 116, 144, .08); }  /* un ticket est ouvert */
.fcard--clear   { --ton: #15803d; --ton-wash: rgba(21, 128, 61, .08); }   /* rien à réclamer   */

.fcard.is-chosen { box-shadow: 0 0 0 2px var(--ton), 0 12px 22px -14px rgba(15, 23, 42, .75); }

.fcard__top {
    display: flex; align-items: center; gap: .6rem; margin-top: .25rem;
    padding-bottom: .5rem; border-bottom: 1px dashed var(--border);
}

/* Le numéro de chambre est ce qu'on cherche : il est le repère de la carte.
   L'ombre reprend sa teinte — un léger relief, pas un aplat posé à plat. */
.fcard__room {
    flex: 0 0 auto;
    display: grid; place-items: center;
    min-width: 40px; height: 40px; padding: 0 .4rem;
    border-radius: 12px;
    background: var(--ton); color: #fff;
    box-shadow: 0 4px 10px -4px var(--ton);
    font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.fcard__who { min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.fcard__guest {
    font-size: .88rem; font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fcard__ref { font-size: .68rem; color: var(--text-muted); }

.fcard__amount {
    font-size: 1.55rem; font-weight: 700; line-height: 1.05;
    font-variant-numeric: tabular-nums;
}
.fcard__amount small { font-size: .66rem; font-weight: 700; margin-left: .3rem; color: var(--text-muted); }

.fcard__state { font-size: .72rem; color: var(--text-muted); }

/* Ce qui n'est pas encore sur la note : dit à part, sinon le solde grossirait
   sans explication au moment de l'imputation. */
.fcard__pending {
    align-self: flex-start;
    padding: .12rem .5rem; border-radius: 999px;
    background: rgba(14, 116, 144, .12); color: #0e7490;
    font-size: .72rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

.fcard__actions { display: flex; gap: .4rem; margin-top: .45rem; }
.fcard__actions .btn { flex: 1; }

@media (prefers-reduced-motion: reduce) {
    .fcard:hover { transform: none; }
}

/* La fiche de l'onglet Chambre est étroite, et cinq chambres doivent s'y
   lire sans que ça déborde trop : la carte se resserre — un peu moins qu'au
   départ, pour rester lisible — sans perdre ce qui compte : qui, combien,
   les deux gestes possibles. Portée à l'identifiant du conteneur, pas à la
   classe : la modale garde ses cartes à taille normale, où la place ne
   manque pas. */
#ticket-folios-body.folios { gap: .5rem; }
#ticket-folios-body .fcard { padding: .65rem .75rem .6rem; gap: .3rem; border-radius: 13px; }
#ticket-folios-body .fcard__top { gap: .55rem; margin-top: .05rem; padding-bottom: .4rem; }
#ticket-folios-body .fcard__room { min-width: 34px; height: 34px; border-radius: 10px; font-size: 1rem; }
#ticket-folios-body .fcard__guest { font-size: .86rem; }
#ticket-folios-body .fcard__ref { font-size: .66rem; }
#ticket-folios-body .fcard__amount { font-size: 1.3rem; }
#ticket-folios-body .fcard__amount small { font-size: .64rem; margin-left: .25rem; }
#ticket-folios-body .fcard__state,
#ticket-folios-body .fcard__pending { font-size: .68rem; padding: .08rem .45rem; }
#ticket-folios-body .fcard__actions { margin-top: .3rem; gap: .35rem; }
#ticket-folios-body .fcard__actions .btn {
    min-height: 32px; padding: .25rem .5rem; font-size: .78rem;
}

/* Bandeau : un ticket déjà composé attend qu'on lui choisisse une chambre. */
.pos__link-banner {
    display: flex; flex-direction: column; gap: .3rem;
    margin-bottom: .8rem; padding: .75rem .9rem;
    border-radius: 14px;
    background: linear-gradient(135deg, rgba(245, 158, 11, .14), rgba(245, 158, 11, .05));
    border: 1px solid rgba(245, 158, 11, .35);
}
.pos__link-banner strong { font-size: .92rem; color: var(--text); }
.pos__link-banner span { font-size: .78rem; color: var(--text-muted); }
.pos__link-banner #pos-link-cancel { align-self: flex-start; margin-top: .35rem; }

/* Règlement : il s'ouvre sous les cartes, une fois le folio choisi. */
.folio-pay {
    margin-top: .9rem; padding: .85rem .9rem;
    border-radius: 16px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.folio-pay__head { font-weight: 700; margin-bottom: .6rem; }
.folio-pay__form { display: flex; gap: .7rem; align-items: flex-end; flex-wrap: wrap; }
.folio-pay__form .form-group { flex: 1 1 150px; margin: 0; }
.folio-pay__form .btn { min-height: 44px; }

@media (prefers-reduced-motion: reduce) {
    .fcard { animation: none; }
}

/* ------------------------------------------------------------------ Reçu ---
   La note d'un client qui a consommé dans sa chambre. Colonne étroite,
   chiffres alignés à droite, police tabulaire : c'est un document qu'on lit
   ligne à ligne, pas un écran qu'on balaie. */

.receipt {
    max-width: 320px; margin: 0 auto;
    font-variant-numeric: tabular-nums;
}
.receipt__brand {
    display: flex; flex-direction: column; align-items: center; gap: .1rem;
    text-align: center; padding-bottom: .55rem;
    border-bottom: 1px dashed var(--border);
}
.receipt__brand strong { font-size: .98rem; letter-spacing: .02em; }
.receipt__brand span { font-size: .8rem; text-transform: uppercase; font-weight: 600; }
.receipt__logo { max-width: 55%; max-height: 90px; object-fit: contain; margin-bottom: .35rem; }

.receipt__head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .6rem; padding: .5rem 0;
    border-bottom: 1px dashed var(--border);
}
.receipt__head span { font-size: .74rem; color: var(--text-muted); }
.receipt__room { padding: .5rem 0; font-size: .8rem; color: var(--text-muted); }

.receipt__lines { list-style: none; margin: 0; padding: .3rem 0; }
.receipt__lines li {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .8rem; padding: .22rem 0; font-size: .84rem;
}
.receipt__lines small { color: var(--text-muted); margin-left: .3rem; }
.receipt__mod {
    display: block !important; padding: 0 0 .1rem .8rem !important;
    font-size: .74rem; color: var(--text-muted);
}

.receipt__total,
.receipt__balance {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .8rem; padding: .35rem 0;
}
.receipt__total {
    border-top: 1px dashed var(--border);
    font-size: 1.05rem; font-weight: 700;
}
.receipt__balance { font-size: .84rem; color: var(--text-muted); }
.receipt__note {
    margin: .6rem 0 0; padding-top: .5rem; font-size: .74rem; text-align: center;
    color: var(--text-muted); border-top: 1px dashed var(--border);
}

/* Reçu de vente imprimé sans modale : rendu hors écran, la feuille
   d'impression ci-dessous le ramène en place. */
.receipt--silent { position: fixed; left: -10000px; top: 0; width: 72mm; }

/* À l'impression, seul le reçu reste : le navigateur sert d'imprimante,
   sur une largeur de ticket. Pour du 80 mm, régler le format papier dans le
   pilote de l'imprimante ; le reste s'y adapte. */
@media print {
    @page { margin: 4mm; }
    body * { visibility: hidden; }
    #pos-receipt, #pos-receipt *,
    #ord-receipt, #ord-receipt *,
    #pos-sale-receipt, #pos-sale-receipt * { visibility: visible; }
    #pos-receipt, #ord-receipt, #pos-sale-receipt {
        position: absolute; inset: 0 auto auto 0; left: 0;
        width: 72mm; max-width: none; margin: 0; padding: 0;
        color: #000; font-size: 11px; line-height: 1.4;
        background: #fff; box-shadow: none; border-radius: 0;
    }
    .ojx__ticket { background: none; padding: 0; }
    #pos-receipt .receipt__brand, #ord-receipt .receipt__brand,
    #pos-sale-receipt .receipt__brand { border-color: #000; }
    #pos-receipt .receipt__head, #pos-receipt .receipt__total, #pos-receipt .receipt__note,
    #ord-receipt .receipt__head, #ord-receipt .receipt__total, #ord-receipt .receipt__note,
    #pos-sale-receipt .receipt__head, #pos-sale-receipt .receipt__total,
    #pos-sale-receipt .receipt__note { border-color: #000; }
    #pos-receipt small, #pos-receipt .receipt__brand span,
    #pos-receipt .receipt__head span, #pos-receipt .receipt__balance,
    #pos-receipt .receipt__mod, #pos-receipt .receipt__note,
    #ord-receipt small, #ord-receipt .receipt__brand span,
    #ord-receipt .receipt__head span, #ord-receipt .receipt__balance,
    #ord-receipt .receipt__mod, #ord-receipt .receipt__note,
    #pos-sale-receipt small, #pos-sale-receipt .receipt__brand span,
    #pos-sale-receipt .receipt__head span, #pos-sale-receipt .receipt__balance,
    #pos-sale-receipt .receipt__mod, #pos-sale-receipt .receipt__note { color: #000; }
    .modal-backdrop { position: static; background: none; }

    /* Relevé des ventes : document pleine page, imprimé depuis la page Commandes. */
    body.is-releve #ord-receipt, body.is-releve #ord-receipt * { visibility: hidden; }
    body.is-releve #ord-releve, body.is-releve #ord-releve * { visibility: visible; }
    body.is-releve #ord-releve {
        display: block; position: absolute; inset: 0 auto auto 0;
        width: 100%; margin: 0; padding: 0; color: #000;
        font-size: 11px; line-height: 1.45; background: #fff;
    }
    body.is-releve .releve__head { text-align: center; margin-bottom: .4rem; }
    body.is-releve .releve__head strong { display: block; font-size: 15px; letter-spacing: .04em; }
    body.is-releve .releve__head span { display: block; font-size: 10px; }
    body.is-releve .releve__title { font-size: 16px; margin: .3rem 0 .1rem; text-align: center; }
    body.is-releve .releve__meta,
    body.is-releve .releve__totals { display: flex; flex-wrap: wrap; gap: .2rem 1.4rem; margin: .5rem 0; }
    body.is-releve .releve__meta div,
    body.is-releve .releve__totals div { display: flex; flex-direction: column; }
    body.is-releve .releve__meta span,
    body.is-releve .releve__totals span { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #333; }
    body.is-releve .releve__totals { border: 1px solid #000; padding: .4rem .6rem; border-radius: 3px; }
    body.is-releve .releve__totals strong { font-size: 12px; }
    body.is-releve .releve__h2 { font-size: 12px; margin: .9rem 0 .3rem; border-bottom: 1px solid #000; }
    body.is-releve .releve__table { width: 100%; border-collapse: collapse; margin-top: .3rem; }
    body.is-releve .releve__table th,
    body.is-releve .releve__table td { border: 1px solid #999; padding: 2px 4px; text-align: left; }
    body.is-releve .releve__table thead th { background: #eee; font-size: 9px; text-transform: uppercase; }
    body.is-releve .releve__table tfoot th { background: #eee; }
    body.is-releve .releve__num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
    body.is-releve .releve__void td { text-decoration: line-through; color: #666; }
    body.is-releve .releve__table--dept { width: 60%; }
    body.is-releve thead { display: table-header-group; }
    body.is-releve tr { page-break-inside: avoid; }
    body.is-releve .releve__foot {
        margin-top: 1.6rem; padding-top: .5rem; border-top: 1px solid #000;
        display: flex; align-items: baseline; flex-wrap: wrap; gap: .1rem .5rem;
        page-break-inside: avoid;
    }
    body.is-releve .releve__foot span { font-size: 10px; color: #333; }
    body.is-releve .releve__foot strong { font-size: 13px; }
    body.is-releve .releve__foot .releve__sign {
        margin-left: auto; padding: 0 2.5rem; border-bottom: 1px solid #000;
        align-self: flex-end;
    }
}

/* Vendre ou réserver : deux gestes sur le même parc. L'interrupteur est
   toujours visible en tête de l'onglet — savoir lequel des deux on est en
   train de faire compte plus que le gagner d'un clic. */
.pos__mode {
    display: inline-flex; padding: 3px; gap: 2px;
    border-radius: 999px; background: var(--surface-2);
}
.pos__mode-btn {
    min-height: 34px; padding: .3rem .85rem;
    border: 0; border-radius: 999px;
    background: none; color: var(--text-muted);
    font-family: inherit; font-size: .82rem; font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.pos__mode-btn.is-active { background: linear-gradient(155deg, var(--brand-600), var(--brand-700)); color: #fff; box-shadow: 0 4px 12px -4px rgba(35, 64, 127, .55); }
.pos__mode-btn:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .pos__mode-btn { transition: none; }
}

/* ---- Formules : rail horizontal à défilement calé ---- */

.pos__rooms .plans {
    display: flex; gap: .6rem;
    padding: .2rem .2rem .5rem;
    overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
}

.pos__rooms .plan {
    flex: 0 0 212px;
    scroll-snap-align: start;
    gap: .25rem;
    padding: .8rem .85rem .7rem;
    border-color: transparent;
    border-radius: 0;
    background: rgba(var(--tone-rgb, 148, 163, 184), .07);
    box-shadow: none;
    animation: rooms-in .3s ease both;
    animation-delay: calc(var(--index, 0) * 40ms);
}
.pos__rooms .plan:hover {
    background: rgba(var(--tone-rgb, 148, 163, 184), .13);
    border-color: transparent;
    box-shadow: 0 8px 18px -12px rgba(15, 23, 42, .55);
}

/* Le bandeau devient un filet vertical : sur un rail, l'œil suit les bords. */
.pos__rooms .plan__band { inset: .8rem auto .7rem 0; width: 3px; height: auto; border-radius: 3px; }
.pos__rooms .plan__head { margin-top: 0; padding-left: .55rem; }
.pos__rooms .plan__price,
.pos__rooms .plan__desc,
.pos__rooms .plan__includes,
.pos__rooms .plan__foot { padding-left: .55rem; }

.pos__rooms .plan__price { font-size: 1.65rem; }
.pos__rooms .plan__desc {
    /* Deux lignes suffisent : le détail se lit sur l'écran Vente chambre. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; font-size: .74rem;
}
.pos__rooms .plan__includes { display: none; }

/* Formule retenue : la carte se remplit de sa teinte. Aucune ambiguïté sur
   ce qui est en cours de vente, même vu de loin. */
.pos__rooms .plan.is-chosen {
    background: var(--tone, var(--brand-600));
    box-shadow: 0 10px 22px -14px var(--tone, var(--brand-600));
}
.pos__rooms .plan.is-chosen .plan__band { background: var(--tone-ink-soft, rgba(255, 255, 255, .55)); }

/* L'encre est choisie par la luminance de la teinte, pas posée en blanc par
   défaut : une formule ambre remplie de blanc se devine au lieu de se lire. */
.pos__rooms .plan.is-chosen .plan__name,
.pos__rooms .plan.is-chosen .plan__price,
.pos__rooms .plan.is-chosen .plan__state--ok { color: var(--tone-ink, #fff); }
.pos__rooms .plan.is-chosen .plan__duration,
.pos__rooms .plan.is-chosen .plan__desc,
.pos__rooms .plan.is-chosen .plan__price small { color: var(--tone-ink-soft, rgba(255, 255, 255, .82)); }

/* ---- Chambres : pastilles larges, état lisible à un mètre ---- */

.pos__rooms .rooms-board {
    grid-template-columns: repeat(auto-fill, minmax(184px, 1fr));
    gap: .75rem;
}

.pos__rooms .rtile {
    position: relative; overflow: hidden;
    min-height: 126px; padding: .85rem .9rem .8rem;
    border: 0; border-radius: 0;
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 10px 20px -18px rgba(15, 23, 42, .4);
    transition: box-shadow .18s ease, transform .16s ease;
    animation: rooms-in .3s ease both;
    animation-delay: calc(var(--index, 0) * 30ms + 80ms);
}

/* Le filet de gauche devient un bandeau haut : la couleur porte plus loin,
   et s'estompe vers la droite plutôt que de s'arrêter net. */
.pos__rooms .rtile::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
    background: linear-gradient(90deg, var(--tone), transparent);
    z-index: 1;
}
.pos__rooms .rtile:hover { box-shadow: 0 16px 30px -18px rgba(15, 23, 42, .55); transform: translateY(-2px); }

/* Au comptoir la pastille est plus large et plus arrondie : la vignette suit
   son retrait, sinon elle laisserait une marge blanche sur les côtés. Une
   vraie photo respire légèrement au survol — sans photo, l'aplat de couleur
   gagne un souffle de lumière et une ombre portée, pour ne plus être un bloc
   plat posé sur la carte. */
.pos__rooms .rtile__photo {
    height: 96px;
    margin: -.85rem -.9rem .6rem;
    border-radius: 0;
    transition: transform .3s ease;
}
.pos__rooms .rtile:hover .rtile__photo:not(.rtile__photo--flat) { transform: scale(1.05); }

.pos__rooms .rtile__photo--flat {
    background:
        radial-gradient(140% 160% at 12% -20%, rgba(255, 255, 255, .32), rgba(255, 255, 255, 0) 55%),
        linear-gradient(200deg, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, .3)),
        var(--tone);
    font-size: 1.75rem; letter-spacing: .02em;
    text-shadow: 0 2px 6px rgba(0, 0, 0, .25);
}

.pos__rooms .rtile__top { margin-top: .05rem; }
.pos__rooms .rtile__number { font-size: 1.55rem; line-height: 1.05; }
.pos__rooms .rtile__type { font-size: .72rem; }

/* L'état devient une pastille : il se reconnaît à sa forme avant même d'être
   lu, comme le solde d'un folio ou le prix d'une formule. Chaque teinte est
   reprise en rgba à la main — une variable CSS hexadécimale ne se dilue pas
   toute seule. */
.pos__rooms .rtile__state {
    display: inline-flex; align-self: flex-start;
    padding: .12rem .5rem; margin-top: .1rem; border-radius: 999px;
    background: rgba(100, 116, 139, .12);
    font-size: .74rem; font-weight: 700;
}
.pos__rooms .rtile--free .rtile__state       { background: rgba(21, 128, 61, .12); }
.pos__rooms .rtile--occupied .rtile__state   { background: rgba(190, 18, 60, .12); }
.pos__rooms .rtile--reserved .rtile__state,
.pos__rooms .rtile--to_inspect .rtile__state { background: rgba(180, 83, 9, .12); }
.pos__rooms .rtile--cleaning .rtile__state   { background: rgba(14, 116, 144, .12); }
.pos__rooms .rtile--out .rtile__state        { background: rgba(71, 85, 105, .12); }

/* Le délai est le chiffre qu'on cherche : il sort du texte courant. */
.pos__rooms .rtile__free:not(:empty) {
    align-self: flex-start;
    padding: .16rem .5rem; border-radius: 999px;
    background: rgba(15, 23, 42, .06);
    font-size: .72rem; font-weight: 600; color: var(--text);
}
.pos__rooms .rtile.is-overdue .rtile__free:not(:empty) {
    background: rgba(220, 38, 38, .12); color: var(--danger);
}

.pos__rooms .rtile__guest {
    margin-top: auto; padding-top: .3rem;
    font-weight: 600; color: var(--text);
}

/* Chambre libre : la pastille s'annonce d'elle-même, et son point respire —
   c'est le seul signal que le caissier balaie vraiment du regard sur la
   grille entière avant de choisir. */
.pos__rooms .rtile--free { background: rgba(21, 128, 61, .05); }
.pos__rooms .rtile--free .rtile__dot {
    box-shadow: 0 0 0 4px rgba(21, 128, 61, .16);
    animation: rtile-pulse 2.6s ease-in-out infinite;
}

@keyframes rtile-pulse {
    0%, 100% { box-shadow: 0 0 0 4px rgba(21, 128, 61, .16); }
    50%      { box-shadow: 0 0 0 8px rgba(21, 128, 61, .07); }
}

/* Chambre invendable : montrée, jamais cliquable — le caissier doit pouvoir
   répondre au client sans changer d'écran. L'aplat perd de son éclat pour le
   dire sans un mot de plus. */
.pos__rooms .rtile.is-blocked { background: var(--surface-2); box-shadow: none; }
.pos__rooms .rtile.is-blocked:hover { box-shadow: none; transform: none; }
.pos__rooms .rtile.is-blocked .rtile__photo { filter: saturate(.7) brightness(.96); opacity: .9; }

/* Chambre retenue : c'est elle qu'on est en train de vendre, et les formules
   qui s'ouvrent en dessous la concernent. Le cerclage doit être posé ici et
   pas seulement sur « .rtile.is-chosen » : à spécificité égale, la règle
   d'onglet écrite plus bas dans la feuille l'emporterait et effacerait le
   cerclage en remettant l'ombre de repos. */
.pos__rooms .rtile.is-chosen {
    box-shadow: 0 0 0 2px var(--tone), 0 16px 28px -16px rgba(15, 23, 42, .6);
    transform: translateY(-2px);
}

@keyframes rooms-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .pos__rooms .plan, .pos__rooms .rtile { animation: none; }
    .pos__rooms .rtile, .pos__rooms .rtile__photo { transition: none; }
    .pos__rooms .rtile:hover, .pos__rooms .rtile.is-chosen { transform: none; }
    .pos__rooms .rtile--free .rtile__dot { animation: none; }
}

/* Grille de produits : seule zone qui défile à gauche. */
.pos__products {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
    /* Les lignes suivent la hauteur réelle des cartes. Sans ça, dans ce
       conteneur défilant à hauteur fixe, une carte flex dont la vignette porte
       une marge négative voit sa ligne se caler sur son min-height : le nom et
       la photo sont alors écrasés à zéro. */
    grid-auto-rows: max-content;
    gap: .6rem;
    overflow-y: auto; padding: .15rem .35rem .8rem 0;
    align-content: start; flex: 1; min-height: 0;
}

/* Menu à plusieurs rubriques (le Restaurant et ses sept sections, par
   exemple) : la grille cède la place à une colonne de rubriques, chacune
   gardant sa propre grille — comme la carte imprimée qu'on feuillette. */
.pos__products.pos__products--sectioned {
    display: flex; flex-direction: column; gap: 1.3rem;
}
.pos__section-title {
    display: flex; align-items: center; gap: .6rem;
    margin: 0 0 .55rem;
    font-size: .74rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .07em;
    color: var(--brand-600);
}
.pos__section-title::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.pos__products-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
    grid-auto-rows: max-content;
    gap: .6rem;
}
.pos__product {
    /* Couleur de l'action « Ajouter » et du compteur, assortie à la bordure
       bleu marine de la carte. */
    --pos-accent: #23407f;
    --pos-pad-x: .8rem;
    --pos-pad-y: .85rem;
    position: relative; overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--brand-600);
    border-radius: 0;
    padding: var(--pos-pad-y) var(--pos-pad-x); cursor: pointer; text-align: left; font-family: inherit;
    display: flex; flex-direction: column; gap: .2rem; min-height: 108px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
    transition: transform .1s ease, border-color .15s ease, box-shadow .15s ease;
}
.pos__product:hover { border-color: var(--brand-600); box-shadow: var(--shadow); transform: translateY(-2px); }
.pos__product:active { transform: scale(.97); }
.pos__product:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

/* Vignette : photo du produit, ou aplat de sa couleur avec son initiale.
   Elle occupe toute la largeur de la carte, bord à bord avec le contour :
   les marges négatives annulent le padding, sur les trois côtés du haut. */
.pos__product-photo {
    width: calc(100% + 2 * var(--pos-pad-x));
    height: 104px; object-fit: cover;
    margin: calc(-1 * var(--pos-pad-y)) calc(-1 * var(--pos-pad-x)) .55rem;
    border-radius: 0;
    background: var(--surface-2);
}
.pos__product-photo--flat {
    display: grid; place-items: center;
    background: var(--tile, #e2e8f0);
    color: #fff; font-size: 1.8rem; font-weight: 700;
    text-shadow: 0 1px 2px rgba(15, 23, 42, .25);
}

.pos__product-name {
    font-weight: 600; font-size: .9rem; line-height: 1.25;
    overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.pos__product-price {
    padding: .2rem 0 .5rem;
    font-weight: 700; font-size: 1.02rem; color: var(--text);
    font-variant-numeric: tabular-nums;
}
.pos__product-price small {
    margin-left: .3rem;
    font-size: .72rem; font-weight: 600; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .03em;
}
.pos__product-badge {
    position: absolute; top: 0; left: 0;
    padding: .14rem .45rem; border-radius: 0;
    background: var(--accent); color: #3b2200;
    font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}

/* Repère de stock, posé en haut à droite de la vignette, face au badge
   « options ». Vert tant que la réserve tient, jaune abricot quand la rupture
   approche, rouge à la rupture. */
.pos__product-stock {
    position: absolute; top: 0; right: 0; z-index: 1;
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .14rem .45rem; border-radius: 0;
    font-size: .68rem; font-weight: 700; font-variant-numeric: tabular-nums;
    background: rgba(255, 255, 255, .92); color: var(--text-muted);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .18);
}
.pos__product-stock-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.pos__product-stock--ok  { background: #dcfce7; color: #15803d; }
.pos__product-stock--low { background: #fce3c9; color: #9a4a06; }
.pos__product-stock--out { background: #fee2e2; color: #b91c1c; }

/* Action de la carte : « Ajouter », remplacé par le compteur dès que le
   produit est au ticket — corriger la quantité sans quitter la grille. */
.pos__product-add {
    display: flex; align-items: center; justify-content: center; gap: .35rem;
    margin-top: auto; padding: .6rem;
    border: 1px solid var(--pos-accent); border-radius: 0;
    background: var(--surface); color: var(--pos-accent);
    font-size: .84rem; font-weight: 700; text-align: center;
    transition: background .12s ease, color .12s ease;
}
.pos__product-add::before {
    content: '+'; font-size: 1.05rem; line-height: 1; font-weight: 700;
}
.pos__product:hover .pos__product-add,
.pos__product:active .pos__product-add { background: var(--pos-accent); color: #fff; }

.pos__stepper {
    display: grid; grid-template-columns: 40px 1fr 40px;
    align-items: stretch; margin-top: auto;
    border: 1px solid var(--pos-accent); border-radius: 0; overflow: hidden;
}
.pos__step {
    border: 0; background: var(--pos-accent); color: #fff;
    font-size: 1.2rem; line-height: 1; cursor: pointer;
    display: grid; place-items: center;
}
.pos__step:hover { filter: brightness(1.08); }
.pos__step:focus-visible { outline: 2px solid var(--brand-600); outline-offset: -2px; }
.pos__step-qty {
    display: grid; place-items: center;
    background: var(--surface); color: var(--pos-accent);
    font-weight: 700; font-size: .95rem; font-variant-numeric: tabular-nums;
}

.pos__product.is-chosen { border-color: var(--brand-600); box-shadow: 0 0 0 2px rgba(35, 64, 127, .28); }

/* Rupture de stock : la carte est verrouillée jusqu'au réapprovisionnement.
   Elle reste visible — le caissier doit pouvoir répondre au client — mais
   plus rien ne s'y ajoute. */
.pos__product.is-oos { cursor: not-allowed; border-style: dashed; }
.pos__product.is-oos:hover {
    transform: none; border-color: var(--brand-600);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}
.pos__product.is-oos .pos__product-photo,
.pos__product.is-oos .pos__product-name,
.pos__product.is-oos .pos__product-price { opacity: .45; }

.pos__product-add--blocked {
    border-color: var(--border);
    background: var(--surface-2); color: var(--text-muted);
    cursor: not-allowed;
}
.pos__product-add--blocked::before { display: none; }
.pos__product:hover .pos__product-add--blocked,
.pos__product:active .pos__product-add--blocked {
    background: var(--surface-2); color: var(--text-muted);
}

/* ------------------------------------------------ Règlement en tuiles */

/* Trois pastilles sur une ligne : elles choisissent, elles nagissent pas.
   Les tuiles carrees mangeaient un quart de la hauteur du ticket. */
.pos__methods {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: .25rem;
    padding: .25rem; background: var(--surface-2); border-radius: 10px;
}
.pos__method {
    display: flex; align-items: center; justify-content: center; gap: .3rem;
    min-height: 38px; padding: .35rem .3rem;
    border: 0; border-radius: 8px;
    background: transparent; color: var(--text-muted);
    font-family: inherit; font-size: .78rem; font-weight: 500; cursor: pointer;
}
.pos__method .icon { width: 15px; height: 15px; }
.pos__method.is-active { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(15, 23, 42, .1); }
.pos__method:disabled { opacity: .45; cursor: not-allowed; }
.pos__method:focus-visible { outline: 2px solid var(--success); outline-offset: 1px; }

/* L'action de sortie : pleine largeur, verte, impossible à manquer. */
.pos__place {
    min-height: 56px !important;
    background: var(--success) !important; border-color: var(--success) !important;
    font-size: 1rem; font-weight: 600;
}
.pos__place:disabled { opacity: .5; }


/* -------------------------------------------------------------- Ticket --- */

/* Le ticket n'est pas une carte posée sur la page : c'est un volet de
   l'écran. Il touche le bord droit et va du haut du contenu jusqu'au bas de
   la fenêtre — les marges négatives annulent le retrait du conteneur. Ni
   arrondi ni ombre : un angle rond au ras de l'écran ne fait que découper un
   coin de vide. */
.pos__ticket {
    background: var(--surface);
    border: 0; border-left: 1px solid var(--border);
    border-radius: 0; box-shadow: none;
    display: flex; flex-direction: column;
    min-height: 0; overflow: hidden;
    margin: -.9rem -1rem -1.2rem 0;
}
.pos__ticket-header {
    padding: .9rem 1rem;
    background: var(--brand-900); color: #fff;
}
.pos__ticket-header .badge { background: rgba(255, 255, 255, .16); color: #fff; }
.pos__ticket-header .muted { color: #94a3b8 !important; }

.pos__ticket-lines {
    flex: 1; overflow-y: auto; padding: .5rem; min-height: 100px;
    /* Le défilement reste actif si la fiche compte vraiment plus qu'un
       écran ; la barre, elle, n'apporte rien de plus que le contenu. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.pos__ticket-lines::-webkit-scrollbar { display: none; }
.pos__ticket-totals { padding: .8rem 1rem; border-top: 1px solid var(--border); background: var(--surface-2); }
.pos__ticket-actions { padding: .75rem; border-top: 1px solid var(--border); display: grid; gap: .45rem; }
.pos__ticket-actions .btn { min-height: 48px; }
.pos__pay-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .45rem; }

/* L'encaissement est l'action attendue : plus haute et plus lourde que le reste. */
.pos__pay { min-height: 56px !important; font-size: 1rem; font-weight: 600; }
.pos__danger { color: var(--danger); }

.pos__line {
    display: flex; gap: .5rem; align-items: baseline;
    padding: .5rem; border-radius: var(--radius-sm);
    border-bottom: 1px solid var(--border);
}
.pos__line:last-child { border-bottom: 0; }
.pos__line:hover { background: var(--surface-2); }
.pos__line.is-sent { opacity: .75; }

.pos__line-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.pos__line-name { font-size: .88rem; font-weight: 600; }

/* Quantité et prix unitaire sur la même ligne discrète, sous le nom :
   « 2 × 500,00 ». Le produit prime, le compteur l'accompagne. */
/* Ligne déjà portée à la note de la chambre : elle se lit comme un produit —
   c'est ce que le client doit — mais elle n'entre pas dans le total du ticket,
   qui reste ce qui reste à imputer. Le liseré et le fond la distinguent sans
   la reléguer. */
.pos__line--folio {
    background: rgba(35, 64, 127, .05);
    border-left: 3px solid var(--brand-500);
    border-radius: var(--radius-sm);
}
.pos__line--folio .pos__line-name { color: var(--brand-600); }

.pos__line-meta {
    font-size: .75rem; color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.pos__line-total { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pos__line-remove { background: none; border: 0; color: var(--text-muted); cursor: pointer; font-size: 1.1rem; padding: 0 .2rem; }
.pos__line-remove:hover { color: var(--danger); }

.pos__total-row { display: flex; justify-content: space-between; font-size: .85rem; padding: .15rem 0; }
.pos__total-row--grand {
    font-size: 1.6rem; font-weight: 700; padding-top: .5rem; margin-top: .35rem;
    border-top: 1px solid var(--border); font-variant-numeric: tabular-nums;
}
.pos__total-row--hint { font-size: .72rem; color: var(--text-muted); }

.pos__empty { text-align: center; color: var(--text-muted); padding: 2rem 1rem; font-size: .87rem; }

/* ------------------------------------------- Navigation rétractée (POS) ---
   Sur cette page la barre latérale glisse hors champ et le contenu prend
   toute la largeur. Elle revient par-dessus, sans repousser le catalogue :
   un poste de caisse ne doit pas se réorganiser sous les doigts. */

body[data-page="pos"] .sidebar { transform: translateX(-100%); box-shadow: none; }
body[data-page="pos"] .main { margin-left: 0; }
body[data-page="pos"] .content { padding: .9rem 1rem 1.2rem; }
body[data-page="pos"] .sidebar-toggle { display: none; }

/* On réutilise « is-open », le même interrupteur que la version mobile : un
   seul mécanisme de barre latérale dans toute l'application, déjà éprouvé. */
body[data-page="pos"] .sidebar.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
}

/* --------------------------------------- Navigation rétractée (Catalogue) ---
   L'arborescence des catégories et la grille de produits réclament toute la
   largeur. La barre latérale glisse hors champ ; le bouton menu de la barre
   du haut la ramène par-dessus (même interrupteur « is-open »). */
body[data-page="catalog"] .sidebar { transform: translateX(-100%); box-shadow: none; }
body[data-page="catalog"] .main { margin-left: 0; }
body[data-page="catalog"] .sidebar-toggle { display: block; }
body[data-page="catalog"] .sidebar.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
}

.pos__scrim {
    position: fixed; inset: 0; z-index: 39;
    background: rgba(15, 23, 42, .45);
    opacity: 0; transition: opacity .25s ease;
}
body[data-page="pos"].is-nav-open .pos__scrim { opacity: 1; }

@media (max-width: 1080px) {
    .pos { grid-template-columns: 1fr; height: auto; }
    .pos__products { overflow: visible; }

    /* En colonne, le ticket revient dans le flux : il se colle en bas de
       l'écran sur toute la largeur, sans déborder du conteneur. */
    .pos__ticket {
        position: sticky; bottom: 0; max-height: 60vh;
        margin: 0 -1rem -1.2rem;
        border-left: 0; border-top: 1px solid var(--border);
    }
}

@media (prefers-reduced-motion: reduce) {
    .sidebar, .pos__scrim, .pos__product { transition: none; }
    .pos__product:hover { transform: none; }
}

.kds { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.kds__card { background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--brand-600); border-radius: var(--radius); box-shadow: var(--shadow); }
.kds__card--preparing { border-left-color: var(--warning); }
.kds__card--ready { border-left-color: var(--success); }
.kds__header { padding: .7rem .9rem; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
.kds__body { padding: .8rem .9rem; }
.kds__item { font-size: 1.05rem; font-weight: 600; }
.kds__notes { font-size: .8rem; color: var(--warning); margin-top: .25rem; }
.kds__footer { padding: .6rem .9rem; border-top: 1px solid var(--border); display: flex; gap: .4rem; }
.kds__age { font-size: .75rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------- Graphiques (sans lib) --- */

.chart {
    display: flex; align-items: flex-end; gap: .5rem;
    height: 180px; padding: 1rem 1.15rem .4rem;
    border-bottom: 1px solid var(--border);
}
.chart__col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; min-width: 0; }
.chart__bar {
    width: 100%; max-width: 46px; border-radius: 6px 6px 0 0;
    background: linear-gradient(180deg, var(--brand-500), var(--brand-700));
    transition: opacity .15s ease;
}
.chart__col:hover .chart__bar { opacity: .8; }
.chart__label {
    font-size: .68rem; color: var(--text-muted); margin-top: .35rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

.sparkline { display: flex; align-items: flex-end; gap: 3px; height: 56px; }
.sparkline__bar { flex: 1; background: var(--brand-500); border-radius: 2px 2px 0 0; min-height: 2px; opacity: .85; }
.sparkline__bar:last-child { background: var(--accent); opacity: 1; }

.skeleton { background: linear-gradient(90deg, #eef2f7 25%, #f8fafc 50%, #eef2f7 75%); background-size: 200% 100%; animation: shimmer 1.3s infinite; border-radius: 6px; height: 14px; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

.sidebar-toggle { display: none; background: none; border: 0; font-size: 1.4rem; cursor: pointer; color: var(--text); padding: 0 .3rem; }

/* -------------------------------------------------------------- Responsive */

@media (max-width: 1024px) {
    .auth { grid-template-columns: 1fr; }
    .auth__side { display: none; }
}

@media (max-width: 900px) {
    .sidebar { transform: translateX(-100%); }
    .sidebar.is-open { transform: none; }
    .main { margin-left: 0; }
    .sidebar-toggle { display: block; }
    .content { padding: 1rem; }
    .topbar__clock { display: none; }
}

@media (max-width: 640px) {
    .page-header { flex-direction: column; align-items: stretch; }
    .toolbar .input, .toolbar .select { width: 100%; min-width: 0; }
    .user-menu__name, .user-menu__role { display: none; }
}

/* ============================================================ Dépenses ==== */
/* Un relevé : un seul feuillet, les dépenses regroupées par journée. */

.xp {
    --xp-exp: #dc2626;
    display: flex; flex-direction: column; gap: 1rem;
}

.xp__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.xp__head h1 { margin: 0; font-size: 1.5rem; }
.xp__sub { margin: .25rem 0 0; color: var(--text-muted); font-size: .88rem; max-width: 62ch; }
.xp__tools { display: flex; gap: .5rem; flex-wrap: wrap; }
.xp__tools .btn { display: inline-flex; align-items: center; gap: .4rem; }

/* -------------------------------------------------------------- Le feuillet */
.xp__sheet {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 16px; box-shadow: var(--shadow); overflow: hidden;
}

.xp__sheet-top {
    display: flex; align-items: flex-end; flex-wrap: wrap;
    gap: .7rem 1rem;
    padding: .9rem 1.3rem; border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.xp__range-field { display: flex; flex-direction: column; gap: .28rem; }
.xp__range-field > span {
    font-size: .72rem; font-weight: 600; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .03em;
}
.xp__range-field .select { min-width: 170px; }
.xp__range-field .input { width: 160px; }
.xp__range-label {
    align-self: center; margin-left: auto;
    font-size: .8rem; font-weight: 600; color: var(--text-muted);
    font-variant-numeric: tabular-nums; text-transform: capitalize;
}

/* Bandeau de synthèse */
.xp__balance {
    display: flex; align-items: center; flex-wrap: wrap; gap: .4rem 1.9rem;
    padding: 1.1rem 1.3rem;
    border-bottom: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}
.xp__bal-item { display: flex; flex-direction: column; gap: .05rem; }
.xp__bal-item > span { font-size: .72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
.xp__bal-item b { font-size: 1.35rem; font-weight: 700; }
.xp__bal-item b small { font-size: .62rem; font-weight: 600; color: var(--text-muted); }
.xp__bal-exp { color: var(--xp-exp); }
.xp__bal-net b { color: var(--brand-600); }
.xp__bal-net.is-negative b { color: var(--xp-exp); }
.xp__bal-pending {
    align-self: center; margin-left: auto;
    padding: .32rem .7rem; border-radius: 999px;
    background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
    font-size: .78rem; font-weight: 700;
}
.xp__bal-over {
    align-self: center; font-size: .78rem; font-weight: 700; color: var(--xp-exp);
}

/* Champ libre */
.xp__quick {
    display: grid;
    grid-template-columns: minmax(180px, 1fr) 140px 160px minmax(180px, 1.4fr) auto;
    gap: .55rem;
    padding: .9rem 1.3rem; border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.xp__quick .input, .xp__quick .select, .xp__quick .datefr { min-width: 0; }
.xp__quick-amount { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.xp__quick-cat--empty { color: var(--text-muted); }
.xp__quick-note--required { border-color: var(--warning); }
.xp__quick-note--required::placeholder { color: var(--warning); }
.xp__quick button[type="submit"] { white-space: nowrap; padding-inline: 1.3rem; }

.xp__filter { display: flex; flex-wrap: wrap; gap: .6rem; padding: .8rem 1.3rem; border-bottom: 1px solid var(--border); }
.xp__filter .select { max-width: 260px; }

/* -------------------------------------------------------- Relevé par jour */
.xp__days { display: flex; flex-direction: column; }
.xp__day + .xp__day { border-top: 1px solid var(--border); }
.xp__day-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: .8rem 1.3rem .5rem;
    font-size: .78rem; font-weight: 700; text-transform: capitalize;
    color: var(--text-muted);
}
.xp__day-total { color: var(--xp-exp); font-variant-numeric: tabular-nums; }
.xp__day-total small { font-size: .62rem; font-weight: 600; color: var(--text-muted); }

.xp__erow {
    display: grid;
    grid-template-columns: 10px 1fr auto auto auto;
    align-items: center; gap: .3rem 1rem;
    padding: .7rem 1.3rem;
}
.xp__erow + .xp__erow { border-top: 1px solid var(--surface-2); }
.xp__erow:hover { background: var(--surface-2); }
.xp__erow-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--border); }
.xp__erow--pending  .xp__erow-dot { background: var(--warning); }
.xp__erow--approved .xp__erow-dot { background: var(--info, #0284c7); }
.xp__erow--paid     .xp__erow-dot { background: var(--success); }
.xp__erow--rejected { opacity: .6; }
.xp__erow--rejected .xp__erow-dot { background: var(--danger); }
.xp__erow-body { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.xp__erow-desc { font-weight: 600; font-size: .9rem; }
.xp__erow-meta { font-size: .74rem; color: var(--text-muted); }
.xp__erow-amount { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.xp__erow-amount small { font-size: .64rem; font-weight: 600; color: var(--text-muted); }
.xp__erow-acts { display: flex; gap: .35rem; }
.xp__danger { color: var(--danger); }

.xp__pill { padding: .16rem .55rem; border-radius: 999px; font-size: .68rem; font-weight: 700; white-space: nowrap; }
.xp__pill--pending  { background: #fef3c7; color: #92400e; }
.xp__pill--approved { background: #e0f2fe; color: #075985; }
.xp__pill--paid     { background: #dcfce7; color: #166534; }
.xp__pill--rejected { background: #fee2e2; color: #b91c1c; }

.xp__empty { padding: 2.6rem 1rem; text-align: center; color: var(--text-muted); }
.xp__sheet .pagination { padding: .85rem 1.3rem; }

/* Historique par catégorie — page /expenses/history */
.xph__back { margin-bottom: .8rem; }
.xph__back-icon { transform: rotate(180deg); }

.xph__filters { display: flex; flex-wrap: wrap; gap: .9rem; align-items: flex-end; }
.xph__field { display: flex; flex-direction: column; gap: .3rem; }
.xph__field .label { margin: 0; }
.xph__field .select, .xph__field .input { min-width: 150px; }

/* Graphiques de la page */
.xph__loading { padding: 2.6rem 1.15rem; text-align: center; color: var(--text-muted); }
.xph__charts {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1.6rem 2.4rem; padding: 1.4rem 1.15rem;
}
.xph__chart-title {
    font-size: .78rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--text-muted); margin-bottom: .7rem;
}
.xph__chart .chart { padding: 0; border: 0; height: 150px; }
.xph__chart .chart__bar { background: linear-gradient(180deg, var(--brand-500), var(--brand-700)); }

.xph__cats { display: grid; gap: .55rem; }
.xph__cat { display: grid; grid-template-columns: minmax(0, 9rem) 1fr auto; align-items: center; gap: .7rem; }
.xph__cat-name { font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xph__cat-track { height: 12px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.xph__cat-fill { display: block; height: 100%; border-radius: 999px; background: var(--brand-500); min-width: 2px; }
.xph__cat-val { font-size: .8rem; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.xph__cat-val small { color: var(--text-muted); font-weight: 500; }

@media print {
    .xph__back { display: none !important; }
    .xph__charts { break-inside: avoid; }
}

.xp-catform { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.xp-catform__actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: .6rem; }

@media (max-width: 760px) {
    .xp__quick { grid-template-columns: 1fr 1fr; }
    .xp__quick button[type="submit"] { grid-column: 1 / -1; }
    .xp__erow {
        grid-template-columns: 10px 1fr auto;
        grid-template-areas: "dot body amount" ". pill pill" ". acts acts";
    }
    .xp__erow-dot { grid-area: dot; }
    .xp__erow-body { grid-area: body; }
    .xp__erow-amount { grid-area: amount; text-align: right; }
    .xp__pill { grid-area: pill; justify-self: start; margin-top: .3rem; }
    .xp__erow-acts { grid-area: acts; margin-top: .3rem; }
    .xp__balance { gap: .4rem 1.2rem; }
    .xp__bal-pending { margin-left: 0; }
}

/* ------------------------------------------ Suivi des chambres (/room-watch)
   Reprend le jeu de tuiles dash__* : même densité, même grille, même palette
   que le tableau de bord — c'est un écran de pilotage. */
.rwx__head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.15rem;
}
.rwx__title { font-size: 1.45rem; font-weight: 600; margin: 0; color: var(--d-text); }
.rwx__sub { margin: .2rem 0 0; color: var(--d-muted); font-size: .86rem; max-width: 46ch; }

.rwx__tile--wide { grid-column: span 7; }
.rwx__tile--side { grid-column: span 5; }
.rwx__tile--full { grid-column: span 12; }
@media (max-width: 1000px) {
    .rwx__tile--wide, .rwx__tile--side, .rwx__tile--full { grid-column: 1 / -1; }
}

.rwx__hero { display: flex; align-items: center; gap: 1.6rem; flex-wrap: wrap; margin: .3rem 0 .6rem; }
.rwx__figs {
    list-style: none; margin: 0; padding: 0; flex: 1; min-width: 190px;
    display: grid; grid-template-columns: 1fr 1fr; gap: .55rem 1.4rem;
}
.rwx__figs li { display: flex; flex-direction: column; }
.rwx__fig-val { font-size: 1.55rem; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; color: var(--d-text); }
.rwx__fig-lbl { font-size: .74rem; color: var(--d-muted); margin-top: .2rem; }

/* Occupation des prochaines nuits : une colonne par nuit. */
.rwx__nights {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: .5rem; align-items: end; height: 140px; margin-top: .7rem;
}
.rwx__night {
    display: flex; flex-direction: column; align-items: center; gap: .25rem;
    height: 100%; justify-content: flex-end;
}
.rwx__night-bar {
    width: 100%; max-width: 34px; border-radius: 5px 5px 0 0;
    background: linear-gradient(180deg, var(--d-accent), #1e40af);
    min-height: 4px;
}
.rwx__night-pct { font-size: .68rem; font-weight: 600; color: var(--d-muted); font-variant-numeric: tabular-nums; }
.rwx__night-day { font-size: .64rem; color: var(--d-muted); }

.rwx__filters { display: flex; gap: .5rem; }
.input--sm, .select--sm { height: 34px; font-size: .82rem; padding: .2rem .55rem; }

.rwx__table { margin-top: .4rem; }
.rwx__table th { background: transparent; }
.rwx__pill {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .12rem .5rem; border-radius: 999px;
    font-size: .74rem; font-weight: 600;
    color: var(--pc, var(--d-text));
    background: color-mix(in srgb, var(--pc, var(--d-muted)) 14%, transparent);
}
.rwx__pill::before {
    content: ""; width: 7px; height: 7px; border-radius: 50%;
    background: var(--pc, var(--d-muted));
}
.rwx__late { color: var(--d-danger); font-weight: 600; }
.rwx__wait { color: var(--d-warn); }

@media (max-width: 720px) {
    .rwx__figs { grid-template-columns: 1fr 1fr; }
    .rwx__nights { grid-auto-columns: minmax(24px, 1fr); overflow-x: auto; }
}

/* ============================================ Journal des commandes (/orders)
   Un registre : la journée en tête, une bande de chiffres, puis les ventes en
   lignes-fiches — repère de statut au bord gauche, montant qui domine à droite. */
.ojx {
    --o-ink:     #16233f;
    --o-muted:   #667085;
    --o-line:    #e7e9ef;
    --o-surface: #ffffff;
    --o-raise:   #f6f7fb;
    --o-brand:   #23407f;
    --o-paid:    #15803d;
    --o-unpaid:  #b45309;
    --o-room:    #1d4ed8;
    --o-void:    #94a3b8;
    color: var(--o-ink);
    display: flex; flex-direction: column; gap: 1.1rem;
}

.ojx__head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
}
.ojx__head h1 { font-size: 1.5rem; font-weight: 600; margin: 0; color: var(--o-ink); }
.ojx__head p { margin: .2rem 0 0; color: var(--o-muted); font-size: .86rem; }
.ojx__day { display: flex; flex-direction: column; gap: .25rem; }
.ojx__day span { font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--o-muted); }
.ojx__day input {
    border: 1px solid var(--o-line); border-radius: 10px;
    padding: .5rem .7rem; font: inherit; color: var(--o-ink); background: var(--o-surface);
}

/* Bande de synthèse : chiffres alignés, séparés par des filets. */
.ojx__band {
    display: flex; flex-wrap: wrap;
    background: var(--o-surface); border: 1px solid var(--o-line);
    border-radius: 16px; overflow: hidden;
    /* Les cartes restent sous les yeux quand la vue descend sur la liste :
       on peut cliquer d'une carte à l'autre sans remonter. */
    position: sticky; top: calc(var(--topbar-height) + .6rem); z-index: 15;
    box-shadow: 0 6px 18px -12px rgba(22, 35, 63, .35);
}
.ojx__stat {
    flex: 1 1 160px; min-width: 140px;
    padding: .95rem 1.15rem;
    border-right: 1px solid var(--o-line);
    display: flex; flex-direction: column; gap: .15rem;
    /* c'est un <button> : on remet à plat + on rend le clic évident */
    font: inherit; text-align: left; color: inherit;
    background: none; border-top: 0; border-bottom: 0; border-left: 0;
    cursor: pointer; position: relative; transition: background .12s ease;
}
.ojx__stat:last-child { border-right: 0; }
.ojx__stat:hover { background: var(--o-raise); }
.ojx__stat:focus-visible { outline: 2px solid var(--o-brand); outline-offset: -2px; }
.ojx__stat.is-active { background: color-mix(in srgb, var(--o-brand) 8%, transparent); }
.ojx__stat.is-active::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: var(--o-brand);
}
.ojx__stat.is-active .ojx__stat-lbl { color: var(--o-brand); font-weight: 600; }
.ojx__stat-val { font-size: 1.5rem; font-weight: 650; line-height: 1.05; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.ojx__stat-val small { font-size: .8rem; font-weight: 600; color: var(--o-muted); margin-left: .25rem; }
.ojx__stat-lbl { font-size: .74rem; color: var(--o-muted); }
.ojx__stat--hero .ojx__stat-val { color: var(--o-brand); font-size: 1.8rem; }

/* Filtres : compacts, sur une ligne. */
.ojx__toolbar { display: flex; flex-wrap: wrap; gap: .55rem; align-items: center; }
.ojx__search {
    position: relative; flex: 1 1 240px; min-width: 200px;
}
.ojx__search .icon {
    position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: var(--o-muted); pointer-events: none;
}
.ojx__search input {
    width: 100%; border: 1px solid var(--o-line); border-radius: 10px;
    padding: .55rem .7rem .55rem 2.1rem; font: inherit; color: var(--o-ink); background: var(--o-surface);
}
.ojx__toolbar select {
    border: 1px solid var(--o-line); border-radius: 10px;
    padding: .55rem .7rem; font: inherit; color: var(--o-ink); background: var(--o-surface);
}
.ojx__search input:focus, .ojx__toolbar select:focus, .ojx__day input:focus {
    outline: 2px solid var(--o-brand); outline-offset: 1px;
}
.ojx__print { margin-left: auto; display: inline-flex; align-items: center; gap: .35rem; }
.ojx__print .icon { width: 15px; height: 15px; }

/* Relevé imprimable : jamais à l'écran, seulement sous @media print. */
.releve { display: none; }
.releve-modal__presets { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }

/* La liste : une fiche cliquable par vente. */
.ojx__list { display: flex; flex-direction: column; gap: .4rem; }
.ojx__empty { padding: 2.6rem 1rem; text-align: center; color: var(--o-muted); }

.ojx__row {
    display: grid;
    grid-template-columns: 3px minmax(9rem, auto) 1fr auto;
    align-items: center; gap: 0 1rem;
    width: 100%; text-align: left;
    background: var(--o-surface); border: 1px solid var(--o-line);
    border-radius: 13px; padding: .7rem 1.1rem .7rem 0;
    font: inherit; color: inherit; cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.ojx__row:hover { border-color: color-mix(in srgb, var(--o-brand) 45%, var(--o-line)); box-shadow: 0 6px 18px -10px rgba(22, 35, 63, .25); }
.ojx__row:active { transform: translateY(1px); }
.ojx__row:focus-visible { outline: 2px solid var(--o-brand); outline-offset: 2px; }

.ojx__rail { align-self: stretch; border-radius: 13px 0 0 13px; background: var(--o-void); }
.ojx__row--paid   .ojx__rail { background: var(--o-paid); }
.ojx__row--unpaid .ojx__rail { background: var(--o-unpaid); }
.ojx__row--room   .ojx__rail { background: var(--o-room); }
.ojx__row--open   .ojx__rail { background: var(--o-brand); }

.ojx__id { display: flex; flex-direction: column; gap: .1rem; }
.ojx__num { font-family: var(--font-mono, ui-monospace, "SFMono-Regular", Menlo, monospace); font-weight: 700; font-size: .9rem; letter-spacing: -.01em; }
.ojx__time { font-size: .74rem; color: var(--o-muted); font-variant-numeric: tabular-nums; }

.ojx__meta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; min-width: 0; }
.ojx__chip {
    font-size: .72rem; font-weight: 600;
    padding: .12rem .5rem; border-radius: 999px;
    background: var(--o-raise); color: var(--o-muted);
    white-space: nowrap;
}
.ojx__where { font-size: .82rem; color: var(--o-ink); font-weight: 500; }
.ojx__who { font-size: .8rem; color: var(--o-muted); }

.ojx__right {
    display: grid; align-items: center; gap: .75rem;
    grid-template-columns: minmax(6rem, auto) 6.4rem 16px;
}
.ojx__total { font-size: 1.05rem; font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -.01em; text-align: right; }
.ojx__pill { justify-self: start; }
.ojx__row--void .ojx__total { text-decoration: line-through; color: var(--o-muted); font-weight: 500; }

.ojx__pill {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .72rem; font-weight: 650; white-space: nowrap;
    padding: .2rem .6rem; border-radius: 999px;
    background: color-mix(in srgb, var(--pill, var(--o-muted)) 13%, transparent);
    color: var(--pill, var(--o-muted));
}
.ojx__pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--pill, var(--o-muted)); }

.ojx__go { color: var(--o-muted); width: 16px; height: 16px; flex: 0 0 auto; }
.ojx__row:hover .ojx__go { color: var(--o-brand); }

/* Détail : la fiche imprimable, posée sur un fond papier dans la modale. */
.ojx__ticket { background: var(--o-raise); padding: 1.4rem 1rem; border-radius: 12px; }
.ojx__ticket .receipt {
    background: #fff; padding: 1.1rem 1.15rem 1rem;
    border-radius: 4px; box-shadow: 0 2px 10px -4px rgba(22, 35, 63, .18);
}
.ojx__ticket .receipt__void {
    margin: .1rem 0 .5rem; padding: .3rem .5rem;
    text-align: center; font-weight: 700; font-size: .78rem; letter-spacing: .06em;
    color: var(--o-unpaid); background: color-mix(in srgb, var(--o-unpaid) 12%, transparent);
    border-radius: 5px;
}

/* Changer de page fait remonter le journal juste sous la barre du haut. */
.ojx #ord-pagination,
.ojx .ojx__toolbar { scroll-margin-top: calc(var(--topbar-height) + 1rem); }

/* Statistiques : deux tuiles — l'activité sur 14 jours, la part par département. */
.ojx__stats { display: grid; grid-template-columns: 1.5fr 1fr; gap: .9rem; }
.ojx__panel {
    background: var(--o-surface); border: 1px solid var(--o-line);
    border-radius: 16px; padding: 1rem 1.1rem 1.1rem;
    display: flex; flex-direction: column; gap: .8rem;
}
.ojx__panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.ojx__panel-title { font-size: .82rem; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--o-muted); }
.ojx__panel-sum { font-size: .95rem; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--o-ink); }
.ojx__panel-sum small { color: var(--o-muted); font-weight: 500; margin-left: .2rem; }

.ojx__chart { display: flex; align-items: flex-end; gap: .35rem; height: 150px; }
.ojx__chart-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; min-width: 0; gap: .3rem; }
.ojx__chart-bar {
    width: 100%; max-width: 34px; min-height: 3px; border-radius: 5px 5px 0 0;
    background: linear-gradient(180deg, color-mix(in srgb, var(--o-brand) 78%, #fff), var(--o-brand));
    transition: opacity .15s ease;
}
.ojx__chart-col:hover .ojx__chart-bar { opacity: .8; }
.ojx__chart-lbl { font-size: .66rem; color: var(--o-muted); white-space: nowrap; }
.ojx__chart-col--today .ojx__chart-bar { background: linear-gradient(180deg, color-mix(in srgb, var(--o-paid) 78%, #fff), var(--o-paid)); }

.ojx__cats { display: grid; gap: .55rem; }
.ojx__cat { display: grid; grid-template-columns: minmax(0, 7rem) 1fr auto; align-items: center; gap: .6rem; }
.ojx__cat-name { font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ojx__cat-track { height: 10px; border-radius: 999px; background: var(--o-raise); overflow: hidden; }
.ojx__cat-fill { display: block; height: 100%; border-radius: 999px; background: var(--o-brand); min-width: 3px; }
.ojx__cat-val { font-size: .78rem; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.ojx__cat-empty { font-size: .82rem; color: var(--o-muted); }

@media (max-width: 860px) {
    .ojx__stats { grid-template-columns: 1fr; }
    .ojx__row { grid-template-columns: 3px 1fr auto; grid-template-areas: "rail id right" "rail meta right"; row-gap: .3rem; }
    .ojx__rail { grid-area: rail; }
    .ojx__id   { grid-area: id; }
    .ojx__meta { grid-area: meta; }
    .ojx__right { grid-area: right; grid-template-columns: 1fr; justify-items: end; gap: .3rem; }
    .ojx__right .ojx__go { display: none; }
    /* Sur mobile la bande 2×2 mangerait trop d'écran en défilant : pas de sticky. */
    .ojx__band { border-radius: 14px; position: static; box-shadow: none; }
    .ojx__stat { flex-basis: 50%; border-bottom: 1px solid var(--o-line); }
}

/* =========================================================== Clôture de caisse
   Écran dédié (/cash/close) : relevé de l'attendu à gauche, comptage à droite. */
.ccx {
    --c-ink: #16233f; --c-muted: #667085; --c-line: #e7e9ef; --c-surface: #fff;
    --c-raise: #f6f7fb; --c-brand: #23407f;
    --c-ok: #15803d; --c-over: #1d4ed8; --c-short: #be123c;
    --c-violet: #7c3aed;
    max-width: 1240px; color: var(--c-ink);
}
.ccx__back {
    display: inline-flex; align-items: center; gap: .2rem;
    font-size: .82rem; color: var(--c-muted); text-decoration: none; margin-bottom: .5rem;
}
.ccx__back:hover { color: var(--c-brand); }
.ccx__back .icon { width: 15px; height: 15px; transform: rotate(90deg); }
.ccx__head h1 { font-size: 1.5rem; font-weight: 600; margin: 0; }
.ccx__head p { margin: .25rem 0 0; color: var(--c-muted); font-size: .88rem; }

.ccx__guard {
    margin-top: 1.4rem; padding: 1.6rem; border: 1px solid var(--c-line);
    border-radius: 16px; background: var(--c-surface); text-align: center;
}
.ccx__guard p { margin: 0 0 1rem; color: var(--c-muted); }

.ccx__grid {
    margin-top: 1.4rem; display: grid; gap: 1.1rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr) 15rem; align-items: start;
}
.ccx__panel {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-radius: 18px; padding: 1.25rem 1.35rem 1.4rem;
}
.ccx__panel-head { display: flex; align-items: center; gap: .55rem; margin-bottom: 1rem; }
.ccx__panel-head h2 { font-size: 1rem; font-weight: 650; margin: 0; }
.ccx__tag {
    font-size: .64rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    padding: .2rem .5rem; border-radius: 999px;
    background: color-mix(in srgb, var(--c-brand) 12%, transparent); color: var(--c-brand);
}
.ccx__tag--count { background: color-mix(in srgb, var(--c-ok) 14%, transparent); color: var(--c-ok); }
.ccx__tag--calc { background: color-mix(in srgb, var(--c-violet) 14%, transparent); color: var(--c-violet); }

/* --- Relevé de l'attendu (colonne gauche) */
.ccx__flow { list-style: none; margin: 0; padding: 0; }
.ccx__flow-row {
    display: flex; justify-content: space-between; gap: 1rem;
    padding: .6rem 0; border-bottom: 1px dashed var(--c-line);
    font-size: .9rem; font-variant-numeric: tabular-nums;
}
.ccx__flow-row span:first-child { color: var(--c-ink); }
.ccx__flow-row span:last-child { font-weight: 600; }
.ccx__flow-row--out span:last-child { color: var(--c-short); }
.ccx__flow-row.is-zero { color: var(--c-muted); }
.ccx__flow-row.is-zero span:last-child { color: var(--c-muted); font-weight: 500; }
.ccx__expected {
    margin-top: .9rem; padding: .9rem 1rem; border-radius: 12px;
    background: var(--c-raise); display: flex; align-items: baseline;
    justify-content: space-between; gap: 1rem;
}
.ccx__expected span { font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--c-muted); }
.ccx__expected strong { font-size: 1.5rem; font-weight: 700; color: var(--c-brand); font-variant-numeric: tabular-nums; }
.ccx__hint { margin: 1rem 0 0; font-size: .76rem; color: var(--c-muted); line-height: 1.5; }

/* --- Comptage (colonne droite) */
.ccx__countfield { margin-bottom: 1.1rem; }
.ccx__countfield > label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .35rem; }
.ccx__countinput { position: relative; }
.ccx__countinput input {
    width: 100%; border: 2px solid var(--c-line); border-radius: 12px;
    padding: .7rem 3.4rem .7rem .9rem; font-size: 1.7rem; font-weight: 700;
    text-align: right; font-variant-numeric: tabular-nums; color: var(--c-ink);
    -moz-appearance: textfield;
}
.ccx__countinput input:focus { outline: none; border-color: var(--c-brand); }
.ccx__cur {
    position: absolute; right: .9rem; top: 50%; transform: translateY(-50%);
    font-size: .8rem; font-weight: 600; color: var(--c-muted);
}

.ccx__meter { margin-bottom: 1.1rem; }
.ccx__meter-track { height: 8px; border-radius: 999px; background: var(--c-raise); overflow: hidden; }
.ccx__meter-fill { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--c-muted); transition: width .2s ease, background .2s ease; }
.ccx__meter-text { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-top: .45rem; }
.ccx__meter-label { font-size: .85rem; font-weight: 600; }
.ccx__meter-value { font-size: .9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.ccx__meter[data-state="ok"] .ccx__meter-fill { background: var(--c-ok); }
.ccx__meter[data-state="ok"] .ccx__meter-label,
.ccx__meter[data-state="ok"] .ccx__meter-value { color: var(--c-ok); }
.ccx__meter[data-state="over"] .ccx__meter-fill { background: var(--c-over); }
.ccx__meter[data-state="over"] .ccx__meter-label,
.ccx__meter[data-state="over"] .ccx__meter-value { color: var(--c-over); }
.ccx__meter[data-state="short"] .ccx__meter-fill { background: var(--c-short); }
.ccx__meter[data-state="short"] .ccx__meter-label,
.ccx__meter[data-state="short"] .ccx__meter-value { color: var(--c-short); }
.ccx__meter[data-state="idle"] .ccx__meter-label { color: var(--c-muted); }

.ccx__field { display: block; margin-bottom: 1rem; }
.ccx__field > span { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .3rem; }
.ccx__field > span b { color: var(--c-short); }
.ccx__field input, .ccx__field textarea {
    width: 100%; border: 1px solid var(--c-line); border-radius: 10px;
    padding: .55rem .7rem; font: inherit; color: var(--c-ink); resize: vertical;
}
.ccx__field input:focus, .ccx__field textarea:focus { outline: 2px solid var(--c-brand); outline-offset: 1px; }
.ccx__field--reason input { border-color: color-mix(in srgb, var(--c-short) 45%, var(--c-line)); }

.ccx__actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: .3rem; }
.ccx__submit { padding: .7rem 1.4rem; font-size: .95rem; }

/* --- Mini calculatrice (colonne droite) */
.ccx__calc { position: sticky; top: calc(var(--topbar-height) + 1rem); }
.ccx__calc-screen {
    display: block; width: 100%; margin-bottom: .7rem;
    padding: .6rem .8rem; border-radius: 10px;
    background: var(--c-ink); color: #fff;
    font: 700 1.5rem/1 var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    text-align: right; font-variant-numeric: tabular-nums;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ccx__calc-pad { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; }
.ccx__calc-key {
    border: 1px solid var(--c-line); border-radius: 10px; background: var(--c-surface);
    padding: .6rem 0; font: 600 1rem/1 inherit; color: var(--c-ink); cursor: pointer;
    transition: background .1s ease, transform .05s ease;
}
.ccx__calc-key:hover { background: var(--c-raise); }
.ccx__calc-key:active { transform: translateY(1px); }
.ccx__calc-key--op { color: var(--c-brand); background: color-mix(in srgb, var(--c-brand) 6%, var(--c-surface)); }
.ccx__calc-key--fn { color: var(--c-muted); }
.ccx__calc-key--eq {
    grid-row: span 2; background: var(--c-brand); color: #fff; border-color: var(--c-brand);
    font-size: 1.2rem;
}
.ccx__calc-key--eq:hover { background: color-mix(in srgb, var(--c-brand) 88%, #000); }
.ccx__calc-key--zero { grid-column: span 2; }
.ccx__calc-use { width: 100%; margin-top: .7rem; }

@media (max-width: 1080px) {
    .ccx__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .ccx__calc { grid-column: 1 / -1; position: static; max-width: 22rem; }
    .ccx__calc-pad { max-width: 22rem; }
}
@media (max-width: 720px) {
    .ccx__grid { grid-template-columns: 1fr; }
}

/* ============================================================ Rapport de caisse
   Le « ticket Z » : identité de session, réconciliation en tête, puis le détail. */
.zrp {
    --z-ink: #16233f; --z-muted: #667085; --z-line: #e7e9ef; --z-raise: #f6f7fb;
    --z-brand: #23407f; --z-ok: #15803d; --z-short: #be123c;
    color: var(--z-ink); font-variant-numeric: tabular-nums;
}
.zrp__id { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.zrp__num { display: block; font-size: 1.35rem; font-weight: 700; letter-spacing: .01em; }
.zrp__reg { display: block; font-size: .85rem; color: var(--z-muted); margin-top: .1rem; }

.zrp__times { display: flex; flex-wrap: wrap; gap: .3rem 2rem; margin: .9rem 0 1.1rem; }
.zrp__times div { display: flex; flex-direction: column; }
.zrp__times span { font-size: .66rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--z-muted); }
.zrp__times strong { font-size: .92rem; font-weight: 600; }

.zrp__recon {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
    background: var(--z-line); border: 1px solid var(--z-line);
    border-radius: 14px; overflow: hidden; margin-bottom: .6rem;
}
.zrp__recon--open { grid-template-columns: 1fr; }
.zrp__recon-cell { background: #fff; padding: .85rem 1rem; display: flex; flex-direction: column; gap: .25rem; }
.zrp__recon-cell span { font-size: .66rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--z-muted); }
.zrp__recon-cell strong { font-size: 1.25rem; font-weight: 700; }
.zrp__recon-cell--diff.is-ok { background: color-mix(in srgb, var(--z-ok) 9%, #fff); }
.zrp__recon-cell--diff.is-ok strong { color: var(--z-ok); }
.zrp__recon-cell--diff.is-off { background: color-mix(in srgb, var(--z-short) 9%, #fff); }
.zrp__recon-cell--diff.is-off strong { color: var(--z-short); }
.zrp__reason {
    margin: 0 0 1rem; padding: .55rem .8rem; border-radius: 9px; font-size: .84rem;
    background: color-mix(in srgb, var(--z-short) 8%, transparent);
    border-left: 3px solid var(--z-short);
}
.zrp__reason b { font-weight: 700; }

.zrp__sec { margin-top: 1.35rem; }
.zrp__sec h3 {
    font-size: .8rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--z-muted); margin: 0 0 .5rem; padding-bottom: .35rem;
    border-bottom: 1px solid var(--z-line);
}
.zrp__list { list-style: none; margin: 0; padding: 0; }
.zrp__list-row {
    display: grid; grid-template-columns: 1fr auto auto; align-items: baseline;
    gap: .4rem 1rem; padding: .5rem 0; border-bottom: 1px dashed var(--z-line);
}
.zrp__list-row:last-child { border-bottom: 0; }
.zrp__list-name { font-size: .9rem; }
.zrp__list-sub { font-size: .78rem; color: var(--z-muted); white-space: nowrap; }
.zrp__list-amt { font-size: .92rem; font-weight: 650; white-space: nowrap; text-align: right; min-width: 7rem; }
.zrp__list-amt.is-neg { color: var(--z-short); }
.zrp__mono { font-family: var(--font-mono, ui-monospace, Menlo, monospace); font-size: .82rem; color: var(--z-muted); }
.zrp__empty { font-size: .86rem; color: var(--z-muted); margin: .3rem 0; }

.zrp__flow { list-style: none; margin: 0; padding: 0; }
.zrp__flow li {
    display: flex; justify-content: space-between; gap: 1rem;
    padding: .5rem 0; border-bottom: 1px dashed var(--z-line); font-size: .9rem;
}
.zrp__flow li span:last-child { font-weight: 600; }
.zrp__flow li.is-out span:last-child { color: var(--z-short); }
.zrp__flow li.is-zero, .zrp__flow li.is-zero span:last-child { color: var(--z-muted); font-weight: 500; }
.zrp__flow-total {
    margin-top: .7rem; padding: .8rem 1rem; border-radius: 12px; background: var(--z-raise);
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}
.zrp__flow-total span { font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--z-muted); }
.zrp__flow-total strong { font-size: 1.35rem; font-weight: 700; color: var(--z-brand); }

@media (max-width: 560px) {
    .zrp__recon { grid-template-columns: 1fr; }
    .zrp__list-row { grid-template-columns: 1fr auto; }
    .zrp__list-sub { grid-column: 1 / -1; }
}

@media print {
    .sidebar, .topbar, .btn, .toolbar, .filters { display: none !important; }
    .main { margin: 0; }
    .card { box-shadow: none; border: 0; }
    .card__header { border-bottom: 1px solid var(--border); }
    /* Le rapport Z s'imprime seul, à plat — uniquement quand cash.js a posé la
       classe le temps de l'impression (sinon la page Caisses s'imprime normalement). */
    body.is-printing-report .content > *:not(#report-modal) { display: none !important; }
    body.is-printing-report #report-modal {
        position: static; display: block; background: none;
        padding: 0; overflow: visible;
    }
    body.is-printing-report #report-modal .modal {
        box-shadow: none; max-width: none; width: 100%; max-height: none; margin: 0; border-radius: 0;
    }
    body.is-printing-report #report-modal .modal__body { max-height: none; overflow: visible; padding: 0; }
    body.is-printing-report #report-modal .modal__header,
    body.is-printing-report #report-modal .modal__footer { display: none !important; }
    body.is-printing-report .zrp { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    body.is-printing-report .zrp__sec { break-inside: avoid; }

    /* Impression d'une fiche affichée dans une modale (réservation, folio…) :
       hotel.js pose `is-printing-modal` sur <body> et `is-print-target` sur la
       modale visée le temps de l'impression, puis retire les deux. */
    body.is-printing-modal .sidebar,
    body.is-printing-modal .topbar,
    body.is-printing-modal .toast-container { display: none !important; }
    body.is-printing-modal .main { margin: 0; }
    body.is-printing-modal .content > *:not(.is-print-target) { display: none !important; }
    body.is-printing-modal .modal-backdrop.is-print-target {
        position: static; display: block; background: none; padding: 0; overflow: visible;
    }
    body.is-printing-modal .is-print-target .modal {
        box-shadow: none; max-width: none; width: 100%; max-height: none;
        margin: 0; border-radius: 0; animation: none;
    }
    body.is-printing-modal .is-print-target .modal__body { max-height: none; overflow: visible; }
    body.is-printing-modal .is-print-target .modal__header { border-bottom: 1px solid #000; }
    body.is-printing-modal .is-print-target .modal__close,
    body.is-printing-modal .is-print-target .modal__footer,
    body.is-printing-modal .is-print-target .btn { display: none !important; }
}

/* ======================================================= Réservations (/reservations)
   Poste de pilotage : bande d'indicateurs, quatre graphiques dessinés à la main
   (SVG intégré / barres CSS, aucune bibliothèque), puis le registre en
   lignes-fiches. Palette de l'application (bleu de marque). */
.rvx { display: flex; flex-direction: column; gap: 1.15rem; }

.rvx__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.rvx__head h1 { margin: 0; font-size: 1.5rem; font-weight: 600; }
.rvx__head p { margin: .25rem 0 0; color: var(--text-muted); font-size: .87rem; max-width: 66ch; }

/* Bande d'indicateurs */
.rvx__kpis { display: grid; gap: .8rem; grid-template-columns: repeat(6, 1fr); }
.rvx__kpi {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); padding: .9rem 1rem;
    display: flex; flex-direction: column; gap: .1rem; box-shadow: var(--shadow);
}
.rvx__kpi-val { font-size: 1.55rem; font-weight: 650; line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.rvx__kpi-lbl { font-size: .74rem; color: var(--text-muted); }
.rvx__kpi--money .rvx__kpi-val { color: var(--brand-600); font-size: 1.15rem; overflow-wrap: anywhere; }
.rvx__kpi--ring { flex-direction: row; align-items: center; gap: .75rem; }
.rvx__ring {
    flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%;
    background: conic-gradient(var(--brand-600) 0%, var(--border) 0);
}
.rvx__ring::before {
    content: ""; display: block; width: 32px; height: 32px;
    margin: 7px; border-radius: 50%; background: var(--surface);
}
@media (max-width: 1180px) { .rvx__kpis { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .rvx__kpis { grid-template-columns: repeat(2, 1fr); } }

/* Graphiques */
.rvx__charts { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.rvx__card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.1rem 1.2rem 1.2rem;
    display: flex; flex-direction: column; gap: 1rem;
}
.rvx__card--wide { grid-column: 1 / -1; }
.rvx__card-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.rvx__card-head h2 { margin: 0; font-size: .95rem; font-weight: 600; }
.rvx__card-sub { font-size: .74rem; color: var(--text-muted); }
.rvx__card-figure { margin-left: auto; font-size: .82rem; font-weight: 600; color: var(--brand-600); font-variant-numeric: tabular-nums; }
.rvx__muted { color: var(--text-muted); font-size: .85rem; margin: 0; padding: 1.5rem 0; text-align: center; }
.rvx__legend { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .76rem; color: var(--text-muted); margin-left: auto; }
.rvx__legend i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; vertical-align: -1px; margin-right: .35rem; }

/* Barres groupées — arrivées / départs */
.rvx__pipeline { display: flex; align-items: flex-end; gap: .5rem; height: 190px; }
.rvx__pl-day { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; align-items: center; gap: .12rem; justify-content: flex-end; }
.rvx__pl-bars { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 3px; min-height: 0; }
.rvx__pl-bar { width: 42%; max-width: 15px; border-radius: 4px 4px 0 0; min-height: 2px; transition: opacity .15s ease; }
.rvx__pl-bar--a { background: #2563eb; }
.rvx__pl-bar--d { background: #f59e0b; }
.rvx__pl-day:hover .rvx__pl-bar { opacity: .78; }
.rvx__pl-wd { font-size: .64rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.rvx__pl-dm { font-size: .64rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.rvx__pl-day.is-today .rvx__pl-wd, .rvx__pl-day.is-today .rvx__pl-dm { color: var(--brand-600); font-weight: 700; }

/* Anneau — répartition par statut */
.rvx__donut-wrap { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.rvx__donut { flex: 0 0 auto; width: 148px; }
.rvx__donut svg { width: 100%; height: auto; }
.rvx__donut-seg { transition: stroke-dasharray .4s ease; }
.rvx__donut svg text { text-anchor: middle; fill: var(--text); }
.rvx__donut-total { font-size: 7px; font-weight: 700; }
.rvx__donut-cap { font-size: 2.7px; fill: var(--text-muted); text-transform: uppercase; letter-spacing: .08em; }
.rvx__legend-list { list-style: none; margin: 0; padding: 0; flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: .5rem; }
.rvx__legend-list li { display: flex; align-items: center; gap: .5rem; font-size: .82rem; }
.rvx__dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }
.rvx__legend-name { flex: 1; }
.rvx__legend-val { font-weight: 650; font-variant-numeric: tabular-nums; }
.rvx__legend-val small { color: var(--text-muted); font-weight: 500; margin-left: .3rem; }

/* Barres horizontales — origine */
.rvx__bars { display: flex; flex-direction: column; gap: .7rem; }
.rvx__bar { display: grid; grid-template-columns: minmax(0, 6.5rem) 1fr auto; align-items: center; gap: .7rem; }
.rvx__bar-lbl { font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rvx__bar-track { height: 12px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.rvx__bar-fill { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brand-500), var(--brand-600)); }
.rvx__bar-val { font-size: .8rem; font-weight: 650; font-variant-numeric: tabular-nums; }

/* Aire — prise de réservations */
.rvx__spark svg { width: 100%; height: 120px; display: block; }
.rvx__spark-dot { fill: #2563eb; }
.rvx__spark-axis { display: flex; justify-content: space-between; font-size: .68rem; color: var(--text-muted); font-variant-numeric: tabular-nums; margin-top: .3rem; }
@media (max-width: 900px) { .rvx__charts { grid-template-columns: 1fr; } }

/* Registre */
.rvx__panel {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.1rem 1.2rem 1.2rem;
    display: flex; flex-direction: column; gap: .9rem;
}
.rvx__panel-head { display: flex; align-items: center; justify-content: space-between; gap: .8rem; flex-wrap: wrap; }
.rvx__panel-title { font-size: .82rem; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--text-muted); }
.rvx__toolbar { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.rvx__toolbar input[type="date"], .rvx__toolbar select {
    border: 1px solid var(--border); border-radius: 10px;
    padding: .5rem .7rem; font: inherit; color: var(--text); background: var(--surface); min-height: 38px;
}
.rvx__search { position: relative; flex: 1 1 200px; min-width: 170px; }
.rvx__search .icon { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-muted); pointer-events: none; }
.rvx__search input { width: 100%; border: 1px solid var(--border); border-radius: 10px; padding: .5rem .7rem .5rem 2.1rem; font: inherit; min-height: 38px; background: var(--surface); color: var(--text); }
.rvx :focus-visible { outline: 2px solid var(--brand-600); outline-offset: 1px; }

.rvx__list { display: flex; flex-direction: column; gap: .4rem; }
.rvx__row {
    display: grid;
    grid-template-columns: 3px minmax(8rem, auto) 1fr minmax(4rem, auto) auto;
    align-items: center; gap: 0 1rem;
    width: 100%; text-align: left;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 13px; padding: .7rem 1.1rem .7rem 0;
    font: inherit; color: inherit; cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.rvx__row:hover { border-color: color-mix(in srgb, var(--brand-600) 45%, var(--border)); box-shadow: 0 6px 18px -10px rgba(15, 23, 42, .28); }
.rvx__row:active { transform: translateY(1px); }
.rvx__rail { align-self: stretch; border-radius: 13px 0 0 13px; background: #94a3b8; }
.rvx__row--pending     .rvx__rail { background: #d97706; }
.rvx__row--confirmed   .rvx__rail { background: #2563eb; }
.rvx__row--checked_in  .rvx__rail { background: #16a34a; }
.rvx__row--checked_out .rvx__rail { background: #64748b; }
.rvx__row--cancelled   .rvx__rail { background: #dc2626; }
.rvx__row--no_show     .rvx__rail { background: #9333ea; }
.rvx__row-id { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.rvx__code { font-family: var(--font-mono, ui-monospace, "SFMono-Regular", Menlo, monospace); font-weight: 700; font-size: .9rem; }
.rvx__row-guest { font-size: .8rem; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rvx__row-stay { display: flex; flex-direction: column; gap: .1rem; min-width: 0; font-size: .85rem; font-variant-numeric: tabular-nums; }
.rvx__row-meta { font-size: .76rem; color: var(--text-muted); }
.rvx__row-rooms { font-size: .82rem; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rvx__row-right { display: flex; align-items: center; gap: .9rem; }
.rvx__amount { font-size: 1rem; font-weight: 650; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.rvx__amount small { display: block; font-size: .66rem; font-weight: 600; color: var(--text-muted); }
.rvx__go { color: var(--text-muted); width: 16px; height: 16px; flex: 0 0 auto; }
.rvx__row:hover .rvx__go { color: var(--brand-600); }
.rvx__pill {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .72rem; font-weight: 650; white-space: nowrap;
    padding: .2rem .6rem; border-radius: 999px;
    background: color-mix(in srgb, var(--pill, var(--text-muted)) 13%, transparent);
    color: var(--pill, var(--text-muted));
}
.rvx__pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--pill, var(--text-muted)); }

@media (max-width: 820px) {
    .rvx__row {
        grid-template-columns: 3px 1fr auto;
        grid-template-areas: "rail id right" "rail stay right" "rail rooms right";
        row-gap: .25rem;
    }
    .rvx__rail { grid-area: rail; }
    .rvx__row-id { grid-area: id; }
    .rvx__row-stay { grid-area: stay; }
    .rvx__row-rooms { grid-area: rooms; }
    .rvx__row-right { grid-area: right; flex-direction: column; align-items: flex-end; gap: .35rem; }
    .rvx__go { display: none; }
    .rvx__pipeline { height: 150px; }
    .rvx__pl-dm { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .rvx__row, .rvx__pl-bar, .rvx__donut-seg { transition: none; }
}

/* ============================================================ Hôtel (/hotel)
   Écran unifié à onglets : plan des chambres, réservations, folios. L'essentiel
   du style est réutilisé (.seg, .rvx__*, .rwx__*, .dash__*, .modal*) ; ce bloc
   ne pose que le liant. */
.hx { display: flex; flex-direction: column; gap: 1.15rem; }

.hx__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.hx__head h1 { margin: 0; font-size: 1.5rem; font-weight: 600; }
.hx__head p { margin: .25rem 0 0; color: var(--text-muted); font-size: .87rem; max-width: 66ch; }

/* Sélecteur de période : gouverne « Chiffre d'affaires » et « Clients logés ». */
.hx__period { display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end; }
.hx__period-field { display: flex; flex-direction: column; gap: .28rem; }
/* `:not(.datefr)` : le champ date en français remplace le <input> par un
   <span class="datefr"> — sans cette exclusion, le libellé « DU » / « AU »
   s'appliquerait au champ lui-même (texte minuscule, gris, capitales). */
.hx__period-field > span:not(.datefr) { font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.hx__period select,
.hx__period input[type="date"],
.hx__period .datefr__text {
    border: 1px solid var(--border); border-radius: 10px;
    padding: .5rem .7rem; font: inherit; color: var(--text);
    background: var(--surface); min-height: 38px;
}
/* Le champ date passe par le proxy `.datefr` : il doit occuper la même
   largeur que le <select> et garder de la place pour l'icône calendrier. */
.hx__period .datefr { display: block; }
.hx__period .datefr__text { width: 100%; padding-right: 2rem; }
.hx__period .datefr__text:focus {
    outline: none; border-color: var(--brand-500);
    box-shadow: 0 0 0 3px rgba(47, 86, 165, .12);
}

.hx__band { margin: 0; display: flex; flex-direction: column; gap: .9rem; }

/* Barre d'onglets Hôtel : fond bleu plein pour détacher franchement la
   section du contenu blanc — l'onglet actif ressort en pastille blanche. */
.hx__tabs {
    margin: 0;
    background: var(--brand-600);
    border: 1px solid var(--brand-700);
}
.hx__tabs .seg__btn { color: rgba(255, 255, 255, .78); }
.hx__tabs .seg__btn:hover { color: #fff; }
.hx__tabs .seg__btn.is-active { background: var(--surface); color: var(--text); }

/* Bande de chiffres : une carte pleine et colorée par indicateur. */
.hx__figs {
    display: flex; flex-wrap: wrap; gap: .6rem;
    background: none; border: 0; box-shadow: none; border-radius: 0; overflow: visible;
}
.hx__fig {
    flex: 1 1 140px; min-width: 128px;
    padding: .85rem 1.05rem;
    border: 0; border-radius: var(--radius);
    display: flex; flex-direction: column; gap: .15rem;
    color: #fff;
    box-shadow: 0 6px 16px rgba(15, 23, 42, .16);
    transform: translateY(8px); opacity: 0;
    animation: hxFigIn .5s cubic-bezier(.16, 1, .3, 1) forwards;
    transition: transform .18s ease, box-shadow .18s ease;
}
.hx__fig:hover { transform: translateY(-3px); box-shadow: 0 14px 28px rgba(15, 23, 42, .24); }
.hx__fig b {
    font-size: 1.5rem; font-weight: 700; line-height: 1.05;
    font-variant-numeric: tabular-nums; letter-spacing: -.01em; color: #fff;
}
.hx__fig span { font-size: .72rem; color: rgba(255, 255, 255, .85); }
.hx__fig--accent b { font-size: 1.18rem; overflow-wrap: anywhere; }

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

/* Fond plein et foncé par indicateur (dégradé léger) + entrée décalée.
   L'ordre suit le balisage de hotel.php. */
.hx__fig:nth-child(1) { background: linear-gradient(150deg, #15803d, #166534); animation-delay: .00s; }
.hx__fig:nth-child(2) { background: linear-gradient(150deg, #c2410c, #9a3412); animation-delay: .06s; }
.hx__fig:nth-child(3) { background: linear-gradient(150deg, var(--brand-500), var(--brand-700)); animation-delay: .12s; }
.hx__fig:nth-child(4) { background: linear-gradient(150deg, #0e7490, #155e75); animation-delay: .18s; }
.hx__fig:nth-child(5) { background: linear-gradient(150deg, #6d28d9, #5b21b6); animation-delay: .24s; }
.hx__fig:nth-child(6) { background: linear-gradient(150deg, #be185d, #9d174d); animation-delay: .30s; }

@media (prefers-reduced-motion: reduce) {
    .hx__fig { animation-duration: .01s; transform: none; opacity: 1; transition: none; }
    .hx__fig:hover { transform: none; }
}

/* Graphiques de la vue d'ensemble (réutilisent le style .rvx__card / .rvx__*). */
.hx__charts { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
.hx__charts .rvx__card--wide { grid-column: 1 / -1; }
@media (max-width: 900px) { .hx__charts { grid-template-columns: 1fr; } }

.hx__panel { display: flex; flex-direction: column; gap: 1.1rem; }

.hx__card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: 1.1rem 1.2rem 1.2rem;
    display: flex; flex-direction: column; gap: .9rem;
}
.hx__card-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.hx__card-title { font-size: .82rem; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--text-muted); }
.hx__hint { margin: -.4rem 0 0; }

/* Lignes de chambre cliquables */
.hx__rooms tbody tr.hx__room-row { cursor: pointer; }
.hx__rooms tbody tr.hx__room-row:hover { background: #f2f6ff; }
.hx__rooms tbody tr.hx__room-row:focus-within { background: #f2f6ff; }
.hx__room-cta {
    display: none; margin-left: .5rem;
    padding: .05rem .45rem; border-radius: 999px;
    background: var(--brand-600); color: #fff;
    font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    vertical-align: 1px;
}
.hx__rooms tbody tr.hx__room-row:hover .hx__room-cta { display: inline-block; }

/* Lignes de folio : survol cohérent avec le reste */
.hx__folio-row { cursor: pointer; }
.hx__folio-row:hover { background: #f2f6ff; }

/* ==================================================== Rapports — habillage vert
   Portée à la seule page /rapports (body[data-page="reports"]). Accent vert,
   fond gris clair, cartes blanches très arrondies, ombres douces, anneau
   segmenté pour la répartition des entrées. La structure de la page ne change
   pas — c'est un thème local. */
body[data-page="reports"] {
    --rpt-accent:   #1a8a5f;
    --rpt-accent-d: #147049;
    --rpt-line:     #eef0f4;
    background: #eef0f5;
}
body[data-page="reports"] .content { padding: 1.6rem; }
body[data-page="reports"] .page-header h1 { font-size: 1.35rem; }
body[data-page="reports"] .page-header p { font-size: .82rem; }

body[data-page="reports"] .card {
    border: 0; border-radius: 20px;
    box-shadow: 0 10px 34px -14px rgba(19, 32, 48, .16), 0 1px 3px rgba(19, 32, 48, .04);
}
body[data-page="reports"] .card__header {
    border-bottom: 1px solid var(--rpt-line); padding: 1.2rem 1.5rem;
}
body[data-page="reports"] .card__title {
    font-size: .74rem; text-transform: uppercase; letter-spacing: .07em;
    color: #98a0ac; font-weight: 700;
}
body[data-page="reports"] .card__body { padding: 1.4rem 1.5rem; }
body[data-page="reports"] .card__footer {
    background: transparent; border-top: 1px solid var(--rpt-line); border-radius: 0 0 20px 20px;
}

/* Accents verts */
body[data-page="reports"] .btn--primary { background: var(--rpt-accent); }
body[data-page="reports"] .btn--primary:hover { background: var(--rpt-accent-d); }
body[data-page="reports"] .btn--primary:focus-visible { outline-color: var(--rpt-accent-d); }
body[data-page="reports"] .dash__period.is-active {
    background: var(--rpt-accent); border-color: var(--rpt-accent); color: #fff;
}
body[data-page="reports"] .dash__delta--up { background: #e3f5ec; color: var(--rpt-accent-d); }
body[data-page="reports"] .badge--brand,
body[data-page="reports"] .badge { border-radius: 999px; }
body[data-page="reports"] .input:focus,
body[data-page="reports"] .select:focus {
    border-color: var(--rpt-accent); box-shadow: 0 0 0 3px rgba(26, 138, 95, .13);
}

/* Chiffre principal de la comparaison */
body[data-page="reports"] .dash__figure-value { letter-spacing: -.02em; }

/* Encarts « Commandes / Encaissé / Dépenses / Net » — allégés */
body[data-page="reports"] .dash__takings { gap: .7rem; }
body[data-page="reports"] .dash__take {
    background: #f6f8f9; border: 0; border-radius: 14px; padding: .8rem .9rem;
}

/* Tableau plus aéré */
body[data-page="reports"] .table th {
    background: transparent; border-bottom: 2px solid var(--rpt-line);
    font-size: .68rem; color: #98a0ac;
}
body[data-page="reports"] .table td { border-bottom: 1px solid #f4f5f8; padding: .85rem 1rem; }
body[data-page="reports"] .table tbody tr:hover { background: #f5faf7; }
body[data-page="reports"] .table tfoot th { background: #f6f8f9; border-top: 2px solid var(--rpt-line); }

/* Graphique du rapport détaillé — barre verte */
body[data-page="reports"] .rvx__bar-fill { background: linear-gradient(90deg, #46c193, var(--rpt-accent)); }
body[data-page="reports"] .rep-chart { border-bottom-color: var(--rpt-line); }

/* Anneau segmenté — répartition des entrées */
body[data-page="reports"] #cmp-split { margin-top: .4rem; }
body[data-page="reports"] .rpt__donut-wrap {
    display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; padding-top: .6rem;
}
body[data-page="reports"] .rpt__donut { flex: 0 0 auto; width: 168px; }
body[data-page="reports"] .rpt__donut svg { width: 100%; height: auto; }
body[data-page="reports"] .rpt__seg { transition: stroke-dasharray .5s ease; }
body[data-page="reports"] .rpt__donut text { text-anchor: middle; }
body[data-page="reports"] .rpt__donut-total { font-size: 5px; font-weight: 800; fill: #16233f; letter-spacing: -.02em; }
body[data-page="reports"] .rpt__donut-cap { font-size: 2.5px; font-weight: 700; fill: #98a0ac; letter-spacing: .12em; }
body[data-page="reports"] .rpt__legend {
    list-style: none; margin: 0; padding: 0; flex: 1; min-width: 190px;
    display: flex; flex-direction: column; gap: .6rem;
}
body[data-page="reports"] .rpt__legend li {
    display: grid; grid-template-columns: auto 1fr auto auto;
    align-items: center; gap: .6rem; font-size: .84rem;
}
body[data-page="reports"] .rpt__dot { width: 10px; height: 10px; border-radius: 50%; }
body[data-page="reports"] .rpt__leg-name { color: #4a4f5a; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body[data-page="reports"] .rpt__leg-val { font-weight: 650; font-variant-numeric: tabular-nums; }
body[data-page="reports"] .rpt__leg-pct {
    color: #98a0ac; font-size: .78rem; font-variant-numeric: tabular-nums;
    min-width: 3.4rem; text-align: right;
}

@media (prefers-reduced-motion: reduce) {
    body[data-page="reports"] .rpt__seg { transition: none; }
}

/* ==================================================== Location d'espaces (/spaces)
   Écran unifié à onglets : catalogue, planning, réservations. Bandeau de synthèse,
   planning en grille scrollable, réservations en lignes-fiches (repère de statut
   au bord gauche), catalogue en cartes groupées par usage. Réutilise .seg,
   .modal*, .pagination, .picker*, .btn*, .table*. Aucune dépendance externe. */
.spx {
    --sx-line: var(--border);
    --sx-raise: var(--surface-2);
    --sx-brand: var(--brand-600);
    display: flex; flex-direction: column; gap: 1.1rem;
}
.spx .hidden { display: none; }

.spx__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.spx__head h1 { font-size: 1.5rem; font-weight: 600; margin: 0; }
.spx__head p { margin: .3rem 0 0; color: var(--text-muted); font-size: .87rem; max-width: 74ch; }
.spx__head p strong { color: var(--text); font-weight: 600; }
.spx__tools { display: flex; gap: .5rem; flex-wrap: wrap; }

/* Bandeau de synthèse */
.spx__band {
    display: flex; flex-wrap: wrap;
    background: var(--surface); border: 1px solid var(--sx-line);
    border-radius: 16px; overflow: hidden;
}
.spx__stat {
    flex: 1 1 150px; min-width: 130px;
    padding: .9rem 1.1rem;
    border-right: 1px solid var(--sx-line);
    display: flex; flex-direction: column; gap: .15rem;
}
.spx__stat:last-child { border-right: 0; }
.spx__stat-val {
    font-size: 1.45rem; font-weight: 650; line-height: 1.05;
    font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.spx__stat-lbl { font-size: .72rem; color: var(--text-muted); }

/* Segments (usage + onglets + statut) : on repart de .seg */
.spx__usage-seg, .spx__tabs, .spx__status-seg { margin-bottom: 0; flex-wrap: wrap; }
.spx__tabs { align-self: flex-start; }
.spx__usage-seg { align-self: flex-start; }
.spx__status-seg { align-self: flex-start; }

/* Panneaux d'onglet */
.spx__panel { display: flex; flex-direction: column; gap: .9rem; }

.spx__block {
    background: var(--surface); border: 1px solid var(--sx-line);
    border-radius: 16px; padding: 1rem 1.1rem 1.15rem;
    display: flex; flex-direction: column; gap: .85rem;
}
.spx__block-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.spx__block-title { font-size: .8rem; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--text-muted); }
.spx__block-tools { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-end; }

.spx__field { display: flex; flex-direction: column; gap: .28rem; }
.spx__field > span { font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.spx input[type="date"], .spx select, .spx__search input {
    border: 1px solid var(--sx-line); border-radius: 10px;
    padding: .5rem .7rem; font: inherit; color: var(--text);
    background: var(--surface); min-height: 38px;
}
.spx__search { position: relative; flex: 1 1 220px; min-width: 180px; }
.spx__search .icon {
    position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: var(--text-muted); pointer-events: none;
}
.spx__search input { width: 100%; padding-left: 2.1rem; }
.spx :focus-visible { outline: 2px solid var(--sx-brand); outline-offset: 1px; }

.spx__empty { padding: 2.4rem 1rem; text-align: center; color: var(--text-muted); }

/* Catalogue : cartes groupées par usage */
.spx__usages { display: flex; flex-direction: column; gap: 1.15rem; }
.spx__usage { display: flex; flex-direction: column; gap: .6rem; }
.spx__usage-head {
    display: flex; align-items: center; gap: .5rem;
    font-size: .82rem; font-weight: 700; letter-spacing: .01em;
}
.spx__usage-head span {
    font-size: .7rem; font-weight: 700; color: var(--text-muted);
    background: var(--sx-raise); border-radius: 999px; padding: .05rem .5rem;
}
.spx__cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(244px, 1fr)); gap: .7rem; }
.spx__space {
    border: 1px solid var(--sx-line); border-radius: 13px;
    padding: .9rem 1rem; background: var(--surface);
    display: flex; flex-direction: column; gap: .55rem;
}
.spx__space--off { opacity: .6; }
.spx__space-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.spx__space-name { font-weight: 650; font-size: .95rem; }
.spx__space-type { font-size: .74rem; color: var(--text-muted); }
.spx__space-rates { display: flex; gap: 1.3rem; }
.spx__space-rates div { display: flex; flex-direction: column; }
.spx__space-rates span { font-size: .6rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.spx__space-rates b { font-weight: 650; font-size: .86rem; font-variant-numeric: tabular-nums; }
.spx__space-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: auto; }
.spx__space-cap { font-size: .76rem; color: var(--text-muted); }

/* Planning : grille scrollable */
.spx__rack-wrap { overflow-x: auto; border: 1px solid var(--sx-line); border-radius: 12px; }
.spx__rack { border-collapse: separate; border-spacing: 0; width: 100%; font-size: .8rem; }
.spx__rack th, .spx__rack td {
    padding: .35rem .3rem; text-align: center;
    border-bottom: 1px solid var(--sx-line); border-right: 1px solid var(--sx-line);
}
.spx__rack tr:last-child td { border-bottom: 0; }
.spx__rack th:last-child, .spx__rack td:last-child { border-right: 0; }
.spx__rack thead th {
    background: var(--sx-raise); font-size: .64rem; line-height: 1.2;
    font-weight: 700; color: var(--text-muted);
    position: sticky; top: 0; z-index: 2;
}
.spx__rack-date span { font-weight: 700; color: var(--text); font-size: .72rem; }
.spx__rack-date--we { background: #eef2f7; }
.spx__rack-space {
    text-align: left !important; white-space: nowrap; min-width: 152px;
    position: sticky; left: 0; background: var(--surface); z-index: 1; font-weight: 600;
}
.spx__rack thead .spx__rack-space { z-index: 3; background: var(--sx-raise); }
.spx__rack-space small { display: block; font-weight: 500; color: var(--text-muted); font-size: .7rem; }
.spx__cell { min-width: 42px; height: 34px; padding: 3px; }
.spx__slot {
    display: flex; align-items: center;
    width: 100%; height: 26px; padding: 0 .3rem;
    border: 0; border-radius: 5px; background: #f1f5f9;
    font: inherit; font-size: .68rem; font-weight: 600; color: var(--text);
    overflow: hidden; white-space: nowrap; cursor: default;
}
.spx__slot-label { overflow: hidden; text-overflow: ellipsis; }
.spx__slot--free { background: transparent; cursor: pointer; }
.spx__slot--free:hover { background: color-mix(in srgb, var(--sx-brand) 12%, transparent); }
.spx__slot--busy { cursor: pointer; }
.spx__slot--busy:hover { filter: brightness(.94); }
.spx__slot--pending   { background: #fed7aa; }
.spx__slot--confirmed { background: #bfdbfe; }
.spx__slot--progress  { background: #86efac; }

.spx__legend { display: flex; gap: 1.1rem; flex-wrap: wrap; font-size: .76rem; color: var(--text-muted); }
.spx__legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: -1px; margin-right: .35rem; }

/* Réservations : lignes-fiches */
.spx__list { display: flex; flex-direction: column; gap: .4rem; }
.spx__row {
    display: grid;
    grid-template-columns: 3px minmax(8rem, auto) 1fr auto;
    align-items: center; gap: 0 1rem;
    width: 100%; text-align: left;
    background: var(--surface); border: 1px solid var(--sx-line);
    border-radius: 13px; padding: .7rem 1.1rem .7rem 0;
    font: inherit; color: inherit; cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.spx__row:hover { border-color: color-mix(in srgb, var(--sx-brand) 45%, var(--sx-line)); box-shadow: 0 6px 18px -10px rgba(22, 35, 63, .25); }
.spx__row:active { transform: translateY(1px); }

.spx__rail { align-self: stretch; border-radius: 13px 0 0 13px; background: #94a3b8; }
.spx__row--pending     .spx__rail { background: #b45309; }
.spx__row--confirmed   .spx__rail { background: #1d4ed8; }
.spx__row--in_progress .spx__rail { background: #15803d; }
.spx__row--completed   .spx__rail { background: #64748b; }
.spx__row--cancelled   .spx__rail { background: #b91c1c; }

.spx__id { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.spx__code { font-family: var(--font-mono, ui-monospace, "SFMono-Regular", Menlo, monospace); font-weight: 700; font-size: .9rem; }
.spx__when { font-size: .74rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.spx__meta { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.spx__event { font-size: .9rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spx__sub { font-size: .78rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spx__right { display: flex; align-items: center; gap: .9rem; }
.spx__amount { font-size: 1.05rem; font-weight: 650; font-variant-numeric: tabular-nums; text-align: right; }
.spx__amount small { display: block; font-size: .64rem; font-weight: 600; color: #1d4ed8; }
.spx__go { color: var(--text-muted); width: 16px; height: 16px; flex: 0 0 auto; }
.spx__row:hover .spx__go { color: var(--sx-brand); }

.spx__pill {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .72rem; font-weight: 650; white-space: nowrap;
    padding: .2rem .6rem; border-radius: 999px;
    background: color-mix(in srgb, var(--pill, var(--text-muted)) 13%, transparent);
    color: var(--pill, var(--text-muted));
}
.spx__pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--pill, var(--text-muted)); }

/* Détail (modale) */
.spx__detail { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .8rem 1.2rem; }
.spx__detail-item { display: flex; flex-direction: column; gap: .15rem; }
.spx__detail-item > span { font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.spx__detail-item > div { font-size: .9rem; }

@media (max-width: 860px) {
    .spx__stat { flex-basis: 50%; border-bottom: 1px solid var(--sx-line); }
    .spx__row {
        grid-template-columns: 3px 1fr auto;
        grid-template-areas: "rail id right" "rail meta right";
        row-gap: .3rem;
    }
    .spx__rail { grid-area: rail; }
    .spx__id { grid-area: id; }
    .spx__meta { grid-area: meta; }
    .spx__right { grid-area: right; flex-direction: column; align-items: flex-end; gap: .35rem; }
    .spx__go { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .spx__row { transition: none; }
}
