/* La même identité visuelle que la console : un outil interne qui ressemble au
   produit évite d'avoir à réapprendre où l'on est. Les couleurs sont copiées,
   pas importées — les deux applications ne partagent aucun fichier, et c'est
   voulu : la console ne doit pas casser parce qu'on a touché au devis. */
:root {
  --fond: #101216;
  --carte: #181b21;
  --carte-clair: #1f232b;
  --bord: #2b303a;
  --bord-fort: #3a4150;
  --texte: #e8eaee;
  --doux: #98a0ad;
  --faible: #6d7683;
  --ok: #4ade80;
  --alerte: #fbbf24;
  --panne: #f87171;
  --vise: #60a5fa;
  --e1: 4px; --e2: 8px; --e3: 12px; --e4: 18px;
  --r-s: 4px; --r-m: 8px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

/* **`hidden` doit gagner contre nos propres règles d'affichage.** Un `main`
   déclaré en grille reste affiché malgré l'attribut : la règle du navigateur
   est moins spécifique que la nôtre. Sans cette ligne, masquer quelque chose
   depuis le script ne masque rien — c'est un piège déjà refermé sur la
   console. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.muted { color: var(--doux); }
.small { font-size: 12.5px; }

.tete {
  display: flex; align-items: center; gap: var(--e3);
  padding: var(--e3) var(--e4);
  border-bottom: 1px solid var(--bord);
  background: var(--carte);
}
.titre { display: flex; align-items: baseline; gap: var(--e2); }
.titre strong { letter-spacing: .08em; }
.tete-actions { margin-left: auto; display: flex; gap: var(--e2); align-items: center; }

button.ghost {
  background: var(--carte-clair);
  color: var(--texte);
  border: 1px solid var(--bord-fort);
  border-radius: var(--r-s);
  padding: 6px 12px;
  font: inherit;
  cursor: pointer;
}
button.ghost:hover:not(:disabled) { border-color: var(--doux); }
button.ghost:disabled { opacity: .5; cursor: default; }
button.ghost.actif { border-color: var(--vise); }
button.danger { border-color: #5c3232; color: #f6b6b6; }

input, select, textarea {
  background: var(--fond);
  color: var(--texte);
  border: 1px solid var(--bord-fort);
  border-radius: var(--r-s);
  padding: 6px 8px;
  font: inherit;
  width: 100%;
}
label { display: block; margin-bottom: var(--e3); color: var(--doux); font-size: 12.5px; }
label input, label select, label textarea { margin-top: var(--e1); color: var(--texte); }

/* **La grille est celle de l'atelier, pas de tout `main`.** La page d'entrée
   est elle aussi un `main` : sans cette classe elle héritait de la grille à
   deux colonnes, le logo et le texte se chevauchaient dans la première rangée
   et les champs se retrouvaient larges de trente pixels. Une règle de mise en
   page nommée d'après une balise finit toujours par attraper une page qui
   n'était pas prévue. */
main.atelier {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: var(--e4);
  padding: var(--e4);
  align-items: start;
}

/* -- l'avis aux petits écrans -------------------------------------------- */
/*
 * **Le critère est le pointeur, pas seulement la largeur.** Une fenêtre
 * étroite sur un ordinateur reste pilotable à la souris ; un téléphone, non,
 * quelle que soit son orientation. On montre donc l'avis sur un pointeur
 * grossier **ou** un écran vraiment étroit — et on laisse passer qui insiste.
 */
.avis-mobile { display: none; }

@media (pointer: coarse), (max-width: 700px) {
  body:not(.mobile-accepte) .avis-mobile {
    display: grid;
    place-items: center;
    position: fixed;
    inset: 0;
    z-index: 50;
    padding: var(--e4);
    background: var(--fond);
  }
  /* Tant que l'avis est là, rien ne bouge derrière : un outil qu'on devine
     sous un voile invite à essayer quand même. */
  body:not(.mobile-accepte) { overflow: hidden; }
}

.avis-mobile-carte {
  max-width: 420px;
  padding: var(--e4);
  background: var(--carte);
  border: 1px solid var(--bord);
  border-left: 3px solid var(--alerte);
  border-radius: var(--r-m);
}
.avis-mobile-carte h2 { margin: 0 0 var(--e3); font-size: 18px; }
.avis-mobile-carte p { margin: 0 0 var(--e3); line-height: 1.6; }
.avis-mobile-carte button { width: 100%; }

/* -- la page d'entrée ---------------------------------------------------- */

.page-connexion { display: grid; place-items: center; min-height: 100vh; }
.connexion {
  display: block;
  width: min(360px, 92vw);
  padding: var(--e4);
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--r-m);
  text-align: center;
}
/* Pas de logo ici : il est violet pour fond clair, il demandait un filtre pour
   survivre au fond sombre, et il répétait ce que l'onglet dit déjà. Le nom
   suffit. */
.connexion-titre {
  margin: 0 0 var(--e1);
  font-size: 26px; font-weight: 800; letter-spacing: .14em;
}
.connexion form { margin-top: var(--e4); text-align: left; }
.connexion button { width: 100%; margin-top: var(--e2); }
.erreur { color: var(--panne); margin: var(--e3) 0 0; }

