/* ================================================================
   ClimPro — polices hébergées localement (point 111).
   Auparavant chargées depuis Google Fonts : un fichier de 1,7 Ko qui
   coûtait 750 ms sur 4G lente, uniquement à cause de l'ouverture d'une
   connexion vers un serveur externe. En local, ce coût disparaît et les
   polices deviennent disponibles hors-ligne comme le reste de l'appli.
   Seuls latin et latin-ext sont conservés (suffisant pour le français),
   et seules les graisses réellement utilisées sont téléchargées.
   Régénéré depuis Google Fonts le 25/07/2026.
   ================================================================ */
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/jetbrains-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/jetbrains-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/jetbrains-mono-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/jetbrains-mono-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/mulish-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/mulish-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/mulish-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/mulish-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/mulish-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/mulish-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/mulish-800-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/mulish-800-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/syne-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/syne-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/syne-800-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(fonts/syne-800-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ================================================================
   ClimPro — Feuille de style (extraite de index.html le 24/07/2026).
   Chargée par index.html via <link rel="stylesheet">.
   ================================================================ */
:root{
  /* Encre & structure */
  --bd:#123a4c;        /* bleu-encre profond : topbar, titres, structure */
  --bd-deep:#0c2836;   /* extrémité la plus sombre des dégradés */
  --ink:#153039;       /* texte principal */
  /* Action (l'unique couleur d'action) — personnalisable par tenant, voir
     applyAccentColor() ; --azure-rgb doit toujours rester en phase avec --azure */
  --azure:#1580ad;     /* azur : boutons, focus, éléments actifs */
  --azure-rgb:21,128,173;
  --azure-deep:#0f6a92;/* état pressé / bas du dégradé bouton */
  --azure-hi:#1a8dbd;  /* haut du dégradé bouton */
  /* Dégradé de la barre du haut — suit lui aussi la couleur personnalisée
     du tenant (voir applyAccentColor()) ; valeurs par défaut = design de base */
  --topbar-1:#164457;
  --topbar-2:#123a4c;
  /* Fonds frais & clairs */
  --bg:#eef4f7;        /* fond de page */
  --card:#ffffff;
  --lt:#e2eff5;        /* remplissage bleu clair (boutons ghost, icônes) */
  --hair:#d9e6ed;      /* bordures fines (définition « carnet ») */
  /* Accents */
  --gold:#bf8a2e;      /* accent artisanal, usage rare */
  --muted:#4f6b7a;     /* texte secondaire — lisible (contraste ≈ 5:1) */
  --muted-soft:#7b96a4;/* purement décoratif */
  /* Statuts */
  --ok:#1f9152;        /* vendu / synchro OK */
  --warn:#d98a2b;      /* en attente sync */
  --danger:#cf4b4b;
  /* Rayons */
  --r-sm:10px;
  --r-md:14px;
  --r-lg:18px;
  --radius:18px;       /* cartes */
  /* Profondeur — une ombre de carte unique + variantes flottantes */
  --shadow:0 2px 14px rgba(18,58,76,.09),0 1px 2px rgba(18,58,76,.05);
  --shadow-lg:0 16px 44px rgba(12,40,54,.24);
  --shadow-azure:0 6px 18px rgba(var(--azure-rgb),.34);
  --mono:'JetBrains Mono',ui-monospace,monospace;
  /* ---- Socle visuel (points 76/86) : échelle typographique officielle ----
     Toute nouvelle taille de texte DOIT venir de cette liste (voir DESIGN.md).
     15 paliers au lieu des 30 valeurs libres accumulées au fil des ajouts. */
  /* Revue design, constat 10 (03/09/2026) : quinze paliers dont sept entre
     0,64 et 0,90 rem, indistinguables à l'œil, et trois sous 12 px — illisibles
     au soleil. Les NOMS sont conservés (aucun code à toucher), les VALEURS sont
     ramenées à neuf paliers, avec un plancher à 0,75 rem = 12 px pour tout ce
     qui informe. Les noms marqués « = » sont des alias d'un même palier. */
  --fs-display-xl:2.8rem; /* titre de l'écran de connexion */
  --fs-display-l:1.7rem;  /* titre de la carte de connexion */
  --fs-display-m:1.3rem;  /* grands pictogrammes, titres de fenêtre */
  --fs-display-s:1.3rem;  /* = display-m */
  --fs-title:1.15rem;     /* titre de la barre du haut, icônes de section */
  --fs-card-title:1.05rem;/* nom du client, en-tête de fiche */
  --fs-body:1rem;         /* texte courant, champs, boutons */
  --fs-btn:1rem;          /* = body */
  --fs-body-sm:.9rem;     /* textes d'appoint, détails des cartes */
  --fs-detail:.9rem;      /* = body-sm */
  --fs-small:.8rem;       /* sous-titres, aides, pastilles, légendes */
  --fs-small-xs:.8rem;    /* = small */
  --fs-tiny:.8rem;        /* = small */
  --fs-tiny-xs:.75rem;    /* plancher : 12 px — pastilles d'état, badges */
  --fs-label:.75rem;      /* = tiny-xs */
  /* Compléments d'arrondis du socle */
  --r-pill:100px;         /* pilules (pastilles, filtres, bouton flottant) */
  --r-sheet:24px;         /* feuilles surélevées : carte de connexion, fenêtres */
  --safe-b:env(safe-area-inset-bottom,0px);
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html{font-size:16px;}
body{font-family:'Mulish',sans-serif;background:var(--bg);color:var(--ink);min-height:100vh;line-height:1.5;-webkit-font-smoothing:antialiased;}
h1,h2,h3{font-family:'Syne',sans-serif;letter-spacing:-.02em;line-height:1.1;text-wrap:balance;}
button{font-family:inherit;cursor:pointer;border:none;background:none;}
input,textarea,select{font-family:inherit;font-size:var(--fs-body);}
/* Point 62 : en plus du message toast générique ("Remplissez les champs"),
   surligne directement le(s) champ(s) en cause — évite d'avoir à deviner. */
.input-err{border-color:var(--danger)!important;box-shadow:0 0 0 3px rgba(207,75,75,.15)!important;}
/* Point 63 : les mots de passe qu'on saisit pour quelqu'un d'autre (créer un
   utilisateur, en changer un, créer un tenant) restent masqués par défaut,
   comme à la connexion — avec un œil pour les relire avant de les transmettre. */
.pwd-field{position:relative;}
.pwd-field input{padding-right:2.6rem!important;}
.pwd-toggle{position:absolute;top:50%;right:.55rem;transform:translateY(-50%);font-size:var(--fs-card-title);color:var(--muted);padding:.3rem;line-height:1;}
::selection{background:rgba(var(--azure-rgb),.2);}
.view{display:none;}
.view.active{display:block;}

/* ============ TOPBAR ============ */
.topbar{position:sticky;top:0;z-index:50;background:linear-gradient(180deg,var(--topbar-1),var(--topbar-2));color:#fff;padding:.9rem 1rem;display:flex;align-items:center;gap:.7rem;box-shadow:0 4px 20px rgba(12,40,54,.3);}
.topbar h1{font-size:var(--fs-title);font-weight:800;letter-spacing:-.01em;flex:1;min-width:0;display:block;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.topbar h1.long{font-size:var(--fs-body);}
.company-tag{display:none;font-size:var(--fs-small-xs);font-weight:700;color:#cfe6f0;background:rgba(255,255,255,.13);padding:.24rem .6rem;border-radius:var(--r-pill);white-space:nowrap;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);}
@media(min-width:640px){.company-tag{display:inline-block;}}
/* Point 64 : contrairement au nom d'entreprise, le prénom de la personne
   connectée reste visible même sur petit écran (pas de @media ici) — c'est
   l'info la plus utile quand plusieurs comptes partagent le même téléphone. */
.user-tag{display:inline-block;font-size:var(--fs-small-xs);font-weight:700;color:#cfe6f0;background:rgba(255,255,255,.13);padding:.24rem .6rem;border-radius:var(--r-pill);white-space:nowrap;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);}
.user-tag:empty{display:none;}
/* flex-shrink:0 : sans lui, un voisin large (la pastille de synchronisation)
   comprimait le bouton jusqu'à le rendre intouchable au doigt. */
.topbar .back{font-size:var(--fs-display-m);color:#cfe6f0;width:38px;height:38px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border-radius:var(--r-sm);transition:background .15s;}
.topbar .back:active{background:rgba(255,255,255,.16);}
.btn-icon{font-size:var(--fs-display-m);color:#cfe6f0;width:38px;height:38px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border-radius:var(--r-sm);transition:background .15s;}
.btn-icon:active{background:rgba(255,255,255,.16);}
.sync-pill{display:flex;align-items:center;gap:.4rem;font-size:var(--fs-tiny-xs);font-weight:700;padding:.34rem .7rem;border-radius:var(--r-pill);background:rgba(255,255,255,.13);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);}
.sync-pill .dot{width:8px;height:8px;border-radius:50%;background:#4bd489;box-shadow:0 0 0 3px rgba(75,212,137,.22);}
.sync-pill.pending .dot{background:var(--warn);box-shadow:0 0 0 3px rgba(217,138,43,.22);animation:pulse 1.4s infinite;}
.sync-pill.offline .dot{background:var(--danger);box-shadow:0 0 0 3px rgba(207,75,75,.22);}
/* Point 83 : sur téléphone, le mot "Synchronisé" occupait 27% de la largeur et
   tronquait le nom du client en haut de l'écran d'édition. On ne garde que la
   pastille de couleur (le libellé complet reste en infobulle, voir updateSyncPill).
   12/08/2026 : la règle ne visait que l'écran d'édition ; sur la liste des
   relevés, le même mot écrasait le bouton de déconnexion juste à sa droite.
   Elle s'applique désormais à toutes les barres du haut. */
@media(max-width:600px){
  .sync-pill span:not(.dot){display:none;}
  .sync-pill{padding:.34rem .45rem;}
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ============ LOGIN ============ */
#view-login{min-height:100vh;display:none;align-items:center;justify-content:center;background:radial-gradient(120% 90% at 50% 0%,#1b5069 0%,var(--bd) 42%,var(--bd-deep) 100%);padding:1.5rem;}
#view-login.active{display:flex;}
/* Point 112 : afficher l'écran de connexion sans attendre le JavaScript.
   Un petit script dans index.html pose la classe « pre-login » sur la page dès
   sa lecture, quand aucune session locale n'existe. L'écran s'affiche donc dès
   l'arrivée du CSS, sans attendre le téléchargement de Firebase. show() retire
   la classe dès que le JavaScript reprend la main sur ce qui est affiché. */
html.pre-login #view-login{display:flex;}
.login-card{background:#fff;border-radius:var(--r-sheet);padding:2.5rem 1.75rem 2rem;width:100%;max-width:372px;text-align:center;box-shadow:0 24px 60px rgba(6,26,36,.45);}
.login-logo{width:72px;height:72px;border-radius:var(--r-lg);overflow:hidden;display:flex;align-items:center;justify-content:center;margin:0 auto 1.15rem;box-shadow:0 8px 22px rgba(18,58,76,.32);}
.login-logo img{width:100%;height:100%;object-fit:cover;}
.login-card h1{font-size:var(--fs-display-l);color:var(--bd);margin-bottom:.3rem;}
.login-card p{font-size:var(--fs-detail);color:var(--muted);margin-bottom:1.6rem;}
.login-card input{width:100%;padding:.95rem 1rem;border:2px solid var(--hair);border-radius:var(--r-md);font-size:var(--fs-card-title);text-align:center;margin-bottom:1rem;transition:border-color .15s,box-shadow .15s;}
.login-card input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 4px rgba(var(--azure-rgb),.14);}
.login-err{color:var(--danger);font-size:var(--fs-small);font-weight:700;margin-bottom:.75rem;display:none;}

/* ============ BOUTONS ============ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;font-weight:800;font-size:var(--fs-btn);letter-spacing:.005em;padding:.95rem 1.45rem;border-radius:var(--r-md);transition:transform .12s cubic-bezier(.2,.85,.3,1),box-shadow .15s,filter .15s;}
.btn:disabled{opacity:.7;pointer-events:none;}
.btn-spinner{display:inline-block;width:16px;height:16px;border:2.5px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite;flex-shrink:0;}
/* Point 61 : variante sombre du même rond qui tourne, pour les boutons clairs
   (btn-ghost) où un rond blanc ne se verrait pas. */
.btn-spinner-dark{border-color:rgba(var(--azure-rgb),.25);border-top-color:var(--azure);}
@keyframes spin{to{transform:rotate(360deg);}}
.btn:active{transform:scale(.97);}
.btn:focus-visible{outline:3px solid rgba(var(--azure-rgb),.5);outline-offset:2px;}
.btn-primary{background:linear-gradient(180deg,var(--azure-hi),var(--azure));color:#fff;box-shadow:var(--shadow-azure);}
.btn-primary:active{filter:brightness(.94);}
.btn-dark{background:linear-gradient(180deg,#164457,var(--bd));color:#fff;box-shadow:0 4px 14px rgba(18,58,76,.3);}
.btn-ghost{background:var(--lt);color:var(--bd);box-shadow:inset 0 0 0 1.5px var(--hair);}
.btn-gold{background:linear-gradient(180deg,#cf9838,var(--gold));color:#fff;box-shadow:0 4px 14px rgba(191,138,46,.34);}
.btn-danger-ghost{background:#fdeaea;color:var(--danger);box-shadow:inset 0 0 0 1.5px #f6d5d5;}
.btn-danger{background:linear-gradient(180deg,#e05a5a,var(--danger));color:#fff;box-shadow:0 8px 20px rgba(207,75,75,.28);}
.btn-danger:active{filter:brightness(.94);}
.btn-block{width:100%;}
.btn-sm{padding:.5rem .9rem;font-size:var(--fs-small);border-radius:var(--r-sm);}

/* ============ LISTE ============ */
.list-wrap{padding:1rem 1rem calc(10rem + var(--safe-b));max-width:680px;margin:0 auto;}
/* ---- Planning (agenda des RDV) ---- */
.planning-head{display:flex;align-items:center;gap:.4rem;margin-bottom:.85rem;flex-wrap:wrap;}
.planning-head .planning-month{flex:1;text-align:center;font-family:'Syne',sans-serif;font-weight:800;color:var(--bd);font-size:var(--fs-card-title);text-transform:capitalize;min-width:120px;}
.planning-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:.3rem;margin-bottom:1.1rem;}
.planning-dow{text-align:center;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;color:var(--muted);padding-bottom:.2rem;}
.planning-day{aspect-ratio:1;border-radius:var(--r-sm);background:var(--card);border:1.5px solid var(--hair);display:flex;align-items:center;justify-content:center;font-size:var(--fs-small);font-weight:700;color:var(--ink);position:relative;}
.planning-day.other-month{visibility:hidden;}
.planning-day.today{border-color:var(--azure);color:var(--azure);}
.planning-day.selected{background:linear-gradient(180deg,var(--azure-hi),var(--azure));color:#fff;border-color:var(--azure);}
.planning-day .dot{width:5px;height:5px;border-radius:50%;background:var(--azure);position:absolute;bottom:5px;left:50%;transform:translateX(-50%);}
.planning-day.selected .dot{background:#fff;}
.planning-day-title{font-family:'Syne',sans-serif;font-weight:800;color:var(--bd);margin-bottom:.6rem;font-size:var(--fs-btn);text-transform:capitalize;}
/* ---- Paramétrages ---- */
.settings-block{background:var(--card);border-radius:var(--radius);padding:1rem 1.1rem;margin-bottom:.85rem;box-shadow:var(--shadow);border:1px solid var(--hair);}
.settings-label{display:block;font-size:var(--fs-tiny);font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);margin-bottom:.6rem;}
#icsFeedLinkBox .link-box{display:flex;gap:.5rem;}
#icsFeedLinkBox .link-box input{flex:1;padding:.7rem .85rem;border:2px solid var(--hair);border-radius:var(--r-md);font-size:var(--fs-small-xs);color:var(--muted);background:#fbfdfe;}
.dash-toggle{display:flex;align-items:center;gap:.45rem;width:100%;padding:.65rem .9rem;margin-bottom:.7rem;background:var(--card);border:1px solid var(--hair);border-radius:var(--r-md);font-size:var(--fs-small);font-weight:800;color:var(--bd);}
.dash-toggle .chev{margin-left:auto;color:var(--muted);transition:transform .2s cubic-bezier(.2,.85,.3,1);font-size:var(--fs-small-xs);}
.dash-toggle.open .chev{transform:rotate(180deg);}
.dash-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;margin-bottom:.8rem;}
.dash-tile{background:var(--card);border-radius:var(--radius);padding:.85rem .7rem;box-shadow:var(--shadow);border:1px solid var(--hair);text-align:center;}
.dash-tile b{display:block;font-family:'Syne',sans-serif;font-size:var(--fs-display-m);color:var(--bd);line-height:1.1;}
.dash-tile span{display:block;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-top:.25rem;}
.search-bar{display:flex;gap:.5rem;margin-bottom:.85rem;}
.search-bar input{flex:1;padding:.8rem 1rem;border:2px solid var(--hair);border-radius:var(--r-md);background:#fff;transition:border-color .15s,box-shadow .15s;}
.search-bar input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
.filter-tabs{display:flex;gap:.45rem;margin-bottom:1rem;overflow-x:auto;padding:0 2.5rem .25rem 0;scrollbar-width:none;
  /* Le dégradé dit qu'on peut faire défiler ; le padding droit laisse le dernier
     onglet sortir de la zone fondue une fois arrivé au bout. */
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 2.5rem),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 2.5rem),transparent);}
.filter-tabs::-webkit-scrollbar{display:none;}
.filter-tab{flex-shrink:0;font-size:var(--fs-small-xs);font-weight:800;padding:.48rem .95rem;border-radius:var(--r-pill);background:#fff;color:var(--muted);border:1.5px solid var(--hair);transition:all .15s;}
.filter-tab.on{background:linear-gradient(180deg,#164457,var(--bd));color:#fff;border-color:var(--bd);box-shadow:0 3px 10px rgba(18,58,76,.22);}
.releve-card{background:var(--card);border-radius:var(--radius);padding:1.05rem 1.15rem;margin-bottom:.8rem;box-shadow:var(--shadow);display:block;width:100%;text-align:left;border:1px solid var(--hair);transition:border-color .15s,transform .12s,box-shadow .15s;}
.releve-card:active{border-color:var(--azure);transform:scale(.99);}
.releve-head{display:flex;align-items:center;flex-wrap:wrap;gap:.35rem .55rem;margin-bottom:.35rem;}
.releve-head .nom{font-weight:800;font-size:var(--fs-card-title);color:var(--bd);flex:1 1 100%;min-width:0;overflow-wrap:break-word;font-family:'Syne',sans-serif;}
.releve-head .statut-chip,.releve-head .owner-chip,.releve-head .sync-flag{flex-shrink:0;}
.releve-sub{font-size:var(--fs-small);color:var(--muted);display:flex;gap:.85rem;flex-wrap:wrap;}
.statut-chip{font-size:var(--fs-label);font-weight:800;text-transform:uppercase;letter-spacing:.06em;padding:.24rem .62rem;border-radius:var(--r-pill);}
.statut-brouillon{background:#e9eef2;color:#5a6f7c;}
.statut-vendu{background:#dff3e8;color:var(--ok);}
.statut-devis{background:#ebe6f7;color:#5b4a9e;}
.statut-transmis{background:#dcecf8;color:var(--azure);}
.statut-refuse{background:#fbe5e5;color:#c0392b;}
.statut-abandonne{background:#f2ece0;color:#8a6a2f;}
.sync-flag{font-size:var(--fs-detail);}
.empty-state{text-align:center;padding:3.5rem 1.5rem;color:var(--muted);}
.empty-state .ico{font-size:var(--fs-display-xl);margin-bottom:.85rem;opacity:.9;}
.empty-state p{font-size:var(--fs-body-sm);}
/* Un écran vide qui dit quoi faire doit donner le moyen de le faire : sans ces
   boutons, seul l'import était visible et la création manuelle passait pour
   inexistante. Masqués sous 760px, comme le reste de la saisie du catalogue. */
.empty-actions{display:flex;gap:.6rem;justify-content:center;flex-wrap:wrap;margin-top:1.2rem;}
@media(max-width:759px){.empty-actions{display:none;}}
/* Point 82 : le libellé passait sur 2 lignes sur téléphone (bouton de 73px de
   haut occupant la moitié de l'écran, masquant le dossier du dessous). */
.fab{position:fixed;bottom:calc(5.5rem + var(--safe-b));left:50%;transform:translateX(-50%);z-index:40;background:linear-gradient(180deg,var(--azure-hi),var(--azure));color:#fff;box-shadow:0 10px 28px rgba(var(--azure-rgb),.5);padding:1rem 1.8rem;border-radius:var(--r-pill);font-size:var(--fs-body);white-space:nowrap;}
@media(max-width:420px){.fab{padding:.85rem 1.35rem;font-size:var(--fs-btn);}}
body.selecting .fab{display:none;}
.fab:active{transform:translateX(-50%) scale(.96);}
/* mode sélection multiple */
.list-toolbar{display:flex;justify-content:flex-end;gap:.5rem;margin-bottom:.75rem;flex-wrap:wrap;}
.lt-btn{font-size:var(--fs-small-xs);font-weight:800;color:var(--azure);background:var(--lt);padding:.48rem .95rem;border-radius:var(--r-pill);box-shadow:inset 0 0 0 1.5px var(--hair);transition:all .15s;}
.lt-btn.active{background:var(--azure);color:#fff;box-shadow:0 3px 10px rgba(var(--azure-rgb),.28);}
.date-filter-panel{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;background:var(--card);border:1px solid var(--hair);border-radius:var(--r-md);padding:.7rem .85rem;margin-bottom:.75rem;font-size:var(--fs-small);color:var(--muted);}
.date-filter-panel select,.date-filter-panel input[type=date]{padding:.4rem .5rem;border:1.5px solid var(--hair);border-radius:var(--r-sm);font-size:var(--fs-small);color:var(--muted);background:#fbfdfe;}
.sel-box{width:22px;height:22px;border-radius:var(--r-sm);border:2px solid var(--azure);display:flex;align-items:center;justify-content:center;font-size:var(--fs-small);color:#fff;font-weight:900;flex-shrink:0;}
.releve-card.sel{border-color:var(--azure);background:#eff8fc;}
.releve-card.sel .sel-box{background:var(--azure);}
.list-delete-bar{position:fixed;bottom:0;left:0;right:0;z-index:45;background:rgba(255,255,255,.96);backdrop-filter:blur(12px);border-top:1px solid var(--hair);box-shadow:0 -6px 20px rgba(18,58,76,.1);padding:.8rem 1rem calc(.8rem + var(--safe-b));display:none;align-items:center;gap:.5rem;max-width:680px;margin:0 auto;overflow-x:auto;}
.list-delete-bar .btn{padding:.6rem .85rem;font-size:var(--fs-small-xs);white-space:nowrap;}
.list-delete-bar.open{display:flex;}
.list-delete-bar .sel-count{flex:1;font-weight:800;color:var(--bd);font-size:var(--fs-body-sm);}
.list-delete-bar .btn{flex-shrink:0;}

/* ============ NAVIGATION APP (barre latérale bureau / onglets mobile) ============ */
/* body.no-chrome = vues plein écran (login, édition, rapport, admin plateforme) :
   la nav des 4 sections (Relevés/Clients/Devis/Planning) ne doit pas s'y afficher. */
.app-sidebar{display:none;}
.app-bottomnav{position:fixed;bottom:0;left:0;right:0;z-index:60;background:rgba(255,255,255,.96);backdrop-filter:blur(12px);border-top:1px solid var(--hair);box-shadow:0 -6px 20px rgba(18,58,76,.08);display:flex;padding-bottom:var(--safe-b);}
.app-bottomnav .bn-link{flex:1;display:flex;flex-direction:column;align-items:center;gap:.15rem;padding:.55rem 0 .5rem;color:var(--muted);font-size:var(--fs-tiny-xs);font-weight:800;transition:color .15s;}
.app-bottomnav .bn-link .ico{font-size:var(--fs-title);}
.app-bottomnav .bn-link.on{color:var(--azure);}
body.no-chrome .app-sidebar,body.no-chrome .app-bottomnav,body.no-chrome #hubTopbar{display:none;}
@media(min-width:880px){
  .app-sidebar{display:flex;flex-direction:column;position:fixed;top:0;left:0;bottom:0;width:220px;z-index:70;background:linear-gradient(180deg,var(--topbar-1),var(--topbar-2));padding:1.5rem 0 1rem;}
  .sidebar-brand{font-family:'Syne',sans-serif;font-weight:800;font-size:var(--fs-title);color:#fff;padding:0 1.4rem 1.5rem;}
  .sidebar-links{display:flex;flex-direction:column;gap:.3rem;padding:0 .85rem;}
  .sidebar-link{display:flex;align-items:center;gap:.65rem;padding:.75rem .85rem;border-radius:var(--r-md);color:#cfe6f0;font-weight:700;font-size:var(--fs-body-sm);transition:background .15s,color .15s;}
  .sidebar-link .ico{font-size:var(--fs-title);width:22px;text-align:center;}
  .sidebar-link:active{background:rgba(255,255,255,.1);}
  .sidebar-link.on{background:rgba(255,255,255,.14);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);}
  .app-bottomnav{display:none;}
  #hubTopbar,#view-list,#view-clients,#view-devis,#view-planning,#view-parametrages{margin-left:220px;}
  .fab{bottom:calc(1.25rem + var(--safe-b));}
}
/* ---- Point 54 : mieux exploiter la largeur d'écran sur grand ordinateur ---- */
@media(min-width:1200px){
  /* Relevés : grille de cartes au lieu d'une colonne unique */
  #view-list .list-wrap,#view-clients .list-wrap,#view-planning .list-wrap{max-width:1400px;}
  #releveList{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:.8rem;align-items:stretch;}
  #releveList .releve-card{margin-bottom:0;height:100%;}
  #releveList .empty-state{grid-column:1/-1;}

  /* Fiches client : grille multi-colonnes */
  #clientsListEl{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:.8rem;align-items:stretch;}
  #clientsListEl .client-card{margin-bottom:0;height:100%;}
  #clientsListEl .empty-state{grid-column:1/-1;}

  /* Planning : calendrier et détail du jour côte à côte plutôt que l'un sous l'autre */
  #view-planning .list-wrap{display:grid;grid-template-columns:minmax(320px,420px) 1fr;gap:0 1.5rem;align-items:start;}
  #view-planning .planning-head{grid-column:1;grid-row:1;}
  #view-planning .planning-grid{grid-column:1;grid-row:2;margin-bottom:0;}
  #view-planning #planningDayPanel{grid-column:2;grid-row:1/3;}

  /* Édition d'un relevé : sections affichées côte à côte, plus repliées en accordéon.
     ⚠️ Le `columns:2` d'origine servait l'ancien écran en accordéon, où toutes
     les sections s'empilaient. Depuis les vignettes (point 117), la grille gère
     elle-même ses colonnes : les colonnes CSS la coupaient en deux moitiés
     déséquilibrées et laissaient la moitié basse de l'écran vide. */
  #view-edit .edit-progress{max-width:1400px;}
  #view-edit .edit-wrap{max-width:1240px;}
  #view-edit .edit-wrap .section-card{break-inside:avoid;}
  #view-edit .section-body{display:block!important;}
  #view-edit .section-head{cursor:default;}
  #view-edit .section-head .chev{display:none;}
  #view-edit .edit-wrap>.btn-danger-ghost{column-span:all;}
  #view-edit .bottom-bar{max-width:1400px;}
}
body.selecting .app-bottomnav{display:none;}
/* ---- Fiches client (section Clients) ---- */
.client-card{background:var(--card);border-radius:var(--radius);padding:1rem 1.1rem;margin-bottom:.75rem;box-shadow:var(--shadow);border:1px solid var(--hair);}
/* La carte entière ouvre la fiche client en consultation (voir openClientDetail). */
.client-card.clickable{display:block;width:100%;text-align:left;transition:border-color .15s,transform .12s;}
.cc-chev{color:var(--muted-soft);font-size:var(--fs-display-m);flex-shrink:0;line-height:1;} /* signale que la carte s'ouvre */
.client-card.clickable:active{border-color:var(--azure);transform:scale(.99);}
/* Fiche client en lecture seule */
.client-detail-info{background:var(--card);border-radius:var(--radius);padding:1rem 1.1rem;box-shadow:var(--shadow);border:1px solid var(--hair);margin-bottom:.5rem;}
.client-detail-info .cc-line{font-size:var(--fs-body-sm);color:var(--muted);margin-top:.35rem;}
.client-detail-info .cc-line a{color:var(--azure);font-weight:700;}
.detail-title{font-size:var(--fs-body-sm);color:var(--bd);margin:1.4rem 0 .6rem;}
.client-card .cc-head{display:flex;align-items:center;gap:.6rem;margin-bottom:.4rem;}
.client-card .cc-head b{flex:1;font-family:'Syne',sans-serif;color:var(--bd);font-size:var(--fs-card-title);}
.client-card .cc-line{font-size:var(--fs-detail);color:var(--muted);margin-top:.25rem;}
.client-card .cc-line a{color:var(--azure);font-weight:700;}

/* ============ EDIT ============ */
.edit-wrap{padding:1rem 1rem calc(7rem + var(--safe-b));max-width:680px;margin:0 auto;}
.edit-progress{position:sticky;top:0;z-index:40;background:var(--bg);padding:.6rem 1rem .5rem;max-width:680px;margin:0 auto;display:flex;align-items:center;gap:.6rem;}
.edit-progress .progress-track{flex:1;height:6px;border-radius:var(--r-pill);background:var(--hair);overflow:hidden;}
.edit-progress .progress-fill{height:100%;background:linear-gradient(90deg,var(--azure),var(--bd));border-radius:var(--r-pill);transition:width .25s;}
.edit-progress .progress-txt{flex-shrink:0;font-size:var(--fs-tiny);font-weight:800;color:var(--muted);white-space:nowrap;}
.section-card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);border:1px solid var(--hair);margin-bottom:.85rem;overflow:hidden;}
.section-head{display:flex;align-items:center;gap:.7rem;padding:1.05rem 1.1rem;width:100%;text-align:left;transition:background .15s;}
.section-head:active{background:#f6fafc;}
.section-head .ico{position:relative;font-size:var(--fs-display-s);width:40px;height:40px;border-radius:var(--r-md);background:var(--lt);display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.sec-dot{position:absolute;bottom:-2px;right:-2px;width:14px;height:14px;border-radius:50%;background:#fff;border:2px solid var(--hair);box-sizing:border-box;}
.sec-dot.filled{background:var(--ok);border-color:var(--ok);}
.section-head .ttl{flex:1;}
.section-head .ttl b{display:block;font-family:'Syne',sans-serif;font-size:var(--fs-body);color:var(--bd);}
.section-head .ttl span{font-size:var(--fs-tiny);color:var(--muted);}
.section-head .chev{color:var(--muted);transition:transform .25s cubic-bezier(.2,.85,.3,1);font-size:var(--fs-small);}
.section-card.open .chev{transform:rotate(180deg);}
.section-card.open .section-head{border-bottom:1px solid var(--hair);}
.section-body{display:none;padding:1rem 1.1rem 1.1rem;}
.section-card.open .section-body{display:block;}
.fld{margin-bottom:.9rem;}
.fld label{display:block;font-size:var(--fs-tiny);font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);margin-bottom:.4rem;}
.fld input,.fld textarea,.fld select{width:100%;padding:.85rem .95rem;border:2px solid var(--hair);border-radius:var(--r-md);background:#fbfdfe;transition:border-color .15s,box-shadow .15s,background .15s;}
.fld input:focus,.fld textarea:focus,.fld select:focus{outline:none;border-color:var(--azure);background:#fff;box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
.fld textarea{min-height:84px;resize:vertical;}
.fld-row{display:grid;grid-template-columns:1fr 1fr;gap:.65rem;}
.fld-row3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;}
/* align-items:end — un libellé qui passe sur deux lignes (« Isolation (W/m³) »)
   décalait son champ vers le bas et désalignait toute la rangée. Les champs
   s'alignent maintenant par le bas, quelle que soit la hauteur du libellé. */
.dim-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;margin-bottom:.6rem;align-items:end;}
.dim-row span{display:block;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin-bottom:.25rem;text-align:center;}
.dim-row input{width:100%;min-width:0;padding:.7rem .3rem;border:2px solid var(--hair);border-radius:var(--r-sm);background:#fbfdfe;text-align:center;font-size:var(--fs-body);font-family:var(--mono);font-weight:500;color:var(--bd);transition:border-color .15s,box-shadow .15s,background .15s;}
.dim-row input:focus{outline:none;border-color:var(--azure);background:#fff;box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
.vol-line{font-size:var(--fs-small);font-weight:700;color:var(--azure);font-family:var(--mono);letter-spacing:-.01em;margin:-.15rem 0 .8rem;}
.dim-hint{margin:-.15rem 0 .65rem;}
/* Avis persistants. Au-dessus de tout, y compris de l'écran de connexion : la
   mise en garde vaut avant même d'être identifié. Le conteneur porte seul la
   position fixe — deux bandeaux fixés séparément se recouvriraient. */
/* Dans le flux, et non par-dessus : posé en position fixe, le bandeau
   recouvrait la barre du haut et faisait disparaître le bouton de déconnexion
   et la pastille de synchronisation. Il pousse maintenant la page vers le bas. */
#bandeaux{position:relative;z-index:400;padding-top:env(safe-area-inset-top);}
#bandeaux:empty{display:none;}
#bandeaux>div{font-size:var(--fs-small-xs);font-weight:600;line-height:1.4;padding:.6rem .9rem;
  text-align:center;box-shadow:0 2px 10px rgba(0,0,0,.18);}
#bandeaux b{font-weight:900;}
#bandeauStockage{background:var(--warn);color:#fff;}
/* Le trait du bas le détache de la barre du haut, de teinte voisine : sans lui
   les deux se lisent comme un seul bloc sombre. */
#bandeauSession{background:var(--bd);color:#fff;box-shadow:inset 0 -1px 0 rgba(255,255,255,.18);}
#bandeauSession button{display:inline-block;margin-left:.5rem;font-size:var(--fs-tiny-xs);font-weight:800;
  padding:.28rem .7rem;border-radius:var(--r-pill);background:#fff;color:var(--bd);}

/* Point 97 : la solution technique, décidée au relevé. L'encart doit se lire
   d'un coup d'œil sur un téléphone tenu d'une main — d'où le fond distinct du
   reste de la fiche, et le nom de l'article seul sur sa ligne. */
.sol-wrap{border:1.5px solid var(--hair);border-radius:var(--r-md);background:#f4f9fc;padding:.6rem .7rem;margin:.2rem 0 .85rem;}
.sol-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;font-size:var(--fs-label);font-weight:800;color:var(--bd);text-transform:uppercase;letter-spacing:.03em;}
.sol-type{width:auto;flex:0 1 auto;max-width:52%;padding:.28rem .5rem;font-size:var(--fs-tiny-xs);font-weight:700;margin:0;}
.sol-prop{margin:.45rem 0 .1rem;}
.sol-nom{font-size:var(--fs-body-sm);font-weight:800;color:var(--ink);line-height:1.3;}
.sol-nom.sol-vide{font-weight:600;color:var(--muted);}
.sol-tag{display:inline-block;margin-left:.4rem;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:#8a6a2f;background:#f2ecdf;padding:.1rem .42rem;border-radius:var(--r-pill);vertical-align:.08em;}
.sol-detail{font-size:var(--fs-tiny-xs);color:var(--azure);font-family:var(--mono);font-weight:700;margin-top:.15rem;}
.sol-alerte{font-size:var(--fs-tiny-xs);color:var(--warn);font-weight:700;line-height:1.35;margin-top:.3rem;}
.sol-actions{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.5rem;}
.sol-btn{font-size:var(--fs-tiny-xs);font-weight:800;padding:.42rem .7rem;border-radius:var(--r-pill);background:var(--azure);color:#fff;transition:filter .15s;}
.sol-btn:active{filter:brightness(.92);}
.sol-btn-ghost{background:transparent;color:var(--azure);box-shadow:inset 0 0 0 1.5px var(--azure);}
.sol-fab{margin-bottom:.9rem;}
.sol-fab label{display:block;font-size:var(--fs-label);font-weight:800;color:var(--bd);text-transform:uppercase;letter-spacing:.03em;margin-bottom:.28rem;}
.check-line{display:flex;align-items:center;gap:.55rem;font-size:var(--fs-body-sm);font-weight:700;color:var(--bd);padding:.4rem 0;}
.check-line input{width:auto;accent-color:var(--azure);transform:scale(1.15);}
.owner-chip{font-size:var(--fs-label);font-weight:800;padding:.22rem .6rem;border-radius:var(--r-pill);background:#f2ecdf;color:#8a6a2f;}
.owner-chip-btn{cursor:pointer;transition:filter .15s;}
.owner-chip-btn:active{filter:brightness(.92);}
.client-filter-banner{display:flex;align-items:center;gap:.5rem;background:var(--lt);color:var(--azure);font-weight:700;font-size:var(--fs-detail);padding:.55rem .9rem;border-radius:var(--r-md);margin-bottom:.75rem;}
.client-filter-banner button{margin-left:auto;font-weight:800;color:var(--azure);font-size:var(--fs-body);}
.late-brouillon-alert{display:flex;width:100%;align-items:center;gap:.5rem;background:#fdf3e2;color:#8a5a12;font-weight:700;font-size:var(--fs-detail);padding:.6rem .9rem;border-radius:var(--r-md);margin-bottom:.75rem;box-shadow:inset 0 0 0 1.5px #f3ddac;text-align:left;}
/* Point 80 : signalement d'un dossier modifié en parallèle sur deux appareils.
   Ton plus alerte que le rappel de RDV : ici il y a un risque de perte. */
.conflit-alert{display:flex;width:100%;align-items:center;gap:.5rem;background:#fdeaea;color:#9c2f2f;font-weight:700;font-size:var(--fs-detail);padding:.6rem .9rem;border-radius:var(--r-md);margin-bottom:.75rem;box-shadow:inset 0 0 0 1.5px #f3c9c9;text-align:left;}
.conflit-badge{font-size:var(--fs-label);font-weight:800;padding:.22rem .6rem;border-radius:var(--r-pill);background:#fdeaea;color:#9c2f2f;box-shadow:inset 0 0 0 1.5px #f3c9c9;}
.conflit-choix{display:grid;grid-template-columns:1fr 1fr;gap:.6rem;margin:.85rem 0;}
.conflit-col{background:#fbfdfe;border:1.5px solid var(--hair);border-radius:var(--r-md);padding:.6rem .7rem;font-size:var(--fs-small-xs);color:var(--muted);}
.conflit-col b{display:block;color:var(--bd);font-size:var(--fs-small);margin-bottom:.2rem;}
.late-badge{font-size:var(--fs-label);font-weight:800;padding:.22rem .6rem;border-radius:var(--r-pill);background:#fdf3e2;color:#8a5a12;box-shadow:inset 0 0 0 1.5px #f3ddac;}
.user-row{display:flex;align-items:center;gap:.6rem;padding:.7rem .25rem;border-bottom:1px solid var(--hair);font-size:var(--fs-body-sm);}
.user-row b{flex:1;color:var(--bd);font-family:'Syne',sans-serif;}
.user-row .login{color:var(--muted);font-size:var(--fs-small-xs);}
.site-row{display:flex;align-items:center;gap:.6rem;padding:.6rem .25rem;border-bottom:1px solid var(--hair);font-size:var(--fs-detail);}
.site-row .site-info{flex:1;min-width:0;}
.site-row .site-info b{display:block;color:var(--bd);font-family:'Syne',sans-serif;font-size:var(--fs-body-sm);}
.site-row .site-info span{color:var(--muted);font-size:var(--fs-small-xs);}
#clientModal input{padding:.7rem .8rem;border:2px solid var(--hair);border-radius:var(--r-sm);width:100%;font-size:var(--fs-body-sm);transition:border-color .15s,box-shadow .15s;}
#clientModal input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
#usersModal input{padding:.7rem .8rem;border:2px solid var(--hair);border-radius:var(--r-sm);width:100%;font-size:var(--fs-body-sm);transition:border-color .15s,box-shadow .15s;}
#usersModal input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
#newTenantModal input{padding:.7rem .8rem;border:2px solid var(--hair);border-radius:var(--r-sm);width:100%;font-size:var(--fs-body-sm);transition:border-color .15s,box-shadow .15s;}
#newTenantModal input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
.tenant-row{background:var(--card);border-radius:var(--radius);padding:.95rem 1.05rem;margin-bottom:.75rem;box-shadow:var(--shadow);border:1px solid var(--hair);}
.tenant-row .tr-head{display:flex;align-items:center;gap:.6rem;margin-bottom:.5rem;}
.tenant-row .tr-head b{flex:1;color:var(--bd);font-family:'Syne',sans-serif;font-size:var(--fs-body);}
.tenant-row .tr-id{color:var(--muted);font-size:var(--fs-tiny);font-family:var(--mono);background:var(--lt);padding:.15rem .5rem;border-radius:var(--r-sm);}
.tenant-row .tr-seat{display:flex;align-items:center;gap:.5rem;font-size:var(--fs-detail);color:var(--muted);flex-wrap:wrap;}
.tenant-row .tr-seat input{width:64px;padding:.4rem .5rem;border:2px solid var(--hair);border-radius:var(--r-sm);font-size:var(--fs-body-sm);font-family:var(--mono);font-weight:500;text-align:center;color:var(--bd);transition:border-color .15s;}
.tenant-row .tr-seat input:focus{outline:none;border-color:var(--azure);}

/* photos */
.photo-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.5rem;margin-top:.6rem;}
.photo-cell{display:flex;flex-direction:column;gap:.3rem;}
.photo-thumb{position:relative;aspect-ratio:1;border-radius:var(--r-md);overflow:hidden;background:var(--lt);}
.photo-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.photo-del{position:absolute;top:4px;right:4px;width:32px;height:32px;border-radius:50%;background:rgba(20,30,40,.65);color:#fff;font-size:var(--fs-btn);display:flex;align-items:center;justify-content:center;}
.photo-cap-input{width:100%;font-size:var(--fs-small-xs);padding:.38rem .5rem;border:1.5px solid var(--hair);border-radius:var(--r-sm);background:#fbfdfe;color:var(--muted);}
.photo-cap-input:focus{outline:none;border-color:var(--azure);}
.photo-add{aspect-ratio:1;border-radius:var(--r-md);border:2px dashed #a9c9d7;background:#f4fafc;color:var(--azure);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.2rem;font-size:var(--fs-tiny);font-weight:800;transition:background .15s,border-color .15s;}
.photo-add .pic{font-size:var(--fs-display-m);}
.photo-add:active{background:var(--lt);border-color:var(--azure);}
.doc-row{display:flex;align-items:center;gap:.6rem;padding:.75rem .85rem;border-radius:var(--r-md);background:#fbfdfe;border:1.5px solid var(--hair);margin-bottom:.6rem;}
.doc-row .ico{font-size:var(--fs-display-m);flex-shrink:0;}
.doc-row .info{flex:1;min-width:0;}
.doc-row .info b{display:block;font-family:'Syne',sans-serif;font-size:var(--fs-body-sm);color:var(--bd);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.doc-row .info span{font-size:var(--fs-tiny);color:var(--muted);}
.doc-row .doc-del{font-size:var(--fs-title);color:var(--danger);padding:.55rem;flex-shrink:0;}

/* sous-cartes (pièces / zones libres) */
.sub-card{border:1.5px solid var(--hair);border-radius:var(--r-md);padding:.9rem;margin-bottom:.75rem;background:#fbfdfe;}
.sub-card-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.6rem;}
.sub-card-head input{flex:1;padding:.6rem .8rem;border:2px solid var(--hair);border-radius:var(--r-sm);font-weight:700;background:#fff;transition:border-color .15s,box-shadow .15s;}
.sub-card-head input:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
.sub-del{width:40px;height:40px;border-radius:var(--r-sm);background:#fdeaea;color:var(--danger);font-size:var(--fs-body);flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:filter .15s;}
.sub-del:active{filter:brightness(.94);}
.add-sub{width:100%;border:2px dashed #a9c9d7;border-radius:var(--r-md);padding:.9rem;color:var(--azure);font-weight:800;font-size:var(--fs-body-sm);background:#f4fafc;transition:background .15s,border-color .15s;}
.add-sub:active{background:var(--lt);border-color:var(--azure);}

/* statut selector */
.statut-row{display:flex;gap:.5rem;flex-wrap:wrap;}
.statut-opt{flex:1 1 30%;padding:.62rem .4rem;border-radius:var(--r-pill);border:1.5px solid var(--hair);background:#fff;font-size:var(--fs-small-xs);font-weight:800;color:var(--muted);text-align:center;transition:all .15s;}
.statut-opt.on-brouillon{border-color:#6a7f8c;background:#eef2f5;color:#4a5f6c;}
.statut-opt.on-vendu{border-color:var(--ok);background:#e3f5ea;color:var(--ok);}
.statut-opt.on-devis{border-color:#5b4a9e;background:#efeaf9;color:#5b4a9e;}
.statut-opt.on-transmis{border-color:var(--azure);background:#e3effa;color:var(--azure);}
.statut-opt.on-refuse{border-color:#c0392b;background:#fdeaea;color:#c0392b;}
.statut-opt.on-abandonne{border-color:#9a7b3f;background:#f4f0e8;color:#9a7b3f;}

/* barre action bas */
.bottom-bar{position:fixed;bottom:0;left:0;right:0;z-index:40;background:rgba(255,255,255,.94);backdrop-filter:blur(12px);border-top:1px solid var(--hair);box-shadow:0 -6px 20px rgba(18,58,76,.06);padding:.8rem 1rem calc(.8rem + var(--safe-b));display:flex;gap:.6rem;max-width:680px;margin:0 auto;}
.bottom-bar .btn{flex:1;}

/* ============ RAPPORT (lecture seule) ============ */
.report-hero{position:relative;background:radial-gradient(120% 100% at 50% 0%,#1b5069 0%,var(--bd) 45%,var(--bd-deep) 100%);color:#fff;padding:2rem 1.25rem 2.5rem;text-align:center;}
.report-back-top{position:absolute;top:1rem;left:1rem;width:38px;height:38px;border-radius:50%;background:rgba(255,255,255,.15);color:#fff;font-size:var(--fs-display-m);display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px rgba(255,255,255,.22);}
.report-back-top:active{background:rgba(255,255,255,.26);}
.report-hero .badge{display:inline-block;font-size:var(--fs-tiny-xs);font-weight:700;letter-spacing:.12em;text-transform:uppercase;font-family:var(--mono);background:rgba(255,255,255,.14);padding:.32rem .9rem;border-radius:var(--r-pill);margin-bottom:.8rem;color:#cfe6f0;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);}
.report-hero h1{font-size:var(--fs-display-l);margin-bottom:.35rem;}
.report-hero p{font-size:var(--fs-detail);color:#a9cbdb;}
.report-wrap{padding:1.25rem 1rem calc(3rem + var(--safe-b));max-width:680px;margin:0 auto;}
.report-client{background:#fff;border-radius:var(--radius);padding:1.1rem 1.15rem;margin:-1.75rem auto 1.25rem;position:relative;box-shadow:var(--shadow-lg);border:1px solid var(--hair);font-size:var(--fs-body-sm);}
.report-client b{color:var(--bd);}
.report-client .line{margin-bottom:.25rem;}
.report-section{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow);border:1px solid var(--hair);padding:1.15rem;margin-bottom:.85rem;}
.report-section h2{font-size:var(--fs-body);color:var(--bd);display:flex;align-items:center;gap:.55rem;margin-bottom:.55rem;}
.report-section h2 .ico{font-size:var(--fs-title);}
.report-notes{font-size:var(--fs-body-sm);white-space:pre-wrap;color:#3a5563;margin-bottom:.5rem;}
.report-empty{font-size:var(--fs-small);color:var(--muted);font-style:italic;}
.report-photos{display:grid;grid-template-columns:repeat(2,1fr);gap:.55rem;margin-top:.5rem;}
.report-photos img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:var(--r-md);display:block;background:var(--lt);}
.report-photo-cap{font-size:var(--fs-tiny);color:var(--muted);margin-top:.3rem;text-align:center;}
.report-foot{text-align:center;font-size:var(--fs-small-xs);color:var(--muted);padding:1.5rem 1rem 0;}

/* lightbox */
.lightbox{position:fixed;inset:0;z-index:200;background:rgba(8,18,24,.93);display:none;align-items:center;justify-content:center;padding:1rem;}
.lightbox.open{display:flex;}
.lightbox img{max-width:100%;max-height:88vh;border-radius:var(--r-md);
  /* touch-action:none — sinon le navigateur s'empare du pincement et du
     glissement avant nous, et le zoom de la visionneuse ne reçoit rien. */
  touch-action:none;transform-origin:center center;will-change:transform;
  user-select:none;-webkit-user-drag:none;}
/* Agrandie, l'image perd ses coins arrondis : ils rogneraient le détail qu'on
   est justement venu lire. */
.lightbox img.zoome{border-radius:0;cursor:grab;}
.lightbox.zoome{touch-action:none;}
.lightbox-aide{z-index:2;position:absolute;left:0;right:0;bottom:calc(1.4rem + env(safe-area-inset-bottom,0px));
  text-align:center;color:rgba(255,255,255,.72);font-size:var(--fs-small-xs);font-weight:700;
  pointer-events:none;transition:opacity .35s;}
/* z-index : agrandie, l'image recouvrait la croix — on ne pouvait plus fermer
   qu'en dézoomant. La sortie doit rester atteignable à tout moment. */
.lightbox .close{z-index:2;position:absolute;top:calc(1rem + env(safe-area-inset-top,0px));right:1rem;width:42px;height:42px;border-radius:50%;background:rgba(255,255,255,.14);color:#fff;font-size:var(--fs-title);display:flex;align-items:center;justify-content:center;}

/* toast */
.toast{position:fixed;bottom:calc(5.5rem + var(--safe-b));left:50%;transform:translateX(-50%) translateY(20px);background:var(--bd);color:#fff;font-size:var(--fs-detail);font-weight:700;padding:.7rem 1.25rem;border-radius:var(--r-pill);box-shadow:0 8px 24px rgba(0,0,0,.3);opacity:0;pointer-events:none;transition:all .25s;z-index:300;white-space:nowrap;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

/* modal partage */
.modal-bg{position:fixed;inset:0;z-index:150;background:rgba(8,18,24,.55);display:none;align-items:flex-end;justify-content:center;}
/* Les volets de dialogue passent devant TOUS les autres, par construction.
   Ils partageaient le même plan (150) : à égalité, c'est l'ordre de
   déclaration dans index.html qui décidait, et sept volets étaient déclarés
   après eux. Un message de confirmation s'ouvrait donc invisible, derrière le
   formulaire qui l'avait demandé — l'application paraissait figée alors
   qu'elle attendait une réponse (constaté par Thomas le 11/08/2026 en créant
   un tenant). Au-dessus de la visionneuse de photos (200), sous le toast (300). */
#confirmModalBg,#alertModalBg{z-index:210;}
.modal-bg.open{display:flex;}
.modal{background:#fff;border-radius:var(--r-sheet) var(--r-sheet) 0 0;padding:1.5rem 1.25rem calc(1.5rem + var(--safe-b));width:100%;max-width:680px;box-shadow:0 -12px 40px rgba(12,40,54,.25);animation:sheet-up .28s cubic-bezier(.2,.85,.3,1);}
@keyframes sheet-up{from{transform:translateY(100%);}to{transform:translateY(0);}}
.modal h3{font-size:var(--fs-display-s);color:var(--bd);margin-bottom:.35rem;}
.modal p{font-size:var(--fs-detail);color:var(--muted);margin-bottom:1rem;}
.modal .link-box{display:flex;gap:.5rem;margin-bottom:.85rem;}
.modal .link-box input{flex:1;padding:.7rem .85rem;border:2px solid #e0eaef;border-radius:var(--r-md);font-size:var(--fs-small);color:var(--muted);background:#fbfdfe;}
.modal .btn{margin-bottom:.5rem;}

@media(min-width:600px){
  .photo-grid{grid-template-columns:repeat(4,minmax(0,1fr));}
  .report-photos{grid-template-columns:repeat(3,1fr);}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;}}

/* ============ MON ENTREPRISE (point 114) ============
   Formulaire long, rempli une seule fois. Deux colonnes dès qu'il y a la place :
   sur un ordinateur, une colonne unique de trente champs oblige à faire défiler
   sans fin. Sur téléphone il repasse naturellement sur une colonne. */
.ent-aide{font-size:var(--fs-small);color:var(--muted);margin-bottom:.9rem;}
.ent-note{display:block;font-size:var(--fs-small-xs);color:var(--muted);font-weight:500;margin:.15rem 0 .45rem;line-height:1.4;}
.ent-grille{display:grid;grid-template-columns:1fr;gap:.7rem;}
.ent-grille label,.ent-long{display:block;font-size:var(--fs-small);font-weight:700;color:var(--ink);}
.ent-grille input,.ent-grille textarea,.ent-long input,.ent-long textarea{margin-top:.25rem;}
.ent-long{margin-top:.7rem;}
/* Repère discret : ce qui doit légalement figurer sur un devis. */
.ent-oblig{display:inline-block;font-size:var(--fs-tiny);font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--azure);background:var(--lt);border-radius:var(--r-sm);padding:.08rem .35rem;margin-left:.3rem;vertical-align:1px;}
.ent-apercu{display:flex;align-items:center;gap:.6rem;margin-bottom:.6rem;font-size:var(--fs-small);color:var(--muted);}
.ent-apercu img{max-width:100%;max-height:90px;border-radius:var(--r-sm);border:1px solid var(--hair);}
@media(min-width:760px){
  .ent-grille{grid-template-columns:1fr 1fr;}
  .ent-long{grid-column:1/-1;}
}

/* ============ MENU DES RÉGLAGES ============
   Les Réglages étaient un empilement de blocs qu'il fallait parcourir de haut
   en bas pour trouver un paramètre (remarque de Thomas, 28/07/2026). Ils
   deviennent un menu : quatre entrées, chacune ouvrant un écran dédié. */
.reglage-carte{display:flex;align-items:center;gap:.85rem;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--hair);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:1rem 1.1rem;margin-bottom:.7rem;cursor:pointer;
  transition:border-color .15s,transform .15s;}
.reglage-carte:hover{border-color:var(--azure);}
.reglage-carte:active{transform:scale(.995);}
.rc-ico{font-size:1.45rem;line-height:1;flex:none;}
.rc-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:.15rem;}
.rc-txt b{font-size:var(--fs-body);font-weight:800;color:var(--ink);}
.rc-txt span{font-size:var(--fs-small);color:var(--muted);font-weight:500;line-height:1.35;}
.rc-etat{flex:none;font-size:var(--fs-small-xs);font-weight:800;color:var(--azure);}
.rc-chev{flex:none;font-size:1.3rem;color:var(--muted);line-height:1;}

/* ============ MODULE DEVIS ============
   Catalogue, articles, devis. Le fil conducteur : sur mobile l'écran doit
   rester lisible d'un coup d'œil, les réglages techniques n'apparaissent
   qu'à la demande (règle d'or de Thomas, 28/07/2026). */

/* --- Catalogue --- */
.cat-compte{font-size:var(--fs-small-xs);color:var(--muted);font-weight:700;margin:.5rem 0 .35rem;}
.cat-mobile{display:none;font-size:var(--fs-small-xs);color:var(--muted);background:var(--lt);
  border-radius:var(--r-sm);padding:.5rem .6rem;margin-bottom:.6rem;line-height:1.4;}
@media(max-width:759px){.cat-mobile{display:block;}}

/* Outils du catalogue (modèle Excel, import). Masqués sur téléphone comme la
   création d'article : l'administration du catalogue se fait sur ordinateur. */
.cat-outils{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.6rem;}
@media(max-width:759px){.cat-outils{display:none;}}

/* --- Import du catalogue ------------------------------------------------- */
.imp-etapes{margin:.6rem 0 1rem;padding-left:1.2rem;color:var(--muted);
  font-size:var(--fs-body-sm);line-height:1.5;}
.imp-etapes li{margin-bottom:.45rem;}
.imp-etapes b{color:var(--ink);}

.imp-modes{display:grid;grid-template-columns:1fr 1fr;gap:.6rem;margin:.8rem 0;}
@media(max-width:639px){.imp-modes{grid-template-columns:1fr;}}
.imp-mode{display:block;background:var(--card);border:1px solid var(--hair);
  border-radius:var(--r-md);padding:.7rem .8rem;cursor:pointer;}
.imp-mode.on{border-color:var(--azure);box-shadow:0 0 0 1px var(--azure);}
.imp-mode input{margin-right:.4rem;}
.imp-mode b{font-size:var(--fs-body-sm);}
.imp-mode span{display:block;margin-top:.25rem;color:var(--muted);
  font-size:var(--fs-small);line-height:1.4;}

.imp-chiffres{display:flex;flex-wrap:wrap;gap:.5rem;margin:.8rem 0;}
.imp-chiffre{flex:1 1 7rem;background:var(--lt);border-radius:var(--r-sm);
  padding:.6rem .7rem;text-align:center;}
.imp-chiffre b{display:block;font-size:var(--fs-display-s);line-height:1.1;color:var(--ink);}
.imp-chiffre span{display:block;margin-top:.2rem;color:var(--muted);
  font-size:var(--fs-tiny);line-height:1.3;}
.imp-vert b{color:var(--ok);}
.imp-bleu b{color:var(--azure);}
.imp-orange b{color:var(--warn);}
.imp-rouge b{color:var(--danger);}

.imp-avert{background:rgba(217,138,43,.12);border-radius:var(--r-sm);
  padding:.55rem .7rem;margin:.6rem 0;color:var(--ink);
  font-size:var(--fs-small);line-height:1.45;}
.imp-avert>span{margin-right:.35rem;}

.imp-erreurs{background:rgba(207,75,75,.08);border-radius:var(--r-sm);
  padding:.6rem .75rem;margin:.7rem 0;font-size:var(--fs-small);line-height:1.45;}
.imp-erreurs b{display:block;margin-bottom:.35rem;color:var(--danger);}
.imp-erreurs ul{margin:0;padding-left:1.1rem;color:var(--ink);}
.imp-erreurs li{margin-bottom:.2rem;}
/* « À vérifier » : la ligne passe quand même. Orange et non rouge — ce n'est
   pas un refus, c'est un doute qu'on met sous les yeux de l'artisan. */
.imp-doutes{background:rgba(217,138,43,.12);}
.imp-doutes b{color:var(--warn);}

.imp-detail{margin:.5rem 0;font-size:var(--fs-small);}
.imp-detail summary{cursor:pointer;color:var(--azure);padding:.25rem 0;}
.imp-detail ul{margin:.35rem 0 0;padding-left:1.1rem;color:var(--ink);line-height:1.5;}

.art-carte{display:flex;align-items:center;gap:.8rem;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--hair);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:.7rem .85rem;margin-bottom:.5rem;cursor:pointer;
  transition:border-color .15s;}
.art-carte:hover{border-color:var(--azure);}
.art-inactif{opacity:.55;}
.art-off{font-size:var(--fs-label);font-weight:800;text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);background:var(--lt);border-radius:var(--r-pill);padding:.1rem .4rem;}
/* Icônes de famille dessinées plutôt qu'empruntées aux emoji : aucun emoji ne
   représente un split mural ni un groupe extérieur, et 🌬️ (du vent) comme 📦
   (un carton) n'évoquaient pas le matériel (remarque de Thomas du 11/08/2026).
   Elles héritent de la couleur du texte, donc elles suivent le contexte. */
.ico-svg{width:1.05em;height:1.05em;vertical-align:-.16em;flex:none;}
/* Icône dessinée dans un bouton de barre : taille fixe, couleur héritée du
   bouton (stroke="currentColor"). Ne dépend d'aucune police. */
.ico-bouton{width:21px;height:21px;flex:none;}
.art-ico .ico-svg{width:22px;height:22px;vertical-align:0;color:var(--bd);}

.art-ico{flex:none;width:38px;height:38px;display:flex;align-items:center;justify-content:center;
  font-size:1.25rem;background:var(--lt);border-radius:var(--r-sm);overflow:hidden;}
.art-ico img{width:100%;height:100%;object-fit:cover;}
.art-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:.1rem;}
.art-txt b{font-size:var(--fs-small);font-weight:800;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.art-sous{font-size:var(--fs-small-xs);color:var(--muted);font-weight:500;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Les repères de puissance, dans la recherche depuis un devis. Plus lisibles
   que la ligne d'identification au-dessus : c'est sur eux qu'on tranche entre
   deux unités, pas sur la référence du modèle. */
.art-repere{font-size:var(--fs-label);font-weight:700;color:var(--bd);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.art-prix{flex:none;font-size:var(--fs-small);font-weight:800;color:var(--bd);text-align:right;}
.art-prix small{display:block;font-size:var(--fs-label);font-weight:600;color:var(--muted);}

/* --- Formulaire d'article --- */
.modal-large{max-width:860px;max-height:88vh;overflow-y:auto;}
.art-section{border-top:1px solid var(--hair);padding-top:.85rem;margin-top:.85rem;}
.art-section-titre{font-size:var(--fs-tiny);font-weight:800;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted);margin-bottom:.6rem;}
.art-apercu{margin-top:.6rem;font-size:var(--fs-small);color:var(--ink);background:var(--lt);
  border-radius:var(--r-sm);padding:.5rem .65rem;}
.art-forcee{color:var(--azure);font-weight:700;font-size:var(--fs-small-xs);}
.art-case{display:flex;align-items:center;gap:.5rem;font-size:var(--fs-small);font-weight:700;
  color:var(--ink);margin-top:.7rem;}
.art-case input{width:auto;margin:0;}
.art-photo{display:flex;align-items:center;gap:.6rem;margin-bottom:.6rem;}
.art-photo img{width:76px;height:76px;object-fit:cover;border-radius:var(--r-sm);border:1px solid var(--hair);}
.art-nophoto{font-size:var(--fs-small);color:var(--muted);}

/* --- Liste des devis --- */
.devis-carte{display:flex;flex-direction:column;gap:.22rem;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--hair);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:.8rem .9rem;margin-bottom:.55rem;cursor:pointer;
  transition:border-color .15s;}
.devis-carte:hover{border-color:var(--azure);}
.dv-head{display:flex;align-items:center;gap:.5rem;}
.dv-head b{font-size:var(--fs-small);font-weight:800;color:var(--bd);}
.dv-nom{font-size:var(--fs-small);font-weight:700;color:var(--ink);}
.dv-titre{font-size:var(--fs-small-xs);color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.dv-pied{display:flex;justify-content:space-between;font-size:var(--fs-small-xs);
  color:var(--muted);font-weight:700;margin-top:.2rem;}

/* Les statuts de devis réutilisent les pastilles des relevés (brouillon,
   transmis, vendu, refusé, abandonné) : une seule application ne doit pas
   avoir deux vocabulaires visuels pour la même idée. Seul « expiré » manquait. */
.statut-expire{background:#f2ece0;color:var(--warn);}

/* --- Édition d'un devis --- */
.dv-bandeau{font-size:var(--fs-small);font-weight:700;border-radius:var(--r-sm);
  padding:.55rem .7rem;margin-bottom:.7rem;line-height:1.4;}
.dv-etat{font-size:var(--fs-label);font-weight:800;padding:.15rem .5rem;border-radius:var(--r-pill);}
.dv-etat-ok{background:#dff3e8;color:var(--ok);}
.dv-etat-ko{background:#fbe5e5;color:var(--danger);}
.dv-etat-attente{background:#f2ece0;color:var(--warn);}
.dv-client b{display:block;font-size:var(--fs-body);color:var(--ink);}
.dv-client span{font-size:var(--fs-small);color:var(--muted);}

.dv-alerte{background:#f2ece0;border-radius:var(--r-sm);padding:.6rem .75rem;margin-bottom:.7rem;}
.dv-alerte b{display:block;font-size:var(--fs-small);color:var(--warn);margin-bottom:.25rem;}
.dv-alerte ul{margin:0;padding-left:1.1rem;}
.dv-alerte li{font-size:var(--fs-small-xs);color:var(--muted);line-height:1.45;}

.dv-ligne{border:1px solid var(--hair);border-radius:var(--r-sm);padding:.5rem .6rem;
  margin-bottom:.4rem;background:var(--card);}
.dv-ligne-titre{background:var(--lt);border-color:transparent;display:flex;align-items:center;gap:.4rem;}
.dv-ligne-remise{background:#fbe5e5;border-color:var(--hair);}
.dv-titre-input{font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  font-size:var(--fs-small);color:var(--bd);background:transparent;border:none;margin:0;}
.dv-l-haut{display:flex;align-items:center;gap:.5rem;}
/* Icône de famille en tête de ligne : sur téléphone, deux références Carrier
   se ressemblent, et rien ne disait laquelle était le groupe extérieur.
   Discrète — elle informe, elle ne réclame pas l'attention. */
.dv-l-fam{flex:none;display:flex;align-items:center;color:var(--muted);}
.dv-l-fam .ico-svg{width:18px;height:18px;vertical-align:0;}

/* Bandeau de la recherche restreinte à une famille. */
.dv-filtre-fam{display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  background:var(--lt);border-radius:var(--r-sm);padding:.35rem .6rem;margin-bottom:.5rem;
  font-size:var(--fs-small-xs);font-weight:700;color:var(--muted);}
.dv-filtre-fam button{background:none;border:none;padding:.1rem;cursor:pointer;
  font-size:var(--fs-small-xs);font-weight:800;color:var(--azure);text-decoration:underline;}
.dv-l-lib{flex:1;min-width:0;font-size:var(--fs-small);font-weight:700;margin:0;border:none;background:transparent;}
.dv-l-montant{flex:none;font-size:var(--fs-small);font-weight:800;color:var(--bd);}
.dv-l-note{font-size:var(--fs-label);color:var(--muted);margin:.1rem 0 .2rem;}
/* Qté / P.U. HT / TVA côte à côte, plus la corbeille.
   `min-width:0` est indispensable : sans lui, un élément de rangée refuse de
   descendre sous la largeur naturelle de son contenu — et un champ de saisie
   réclame d'office une vingtaine de caractères. Les trois champs additionnés
   dépassaient alors la largeur d'un téléphone, élargissaient toute la page, et
   on pouvait la faire glisser latéralement : la barre du haut se retrouvait
   coupée et le devis sortait de son cadre. */
.dv-l-bas{display:flex;flex-wrap:wrap;align-items:flex-end;gap:.4rem;margin-top:.3rem;}
.dv-l-bas label{flex:1 1 4rem;min-width:0;font-size:var(--fs-label);font-weight:700;color:var(--muted);}
.dv-l-bas input{width:100%;max-width:100%;box-sizing:border-box;
  margin-top:.1rem;padding:.35rem .45rem;font-size:var(--fs-small);}
/* Quatre champs sur un téléphone ne tiennent pas côte à côte sans devenir
   illisibles : quand « Achat » s'ajoute, la rangée passe en deux fois deux. */
/* Panneau technique ouvert : cinq champs (Qté, P.U., TVA, Achat, Coef.).
   Sur téléphone ils passent à deux par ligne plutôt que de se comprimer. */
@media(max-width:480px){.dv-l-bas-4 label{flex:1 1 40%;}}
.dv-l-achat input{background:var(--lt);}
.dv-sup{flex:none;background:none;border:none;font-size:1rem;cursor:pointer;padding:.25rem;opacity:.6;}
.dv-sup:hover{opacity:1;}

/* Monter / descendre / supprimer, groupés sur la ligne du haut, à côté du
   montant — et non avec les champs de saisie. Deux raisons : les champs de
   quantité et de prix gardent toute leur largeur (ils en gagnent même, la
   corbeille les ayant quittés), et la ligne ne s'allonge pas d'une rangée
   supplémentaire. Seul le champ de désignation se resserre, ce qu'un champ de
   texte supporte bien. Mesuré : 90 px de hauteur au lieu de 126. */
.dv-l-actions{display:flex;align-items:center;gap:.15rem;flex:none;}
.dv-mv{position:relative;flex:none;background:none;border:none;cursor:pointer;color:var(--muted);
  font-size:1rem;line-height:1;padding:.35rem .4rem;border-radius:var(--r-sm);
  transition:background .12s,color .12s;}
/* La flèche reste discrète à l'œil, mais sa zone sensible est étendue en
   hauteur : un bouton de 27 px se rate au doigt, surtout debout sur un
   chantier. L'extension est verticale seulement, pour que deux flèches
   voisines ne se chevauchent jamais. */
.dv-mv::after{content:'';position:absolute;left:0;right:0;top:-8px;bottom:-8px;}
/* Sur téléphone, les quatre boutons mangeaient 106 px des 285 de la rangée, et
   le libellé n'en gardait que 83 — trop peu pour lire la référence du modèle,
   qui est justement ce qui distingue deux articles d'une même gamme. On serre
   l'écartement des boutons : la zone tactile, elle, reste étendue par le
   pseudo-élément ci-dessus, donc rien ne devient plus difficile à viser. */
@media(max-width:480px){
  .dv-l-haut .dv-mv{padding:.35rem .18rem;}
  .dv-l-haut .dv-sup{padding:.25rem .1rem;}
}
.dv-mv:hover:not(:disabled){background:var(--lt);color:var(--ink);}
.dv-mv:disabled{opacity:.22;cursor:default;}
.dv-ligne-titre .dv-l-actions{margin-left:.3rem;}

.dv-ajouts{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.6rem;}

/* Totaux : ce que le client verrait. Marge et coûts restent derrière un bouton,
   pour que l'écran ne les étale pas devant lui sur un chantier.
   Le bloc ne SUIT PLUS le défilement (il était `position:sticky`) : sur
   téléphone il occupait le tiers bas de l'écran en permanence et recouvrait les
   lignes du devis (remarque de Thomas du 11/08/2026). Il se lit maintenant en
   fin de devis, là où on va naturellement pour conclure. */
.dv-totaux-bloc{}
.dv-tot-ligne{display:flex;justify-content:space-between;align-items:baseline;
  font-size:var(--fs-small);padding:.18rem 0;color:var(--ink);}
.dv-tot-detail{font-size:var(--fs-small-xs);color:var(--muted);}
.dv-tot-ttc{border-top:1px solid var(--hair);margin-top:.3rem;padding-top:.4rem;
  font-size:var(--fs-body);color:var(--bd);}
.dv-tot-ttc b{font-size:var(--fs-display-s);}
.dv-tech{border-top:1px dashed var(--hair);margin-top:.5rem;padding-top:.5rem;}
.dv-tech-btn{width:100%;margin-top:.5rem;background:none;border:1px dashed var(--hair);
  border-radius:var(--r-sm);padding:.4rem;font-size:var(--fs-small-xs);font-weight:700;
  color:var(--muted);cursor:pointer;}
.dv-tech-btn:hover{border-color:var(--azure);color:var(--azure);}
/* Indicateur de marge : un repère, jamais un garde-fou. L'artisan reste libre
   de descendre sous sa cible (décision de Thomas du 28/07/2026). */
.marge-bon{color:var(--ok);}
.marge-moyen{color:var(--warn);}
.marge-faible{color:var(--danger);}
.marge-neutre{color:var(--ink);}

.dv-actions{display:grid;gap:.45rem;margin-top:.9rem;}
.dv-resultats{max-height:52vh;overflow-y:auto;margin:.6rem 0;}

/* ================================================================
   APERÇU D'UN DEVIS À L'ÉCRAN (point 102, 13/08/2026)
   ----------------------------------------------------------------
   Relire son devis ne produit aucun fichier. Cet écran doit se lire comme le
   document remis au client : fond blanc, largeur de page, hiérarchie du PDF.
   Il n'imite pas le PDF au pixel — il en dit la même chose, dans le même ordre.
   ================================================================ */
.ap-page{background:#fff;border-radius:var(--r-md);box-shadow:0 2px 16px rgba(12,40,54,.1);
  padding:1.1rem 1rem 1.4rem;max-width:760px;margin:0 auto;color:#28323a;
  font-size:var(--fs-small);line-height:1.45;}
.ap-tete{margin-bottom:.5rem;}
.ap-bandeau{width:100%;height:auto;border-radius:var(--r-sm);display:block;}
.ap-ent b{display:block;font-size:var(--fs-title);font-weight:800;color:var(--bd);line-height:1.2;}
.ap-ent span{display:block;font-size:var(--fs-tiny-xs);color:var(--muted);margin-top:.15rem;}
.ap-immat{text-align:center;font-size:var(--fs-label);color:var(--muted);margin:.5rem 0 .8rem;line-height:1.35;}
.ap-numero{display:inline-block;border:1.5px solid var(--hair);border-radius:var(--r-sm);
  padding:.35rem .8rem;font-weight:800;color:var(--bd);font-size:var(--fs-body-sm);margin-bottom:.9rem;}

.ap-haut{display:flex;gap:.9rem;flex-wrap:wrap;margin-bottom:.9rem;}
.ap-info{flex:1 1 55%;min-width:0;background:var(--lt);border-radius:var(--r-sm);padding:.6rem .7rem;}
.ap-info>div{display:flex;gap:.5rem;padding:.14rem 0;}
.ap-info span{flex:0 0 33%;font-weight:800;color:var(--bd);font-size:var(--fs-tiny-xs);
  text-transform:uppercase;letter-spacing:.03em;}
.ap-info b{font-weight:500;min-width:0;overflow-wrap:anywhere;}
.ap-client{flex:1 1 35%;min-width:0;text-align:right;}
.ap-client b{display:block;font-weight:800;color:var(--bd);font-size:var(--fs-body-sm);}
.ap-client span{display:block;color:#3d4a54;overflow-wrap:anywhere;}

.ap-titre{border:1.5px solid var(--hair);border-radius:var(--r-sm);padding:.55rem;text-align:center;
  font-weight:800;color:var(--bd);font-size:var(--fs-body-sm);letter-spacing:.01em;margin-bottom:.8rem;}
.ap-descriptif{white-space:pre-wrap;margin-bottom:.9rem;}

/* Le tableau déborde sur un téléphone : il défile SEUL, la page ne bouge pas. */
.ap-table{width:100%;border-collapse:collapse;display:block;overflow-x:auto;margin-bottom:.9rem;}
.ap-table thead th{background:var(--bd);color:#fff;font-size:var(--fs-label);font-weight:800;
  text-transform:uppercase;letter-spacing:.03em;padding:.4rem .45rem;text-align:left;white-space:nowrap;}
.ap-table td{padding:.45rem;border-bottom:1px solid #e6eff4;vertical-align:top;font-size:var(--fs-tiny-xs);}
.ap-table .ap-des{min-width:210px;}
.ap-num{text-align:right;white-space:nowrap;font-family:var(--mono);}
.ap-mt{font-weight:800;}
.ap-code{color:var(--muted);font-family:var(--mono);}
.ap-tech{display:block;color:var(--muted);font-size:var(--fs-label);margin-top:.18rem;line-height:1.35;}
.ap-rub td{background:#f3f8fb;font-weight:800;color:var(--bd);text-transform:uppercase;
  letter-spacing:.04em;font-size:var(--fs-label);}
.ap-remise td{color:var(--danger);}

.ap-attestation{background:var(--lt);border-radius:var(--r-sm);padding:.6rem .7rem;font-style:italic;
  font-size:var(--fs-tiny-xs);color:#3d4a54;margin-bottom:.9rem;white-space:pre-wrap;}

.ap-recap{margin-left:auto;max-width:380px;margin-bottom:.9rem;}
.ap-recap table{width:100%;border-collapse:collapse;}
.ap-recap th{background:var(--bd);color:#fff;font-size:var(--fs-label);font-weight:800;
  padding:.3rem .4rem;text-align:right;white-space:nowrap;}
.ap-recap td{padding:.3rem .4rem;font-size:var(--fs-tiny-xs);border-bottom:1px solid #e6eff4;}
.ap-totaux{margin-top:.5rem;border-top:2px solid var(--bd);padding-top:.4rem;}
.ap-totaux>div{display:flex;justify-content:space-between;gap:1rem;padding:.16rem 0;}
.ap-totaux span{font-weight:800;color:var(--bd);font-size:var(--fs-tiny-xs);
  text-transform:uppercase;letter-spacing:.03em;}
.ap-totaux b{font-family:var(--mono);font-weight:800;}
.ap-ttc{font-size:var(--fs-body);border-top:1px solid var(--hair);margin-top:.25rem;padding-top:.35rem;}
.ap-ttc span,.ap-ttc b{font-size:var(--fs-body-sm);}

.ap-cond{font-size:var(--fs-tiny-xs);margin-bottom:.6rem;}
.ap-cond>div{padding:.1rem 0;}
.ap-acompte{font-weight:800;color:var(--bd);font-size:var(--fs-tiny-xs);margin-bottom:.9rem;line-height:1.4;}

.ap-signature{display:flex;gap:.8rem;flex-wrap:wrap;margin-bottom:1rem;}
.ap-signature>div{flex:1 1 45%;min-width:150px;border:1.5px solid var(--hair);border-radius:var(--r-sm);
  padding:.6rem .7rem;min-height:72px;}
.ap-signature b{display:block;font-size:var(--fs-tiny-xs);font-weight:800;color:var(--bd);}
.ap-signature span{display:block;font-size:var(--fs-label);color:var(--muted);margin-top:.2rem;}

.ap-legal{border-top:1px solid var(--hair);padding-top:.6rem;font-size:var(--fs-label);
  color:var(--muted);line-height:1.45;}
.ap-legal>div{margin-top:.2rem;}
.ap-legal-t{display:block;font-weight:800;text-transform:uppercase;letter-spacing:.04em;
  color:var(--bd);margin-bottom:.25rem;}

@media(max-width:480px){
  .ap-page{padding:.85rem .7rem 1.1rem;}
  .ap-haut{flex-direction:column;}
  .ap-client{text-align:left;}
  .ap-recap{max-width:none;}
}

/* Annonce d'annexe dans l'aperçu (point 104) : les CGV sont un PDF déposé, pas
   du texte que ClimPro connaît — on ne peut que dire qu'elles seront jointes. */
.ap-annexe{margin-top:.8rem;border-top:1px dashed var(--hair);padding-top:.6rem;
  font-size:var(--fs-tiny-xs);font-weight:700;color:var(--azure);}
.ap-annexe-vide{color:var(--warn);}

/* Date du dernier partage, sous les boutons du devis (point 102). Discret :
   c'est une trace, pas une action. */
.dv-partage{text-align:center;font-size:var(--fs-tiny-xs);color:var(--muted);
  font-weight:700;margin:-.35rem 0 .6rem;}

/* Réglette de marge (point 113) : une glissière qu'on déplace devant le client,
   avec le résultat lu AVANT d'appliquer. */
.dv-reglette{margin:.5rem 0 .3rem;}
.dv-reglette label{display:block;font-size:var(--fs-tiny-xs);font-weight:700;color:var(--muted);margin-bottom:.2rem;}
.dv-reglette label b{color:var(--bd);font-size:var(--fs-body-sm);}
.dv-reglette label small{color:var(--muted);font-weight:600;}
.dv-reglette input[type=range]{width:100%;accent-color:var(--azure);margin:.25rem 0 .35rem;height:28px;}
.dv-reglette-apercu{font-size:var(--fs-tiny-xs);color:var(--bd);line-height:1.4;min-height:2.2em;margin-bottom:.4rem;}
.dv-reglette-apercu b{font-family:var(--mono);}
.dv-reglette-non{color:var(--warn);font-weight:600;}

/* Doublons du catalogue (point 115). Orange, comme tout ce qui avertit sans
   bloquer — et invisible tant qu'il n'y en a pas. */
#catalogueDoublons:empty{display:none;}
.cat-doublons{border:1.5px solid var(--warn);border-radius:var(--r-md);background:#fdf6ef;
  padding:.7rem .8rem;margin-bottom:.8rem;}
.cat-doublons>b{display:block;color:var(--warn);font-size:var(--fs-body-sm);font-weight:800;}
.cat-doublons>span{display:block;font-size:var(--fs-tiny-xs);color:var(--muted);line-height:1.4;margin:.2rem 0 .5rem;}
.cat-doublon{border-top:1px solid #efdcc6;padding-top:.45rem;margin-top:.45rem;}
.cat-doublon-ref{font-size:var(--fs-label);font-weight:800;text-transform:uppercase;
  letter-spacing:.03em;color:var(--muted);margin-bottom:.25rem;}
.cat-doublon-l{display:flex;align-items:center;justify-content:space-between;gap:.6rem;padding:.22rem 0;}
.cat-doublon-l span{font-size:var(--fs-tiny-xs);font-weight:700;color:var(--ink);min-width:0;overflow-wrap:anywhere;}
.cat-doublon-l small{color:var(--muted);font-family:var(--mono);font-weight:500;}
.cat-doublon-l button{flex:none;}

/* ================================================================
   LE RELEVÉ EN VIGNETTES (point 117)
   ----------------------------------------------------------------
   Une grille de postes à la place du défilement. Chaque vignette porte son
   résumé : c'est ce qui en fait un tableau de bord et non un menu.
   ================================================================ */

/* Les deux décisions qui valent pour tout le chantier, en bandeau : elles
   commandent chaque proposition, elles ne peuvent pas être une vignette
   parmi les autres. */
.gr-chantier{display:flex;gap:.5rem;background:var(--bd);border-radius:var(--r-md);
  padding:.6rem .7rem;margin-bottom:.7rem;cursor:pointer;
  box-shadow:0 2px 10px rgba(12,40,54,.18);}
.gr-chantier div{flex:1;min-width:0;}
.gr-chantier small{display:block;font-size:var(--fs-label);font-weight:800;
  letter-spacing:.05em;text-transform:uppercase;color:#8fc4dc;}
.gr-chantier b{display:block;font-size:var(--fs-small-xs);color:#fff;font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

.grille{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;}
.gr-rubrique{grid-column:1/-1;font-size:var(--fs-label);font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  margin:.55rem 0 -.1rem;}

.vg{background:var(--card);border:1.5px solid var(--hair);border-radius:var(--r-md);
  padding:.6rem;position:relative;min-height:98px;display:flex;flex-direction:column;
  text-align:left;width:100%;transition:border-color .15s,transform .1s;}
.vg:active{transform:scale(.985);}
.vg.plein{border-color:#bcdcea;}
.vg.large{grid-column:1/-1;min-height:0;}
.vg-ico{font-size:1.15rem;line-height:1;}
.vg-nom{font-family:'Syne',sans-serif;font-weight:800;font-size:var(--fs-small);
  color:var(--bd);letter-spacing:-.01em;margin-top:.25rem;line-height:1.2;}
.vg.large .vg-nom{margin-top:0;}
/* Le résumé : volume, besoin, référence. En chiffres alignés, parce qu'on les
   compare d'une vignette à l'autre. */
.vg-val{font-family:var(--mono);font-size:var(--fs-label);color:var(--azure);
  font-weight:700;margin-top:.22rem;line-height:1.35;white-space:pre-line;
  font-variant-numeric:tabular-nums;}
.vg-sous{font-size:var(--fs-label);color:var(--muted);margin-top:auto;
  padding-top:.3rem;line-height:1.3;}
/* Trois états qui se lisent sans lire. Un pourcentage demanderait un effort
   que la couleur non. */
.vg-etat{position:absolute;top:.55rem;right:.55rem;width:8px;height:8px;border-radius:50%;}
.vg-etat.ok{background:var(--ok);}
.vg-etat.att{background:var(--warn);}
.vg-etat.vide{background:var(--hair);}
.vg-ajout{border-style:dashed;border-color:#c3d8e3;align-items:center;
  justify-content:center;color:var(--azure);font-weight:800;
  font-size:var(--fs-small-xs);min-height:64px;text-align:center;}

/* Un nom de pièce long ne doit pas casser la vignette. */
.vg-nom{overflow-wrap:anywhere;}

/* Sur ordinateur, la grille respire : trois puis quatre colonnes. Les
   vignettes larges gardent toute la ligne. */
@media(min-width:700px){ .grille{grid-template-columns:repeat(3,1fr);} }
@media(min-width:1000px){ .grille{grid-template-columns:repeat(4,1fr);} }

/* Poste ouvert : plus qu'une seule section à l'écran, son cadre ferait double
   emploi avec celui de la fiche qu'elle contient. */
#view-edit.detail .section-card{background:none;border:0;box-shadow:none;
  border-radius:0;margin-bottom:0;overflow:visible;}
#view-edit.detail .section-body{padding:0;}

/* Menu « auteur » (point 118) : un select qui doit ressembler aux autres
   boutons de la barre, flèche comprise.
   ⚠️ Tout en propriétés détaillées : .lt-btn et .lt-btn.active posent un
   `background` raccourci, qui remet position/répétition/taille à zéro — la
   flèche se répétait alors en mosaïque sur toute la largeur du bouton. */
.lt-select{appearance:none;-webkit-appearance:none;border:0;cursor:pointer;
  padding-right:2rem;max-width:12rem;text-overflow:ellipsis;
  background-color:var(--lt);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%232f7fa3' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .8rem center;background-size:.6rem .4rem;}
.lt-select.active{color:#fff;background-color:var(--azure);
  box-shadow:0 3px 10px rgba(var(--azure-rgb),.28);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .8rem center;background-size:.6rem .4rem;}
/* Le menu déroulant natif s'ouvre avec le fond du système : on force un texte
   lisible dedans, sinon le blanc de l'état actif suit et devient invisible. */
.lt-select option{color:var(--bd);background:#fff;}

/* Pastille « archivé » (point 120) : neutre à dessein. Le statut commercial
   garde sa couleur — archivé n'est pas un statut, juste un rangement. */
.statut-chip.statut-archive{background:var(--sur,#eef4f7);color:var(--muted);
  box-shadow:inset 0 0 0 1px var(--hair);}

/* ================================================================
   POINT 121 — LA GRILLE SUR ORDINATEUR
   ----------------------------------------------------------------
   Sur grand écran, une vignette « large » qui prend toute la largeur devient
   un bandeau de 1 200 px pour une ligne de texte : de la place perdue et une
   lecture qui traverse l'écran. Elle prend deux colonnes, pas toutes.
   ================================================================ */
@media(min-width:1000px){
  .vg.large{grid-column:span 2;min-height:98px;}
  .vg-ajout.large{grid-column:span 2;}
  /* Le texte respire : c'est un tableau de bord lu à 60 cm, pas à bout de bras. */
  .vg-nom{font-size:var(--fs-body);}
  .vg-val{font-size:var(--fs-small-xs);}
  .vg-sous{font-size:var(--fs-small-xs);}
  .gr-chantier b{font-size:var(--fs-body);}
}
/* Poste ouvert sur grand écran : une seule fiche à l'écran, elle n'a aucune
   raison de s'étirer sur 1 240 px — on la ramène à une largeur de lecture. */
@media(min-width:1000px){
  #view-edit.detail .edit-wrap{max-width:860px;}
}

/* ================================================================
   REVUE DESIGN — catégorie A (constats 2, 6, 7, 9)
   ================================================================ */
/* 2. Les champs de recherche des devis et du catalogue n'avaient aucun style :
   même composant que la liste des relevés. */
.search{display:block;width:100%;padding:.8rem 1rem;border:2px solid var(--hair);
  border-radius:var(--r-md);background:#fff;font-size:var(--fs-body);margin-bottom:.85rem;
  transition:border-color .15s,box-shadow .15s;}
.search:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
/* 6. La synchro ne s'affiche que quand elle manque, en mots, pas en pastille :
   la pastille orange voulait dire « commencé » sur la grille du relevé. */
.sync-chip{font-size:var(--fs-small-xs);font-weight:700;color:var(--warn);white-space:nowrap;}
/* 7. Ce qui n'a pas de sens sur téléphone n'y apparaît pas. */
@media(max-width:879px){.masque-mobile{display:none!important;}}
/* 9. Tableau de bord compact : trois chiffres sur une ligne, pas trois cartes. */
.dash-tile{padding:.55rem .6rem;}
.dash-tile b{font-size:var(--fs-card-title);}
.dash-tile span{font-size:var(--fs-tiny);}

/* ================================================================
   REVUE DESIGN — catégorie B (constats 12, 13)
   ================================================================ */
/* 12. Une aide qui se déplie : la phrase utile est visible, le reste attend
   qu'on le demande. Natif (details), donc accessible sans script. */
.aide{font-size:var(--fs-small);color:var(--muted);line-height:1.4;margin:.15rem 0 .6rem;}
.aide summary{cursor:pointer;list-style:none;display:flex;gap:.4rem;align-items:baseline;font-weight:500;}
.aide summary::-webkit-details-marker{display:none;}
.aide summary::before{content:"?";flex-shrink:0;width:1.1rem;height:1.1rem;border-radius:50%;
  background:var(--lt);color:var(--azure);font-weight:800;font-size:var(--fs-small);
  display:inline-flex;align-items:center;justify-content:center;transform:translateY(.05rem);}
.aide[open] summary::before{content:"–";}
.aide p{margin:.35rem 0 0 1.5rem;}
/* 13. Zones tactiles : les quatre boutons d'une ligne faisaient 28 px collés —
   supprimer en voulant remonter n'était qu'une question de temps. 42 px,
   espacés, et la corbeille à l'écart du reste. */
.dv-l-actions{gap:.3rem;}
.dv-l-actions .dv-mv,.dv-l-actions .dv-sup{min-width:42px;height:42px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r-sm);
  font-size:var(--fs-title);line-height:1;}
.dv-l-actions .dv-sup{margin-left:.45rem;}
/* 13 (suite) : à 42 px, quatre boutons prenaient toute la ligne et le NOM de
   l'article disparaissait. Sur écran étroit, les boutons passent sous le nom,
   alignés à droite ; le nom garde la première rangée avec le montant. */
.dv-l-lib{flex:1;min-width:0;}
@media(max-width:600px){
  .dv-l-haut{flex-wrap:wrap;row-gap:.2rem;}
  .dv-l-actions{flex-basis:100%;justify-content:flex-end;}
}

/* ================================================================
   REVUE DESIGN — constat 22 : icônes tracées (lot 1, écran de relevé)
   ----------------------------------------------------------------
   Une icône se dessine au trait, à la couleur du texte. Elle a la hauteur
   d'une lettre par défaut ; chaque emplacement lui donne la sienne.
   ================================================================ */
.ico-svg{width:1.1em;height:1.1em;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;vertical-align:-.18em;flex-shrink:0;}
.section-head .ico .ico-svg{width:22px;height:22px;color:var(--azure);}
.vg-ico .ico-svg{width:1.35rem;height:1.35rem;color:var(--azure);}
.vg.large .vg-nom .ico-svg{width:1.3em;height:1.3em;color:var(--azure);margin-right:.25rem;vertical-align:-.25em;}
.photo-add .pic .ico-svg{width:1.7rem;height:1.7rem;}
.sub-del .ico-svg{width:20px;height:20px;}
.sol-head .ico-svg{width:1.05rem;height:1.05rem;color:var(--azure);vertical-align:-.22em;}
.sol-alerte .ico-svg{color:var(--warn);}
.btn .ico-svg,.statut-opt .ico-svg{margin-right:.1rem;}
.btn-icon .ico-svg{width:22px;height:22px;}
.photo-del .ico-svg{width:16px;height:16px;stroke-width:2.5;}

/* ================================================================
   REVUE DESIGN — constat 22, lots 2 et 3 : icônes partout ailleurs
   ================================================================ */
.sidebar-link .ico .ico-svg,.bn-link .ico .ico-svg{width:22px;height:22px;}
.rc-ico .ico-svg{width:24px;height:24px;color:var(--azure);}
.empty-state .ico .ico-svg{width:2.6rem;height:2.6rem;color:var(--muted-soft);stroke-width:1.5;}
.settings-label .ico-svg,.art-section-titre .ico-svg,.detail-title .ico-svg{width:1.05rem;height:1.05rem;
  color:var(--azure);vertical-align:-.25em;margin-right:.15rem;}
h1 .ico-svg,h2 .ico-svg,h3 .ico-svg{color:var(--azure);}
h2 .ico .ico-svg{width:22px;height:22px;}
.cc-line .ico-svg,.releve-sub .ico-svg{color:var(--muted);}
.back .ico-svg{width:22px;height:22px;}
.pwd-toggle .ico-svg{width:20px;height:20px;}
.lightbox .close .ico-svg{width:20px;height:20px;stroke-width:2.5;}
.statut-chip .ico-svg{width:.95em;height:.95em;vertical-align:-.12em;}
.imp-avert .ico-svg{color:var(--warn);}
.late-badge .ico-svg,.conflit-badge .ico-svg,.sync-chip .ico-svg{vertical-align:-.15em;}
.filter-tab .ico-svg,.lt-btn .ico-svg{margin-right:.1rem;}

/* ================================================================
   REVUE DESIGN — catégorie C : les parcours (constats 14 à 18, 20)
   ================================================================ */
/* 14. La feuille « Filtres et tri » : par le bas sur téléphone, en carte
   centrée sur ordinateur. */
.sheet{position:fixed;inset:0;z-index:120;}
.sheet-fond{position:absolute;inset:0;background:rgba(8,18,24,.45);}
.sheet-corps{position:absolute;left:0;right:0;bottom:0;background:var(--card);
  border-radius:var(--r-sheet) var(--r-sheet) 0 0;padding:1rem 1.1rem calc(1.1rem + var(--safe-b));
  max-height:85vh;overflow:auto;box-shadow:var(--shadow-lg);}
.sheet-tete{display:flex;align-items:center;justify-content:space-between;margin-bottom:.2rem;}
.sheet-tete b{font-family:'Syne',sans-serif;font-size:var(--fs-title);color:var(--bd);}
.sheet-champ{display:block;font-size:var(--fs-small);font-weight:800;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;margin:.9rem 0 0;}
.sheet-select,.sheet-dates input{display:block;width:100%;margin-top:.35rem;padding:.7rem .8rem;
  border:1.5px solid var(--hair);border-radius:var(--r-sm);font-size:var(--fs-body);
  background:#fbfdfe;text-transform:none;letter-spacing:0;font-weight:600;color:var(--ink);font-family:inherit;}
.sheet-dates{display:grid;grid-template-columns:1fr auto 1fr;gap:.4rem;align-items:center;
  text-transform:none;letter-spacing:0;font-weight:500;}
.sheet-dates .sheet-select{grid-column:1/-1;}
.sheet-pied{display:flex;gap:.6rem;margin-top:1.2rem;}
.sheet-pied .btn{flex:1;}
body.sheet-ouverte{overflow:hidden;}
@media(min-width:880px){
  .sheet-corps{left:50%;right:auto;bottom:auto;top:12vh;transform:translateX(-50%);width:440px;border-radius:var(--r-sheet);}
}
/* 15. Une seule case « Photo » ; la galerie en lien sous la grille. */
.photo-galerie{grid-column:1/-1;font-size:var(--fs-small);font-weight:700;color:var(--azure);
  padding:.3rem 0;text-align:left;background:none;border:0;justify-self:start;}
/* 16. Ajouter une pièce ou un groupe se fait depuis la grille, pas depuis un
   poste ouvert. Les zones libres et les documents gardent leur bouton : le
   poste montre toute la liste. */
#view-edit.detail [data-poste="pieces"] .add-sub,#view-edit.detail [data-poste="groupes"] .add-sub{display:none;}
/* 17. La rangée principale du devis, et le reste derrière « Plus ». */
.dv-actions-prim{display:flex;gap:.6rem;margin:.4rem 0 .6rem;}
.dv-actions-prim .btn{flex:1;}
.dv-plus{margin-top:.4rem;}
.dv-plus summary{cursor:pointer;list-style:none;text-align:center;padding:.7rem;
  font-size:var(--fs-small);font-weight:800;color:var(--azure);}
.dv-plus summary::-webkit-details-marker{display:none;}
.dv-plus summary::after{content:" ▾";}
.dv-plus[open] summary::after{content:" ▴";}
.dv-plus-corps{display:flex;flex-direction:column;gap:.5rem;padding-bottom:.4rem;}
/* 18. Les deux champs commerciaux du devis, traités comme des champs. */
.dv-champ input,.dv-champ textarea{display:block;width:100%;margin-top:.35rem;padding:.75rem .85rem;
  border:1.5px solid var(--hair);border-radius:var(--r-sm);font-size:var(--fs-body);
  background:#fbfdfe;font-family:inherit;color:var(--ink);}
.dv-champ input:focus,.dv-champ textarea:focus{outline:none;border-color:var(--azure);box-shadow:0 0 0 3px rgba(var(--azure-rgb),.13);}
/* 19. Sur téléphone, une carte par ligne de devis ; le tableau revient sur
   ordinateur, où il a la place. */
.ap-cartes{display:none;}
.ap-carte{padding:.6rem 0;border-bottom:1px solid #e6eff4;}
.ap-carte-rub{font-weight:800;color:var(--bd);text-transform:uppercase;font-size:var(--fs-small);
  letter-spacing:.04em;border-bottom:2px solid var(--bd);}
.ap-carte-des{font-size:var(--fs-body-sm);color:var(--ink);line-height:1.4;}
.ap-carte-des .ap-tech{display:block;}
.ap-carte-bas{display:flex;justify-content:space-between;align-items:baseline;gap:.6rem;margin-top:.3rem;
  font-size:var(--fs-small);color:var(--muted);font-variant-numeric:tabular-nums;}
.ap-carte-bas b{color:var(--bd);font-size:var(--fs-body-sm);white-space:nowrap;}
@media(max-width:640px){
  .ap-table{display:none;}
  .ap-cartes{display:block;margin-bottom:.9rem;}
}
/* 21. Le planning : les jours à rendez-vous se voient de loin, les autres
   restent à plat ; l'en-tête tient sur une ligne. */
.planning-head{flex-wrap:nowrap;gap:.3rem;}
.planning-head .planning-month{font-size:var(--fs-card-title);white-space:nowrap;text-transform:capitalize;}
.planning-head .btn-sm{padding:.45rem .6rem;white-space:nowrap;}
.planning-day{background:none;border-color:transparent;font-weight:600;color:var(--muted);}
.planning-day.has-rdv{background:var(--lt);color:var(--azure);font-weight:800;}
.planning-day.today{border-color:var(--azure);color:var(--azure);}
.planning-day.selected{background:linear-gradient(180deg,var(--azure-hi),var(--azure));color:#fff;border-color:var(--azure);}
.planning-day .dot{display:none;}
.planning-vide{color:var(--muted);font-size:var(--fs-small);margin:0 0 1rem;}
@media(max-width:480px){.planning-head .pl-txt{display:none;}}
.sheet-pied .btn{white-space:nowrap;padding:.9rem .5rem;font-size:var(--fs-body-sm);}
/* Le mois en Syne 800 à 1,05 rem ne tient pas entre quatre boutons sur 375 px :
   un cran de moins sous 480 px, et une ellipse plutôt qu'un débordement. */
@media(max-width:480px){.planning-head .planning-month{font-size:var(--fs-body-sm);min-width:0;overflow:hidden;text-overflow:ellipsis;}}

/* ================================================================
   REVUE DESIGN — constat 24, écran 1 : la liste des relevés en tableau
   ================================================================ */
#releveList.tableau{display:block;}
.rl-table{width:100%;border-collapse:separate;border-spacing:0;background:var(--card);
  border:1px solid var(--hair);border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow);
  font-size:var(--fs-body-sm);}
.rl-table th{text-align:left;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;
  letter-spacing:.06em;color:var(--muted);padding:.65rem .85rem;border-bottom:1px solid var(--hair);
  background:#f6fafc;white-space:nowrap;user-select:none;}
.rl-table th.triable{cursor:pointer;}
.rl-table th.triable:hover{color:var(--bd);}
.rl-table th.tri-actif{color:var(--azure);}
.rl-table th.tri-actif::after{content:" \25BE";}
.rl-table td{padding:.6rem .85rem;border-bottom:1px solid var(--hair);vertical-align:middle;}
.rl-table tr:last-child td{border-bottom:0;}
.rl-ligne{cursor:pointer;transition:background .12s;}
.rl-ligne:hover td{background:#f4f9fc;}
.rl-ligne.sel td{background:var(--lt);}
.rl-client{font-weight:800;color:var(--bd);font-size:var(--fs-body);}
.rl-sous{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.2rem;}
.rl-adresse{max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted);}
.rl-quand{white-space:nowrap;color:var(--muted);font-variant-numeric:tabular-nums;}
.rl-num{text-align:right;font-variant-numeric:tabular-nums;}
.rl-vide{color:var(--muted-soft);}
.rl-sel{width:2.2rem;}

/* ================================================================
   REVUE DESIGN — constat 24, écrans 2 et 3 : clients en tableau, devis en
   édition sur ordinateur
   ================================================================ */
#clientsListEl.tableau{display:block;}
.rl-table a{color:var(--azure);text-decoration:none;}
.rl-table a:hover{text-decoration:underline;}

/* Le devis en édition : à partir de 1 100 px, deux colonnes — le devis à
   gauche, les totaux et les actions à droite, collés en haut pendant qu'on
   défile dans les lignes. */
.dv-entete{display:none;}
@media(min-width:1100px){
  #view-devis-edit .list-wrap{max-width:1280px;display:grid;column-gap:1.25rem;align-items:start;
    grid-template-columns:minmax(0,1fr) 340px;
    grid-template-areas:"bandeau bandeau" "alertes alertes" "client cote" "proposition cote" "lignes cote";
    grid-template-rows:auto auto auto auto 1fr;}
  #view-devis-edit .dv-bandeau{grid-area:bandeau;}
  #dv_alertes{grid-area:alertes;}
  #dv_blocClient{grid-area:client;}
  #dv_blocProposition{grid-area:proposition;}
  #dv_blocLignes{grid-area:lignes;}
  .dv-totaux-bloc{grid-area:cote;position:sticky;top:1rem;align-self:start;}
  .dv-totaux-bloc .dv-actions-prim{flex-direction:column;}

  /* Les lignes en tableau : chaque ligne devient une rangée de grille, ses
     deux rangées internes (haut/bas) se fondent dedans (display:contents).
     Colonnes : icône · désignation · qté · P.U. · TVA · montant · actions. */
  .dv-entete{display:grid;grid-template-columns:28px minmax(0,1fr) 80px 110px 72px 110px 190px;
    gap:.5rem;padding:.35rem .6rem;font-size:var(--fs-label);font-weight:800;text-transform:uppercase;
    letter-spacing:.06em;color:var(--muted);}
  .dv-entete-tech{grid-template-columns:28px minmax(0,1fr) 80px 110px 72px 100px 72px 110px 190px;}
  .dv-entete .dv-e-num{text-align:right;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre){display:grid;align-items:center;gap:.5rem;
    grid-template-columns:28px minmax(0,1fr) 80px 110px 72px 110px 190px;padding:.4rem .6rem;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre):has(.dv-l-bas-4){
    grid-template-columns:28px minmax(0,1fr) 80px 110px 72px 100px 72px 110px 190px;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-haut,
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-bas{display:contents;}
  /* l'ordre des cases dans la rangée */
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-fam{order:1;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-lib{order:2;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-bas label{order:3;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-bas label.dv-l-achat{order:4;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-montant{order:5;text-align:right;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-actions{order:6;justify-content:flex-end;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-note{order:7;grid-column:2/-1;margin:0;}
  /* le libellé de chaque champ vit dans l'en-tête : la case ne garde que sa saisie */
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-bas label{font-size:0;line-height:0;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-bas input{font-size:var(--fs-body-sm);line-height:1.3;margin:0;}
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-actions .dv-mv,
  #dv_lignes .dv-ligne:not(.dv-ligne-titre) .dv-l-actions .dv-sup{min-width:36px;height:36px;}
  #dv_lignes .dv-ligne{margin-bottom:.35rem;}
}
