:root {
  --ink: #18222f;
  --muted: #6d7785;
  --canvas: #f2f4f7;
  --surface: #ffffff;
  --line: #e4e8ed;
  --nav: #17212e;
  --nav-hover: #243244;
  --brand: #2457d6;
  --brand-soft: #e9efff;
  --green: #138a5b;
  --green-soft: #e6f6ef;
  --orange: #dc6b25;
  --orange-soft: #fff0e5;
  --danger: #c4362e;
  --radius: 16px;
  --shadow: 0 12px 32px rgba(24, 34, 47, .07);
  /* Un graphique a besoin de trois roles que les jetons de page ne couvraient pas :
     le filet de repere doit s'effacer derriere les barres sans disparaitre, la barre
     doit rester lisible imprimee en noir et blanc, et le point culminant doit se
     distinguer autrement que par la couleur seule. */
  --chart-grid: #dde3ea;
  --chart-bar: #4f7ce4;
  --chart-bar-peak: #1c3f9e;
  /* Le filet de separation de la barre laterale etait ecrit en rgba() a trois
     endroits : il devient un role, pour que le repli du menu s'y accroche. */
  --nav-line: rgba(255, 255, 255, .1);
  /* Le voile pose derriere une boite de confirmation modale (<dialog>::backdrop) :
     assez sombre pour couper l'attention du reste de l'ecran, jamais opaque, pour
     que la fiche qu'on s'apprete a modifier reste devinable derriere. */
  --veil: rgba(15, 20, 28, .5);
}