/* -- le plan ------------------------------------------------------------- */

.plan-barre {
  display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap;
  margin-bottom: var(--e3);
}
/* Une liste déroulante prend toute la largeur par défaut, ce qui renvoyait le
   bouton « Poser » à la ligne suivante — le geste et son objet séparés. */
.plan-barre select { width: auto; max-width: 260px; }
.toile-cadre {
  position: relative;
  border: 1px solid var(--bord);
  border-radius: var(--r-m);
  background: #0b0d11;
  overflow: hidden;
}
#toile { display: block; width: 100%; height: auto; cursor: crosshair; }
/* **La bulle d'aide ne prend pas les clics.** Elle flotte au-dessus de la
   toile : posée en bas à gauche, elle recouvrait exactement la cote qu'on
   vient calibrer, et les clics partaient dans le vide. Elle passe en haut, et
   surtout elle laisse passer la souris — sauf quand elle porte le champ de
   saisie de la distance, qui lui doit être cliquable. C'est le même défaut que
   le calque des repères de la console, corrigé de la même façon. */
.toile-aide {
  position: absolute; left: var(--e3); top: var(--e3);
  margin: 0; padding: 4px 10px;
  background: rgba(8, 10, 14, .82);
  border-radius: var(--r-s);
  pointer-events: none;
}
.toile-aide.saisie { pointer-events: auto; display: flex; gap: var(--e2); }
.toile-aide.saisie input { width: 160px; }

/* -- le panneau ---------------------------------------------------------- */

.panneau {
  background: var(--carte);
  border: 1px solid var(--bord);
  border-radius: var(--r-m);
  padding: var(--e3);
  position: sticky; top: var(--e3);
}
.onglets { display: flex; gap: var(--e1); margin-bottom: var(--e3); }
.onglet {
  flex: 1;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--doux); font: inherit; padding: 6px 0; cursor: pointer;
}
.onglet.actif { color: var(--texte); border-bottom-color: var(--vise); }

/* Le verdict d'une caméra : c'est la seule chose de cet outil qu'un
   concurrent ne sait pas calculer, donc c'est elle qui se voit. */
.verdict {
  margin: var(--e3) 0;
  padding: var(--e3);
  border: 1px solid var(--bord);
  border-left: 3px solid var(--bord-fort);
  border-radius: var(--r-s);
  background: var(--carte-clair);
  font-size: 12.5px;
  line-height: 1.6;
}
.verdict.bon { border-left-color: var(--ok); }
.verdict.limite { border-left-color: var(--alerte); }
.verdict.mauvais { border-left-color: var(--panne); }
.verdict b { color: var(--texte); }
.verdict .ligne { display: flex; justify-content: space-between; gap: var(--e3); }
.verdict .ligne span:last-child { color: var(--texte); font-variant-numeric: tabular-nums; }
.verdict .doute { color: var(--alerte); }
/* Un paragraphe collé au bloc qui le précède : la maison n'écrit pas de
   `style=`, ni dans le HTML ni depuis le script. */
.serre { margin-bottom: 0; }

/* La coupe : une vue de profil, dans le panneau, sous les réglages qu'elle
   illustre. Le curseur dit qu'on peut la tirer. */
#coupe {
  display: block;
  width: 100%;
  height: auto;
  margin: var(--e3) 0;
  border: 1px solid var(--bord);
  border-radius: var(--r-s);
  background: #0b0d11;
  cursor: grab;
}
#coupe.tire { cursor: grabbing; }
.coupe-aide { margin: calc(-1 * var(--e2)) 0 var(--e3); }

/* -- le devis ------------------------------------------------------------ */

table.devis { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.devis th {
  text-align: left; color: var(--doux); font-weight: 500;
  border-bottom: 1px solid var(--bord); padding: 4px 2px;
}
table.devis td { padding: 4px 2px; border-bottom: 1px solid var(--bord); }
table.devis td.nombre { text-align: right; font-variant-numeric: tabular-nums; }
table.devis input { width: 56px; padding: 2px 4px; text-align: right; }
table.devis button {
  background: none; border: 0; color: var(--faible); cursor: pointer; font: inherit;
}
.ligne-ajout { display: flex; gap: var(--e2); margin: var(--e3) 0; }
.ligne-ajout select { flex: 1; }
.ligne-ajout input { width: 56px; }
.reglages-prix { display: flex; gap: var(--e3); }
.totaux {
  margin-top: var(--e3); padding-top: var(--e3);
  border-top: 1px solid var(--bord);
  font-variant-numeric: tabular-nums;
}
.totaux .ligne { display: flex; justify-content: space-between; }
.totaux .total { font-size: 16px; font-weight: 600; margin-top: var(--e2); }

.etat {
  position: fixed; right: var(--e4); bottom: var(--e3);
  margin: 0; padding: 4px 10px;
  background: var(--carte); border: 1px solid var(--bord); border-radius: var(--r-s);
}

/* -- le dossier client --------------------------------------------------- */
/*
 * **Le dossier porte la charte, l'outil porte la console.** Les deux vivent
 * dans la même page et n'ont pas le même lecteur : l'outil est un instrument
 * de travail, sombre, dense ; le dossier est ce qu'un client reçoit, et il
 * doit ressembler au site public. Typographie Aspekta, les neuf couleurs de
 * la charte, et rien d'inventé.
 *
 * La police est copiée ici plutôt qu'appelée chez le voisin : l'outil doit
 * tourner sur un portable sans réseau, devant un client.
 */
@font-face {
  font-family: "Aspekta";
  src: url("polices/AspektaVF.woff2") format("woff2-variations");
  font-weight: 100 1000;
  font-style: normal;
  font-display: swap;
}

#dossier {
  --violet-1: #290d4f;
  --violet-2: #7342ed;
  --violet-3: #1c0d33;
  --vert-1: #7ad633;
  --vert-3: #132211;
  --neutre-1: #ffffff;
  --neutre-2: #faffe5;
  --neutre-3: #292b26;
  /* Le vert ne tient pas sur du clair — 1,78 de contraste, mesuré pour le site
     public. Il ne sert donc jamais de couleur de texte ici : seulement en
     aplat, en filet et en pastille. */
  background: var(--neutre-1);
  color: var(--neutre-3);
  font-family: "Aspekta", system-ui, sans-serif;
  padding: 14mm;
  max-width: 210mm;
  margin: 0 auto;
}

.dossier-tete {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--e4);
  padding-bottom: var(--e3);
  border-bottom: 3px solid var(--vert-1);
}
.dossier-tete img { width: 118px; height: auto; }
.dossier-tete .quoi { text-align: right; font-size: 12px; color: var(--violet-2); }
.dossier-tete .quoi b { display: block; font-size: 15px; color: var(--violet-1);
  font-weight: 700; letter-spacing: .01em; }

#dossier h1 {
  font-size: 30px; font-weight: 800; letter-spacing: -.015em;
  color: var(--violet-1);
  margin: var(--e4) 0 var(--e1);
}
#dossier .client { color: var(--violet-2); font-size: 14px; margin: 0 0 var(--e4); }
#dossier h2 {
  font-size: 12px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--violet-2);
  margin: 28px 0 var(--e2);
  padding-bottom: 5px;
  border-bottom: 1px solid color-mix(in srgb, var(--violet-2) 25%, transparent);
}
#dossier p { font-size: 13px; }
#dossier img.plan {
  width: 100%;
  border: 1px solid color-mix(in srgb, var(--violet-1) 20%, transparent);
  border-radius: 3px;
}
#dossier .legende-plan { font-size: 11.5px; color: var(--violet-2); margin-top: 6px; }

/* Les repères : une pastille de la couleur du plan, le nom, le matériel. */
.reperes-liste { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 20px; }
.reperes-liste div { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.reperes-liste .pastille {
  width: 13px; height: 13px; border-radius: 50%; flex: none;
  border: 1.5px solid color-mix(in srgb, var(--violet-1) 45%, transparent);
}
.reperes-liste b { color: var(--violet-1); font-weight: 700; min-width: 34px; }

#dossier table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
#dossier th {
  text-align: left; font-weight: 700; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--violet-2);
  border-bottom: 1px solid color-mix(in srgb, var(--violet-2) 30%, transparent);
  padding: 6px 2px;
}
#dossier td {
  padding: 7px 2px;
  border-bottom: 1px solid color-mix(in srgb, var(--violet-1) 12%, transparent);
}
#dossier td.nombre, #dossier th.nombre {
  text-align: right; font-variant-numeric: tabular-nums;
}
#dossier .totaux-client {
  margin-top: var(--e3);
  margin-left: auto;
  width: 54%;
  font-size: 13px;
}
#dossier .totaux-client .ligne {
  display: flex; justify-content: space-between; padding: 4px 0;
}
#dossier .totaux-client .total {
  margin-top: 4px; padding-top: 8px;
  border-top: 2px solid var(--vert-1);
  font-size: 17px; font-weight: 800; color: var(--violet-1);
}

@media print {
  /* Sur papier, le fond sombre coûte une cartouche et se lit mal. */
  body { background: #fff; color: #111; }
  .tete, main, .etat { display: none !important; }
  #dossier { display: block !important; max-width: none; }
  #dossier img.plan { break-inside: avoid; }
  table { break-inside: auto; }
  tr { break-inside: avoid; }
  h2 { break-after: avoid; }
  /* **Marges à zéro, et c'est délibéré.** C'est le seul moyen de faire taire
     l'en-tête et le pied de page du navigateur — l'adresse du site et la date
     imprimées en petit dans les coins, qui n'ont rien à faire sur un document
     remis à un client. La marge revient par le remplissage du dossier. */
  @page { margin: 0; }
}

@media (max-width: 900px) {
  main.atelier { grid-template-columns: minmax(0, 1fr); }
  .panneau { position: static; }
}