* { box-sizing: border-box; }
html { color-scheme: light; }
body { margin: 0; background: var(--canvas); color: var(--ink); font-family: Inter, ui-sans-serif, system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
button, input, select, textarea { font: inherit; }
a { color: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; z-index: 100; top: .75rem; left: .75rem; transform: translateY(-180%); background: var(--surface); padding: .75rem 1rem; border-radius: 10px; box-shadow: var(--shadow); }
.skip-link:focus { transform: none; }

.app-frame { min-height: 100vh; display: grid; grid-template-columns: 264px minmax(0, 1fr); }
.app-sidebar { position: sticky; top: 0; height: 100vh; padding: 1.4rem 1rem; display: flex; flex-direction: column; color: #f7f9fc; background: var(--nav); }
.app-brand { display: flex; align-items: center; gap: .75rem; padding: .4rem .55rem 1.7rem; text-decoration: none; }
.app-brand-mark { display: grid; width: 2.25rem; height: 2.25rem; place-items: center; flex: 0 0 auto; border-radius: 11px; color: white; background: linear-gradient(145deg, #3b72f2, #234cb8); font-weight: 800; box-shadow: 0 6px 18px rgba(36, 87, 214, .35); }
.app-brand strong, .app-brand small { display: block; }
.app-brand strong { font-size: 1.05rem; letter-spacing: -.02em; }
.app-brand small { margin-top: .1rem; color: #98a7bb; font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; }
.app-nav { display: grid; gap: .3rem; }
.app-nav-label { margin: 1.2rem .7rem .35rem; color: #8291a5; font-size: .68rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.app-nav-link { display: flex; align-items: center; gap: .75rem; min-height: 2.8rem; padding: .65rem .75rem; border-radius: 11px; color: #ccd5e1; text-decoration: none; font-size: .9rem; font-weight: 550; }
.app-nav-link:hover { color: white; background: var(--nav-hover); }
.app-nav-link.is-active { color: white; background: #2b5dce; box-shadow: 0 8px 22px rgba(17, 43, 102, .35); }
/* Les emoji qui tenaient lieu d'icônes n'avaient ni boîte ni chasse constantes : chaque
   libellé démarrait à une abscisse différente. Une boîte carrée figée, hors du calcul de
   la police, aligne toutes les entrées sur la même colonne. */
.icone { flex: none; width: 1.25rem; height: 1.25rem; }
.app-nav-icon { display: grid; place-items: center; width: 1.3rem; height: 1.3rem; }
.app-sidebar-account { margin-top: auto; padding: 1rem .55rem .2rem; border-top: 1px solid var(--nav-line); }
.app-account-copy { display: flex; align-items: center; gap: .65rem; min-width: 0; color: inherit; text-decoration: none; border-radius: 10px; }
.app-account-copy:hover { background: rgba(255, 255, 255, .06); }
.app-account-copy > span:last-child { min-width: 0; }
.app-account-copy strong, .app-account-copy small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-account-copy strong { max-width: 150px; font-size: .78rem; }
.app-account-copy small { margin-top: .2rem; color: #8fa0b5; font-size: .67rem; text-transform: capitalize; }
.app-avatar { display: grid; width: 2.15rem; height: 2.15rem; place-items: center; flex: 0 0 auto; overflow: hidden; border-radius: 50%; color: #dbe7ff; background: #30425a; font-size: 0; }
.app-avatar::first-letter { font-size: .78rem; }
.app-signout { margin-top: .75rem; padding: 0; border: 0; color: #aebacc; background: transparent; cursor: pointer; font-size: .75rem; }
.app-signout:hover { color: white; }

/* Repli de la barre laterale ------------------------------------------------
   Sur grand ecran la barre occupait 264 px en permanence, sans aucun moyen de la
   refermer : le bouton de menu etait masque au-dessus de 760 px et le script
   forcait meme la fermeture en repassant en grand ecran. Un tableau de chiffre
   d'affaires large perdait donc un quart de la fenetre au profit de cinq liens
   qui ne changent jamais. Repliee, la barre garde ses icones : on continue de
   naviguer d'un clic, et les libelles restent dans l'arbre d'accessibilite pour
   les lecteurs d'ecran. */
.app-nav-collapse { display: grid; width: 2rem; height: 2rem; margin-left: auto; place-items: center; flex: 0 0 auto; border: 0; border-radius: 9px; color: inherit; background: transparent; cursor: pointer; opacity: .65; }
.app-nav-collapse:hover { opacity: 1; background: var(--nav-hover); }
.app-nav-collapse:focus-visible { outline: 2px solid var(--chart-bar); outline-offset: 2px; opacity: 1; }
.app-sidebar-head { display: flex; align-items: center; gap: .5rem; padding: .4rem .55rem 1.7rem; }
.app-sidebar-head .app-brand { flex: 1 1 auto; min-width: 0; padding: 0; }
/* Le libelle disparait de l'oeil sans quitter l'arbre d'accessibilite : replier
   le menu ne doit pas rendre l'application muette au lecteur d'ecran. */
.nav-collapsed .app-frame { grid-template-columns: 4.75rem minmax(0, 1fr); }
.nav-collapsed .app-sidebar { padding-left: .55rem; padding-right: .55rem; }
.nav-collapsed .app-sidebar-head { flex-direction: column; gap: .8rem; padding-left: 0; padding-right: 0; }
.nav-collapsed .app-nav-collapse { margin-left: 0; }
.nav-collapsed .app-brand { justify-content: center; }
.nav-collapsed .app-nav-link, .nav-collapsed .app-account-copy, .nav-collapsed .app-signout { justify-content: center; gap: 0; }
.nav-collapsed .app-nav-link { padding-left: 0; padding-right: 0; }
.nav-collapsed .app-sidebar-account { padding-left: 0; padding-right: 0; }
.nav-collapsed .app-signout { display: grid; width: 100%; height: 2.4rem; place-items: center; margin-top: .5rem; border-radius: 9px; }
.nav-collapsed .app-signout:hover { background: var(--nav-hover); }
.nav-collapsed .app-brand > span:last-child,
.nav-collapsed .app-nav-label,
.nav-collapsed .app-nav-link > span:last-child,
.nav-collapsed .app-account-copy > span:last-child,
.nav-collapsed .app-signout > span { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.app-signout-icon { display: none; }
.nav-collapsed .app-signout-icon { display: block; }

.app-workspace { min-width: 0; }
.app-topbar { min-height: 112px; padding: 1rem clamp(1rem, 3vw, 2.5rem); display: flex; align-items: center; gap: 1rem; border-bottom: 1px solid var(--line); background: rgba(255, 255, 255, .94); backdrop-filter: blur(16px); }
.app-page-header { width: min(1240px, 100%); margin: 0 auto; display: grid; gap: .45rem; }
.app-page-header-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; }
.app-page-header-copy h1 { margin: .1rem 0 0; font-size: clamp(1.55rem, 2.5vw, 2.15rem); line-height: 1.05; letter-spacing: -.04em; }
.app-page-header-copy > p:last-child:not(.page-eyebrow) { max-width: 760px; margin: .35rem 0 0; color: var(--muted); font-size: .85rem; line-height: 1.45; }
.app-header-breadcrumb { display: flex; align-items: center; gap: .55rem; color: var(--muted); font-size: .72rem; }
.app-header-breadcrumb a { display: inline-flex; align-items: center; gap: .35rem; color: var(--brand); text-decoration: none; font-weight: 700; }
.app-header-breadcrumb .icone { width: 1rem; height: 1rem; }
.app-menu-button, .app-mobile-brand { display: none; }
.app-main { width: min(1240px, 100%); margin: 0 auto; padding: clamp(1.2rem, 2.5vw, 2rem); }
.app-nav-scrim { display: none; }

.page-section { display: grid; gap: 2rem; }
.page-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; }
.page-heading h1 { margin: .2rem 0 .65rem; font-size: clamp(2rem, 4vw, 3rem); line-height: 1.05; letter-spacing: -.045em; }
.page-heading > div:first-child > p:last-child { max-width: 690px; margin: 0; color: var(--muted); line-height: 1.6; }
.page-eyebrow, .client-card-kicker { margin: 0; color: var(--brand); font-size: .7rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; }
.page-summary { display: flex; align-items: baseline; gap: .45rem; padding: .7rem 1rem; flex: 0 0 auto; border: 1px solid #d6def1; border-radius: 999px; background: var(--brand-soft); color: #274788; }
.page-summary strong { font-size: 1.2rem; }
.page-summary span { font-size: .75rem; font-weight: 650; }
.page-summary-link { text-decoration: none; transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease; }.page-summary-link:hover { transform: translateY(-1px); border-color: #9eb3e6; box-shadow: 0 5px 16px rgba(36,87,214,.12); }.page-summary-link:focus-visible { outline: 3px solid #cbd9ff; outline-offset: 2px; }

.client-card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.1rem; }
.client-card { min-width: 0; padding: 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: 0 1px 2px rgba(24, 34, 47, .03); transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.client-card-link { display: block; text-decoration: none; }
.client-card:hover { transform: translateY(-2px); border-color: #d2d9e3; box-shadow: var(--shadow); }
.client-card-header { min-height: 3.3rem; display: flex; align-items: center; gap: .85rem; }
.client-card-monogram { display: grid; width: 2.8rem; height: 2.8rem; place-items: center; flex: 0 0 auto; border-radius: 13px; color: #24448e; background: var(--brand-soft); font-size: .78rem; font-weight: 800; letter-spacing: .03em; }
.client-card-header h2 { margin: .2rem 0 0; overflow: hidden; font-size: 1.03rem; line-height: 1.3; letter-spacing: -.015em; text-overflow: ellipsis; white-space: nowrap; }
.package-period-filter { width: fit-content; margin-bottom: 1.2rem; padding: .3rem; display: flex; gap: .25rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }.package-period-filter a { padding: .6rem .85rem; border-radius: 9px; color: var(--muted); text-decoration: none; font-size: .76rem; font-weight: 750; }.package-period-filter a[aria-current="page"] { color: white; background: var(--brand); box-shadow: 0 4px 10px rgba(36,87,214,.2); }
.client-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .55rem; margin: 1.25rem 0 0; }
.client-metric { min-width: 0; padding: .85rem .7rem; border-radius: 12px; background: #f4f6f8; }
.client-metric dt { min-height: 2.2em; color: var(--muted); font-size: .64rem; line-height: 1.15; }
.client-metric dd { margin: .35rem 0 0; font-size: 1.55rem; font-weight: 780; letter-spacing: -.04em; }
.client-metric-deliveries { background: var(--brand-soft); }.client-metric-deliveries dd { color: var(--brand); }
.client-metric-packages { background: var(--green-soft); }.client-metric-packages dd { color: var(--green); }
.client-metric-anomalies { background: var(--orange-soft); }.client-metric-anomalies dd { color: var(--orange); }
.client-metric-revenue { background: var(--brand-soft); }.client-metric-revenue dd { color: var(--brand); }
.client-metric-average { background: var(--green-soft); }.client-metric-average dd { color: var(--green); }
.revenue-metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.billing-line-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.revenue-panel-actions { display: flex; align-items: center; gap: .9rem; }.revenue-panel-actions > a:first-child { color: var(--brand); text-decoration: none; font-size: .78rem; font-weight: 750; white-space: nowrap; }
/* Les montants sans colis se lisent en une phrase plutot qu'en colonnes : a 400 px,
   un tableau de sept colonnes obligerait a defiler pour verifier un total. */
.billing-line-create-form { grid-template-columns: minmax(200px,1fr) minmax(200px,1fr) minmax(160px,.7fr); align-items: end; }.billing-line-create-form .form-wide { grid-column: 1 / -1; }.billing-line-create-form .scan-launch { grid-column: 1 / -1; justify-self: start; margin: 0; min-height: 2.85rem; }
.daily-units-jump { display: flex; align-items: end; gap: .6rem; }.daily-units-jump .scan-launch { margin: 0; min-height: 2.85rem; }.daily-units-help { margin: 0 0 1rem; color: var(--muted); font-size: .8rem; line-height: 1.55; }.daily-units-list { display: grid; gap: .65rem; }.daily-units-row { display: grid; grid-template-columns: minmax(0,1.5fr) 7.5rem minmax(0,1fr); align-items: center; gap: .85rem; padding: .85rem; border: 1px solid var(--line); border-radius: 12px; }.daily-units-identity strong { display: block; }.daily-units-identity span { display: block; margin-top: .15rem; color: var(--muted); font-size: .78rem; }.daily-units-identity small { display: block; margin-top: .2rem; color: var(--muted); font-size: .68rem; }.daily-units-count { margin: 0; }.daily-units-result { display: grid; justify-items: end; gap: .2rem; text-align: right; }.daily-units-result small { color: var(--muted); font-size: .72rem; }.daily-units-form > .scan-launch { margin-top: 1rem; }.daily-units-unpriced { display: flex; align-items: center; justify-content: space-between; }
@media (max-width: 720px) { .daily-units-row { grid-template-columns: minmax(0,1fr); }.daily-units-result { justify-items: start; text-align: left; }.daily-units-jump { flex-wrap: wrap; } }
.configured-billing-line { padding: .85rem; display: flex; align-items: center; justify-content: space-between; gap: .85rem; border: 1px solid var(--line); border-radius: 12px; }.billing-line-summary { margin: 0; font-size: .82rem; line-height: 1.6; }.billing-line-summary .anomaly-badge { margin: 0 .15rem; }
/* Ecrans de chiffre d'affaires ---------------------------------------------
   Les totaux etaient rendus dans la police courante, a chasse proportionnelle :
   deux montants empiles ne s'alignaient pas sur la virgule et il fallait les
   relire chiffre a chiffre pour savoir lequel etait le plus gros. Le libelle,
   pose au-dessus, arrivait aussi avant la valeur alors que c'est la valeur qu'on
   vient chercher. */
.revenue-figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); gap: .75rem; margin: 0; }
.revenue-figure { display: flex; flex-direction: column-reverse; padding: 1rem 1.15rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.revenue-figure dt { margin-top: .3rem; color: var(--muted); font-size: .74rem; font-weight: 700; }
.revenue-figure dd { margin: 0; font-size: clamp(1.55rem, 3.4vw, 2.15rem); font-weight: 800; line-height: 1.05; letter-spacing: -.045em; font-variant-numeric: tabular-nums; }
.revenue-figure-total { border-color: var(--brand); background: var(--brand-soft); }
.revenue-figure-total dd { color: var(--brand); }
.revenue-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.revenue-actions a { display: inline-flex; align-items: center; gap: .5rem; min-height: 2.85rem; padding: .6rem 1rem; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: var(--surface); text-decoration: none; font-size: .82rem; font-weight: 700; }
.revenue-actions a:hover { border-color: var(--brand); color: var(--brand); }
.revenue-actions a:focus-visible { outline: 3px solid var(--brand-soft); outline-offset: 1px; }
.revenue-actions .icone { width: 1.1rem; height: 1.1rem; }

.revenue-chart-peak { margin: 0; display: grid; justify-items: end; text-align: right; }
.revenue-chart-peak strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.revenue-chart-peak span { color: var(--muted); font-size: .72rem; }
.revenue-chart { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 .6rem; }
.revenue-chart-scale { display: flex; flex-direction: column; justify-content: space-between; margin: 0; padding: 0; list-style: none; color: var(--muted); font-size: .68rem; font-variant-numeric: tabular-nums; text-align: right; }
.revenue-chart-scale li { transform: translateY(-.35em); }
.revenue-chart-scale li:last-child { transform: translateY(.35em); }
/* Le trace est etire en largeur, jamais en hauteur : les barres gardent leur
   rapport de lecture et aucun texte n'entre dans le SVG, donc rien ne se deforme. */
.revenue-chart-plot { width: 100%; height: 11.25rem; overflow: visible; }
.revenue-chart-rule { stroke: var(--chart-grid); stroke-width: 1; vector-effect: non-scaling-stroke; }
.revenue-chart-base { stroke: var(--line); stroke-width: 2; vector-effect: non-scaling-stroke; }
.revenue-chart-bar { fill: var(--chart-bar); }
.revenue-chart-bar.is-peak { fill: var(--chart-bar-peak); }
.revenue-chart-axis { grid-column: 2; display: flex; justify-content: space-between; margin: .45rem 0 0; padding: 0; list-style: none; color: var(--muted); font-size: .68rem; font-variant-numeric: tabular-nums; }

.revenue-client-list { margin: 0; padding: 0; display: grid; gap: .9rem; list-style: none; }
.revenue-client { display: grid; gap: .3rem; }
.revenue-client-head { margin: 0; display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.revenue-client-head strong { min-width: 0; overflow: hidden; font-size: .92rem; text-overflow: ellipsis; white-space: nowrap; }
.revenue-client-total { flex: 0 0 auto; font-size: 1rem; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
/* La part de chaque client se lit d'abord a la longueur de la barre, et le
   pourcentage est ecrit juste dessous : imprime en noir et blanc, l'ecran garde
   exactement la meme information. */
.revenue-client-bar { width: 100%; height: .4rem; border: 0; border-radius: 999px; accent-color: var(--chart-bar); background: var(--canvas); }
.revenue-client-bar::-webkit-progress-bar { border-radius: 999px; background: var(--canvas); }
.revenue-client-bar::-webkit-progress-value { border-radius: 999px; background: var(--chart-bar); }
.revenue-client-bar::-moz-progress-bar { border-radius: 999px; background: var(--chart-bar); }
.revenue-client-facts { margin: 0; display: flex; justify-content: space-between; gap: 1rem; color: var(--muted); font-size: .74rem; font-variant-numeric: tabular-nums; }

/* Le compteur de scans etait ecrit « 12 scan(s) » : la parenthese de pluriel se
   lit mal a bout de bras dans un depot, et le titre dit deja de quoi on compte. */
.scan-history-count { padding: .3rem .6rem; border-radius: 999px; color: var(--brand); background: var(--brand-soft); font-size: .82rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.billing-line-summary { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .15rem 1rem; align-items: center; flex: 1 1 auto; min-width: 0; }
.billing-line-identity { margin: 0; display: grid; gap: .1rem; min-width: 0; }
.billing-line-identity strong { overflow: hidden; font-size: .9rem; text-overflow: ellipsis; white-space: nowrap; }
.billing-line-identity span { color: var(--muted); font-size: .78rem; }
.billing-line-meta { grid-column: 1; margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; color: var(--muted); font-size: .72rem; }
.billing-line-amount { grid-row: 1 / span 2; grid-column: 2; margin: 0; font-size: 1.1rem; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; text-align: right; }
.billing-line-fuel-table td:last-child, .package-table td strong { font-variant-numeric: tabular-nums; }
.empty-panel { padding: 4rem 2rem; border: 1px dashed #cdd5df; border-radius: var(--radius); text-align: center; background: rgba(255, 255, 255, .6); }
.empty-panel-icon { display: grid; width: 3rem; height: 3rem; margin: 0 auto 1rem; place-items: center; border-radius: 50%; background: var(--brand-soft); color: var(--brand); }
.empty-panel-icon .icone { width: 1.5rem; height: 1.5rem; }
.empty-panel h2 { margin: 0; }.empty-panel p { color: var(--muted); }
.notice { margin-bottom: 1rem; padding: .9rem 1rem; border-radius: 12px; font-size: .88rem; }
.notice-error { color: #8f2420; background: #feeceb; }.notice-success { color: #0b6944; background: #e3f6ed; }

.scan-page { display: grid; gap: 2.2rem; }.scan-heading { align-items: center; }.scan-launch { display: inline-flex; align-items: center; justify-content: center; gap: .55rem; min-height: 3.4rem; padding: .9rem 1.25rem; border: 0; border-radius: 14px; color: white; background: var(--brand); cursor: pointer; font-weight: 750; box-shadow: 0 10px 24px rgba(36,87,214,.25); }.scan-launch .icone { width: 1.35rem; height: 1.35rem; }.scan-feedback:empty { display: none; }.scan-feedback { padding: .85rem 1rem; border-radius: 12px; }.scan-feedback.is-success { color: #0b6944; background: var(--green-soft); }.scan-feedback.is-error { color: #8f2420; background: #feeceb; }.scan-history { padding: 1.3rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }.scan-history-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }.scan-history-heading h2 { margin: .2rem 0 0; }.scan-history-heading > span { color: var(--muted); font-size: .8rem; }.scan-history-list { display: grid; gap: .65rem; }.scan-history-item { position: relative; display: grid; grid-template-columns: auto minmax(0,1fr) auto auto; align-items: center; gap: .85rem; min-height: 3.6rem; padding: .9rem; border: 1px solid var(--line); border-radius: 12px; }.scan-history-item:focus-within { border-color: var(--brand); box-shadow: var(--shadow); }.scan-status-indicator { width: .7rem; height: .7rem; border-radius: 50%; background: var(--orange); }.scan-status-success .scan-status-indicator { background: var(--green); }.scan-status-failed .scan-status-indicator { background: var(--danger); }.scan-history-copy strong,.scan-history-copy time,.scan-history-copy small,.scan-history-open,.scan-history-address { display: block; }.scan-history-copy strong,.scan-history-open { color: var(--ink); font-weight: 750; text-decoration: none; }
/* Le titre etire sa zone cliquable a toute la carte : la ligne entiere est la
   cible tactile, et le bouton de reprise reste au-dessus d'elle. */
.scan-history-open::after { content: ""; position: absolute; inset: 0; border-radius: 12px; }.scan-history-address { margin-top: .1rem; color: var(--muted); font-size: .82rem; }.scan-history-copy time,.scan-history-copy small,.scan-status-label { color: var(--muted); font-size: .72rem; }.scan-history-failure { margin-top: .2rem; color: var(--danger); }.scan-status-label,.scan-review { position: relative; z-index: 1; }.scan-review { border: 0; color: var(--danger); background: transparent; cursor: pointer; font-size: .76rem; font-weight: 700; }.camera-dialog,.scan-review-dialog { width: 100%; max-width: none; height: 100%; max-height: none; padding: 0; border: 0; background: #05080c; }.camera-dialog::backdrop,.scan-review-dialog::backdrop { background: #05080c; }.camera-shell { height: 100%; display: grid; grid-template-rows: minmax(0,1fr) auto auto; color: white; }.camera-shell video { width: 100%; height: 100%; object-fit: contain; }.camera-controls { display: flex; align-items: center; justify-content: center; gap: 2rem; padding: 1rem; }.camera-controls button { color: white; background: transparent; border: 0; }.camera-controls .camera-shutter { width: 4.4rem; height: 4.4rem; border: .35rem solid white; border-radius: 50%; box-shadow: inset 0 0 0 .25rem #05080c; background: white; }.camera-shell > p { margin: 0; padding: 0 1rem 1.25rem; text-align: center; color: #c8d0da; }.scan-review-shell { min-height: 100%; padding: 1rem; display: grid; place-items: center; gap: 1rem; }.scan-review-shell img { max-width: 100%; max-height: 72vh; object-fit: contain; }.scan-dialog-close { justify-self: end; color: white; border: 0; background: transparent; font-size: 2rem; cursor: pointer; }
.client-admin-layout { display: grid; grid-template-columns: minmax(0,1.5fr) minmax(280px,.7fr); gap: 1.2rem; align-items: start; }.client-admin-panel { padding: 1.3rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }.client-admin-panel > h2 { margin: 0 0 1rem; }.configured-client-list { display: grid; gap: .65rem; }.configured-client { display: flex; align-items: center; gap: .85rem; padding: .85rem; border: 1px solid var(--line); border-radius: 12px; }.configured-client strong,.configured-client small { display: block; }.configured-client small { margin-top: .2rem; color: var(--muted); font-size: .72rem; }.client-admin-form { display: grid; gap: .65rem; }.client-admin-form label { margin-top: .35rem; font-size: .78rem; font-weight: 750; }.client-admin-form label span,.client-admin-form small { color: var(--muted); font-weight: 400; }.client-admin-form input,.client-admin-form select { width: 100%; padding: .8rem .9rem; border: 1px solid #cfd6df; border-radius: 10px; color: var(--ink); background: var(--surface); }.client-admin-form input:focus,.client-admin-form select:focus { outline: 3px solid #dce6ff; border-color: var(--brand); }.client-admin-form button { margin-top: .6rem; }
.territory-form { margin: 0 0 1rem; padding: 1rem; border-radius: 12px; background: var(--brand-soft); }.client-admin-form textarea { width: 100%; padding: .8rem .9rem; border: 1px solid #cfd6df; border-radius: 10px; resize: vertical; }.client-admin-form textarea:focus { outline: 3px solid #dce6ff; border-color: var(--brand); }
.clients-settings-page { gap: 1.2rem; }.settings-section-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }.settings-section-heading h2 { margin: .2rem 0 0; }.settings-section-heading > span { display: grid; min-width: 2.2rem; height: 2.2rem; padding: 0 .6rem; place-items: center; border-radius: 999px; color: var(--brand); background: var(--brand-soft); font-weight: 800; }.client-create-form { grid-template-columns: minmax(220px,1.5fr) minmax(180px,.8fr) auto; align-items: end; }.client-create-form .scan-launch { margin: 0; min-height: 2.85rem; }.configured-client-list .configured-client { display: grid; grid-template-columns: minmax(220px,1.5fr) minmax(180px,.8fr) auto; align-items: end; gap: .8rem; }.configured-client label { margin: 0; }.client-row-actions { display: flex; align-items: center; gap: .5rem; }.client-row-actions button { min-height: 2.7rem; margin: 0; padding: .65rem .8rem; border: 1px solid #cfd6df; border-radius: 9px; background: white; cursor: pointer; font-size: .75rem; font-weight: 700; }.client-row-actions .danger-button { color: var(--danger); border-color: #efc5c2; }.client-row-actions .danger-button:hover { background: #feeceb; }
.area-create-form { grid-template-columns: minmax(200px,.55fr) minmax(360px,1.45fr) auto; align-items: end; }.area-create-form .scan-launch { margin: 0 0 .05rem; }.configured-area-list .configured-area { display: grid; grid-template-columns: minmax(180px,.45fr) minmax(360px,1.55fr) auto; align-items: end; gap: .8rem; padding: 1rem; border: 1px solid var(--line); border-radius: 12px; }.configured-area label { margin: 0; }.configured-area textarea { min-height: 7rem; font-family: ui-monospace,SFMono-Regular,Menlo,monospace; font-size: .7rem; }

.invite-user-form { grid-template-columns: minmax(260px,1.6fr) minmax(200px,.9fr) auto; align-items: end; }.invite-user-form .scan-launch { margin: 0; min-height: 2.85rem; }
.configured-user-list .configured-user { grid-template-columns: minmax(160px,1fr) minmax(200px,1.3fr) minmax(180px,.95fr) auto; }
.configured-user label { display: grid; gap: .35rem; }.configured-user label > span:first-of-type { font-weight: 400; }
.role-chip, .status-chip { display: inline-flex; align-items: center; gap: .35rem; padding: .3rem .6rem; border-radius: 999px; color: var(--muted); background: #eef0f3; font-size: .66rem; font-weight: 750; letter-spacing: .01em; white-space: nowrap; }
.status-chip::before { content: ""; width: .45rem; height: .45rem; border-radius: 999px; background: currentColor; }
.role-chip-owner { color: #8b5717; background: var(--orange-soft); }
.role-chip-admin { color: #0b6944; background: var(--green-soft); }
.role-chip-dispatcher, .role-chip-driver { color: #274788; background: var(--brand-soft); }
.status-chip-active { color: #0b6944; background: var(--green-soft); }
.status-chip-disabled, .status-chip-locked, .status-chip-deletion_requested { color: #8f2420; background: #feeceb; }
.status-chip-pending_invite, .status-chip-pending_verification { color: #9a4318; background: var(--orange-soft); }
.configured-user-locked { align-items: center; }.configured-user-locked small { display: block; margin-top: .2rem; color: var(--muted); font-size: .72rem; }.configured-user-locked > div:last-child { display: grid; justify-items: end; gap: .3rem; }

.page-breadcrumb { display: flex; align-items: center; gap: .55rem; color: var(--muted); font-size: .78rem; }.page-breadcrumb a { color: var(--brand); text-decoration: none; font-weight: 700; }.package-table-shell { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }.package-table { width: 100%; border-collapse: collapse; }.package-table th { padding: .85rem 1rem; color: var(--muted); background: #f7f8fa; text-align: left; font-size: .7rem; letter-spacing: .05em; text-transform: uppercase; }.package-table td { padding: 1rem; border-top: 1px solid var(--line); vertical-align: middle; }.package-table-row { cursor: pointer; }.package-table-row:hover,.package-table-row:focus { outline: none; background: #f8faff; }.package-table td:first-child strong,.package-table td:first-child span { display: block; }.package-table td:first-child span { max-width: 500px; margin-top: .25rem; color: var(--muted); font-size: .78rem; }.anomaly-badge { display: inline-flex; padding: .35rem .55rem; border-radius: 999px; color: #9a4318; background: var(--orange-soft); font-size: .72rem; font-weight: 750; }.no-anomaly { color: var(--muted); font-size: .75rem; }.completion-value { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }.completion-value span { color: var(--muted); font-size: .7rem; }.package-table progress { width: 100%; height: .35rem; margin-top: .45rem; accent-color: var(--green); }.table-edit { border: 0; color: var(--brand); background: transparent; cursor: pointer; font-size: 1.7rem; }.package-edit-dialog { position: fixed; z-index: 80; inset: 0; width: 100%; max-width: none; height: 100%; max-height: none; margin: 0; padding: 0; border: 0; background: transparent; }.package-edit-backdrop { position: absolute; inset: 0; background: rgba(12,20,30,.56); }.package-edit-panel { position: absolute; inset: 0 0 0 auto; width: min(720px, 100%); height: 100%; overflow-y: auto; padding: clamp(1.2rem,4vw,2rem); background: var(--surface); box-shadow: -18px 0 55px rgba(12,20,30,.2); }.package-edit-panel > header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.4rem; }.package-edit-panel h2 { margin: .25rem 0 0; font-size: 1.6rem; }.overlay-close { border: 0; color: var(--muted); background: transparent; cursor: pointer; font-size: 2rem; line-height: 1; }.package-edit-form { display: grid; gap: 1rem; }.package-edit-form fieldset { margin: 0; padding: 1rem; display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .8rem; border: 1px solid var(--line); border-radius: 13px; }.package-edit-form legend { padding: 0 .35rem; font-size: .8rem; font-weight: 800; }.package-edit-form label { display: grid; gap: .35rem; color: #3a4654; font-size: .73rem; font-weight: 700; }.package-edit-form input,.package-edit-form select,.package-edit-form textarea { width: 100%; padding: .7rem .75rem; border: 1px solid #cfd6df; border-radius: 9px; color: var(--ink); background: white; }.package-edit-form textarea { resize: vertical; }.package-edit-form input:focus,.package-edit-form select:focus,.package-edit-form textarea:focus { outline: 3px solid #dce6ff; border-color: var(--brand); }.package-edit-form .form-wide { grid-column: 1 / -1; }.package-edit-form small { color: var(--muted); font-weight: 400; }.package-edit-form footer { position: sticky; bottom: -2rem; margin: .5rem -2rem -2rem; padding: 1rem 2rem; display: flex; align-items: center; justify-content: space-between; gap: 1rem; border-top: 1px solid var(--line); background: rgba(255,255,255,.95); }.package-edit-form footer > span { color: var(--muted); font-size: .75rem; }

.package-details-page { display: grid; gap: 1.2rem; }.package-details-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; }.package-details-heading h1 { margin: .2rem 0 0; font-size: clamp(1.8rem,3vw,2.5rem); letter-spacing: -.04em; }.autosave-status { padding: .45rem .7rem; border-radius: 999px; color: var(--green); background: var(--green-soft); font-size: .72rem; font-weight: 700; }.autosave-status[data-state="pending"],.autosave-status[data-state="saving"] { color: #8b5717; background: var(--orange-soft); }.autosave-status[data-state="error"] { color: var(--danger); background: #feeceb; }.autosave-status.htmx-request { opacity: .6; }.package-view-switcher { display: none; }.package-details-workspace { display: grid; grid-template-columns: minmax(320px,.9fr) minmax(520px,1.1fr); gap: 1.2rem; align-items: start; }.package-image-column { position: sticky; top: 1.2rem; display: grid; gap: .8rem; }.package-image-stage,.package-image-zoom { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: #e9edf2; }.package-image-stage { position: relative; min-height: 360px; height: min(48vh,520px); }.package-image-stage img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: contain; cursor: crosshair; }.package-image-zoom { height: min(25vh,230px); display: grid; place-items: center; color: var(--muted); background-repeat: no-repeat; font-size: .75rem; }.package-image-zoom.is-active span { visibility: hidden; }.package-form-column { min-width: 0; }.package-completion { margin: 0; padding: .8rem 1rem; border-radius: 12px; color: var(--muted); background: var(--brand-soft); font-size: .78rem; }.package-completion strong { color: var(--brand); font-size: 1rem; }.table-edit { display: inline-grid; place-items: center; text-decoration: none; }
.package-heading-actions,.package-row-actions { display: flex; align-items: center; gap: .6rem; }.package-rerun-button { padding: .48rem .7rem; border: 1px solid #ccd5e1; border-radius: 9px; color: #46566a; background: white; cursor: pointer; font-size: .72rem; font-weight: 700; }.package-rerun-button:hover { color: var(--brand); border-color: #9eb3e6; background: var(--brand-soft); }.package-row-actions form { margin: 0; }
.package-details-actions { display: flex; align-items: center; justify-content: flex-end; gap: .6rem; }
.scan-primary-action { display: flex; justify-content: flex-end; }

.auth-shell { width: min(460px, calc(100% - 2rem)); min-height: 100vh; margin: auto; padding: 5rem 0; display: flex; flex-direction: column; justify-content: center; }
.auth-brand { display: flex; align-items: center; gap: .65rem; align-self: center; margin-bottom: 1.5rem; text-decoration: none; font-size: 1.1rem; font-weight: 800; }
.auth-card { padding: clamp(1.5rem, 6vw, 2.5rem); border: 1px solid var(--line); border-radius: 22px; background: var(--surface); box-shadow: var(--shadow); }
.auth-card h1 { margin: .45rem 0 .75rem; font-size: 1.8rem; letter-spacing: -.035em; }
.auth-intro { margin: 0 0 1.6rem; color: var(--muted); line-height: 1.55; }
.auth-form { display: grid; gap: .75rem; }.auth-form label { font-size: .78rem; font-weight: 700; }
.auth-form input { width: 100%; padding: .85rem 1rem; border: 1px solid #cfd6df; border-radius: 11px; color: var(--ink); background: white; }
.auth-form input:focus { outline: 3px solid #dce6ff; border-color: var(--brand); }
.auth-form button { margin-top: .35rem; padding: .85rem 1rem; border: 0; border-radius: 11px; color: white; background: var(--brand); cursor: pointer; font-weight: 700; }
.auth-form button:hover { background: #1947bd; }
.auth-divider { margin: 1.3rem 0; color: var(--muted); font-size: .72rem; font-weight: 700; text-align: center; text-transform: uppercase; letter-spacing: .08em; }
.auth-dev-link { margin: .6rem 0 0; padding: .7rem .9rem; border-radius: 10px; color: #9a4318; background: var(--orange-soft); font-size: .78rem; }
.auth-secondary-button { width: 100%; margin-top: .9rem; padding: .85rem 1rem; border: 1px solid #cfd6df; border-radius: 11px; color: var(--ink); background: white; cursor: pointer; font-weight: 700; }
.auth-secondary-button:hover { border-color: var(--brand); background: var(--brand-soft); }
.auth-secondary-button:disabled { opacity: .6; cursor: wait; }
.auth-feedback:empty { display: none; }
.auth-feedback { margin: .7rem 0 0; font-size: .78rem; }
.auth-feedback.is-error { color: #8f2420; }
.auth-feedback.is-success { color: #0b6944; }

.passkey-feedback:empty { display: none; }
.passkey-feedback { margin: .5rem 0 0; font-size: .78rem; }
.passkey-feedback.is-error { color: #8f2420; }
.passkey-feedback.is-success { color: #0b6944; }
.configured-client-list .configured-passkey { grid-template-columns: minmax(160px,1fr) minmax(160px,1fr) auto; }

@media (max-width: 1040px) { .client-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) {
  .app-frame { display: block; }
  .app-sidebar { position: fixed; z-index: 40; inset: 0 auto 0 0; width: min(290px, 86vw); transform: translateX(-105%); transition: transform .22s ease; box-shadow: 18px 0 50px rgba(12, 20, 30, .2); }
  .nav-open .app-sidebar { transform: none; }
  /* Le telephone a deja son tiroir : le repli grand ecran ne doit rien y changer,
     sous peine de rendre les libelles illisibles aux livreurs. */
  .app-nav-collapse { display: none; }
  .nav-collapsed .app-frame { grid-template-columns: none; }
  .nav-collapsed .app-sidebar { padding-left: 1rem; padding-right: 1rem; }
  .nav-collapsed .app-sidebar-head { flex-direction: row; padding: .4rem .55rem 1.7rem; }
  .nav-collapsed .app-nav-link, .nav-collapsed .app-account-copy { justify-content: flex-start; gap: .75rem; }
  .nav-collapsed .app-nav-link { padding-left: .75rem; padding-right: .75rem; }
  .nav-collapsed .app-sidebar-account { padding-left: .55rem; padding-right: .55rem; }
  .nav-collapsed .app-signout { display: inline; width: auto; height: auto; margin-top: .75rem; }
  .nav-collapsed .app-signout-icon { display: none; }
  .nav-collapsed .app-brand > span:last-child,
  .nav-collapsed .app-nav-label,
  .nav-collapsed .app-nav-link > span:last-child,
  .nav-collapsed .app-account-copy > span:last-child,
  .nav-collapsed .app-signout > span { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; }
  .app-nav-scrim { position: fixed; z-index: 30; inset: 0; width: 100%; height: 100%; border: 0; background: rgba(12, 20, 30, .5); opacity: 0; pointer-events: none; transition: opacity .22s ease; }
  .nav-open .app-nav-scrim { display: block; opacity: 1; pointer-events: auto; }
  .app-topbar { position: sticky; z-index: 20; top: 0; min-height: 72px; padding: .65rem 1rem; align-items: flex-start; }
  .app-menu-button { display: grid; width: 2.4rem; height: 2.4rem; place-items: center; border: 1px solid var(--line); border-radius: 10px; background: white; color: var(--ink); cursor: pointer; }
  .app-mobile-brand { display: none; }
  .app-page-header { min-width: 0; gap: .25rem; }
  .app-page-header-row { align-items: center; gap: .6rem; }
  .app-page-header-copy { min-width: 0; }
  .app-page-header-copy .page-eyebrow,.app-page-header-copy > p:last-child:not(.page-eyebrow),.app-header-breadcrumb span { display: none; }
  .app-page-header-copy h1 { overflow: hidden; margin: .15rem 0; font-size: 1.25rem; text-overflow: ellipsis; white-space: nowrap; }
  .app-header-breadcrumb { font-size: .68rem; }
  .app-header-breadcrumb a { overflow: hidden; max-width: 42vw; text-overflow: ellipsis; white-space: nowrap; }
  .app-topbar .page-summary { padding: .45rem .65rem; gap: .3rem; }.app-topbar .page-summary strong { font-size: 1rem; }.app-topbar .page-summary span { display: none; }
  .app-main { padding: 1rem 1rem 2.5rem; }
  .revenue-chart-plot { height: 9rem; }
  .revenue-figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .revenue-actions a { flex: 1 1 auto; justify-content: center; }
  .billing-line-summary { grid-template-columns: minmax(0, 1fr); }.billing-line-amount { grid-row: auto; grid-column: 1; text-align: left; }
  .page-heading { align-items: flex-start; flex-direction: column; gap: 1rem; }.page-heading h1 { font-size: 2.1rem; }
  .client-card-grid { grid-template-columns: 1fr; }.client-card { padding: 1.1rem; }
  .scan-primary-action .scan-launch { width: 100%; min-height: 5rem; font-size: 1.05rem; }.scan-history { padding: .9rem; }.scan-history-item { grid-template-columns: auto minmax(0,1fr) auto; }.scan-review { grid-column: 2 / -1; justify-self: start; min-height: 44px; padding: .25rem 0; }
  .client-admin-layout { grid-template-columns: 1fr; }
  .billing-line-create-form { grid-template-columns: 1fr; }.configured-billing-line { align-items: flex-start; flex-direction: column; }
  .client-create-form,.configured-client-list .configured-client,.area-create-form,.configured-area-list .configured-area,.invite-user-form,.configured-user-list .configured-user { grid-template-columns: 1fr; }.client-row-actions { justify-content: flex-end; }.configured-user-locked { align-items: flex-start; }.configured-user-locked > div:last-child { justify-items: start; }
  .package-table th:nth-child(2),.package-table td:nth-child(2) { display: none; }.billing-line-fuel-table th:nth-child(2),.billing-line-fuel-table td:nth-child(2) { display: table-cell; }.package-table th,.package-table td { padding: .8rem; }.package-edit-form fieldset { grid-template-columns: 1fr; }.package-edit-form .form-wide { grid-column: auto; }.package-edit-form footer { bottom: -1.2rem; margin: .5rem -1.2rem -1.2rem; padding: 1rem 1.2rem; }
  .package-details-heading { align-items: flex-start; flex-direction: column; }.package-view-switcher { position: sticky; z-index: 10; top: 70px; padding: .3rem; display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }.package-view-switcher button { padding: .65rem; border: 0; border-radius: 9px; color: var(--muted); background: transparent; font-weight: 700; }.package-view-switcher button[aria-pressed="true"] { color: white; background: var(--brand); }.package-details-workspace { display: block; }.package-details-workspace [data-package-panel] { display: none; }.package-details-workspace[data-active-view="image"] [data-package-panel="image"],.package-details-workspace[data-active-view="form"] [data-package-panel="form"] { display: grid; }.package-image-column { position: static; }.package-image-stage { height: min(58vh,560px); min-height: 300px; }.package-image-zoom { display: none; }
  .invoices-toolbar { flex-direction: column; align-items: stretch; }.invoices-upload-bar { justify-content: center; }.invoices-upload-bar .invoice-upload-status { position: static; margin: .5rem 0 0; white-space: normal; text-align: center; }.invoices-filter-form { width: 100%; }.invoices-filter-field { flex: 1 1 120px; }.invoices-filter-field select { width: 100%; }.invoice-type-switch { width: 100%; }.invoice-type-option { flex: 1; }.invoice-type-option span { justify-content: center; }.invoice-period-field { flex: 1 1 100%; }.invoice-period-picker { width: 100%; }.invoice-period-month { flex: 1; }.invoice-export-link { justify-content: center; }
  /* HT/TVA/TTC (7,8,9) always stay visible and unclipped; only the
     compressible columns shrink further as the viewport narrows. */
  .invoices-table td:nth-child(2),.invoices-table td:nth-child(3) { max-width: 2.6rem; }
  .invoices-table td:nth-child(4) { max-width: 6.5rem; }
  .invoices-table td:nth-child(5),.invoices-table td:nth-child(6) { max-width: 3rem; }
  .invoices-table tfoot tr { display: flex; flex-wrap: wrap; gap: .3rem 1.1rem; }
  .invoices-table tfoot td { display: block; width: auto; padding: 0; border: 0; background: transparent; }
  .invoices-table tfoot td:first-child { flex-basis: 100%; }
  .invoices-table tfoot td:nth-child(2)::before { content: "HT "; color: var(--muted); font-weight: 650; }
  .invoices-table tfoot td:nth-child(3)::before { content: "TVA "; color: var(--muted); font-weight: 650; }
  .invoices-table tfoot td:nth-child(4)::before { content: "TTC "; color: var(--muted); font-weight: 650; }
}
@media (max-width: 390px) { .client-metrics { grid-template-columns: 1fr; }.client-metric { display: flex; align-items: center; justify-content: space-between; }.client-metric dt { min-height: 0; }.client-metric dd { margin: 0; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; } }
.app-main:has(.invoices-page) { width: 100%; max-width: none; }
.invoices-page { display: flex; flex-direction: column; gap: .6rem; min-height: calc(100vh - 13rem); }
.invoices-filter-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .7rem; }
.invoices-filter-field { display: grid; gap: .35rem; }
.invoices-filter-field > span { color: #46566a; font-size: .66rem; font-weight: 750; letter-spacing: .04em; text-transform: uppercase; }
.invoices-filter-field select { min-height: 2.65rem; padding: 0 2rem 0 .85rem; border: 1px solid #cfd6df; border-radius: 10px; color: var(--ink); background: white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%236d7785' stroke-width='1.6'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E") no-repeat right .6rem center; background-size: 1rem; -webkit-appearance: none; appearance: none; cursor: pointer; font-size: .82rem; font-weight: 650; transition: border-color .15s ease, box-shadow .15s ease; }
.invoices-filter-field select:hover { border-color: #b7c2d1; }
.invoices-filter-field select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px #dce6ff; }
.invoice-type-switch { display: inline-flex; min-height: 2.65rem; padding: .25rem; gap: .2rem; border: 1px solid #cfd6df; border-radius: 10px; background: #f7f8fa; }
.invoice-type-option { position: relative; display: flex; }
.invoice-type-option input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.invoice-type-option span { display: flex; align-items: center; padding: 0 .9rem; border-radius: 7px; color: var(--muted); font-size: .8rem; font-weight: 700; white-space: nowrap; transition: color .15s ease, background .15s ease, box-shadow .15s ease; }
.invoice-type-option:has(input:checked) span { color: white; background: var(--brand); box-shadow: 0 4px 10px rgba(36,87,214,.25); }
.invoice-type-option:has(input:hover) span { color: var(--ink); }
.invoice-type-option:has(input:checked:hover) span { color: white; }
.invoice-type-option:has(input:focus-visible) span { outline: 3px solid #dce6ff; outline-offset: 1px; }
.avoir-badge { display: inline-flex; padding: .12rem .45rem; border-radius: 999px; color: #9a4318; background: var(--orange-soft); font-size: .64rem; font-weight: 750; }
.invoice-avoir-field { display: flex !important; flex-wrap: wrap; align-items: center; gap: .5rem; }
.invoice-avoir-field input { width: auto; }
.invoice-avoir-field small { flex-basis: 100%; }
.invoice-period-field { gap: .35rem; }
.invoice-period-picker { display: flex; align-items: stretch; min-height: 2.65rem; border: 1px solid #cfd6df; border-radius: 10px; background: white; overflow: hidden; transition: border-color .15s ease, box-shadow .15s ease; }
.invoice-period-picker:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px #dce6ff; }
.invoice-period-nav { display: grid; flex: 0 0 auto; width: 2rem; place-items: center; border: 0; color: var(--muted); background: #f7f8fa; cursor: pointer; font-size: 1.05rem; line-height: 1; transition: color .15s ease, background .15s ease; }
.invoice-period-nav:hover { color: var(--brand); background: var(--brand-soft); }
.invoice-period-nav:first-child { border-right: 1px solid var(--line); }
.invoice-period-nav:last-child { border-left: 1px solid var(--line); }
.invoice-period-month, .invoice-period-year { border: 0; background: transparent; color: var(--ink); text-align: center; font-size: .82rem; font-weight: 700; }
.invoice-period-month { padding: 0 1.6rem 0 .7rem; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%236d7785' stroke-width='1.6'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right .35rem center; background-size: .9rem; -webkit-appearance: none; appearance: none; cursor: pointer; border-right: 1px solid var(--line); }
.invoice-period-year { width: 4.1rem; padding: 0 .5rem; -moz-appearance: textfield; }
.invoice-period-year::-webkit-inner-spin-button, .invoice-period-year::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.invoice-period-month:focus, .invoice-period-year:focus { outline: none; }
.invoices-toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem; }
.invoices-upload-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; position: relative; }
.invoice-upload-trigger { display: grid; flex: 0 0 auto; width: 3.2rem; height: 3.2rem; place-items: center; border: 0; border-radius: 999px; color: white; cursor: pointer; background: var(--brand); box-shadow: 0 10px 24px rgba(36,87,214,.28); transition: transform .18s ease, filter .18s ease; }
.invoice-upload-trigger span { font-size: 1.6rem; font-weight: 700; line-height: 1; }
.invoice-upload-trigger:hover { transform: translateY(-1px); filter: brightness(1.06); }
.invoice-upload-trigger:focus-visible { outline: 3px solid #dce6ff; outline-offset: 2px; }
.invoice-upload-status:empty { display: none; }
.invoice-upload-status { position: absolute; top: 100%; right: 0; margin-top: .5rem; padding: .5rem .8rem; border-radius: 10px; color: var(--brand); background: var(--brand-soft); font-size: .78rem; font-weight: 700; white-space: nowrap; }
.invoice-upload-form { margin: 0; }
#invoice-upload-file { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* Data-grid density: small text, tight cells, HT/TVA/TTC always full width
   and never truncated; every other column compresses (ellipsis) first. */
.invoices-table-shell { flex: 1; }
.invoices-table { table-layout: auto; }
.invoices-table th { padding: .4rem .55rem; font-size: .62rem; }
.invoices-table td { padding: .4rem .55rem; font-size: .78rem; }
.invoices-table td:first-child { width: 1%; padding-right: 0; white-space: nowrap; }
.invoices-table td:nth-child(2), .invoices-table td:nth-child(3), .invoices-table td:nth-child(4), .invoices-table td:nth-child(5), .invoices-table td:nth-child(6) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.invoices-table td:nth-child(2), .invoices-table td:nth-child(3) { max-width: 5.5rem; }
.invoices-table td:nth-child(4) { max-width: 15rem; }
.invoices-table td:nth-child(5) { max-width: 6rem; }
.invoices-table td:nth-child(6) { max-width: 5.5rem; }
.invoices-table td:nth-child(7), .invoices-table td:nth-child(8), .invoices-table td:nth-child(9) { white-space: nowrap; }
.invoices-table tfoot td { padding: .5rem .55rem; border-top: 2px solid var(--line); color: var(--ink); background: #f7f8fa; font-size: .78rem; font-weight: 750; }
.invoices-table tfoot td:first-child { color: var(--muted); font-weight: 650; }
.invoices-table tfoot td:nth-child(n+2) { text-align: right; }
.invoice-export-link { display: inline-flex; flex: 0 0 auto; align-items: center; gap: .45rem; padding: .6rem .95rem; border: 1px solid #d6def1; border-radius: 999px; color: #274788; background: var(--brand-soft); text-decoration: none; font-size: .76rem; font-weight: 750; transition: border-color .18s ease, transform .18s ease; }
.invoice-export-link:hover { transform: translateY(-1px); border-color: #9eb3e6; }
.invoice-export-link .icone { width: 1rem; height: 1rem; }
.status-dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 999px; background: var(--muted); }
.status-dot-validated { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }
.status-dot-needs_review { background: var(--orange); box-shadow: 0 0 0 3px var(--orange-soft); }
.status-dot-failed { background: var(--danger); box-shadow: 0 0 0 3px #feeceb; }
.status-dot-draft { background: var(--muted); box-shadow: 0 0 0 3px #eef0f3; }


/* --- Capture guidée --------------------------------------------------------
   Le contour détecté est superposé au flux vidéo : vert quand la prise de vue
   est autorisée, orange sinon. Le déclencheur reste inactif tant que
   l'étiquette n'est pas exploitable — c'est cette contrainte qui rend le
   cadrage reproductible d'un colis à l'autre. */
/* --- Viseur de la capture guidée -------------------------------------------
   Trois exigences qui se contraignent l'une l'autre, et qu'il faut tenir
   ensemble :

   1. La vidéo ne doit JAMAIS déborder de l'écran. Son image fait 720 px de
      large ; laissée à sa taille naturelle sur un téléphone de 412 px, elle
      débordait et le navigateur dézoomait la page entière pour la faire
      tenir — commandes comprises. D'où `width`/`height` à 100 % du cadre,
      avec `object-fit: contain`, qui ne dépasse par construction.

   2. Le cadre ne doit jamais recouvrir les commandes. Sa ligne de grille est
      bornée (`minmax(0, 1fr)` en hauteur comme en largeur) et il ne la
      déborde pas.

   3. Le viseur doit désigner EXACTEMENT la zone qui sera découpée à la
      capture. C'est la plus importante : un décalage ferait viser l'agent à
      côté sans que rien ne le lui signale. Comme `contain` laisse des bandes
      quand les proportions diffèrent, la taille et la position du calque ne
      peuvent pas être décrites en CSS — app.js les calcule à partir de
      l'image réellement affichée. Ici on se contente de superposer le calque
      à la vidéo dans la même cellule. */
.camera-shell { grid-template-columns: minmax(0, 1fr); }

.camera-frame {
  display: grid; place-items: center;
  height: 100%; min-height: 0; width: 100%; min-width: 0;
  overflow: hidden; line-height: 0;
}
.camera-frame > video,
.camera-frame > .camera-overlay { grid-area: 1 / 1; }

.camera-frame video {
  display: block; width: 100%; height: 100%; object-fit: contain;
}
.camera-overlay { pointer-events: none; }

.camera-status {
  transition: color .15s ease;
}
.camera-status.is-ready { color: #16a34a; font-weight: 600; }.camera-shell > .camera-read { padding: .6rem 1rem; color: white; font-size: 1.15rem; font-weight: 750; line-height: 1.35; white-space: pre-line; }.camera-shell > .camera-read:empty { display: none; }.camera-shell > .camera-read.is-unread { color: var(--orange); }
/* Déclencheur inactif : visible mais clairement non cliquable. L'agent
   comprend qu'il doit corriger le cadrage, pas que l'application est figée. */
.camera-shutter[disabled] {
  opacity: .4; cursor: not-allowed; filter: grayscale(1);
}
.camera-shutter.is-ready {
  box-shadow: 0 0 0 4px rgba(22,163,74,.35);
}

/* --- Client de la tournée --------------------------------------------------
   L'agent choisit son client en arrivant au dépôt et enchaîne les colis. Le
   bandeau reste visible en permanence : après quarante photos sans revenir en
   arrière, il doit pouvoir vérifier d'un coup d'oeil sur quel compte il
   travaille.

   Pas de logo de transporteur : ce sont des marques déposées. À la place, un
   monogramme — deux lettres sur une pastille dont la TEINTE est dérivée du nom.
   Elle ne change jamais pour un client donné, ce qui le rend reconnaissable
   sans lecture. Le jour où un vrai logo est téléversé, il prend exactement la
   même place. */

/* Le logo officiel et le monogramme de repli occupent la MEME boîte : le
   gabarit ne bouge pas selon qu'une marque dispose d'un logo libre ou non. */
.scan-client-logo {
  flex: 0 0 auto;
  width: 48px; height: 44px;
  object-fit: contain;           /* jamais de logo étiré : la marque y perdrait */
  object-position: center;
}
.scan-client-logo[hidden] { display: none; }

.scan-client-mark {
  --client-hue: 220;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 12px;
  font-weight: 700; font-size: .95rem; letter-spacing: .02em;
  color: hsl(var(--client-hue) 62% 32%);
  background: hsl(var(--client-hue) 82% 94%);
  border: 1px solid hsl(var(--client-hue) 55% 84%);
}

.scan-client-bar {
  display: flex; align-items: center; gap: 12px;
  /* Sans `min-width: 0`, la taille minimale automatique d'un élément de
     grille est sa largeur de contenu INSÉCABLE. Le nom du client étant en
     `nowrap`, le bandeau réclamait 754 px : il débordait de l'écran, et le
     téléphone dézoomait la page entière — jusqu'aux commandes de l'appareil
     photo, qui devenaient minuscules et mal placées. L'ellipse ne peut jouer
     que si l'on autorise d'abord le rétrécissement. */
  min-width: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 16px; margin-bottom: 12px;
}
/* `display: flex` l'emporte sur la feuille par défaut du navigateur : sans
   cette règle, le bandeau reste visible — vide — alors que le script lui a
   posé `hidden`. Même piège pour tout élément stylé en flex/grid. */
.scan-client-bar[hidden], .scan-client-alert[hidden] { display: none; }

.scan-client-identity { flex: 1 1 auto; min-width: 0; }
/* Même précaution pour la page qui accueille le bandeau : une colonne bornée
   ne peut plus être élargie par un seul contenu récalcitrant. */
.scan-page { grid-template-columns: minmax(0, 1fr); }
/* Le nom peut être long ("Eurocoop Alpes Maritimes") : il tronque proprement
   plutôt que de pousser le bouton hors de l'écran. */
.scan-client-bar strong {
  display: block; color: var(--brand); font-size: 1.15rem; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.scan-client-change {
  flex: 0 0 auto;
  background: var(--brand-soft); color: var(--brand); border: 0;
  border-radius: 999px; padding: 10px 18px; font-weight: 600; cursor: pointer;
  min-height: 44px;              /* cible tactile : l'agent porte des gants */
}
.scan-client-change:hover, .scan-client-change:focus-visible {
  background: var(--brand); color: #fff;
}

/* Avertissement, pas erreur : le colis est enregistré, il part simplement en
   vérification. L'agent continue de photographier. */
.scan-client-alert {
  background: var(--orange-soft); color: var(--orange);
  border: 1px solid var(--orange); border-radius: var(--radius);
  padding: 12px 16px; margin-bottom: 12px; font-weight: 600;
}

/* Choix plein écran. L'agent est debout, souvent ganté, et vise au pouce :
   une liste déroulante serait inutilisable dans ce contexte. */
.scan-client-picker {
  border: 0; border-radius: var(--radius); padding: 0;
  width: min(560px, 94vw); max-height: 88vh; overflow: auto;
}
.scan-client-picker::backdrop { background: rgba(24, 34, 47, .55); }
.scan-client-shell { background: var(--surface); padding: 24px; }
.scan-client-shell h2 { margin: 2px 0 0; }

/* Une colonne sur téléphone — le cas d'usage réel. Plusieurs colonnes dès que
   la place existe, sans jamais descendre sous une cible confortable. */
.scan-client-list {
  display: grid; gap: 10px; margin-top: 16px;
  /* `minmax(0, ...)` et non `1fr` seul : le minimum implicite de `1fr` est la
     largeur du CONTENU. Avec un nom d'agence long, la colonne s'élargissait au
     lieu de le tronquer, et le dialogue débordait de l'écran.

     `auto-fit` fait le responsive sans point de rupture : les colonnes se
     créent quand la largeur le permet, et un client unique occupe toute la
     ligne au lieu de rester à l'étroit dans une demi-colonne vide. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
}

.scan-client-option {
  display: flex; align-items: center; gap: 12px; width: 100%;
  text-align: left; padding: 14px 16px; min-height: 68px;
  font-size: 1.05rem; font-weight: 600; color: var(--ink);
  min-width: 0;                  /* autorise l'ellipse du nom à l'intérieur */
  background: var(--canvas); border: 1px solid var(--line);
  border-radius: var(--radius); cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
/* Deux lignes, pas une. Le nom en base est un nom d'AGENCE — "GEODIS
   MEDITERRANEE Agence de Nice Gare St Roch" — et deux agences du même
   transporteur ne se distinguent que par la fin. Tronquer à une ligne les
   rendrait identiques à l'écran. Deux lignes suffisent et bornent la hauteur
   du bouton, donc la place occupée par la liste.

   Trois lignes et non deux : c'est la FIN du nom qui distingue deux agences du
   même transporteur, et deux lignes la coupaient encore. */
.scan-client-label {
  min-width: 0; overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  line-height: 1.25;
}
.scan-client-option:hover, .scan-client-option:focus-visible {
  background: var(--brand-soft); border-color: var(--brand); color: var(--brand);
}
.scan-client-option:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Rappel dans le viseur : quarante photos d'affilée sans revenir à la liste,
   le client actif doit rester sous les yeux. */
.camera-client {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  color: var(--brand); font-weight: 600; margin-bottom: 4px;
}

/* Téléphone en paysage : la hauteur devient la ressource rare, on comprime le
   superflu plutôt que de faire défiler. */
@media (max-height: 520px) {
  .scan-client-shell { padding: 16px; }
  .scan-client-option { min-height: 56px; padding: 10px 14px; }
  .scan-client-mark { width: 36px; height: 36px; }
  .scan-client-logo { width: 40px; height: 36px; }
}

/* --- Colis retenus au contrôle ---------------------------------------------
   Le pendant visible du filtre pose sur les listes de tournee. Sans lui, les
   colis ecartes disparaitraient au lieu d'etre traites.

   Ton orange et non rouge : ce n'est pas une panne, c'est une decision qui
   attend quelqu'un. Le rouge est reserve a ce qui est casse. */
.package-review {
  margin-bottom: 1.5rem; padding: 1.2rem 1.3rem;
  background: var(--orange-soft); border: 1px solid var(--orange);
  border-radius: var(--radius);
}
.package-review-header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.package-review-header h2 { margin: .1rem 0 0; color: var(--orange); }
/* Le compte se lit avant la liste : c'est lui qui dit s'il faut s'arreter. */
.package-review-count {
  flex: 0 0 auto; min-width: 2.4rem; padding: .3rem .7rem;
  border-radius: 999px; text-align: center;
  font-weight: 700; color: #fff; background: var(--orange);
}
.package-review-intro { margin: .5rem 0 1rem; color: #8a4a18; font-size: .85rem; }
.package-review-list { display: grid; gap: .55rem; margin: 0; padding: 0; list-style: none; }
.package-review-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: .9rem;
  padding: .7rem .9rem; background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px;
}
/* Le motif d'abord : il dit quel geste faire, et ils sont tous differents. */
.package-review-kind {
  flex: 0 0 auto; padding: .25rem .6rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700; white-space: nowrap;
  color: var(--orange); background: var(--orange-soft);
}
.package-review-kind[data-kind="out_of_territory"] { color: var(--brand); background: var(--brand-soft); }
.package-review-kind[data-kind="image_unusable"] { color: #8f2420; background: #feeceb; }
.package-review-copy { min-width: 0; }
.package-review-copy strong,
.package-review-copy small,
.package-review-address { display: block; }
/* L'adresse ne se tronque PAS sur une ligne : sur telephone, "288 Chemin des
   Meillieres Est, 06140 Vence" coupe au tiers ne permet plus de reconnaitre le
   colis. Elle passe a la ligne, jusqu'a deux, et le bloc garde une hauteur
   previsible. */
.package-review-address {
  margin-top: .1rem; color: var(--ink); font-size: .82rem; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
/* Les motifs sont parfois longs ("3 champs requis sur 14 renseignés") : ils
   tronquent plutot que d'elargir la ligne et de faire deborder la page. */
.package-review-copy small {
  color: var(--muted); font-size: .74rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Cible tactile pleine : l'admin ouvre la fiche depuis son telephone. */
.package-review-open {
  flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 44px;
  padding: .45rem .9rem; border-radius: 999px;
  font-size: .78rem; font-weight: 600;
  color: var(--brand); background: var(--brand-soft); text-decoration: none;
}
.package-review-open:hover, .package-review-open:focus-visible {
  color: #fff; background: var(--brand);
}

/* Telephone : le motif passe au-dessus, la ligne reste lisible sans defiler. */
@media (max-width: 560px) {
  .package-review-item { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
  .package-review-kind { grid-column: 1 / -1; justify-self: start; }
  .package-review-open { align-self: center; }
}

/* Boite de confirmation destructrice, unique pour tout le site (dialog#data-confirm-dialog
   dans app-layout.html, pilotee par app.js). Conforme aux Apple HIG sur les alertes
   destructrices : le titre porte la consequence, deux boutons seulement, l'action rouge
   n'est jamais le choix par defaut. */
.confirm-dialog { max-width: min(26rem, calc(100vw - 2rem)); margin: auto; padding: 1.5rem; border: 0; border-radius: var(--radius); color: var(--ink); background: var(--surface); box-shadow: var(--shadow); }
.confirm-dialog::backdrop { background: var(--veil); }
.confirm-dialog[open] { display: grid; gap: 1.25rem; }
#confirm-dialog-title { margin: 0; font-size: 1.05rem; font-weight: 800; line-height: 1.35; }
/* N'apparait que lorsque la suppression emporte autre chose avec elle : le titre
   seul ne peut pas chiffrer ce qui part (baremes, factures...). */
.confirm-dialog [data-confirm-dialog-message] { margin: -.5rem 0 0; color: var(--muted); font-size: .9rem; line-height: 1.4; }
.confirm-dialog-actions { display: flex; justify-content: flex-end; gap: .65rem; }
.confirm-dialog-actions button { min-height: 2.75rem; min-width: 6rem; padding: 0 1.1rem; border-radius: 10px; font-weight: 700; cursor: pointer; }
.confirm-dialog-cancel { order: 1; border: 1px solid var(--line); color: var(--ink); background: var(--surface); }
.confirm-dialog-cancel:hover { background: var(--canvas); }
.confirm-dialog-confirm { order: 2; }

/* Base d'un bouton destructeur hors des rangees de reglages (celles-ci le
   colorent deja via .client-row-actions .danger-button) : la fiche colis en
   a besoin seule, en pied d'action. */
.danger-button { border: 0; color: white; background: var(--danger); }
.danger-button:hover { background: #a92a24; }
.package-delete-button { min-height: 2.85rem; padding: 0 1.1rem; border-radius: 10px; font-weight: 700; cursor: pointer; }

/* Livreur sur telephone, dehors, a une main : la boite devient une feuille
   ancree en bas de l'ecran, les deux boutons pleine largeur et empiles --
   aucune cible etroite a viser du pouce. */
@media (max-width: 480px) {
  .confirm-dialog { position: fixed; inset: auto 0 0 0; max-width: none; width: 100%; margin: 0; border-radius: var(--radius) var(--radius) 0 0; padding: 1.25rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom)); }
  .confirm-dialog-actions { flex-direction: column-reverse; }
  .confirm-dialog-actions button { width: 100%; min-height: 3.1rem; }
}
