/* Composition du dashboard. Les palettes viennent de garage/themes.py.
   La couverture (connexion, verrou, verification en deux temps) est l'entree
   de l'application : son titre, ses champs et ses boutons en prennent
   l'habit, `.cover` rejoignant les regles de `.dashboard-app` (spec
   Finitions 6.4). */
body {
  font-family:var(--sans);
  color:var(--ink)
}
body.dashboard-app {
  background:var(--ground)
}
/* Une seule famille dans l'espace connecté (spec Finitions 2.1) : les titres
   qui lisaient --serif (tuiles d'Ajouter, noms du parc, titres des analyses)
   passent dans la famille des titres de page. Les pages publiques n'ont pas
   la classe et gardent leur serif. */
.dashboard-app {
  --serif:var(--sans)
}
body.dashboard-app:before {
  opacity:.035
}
body.dashboard-app[data-traces="non"]:before {
  display:none
}
.dashboard-app h1,.dashboard-app h2,.dashboard-app h3,.cover h1 {
  font-family:var(--sans);
  letter-spacing:-.025em
}
.dashboard-app h1 {
  font-size:32px;
  font-weight:600;
  line-height:1.2
}
.dashboard-app h2 {
  font-size:18px;
  font-weight:600
}
.dashboard-app a {
  text-decoration:none
}
.dashboard-app a:hover {
  color:var(--accent-texte)
}
.dashboard-app .num {
  font-family:var(--sans);
  font-variant-numeric:tabular-nums
}
.dashboard-app .micro {
  font-size:11px;
  letter-spacing:0;
  text-transform:none
}
.dashboard-app .icon {
  stroke-width:1.65
}
.dashboard-app .muted {
  color:var(--ink-faint)
}
.dashboard-app button,.dashboard-app .btn,.cover button,.cover .btn {
  font-family:var(--sans);
  font-size:12px;
  min-height:43px;
  padding:10px 15px;
  border-radius:var(--r-vif);
  border:1px solid var(--hair-2);
  background:transparent;
  color:var(--accent-texte);
  text-transform:none;
  letter-spacing:0;
  box-shadow:none
}
/* Composants (spec du 09/10/2026, section 4) : la navigation et le tableau
   de bord livres par Maison gardent leur forme. Leurs boutons lisent la
   base d'avant le lot A ; `:where()` ne pese rien, la regle garde le poids
   et la place de la base, et chaque regle propre a un bouton de Maison
   passe devant elle comme avant. Meme liste de blocs dans interface.css,
   tenue par test_les_blocs_de_maison_sont_nommes_par_la_meme_liste. */
.dashboard-app :where(.masthead,.ears,.installer,.ouverture,.prioritaire,.chiffres,.raccourcis,.journal,.accueil-garage) button,.dashboard-app :where(.masthead,.ears,.installer,.ouverture,.prioritaire,.chiffres,.raccourcis,.journal,.accueil-garage) .btn {
  border-radius:999px;
  background:var(--ground-2);
  color:var(--ink)
}
.dashboard-app button:hover,.dashboard-app .btn:hover,.dashboard-app a.entree:hover,.cover button:hover,.cover .btn:hover {
  border-color:var(--accent);
  color:var(--accent-texte)
}
/* « Fait » de la routine d'hivernage (spec 2.4) : un tap au telephone, sur
   une cible d'au moins 44 px. `.dashboard-app .btn-fait` (une classe de
   plus que `.dashboard-app button` juste au-dessus) l'emporte par
   specificite et pose 44 px la ou la regle generale pose 43. Meme cible
   pour `.btn-tactile`, les gestes « Monter », « Annuler » et « Retirer »
   du stock de pieces (taches B4 et B6), et les « Retirer » au trait d'une
   video ou d'un frais de sortie : `.dashboard-app .btn-danger.trait`, plus
   bas, pose 30 px a (0,3,0) ; la troisieme forme (0,4,0) l'emporte quelle
   que soit la place des regles. */
@media (max-width: 720px) {
  .dashboard-app .btn-fait, .dashboard-app .btn-tactile,
  .dashboard-app .btn-danger.trait.btn-tactile { min-height: 44px; min-width: 44px; }
}
/* « Annuler » une coche d'hivernage (spec 2.4) : une commande discrete de
   rangee, distincte du gros bouton plein de « Fait ». `.micro` fixe sa
   taille de texte mais `.dashboard-app button` juste au-dessus pose quand
   meme le contour, le fond et les 43 px de tout bouton : cette regle les
   retire. Restreinte a `.rangee-hivernage`, la classe dediee aux rangees
   d'Hivernage (gestes et historique) : les autres `.filet-row` de l'app
   gardent leurs boutons. */
.dashboard-app .rangee-hivernage button.micro {
  background:none;
  border:0;
  padding:0;
  min-height:0;
  color:var(--ink-2)
}
.dashboard-app .rangee-hivernage button.micro:hover {
  color:var(--accent-texte)
}
.dashboard-app .btn-primary,.cover .btn-primary {
  background:var(--ink);
  border-color:var(--ink);
  color:var(--ground-2)
}
.dashboard-app .btn-primary:hover,.cover .btn-primary:hover {
  background:var(--accent);
  color:var(--on-accent)
}
/* Confirmation destructive (spec Finitions 2.3) : la teinte du danger. */
.dashboard-app .btn-danger {
  background:var(--danger);
  border-color:var(--danger);
  color:var(--on-accent)
}
/* Au survol l'aplat fonce vers l'encre et reste plein : le contrat des themes
   tient le libelle sur ce fond (test_le_danger_plein_reste_plein_au_survol). */
.dashboard-app .btn-danger:hover {
  background:color-mix(in srgb, var(--danger) 80%, var(--ink));
  border-color:color-mix(in srgb, var(--danger) 80%, var(--ink));
  color:var(--on-accent)
}
/* Geste destructif en liste ou dans un formulaire d'edition : le trait du
   danger, au gabarit compact, pour que la rangee garde la hauteur de ses
   voisines. Le plein reste aux ecrans de confirmation. */
.dashboard-app .btn-danger.trait {
  background:transparent;
  border-color:color-mix(in srgb, var(--danger) 50%, transparent);
  color:var(--danger);
  min-height:30px;
  padding:5px 10px
}
/* Dans une rangee de liste, le bouton deborde de 4 px sur le retrait de la
   rangee au lieu de la grandir : 30 px de bouton pour 22 px de ligne de texte,
   la rangee garde la hauteur de ses voisines sans geste (mesure au navigateur
   sur l'onglet Couts de la fiche). */
.dashboard-app .filet-row .btn-danger.trait {
  margin-block:-4px
}
.dashboard-app .btn-danger.trait:hover {
  background:color-mix(in srgb, var(--danger) 10%, transparent);
  border-color:var(--danger);
  color:var(--danger)
}
/* La tuile-lien de l'écran « Ajouter un véhicule » garde l'icône de la
   tuile-bouton de la saisie (retours testeur du 01/10). */
.dashboard-app button .icon,.dashboard-app .btn .icon,.dashboard-app a.entree .icon {
  width:17px;
  height:17px
}
.dashboard-app input:not([type="checkbox"]):not([type="radio"]),.dashboard-app select,.dashboard-app textarea,.cover input:not([type="checkbox"]):not([type="radio"]) {
  background:var(--ground-2);
  color:var(--ink);
  border:1px solid var(--hair);
  border-radius:var(--r-controle);
  padding:11px 12px;
  font-size:14px;
  min-height:44px;
  max-width:100%
}
/* Un champ desactive (la quantite d'une piece deja montee, recette B6) ne
   se lit pas comme un champ a saisir : sans fond, encre secondaire, filet
   en tirets. */
.dashboard-app input:disabled:not([type="checkbox"]):not([type="radio"]) {
  background:transparent;
  color:var(--ink-2);
  border-style:dashed;
  cursor:not-allowed
}
/* Les menus de la charte (spec Finitions 6 bis, point 6) : la flèche du
   navigateur cède la place au chevron de la charte, au trait et à l'encre
   secondaire, tourné vers le bas ; le texte s'arrête avant lui. Deux
   dégradés tracent chacun une branche en diagonale de sa boîte (la bande
   centrale de « to top right » joint les coins haut gauche et bas droit) :
   une image SVG ne lirait pas l'encre du thème. Deux demi-carrés pleins
   peignaient un triangle (revue de qualité du lot E2). */
.dashboard-app select {
  -webkit-appearance:none;
  appearance:none;
  padding-right:30px;
  background-image:linear-gradient(to top right,transparent calc(50% - 1.1px),var(--ink-2) calc(50% - .3px),var(--ink-2) calc(50% + .3px),transparent calc(50% + 1.1px)),linear-gradient(to top left,transparent calc(50% - 1.1px),var(--ink-2) calc(50% - .3px),var(--ink-2) calc(50% + .3px),transparent calc(50% + 1.1px));
  background-position:calc(100% - 20px) 50%,calc(100% - 16px) 50%;
  background-size:5px 5px;
  background-repeat:no-repeat
}
/* La liste de rattachement d'un entretien (spec intervenants 4.5) : sa borne
   de largeur vit ICI parce que la regle ci-dessus la contredit, et qu'app.css
   est servi AVANT cette feuille. `width: auto` dimensionne la liste sur son
   option la plus longue ; a 1280 px, ou la colonne de contenu est plus
   etroite qu'a 900 px (l'aside), un nom d'atelier de 57 caracteres poussait
   la ligne sur trois rangs. Sur une colonne plus etroite que 20rem, c'est
   `flex-shrink` qui ramene la liste dans le rang. */
.dashboard-app .ligne-rattachement select { max-width:20rem }
.dashboard-app input[type="checkbox"],.dashboard-app input[type="radio"] {
  accent-color:var(--accent)
}
.dashboard-app label {
  color:var(--ink-2);
  font-size:13px
}
/* L'anneau de focus (3 px a 3 px du champ) deborde de 6 px au-dessus du
   champ : l'espace sous le libelle le garde hors du texte. Une case ou un
   bouton radio tient sa rangee sans cet espace. */
.dashboard-app label:has(+ input:not([type="checkbox"]):not([type="radio"])),
.dashboard-app label:has(+ select),
.dashboard-app label:has(+ textarea) {
  margin-bottom:8px
}
/* Sauf dans une rangee de rattachement, en flex centre : la marge entrerait
   dans le centrage et leverait le libelle au-dessus de l'axe de son menu. */
.dashboard-app .ligne-rattachement label {
  margin-bottom:0
}
/* Ni dans la ligne d'une échéance proposée (premières échéances) : la
   case, son libellé et la date tiennent une rangée centrée, et la marge
   descendait la case de 4 px sous l'axe de son libellé. La règle défaite
   pèse (0,3,2), les deux `:not` de son `:has` comptés ; celle-ci pèse
   (0,3,3) en nommant le paragraphe et la date qui suit le libellé. */
.dashboard-app p.echeance-proposee > label:has(+ input[type="date"]) {
  margin-bottom:0
}
.dashboard-app :focus-visible {
  outline:3px solid var(--accent);
  outline-offset:3px
}
.dashboard-app [hidden] {
  display:none!important
}
/* La navigation est définie une seule fois, badge compris, à toute largeur.
   Maison (spec du 08/10, 3.1) : la colonne est un aplat à filet, sans ombre,
   large de `--colonne` (232 px, 254 dès 1600 px, 76 en rail), sur
   `--colonne-fond` ; interface.css pose les deux jetons. */
.dashboard-app .masthead {
  position:fixed;
  left:0;
  top:0;
  bottom:0;
  width:var(--colonne);
  max-width:none;
  margin:0;
  padding:18px 18px 14px;
  border:0;
  border-right:1px solid var(--hair-2);
  background:var(--colonne-fond);
  box-shadow:none;
  display:flex;
  flex-direction:column;
  text-align:left;
  z-index:5;
  overflow:hidden
}
/* La marque de la barre est le logo, pas un mot composé au clavier : la
   couronne et PADDOCK COLLECTION arqué, centrés en tête de colonne. */
.dashboard-app .masthead .wordmark {
  display:flex;
  align-items:center;
  justify-content:center;
  margin:0 0 12px;
  padding:0
}
.dashboard-app .masthead .wordmark img {
  display:block
}
/* Le logo se sert a la taille de son DESSIN, pas de sa boite : le fichier
   centre la couronne sur une toile carree et laisse pres d'un quart de vide
   de chaque cote, si bien qu'un carre de 132 px n'en dessinait que 71
   (mesure du 10/09, « je trouve que le logo est trop petit »). La boite
   prend la colonne moins ses marges, et `cover` recoupe le vide vertical
   que la couronne n'occupe pas : sans lui, 44 px de blanc au-dessus et
   au-dessous repousseraient la barre. Le fichier n'est pas retouche : sa
   toile sert aussi de repere au logo rejoue dans le PDF de la carte.
   Maison : 178 px de toile dessinent une couronne de 96 px de large, dans
   une boite de 96 px de haut (la maquette : 104 sur 94). */
.marque-long {
  width:178px;
  height:96px;
  object-fit:cover
}
/* Le logo est encré en foncé, comme le PDF et la plaque : sur les deux
   thèmes de nuit il faut le retourner, sans quoi il disparaît dans le fond.
   L'inversion rend une couronne crème et laisse les contreformes des
   lettres au ras du fond, ce qui est exactement leur rôle. La liste des
   thèmes sombres est tenue par test_marque_inversee_sur_tous_les_themes
   sombres : un thème de nuit ajouté sans être nommé ici fait tomber la
   suite plutôt que de servir un logo invisible. */
[data-theme="nuit-atelier"] .wordmark img,
[data-theme="weissach"] .wordmark img {
  filter:invert(1)
}
/* Le logo d'une maison (spec Hotes et marque blanche, 5.2) garde ses couleurs
   et ses proportions : ni le recadrage du logo de Paddock, dont la toile
   carree laisse du vide, ni l'inversion des themes de nuit. Sa boite est celle
   de ses attributs width et height, calcules a la taille du logement. */
[data-theme] .wordmark img.marque-maison {
  filter:none
}
.marque-long.marque-maison {
  width:auto;
  height:auto;
  max-width:100%;
  object-fit:contain
}
.dashboard-workspace {
  padding:13px 10px;
  border:1px solid var(--hair-2);
  border-radius:var(--r-vif);
  display:flex;
  align-items:center;
  gap:10px
}
.dashboard-workspace .icon {
  width:20px;
  color:var(--ink-faint)
}
.dashboard-workspace strong {
  display:block;
  font-size:12px;
  overflow-wrap:anywhere
}
.dashboard-workspace small {
  display:block;
  color:var(--ink-faint);
  font-size:10px;
  margin-top:5px
}
/* Le bouton « Ajouter un document » du client, à la place de l'encart
   (spec Finitions 3.1) : toute la largeur de la colonne, le même écart que
   l'encart avec l'étiquette qui le suit. */
.dashboard-ajouter {
  width:100%;
  justify-content:center;
  white-space:nowrap
}
/* Le bouton du tableau de bord redit celui de la colonne : pour le client,
   il ne paraît qu'au téléphone, où la colonne n'en porte pas. La
   conciergerie, sans bouton dans sa colonne, garde le sien partout. Sous
   `.dashboard-app`, le masquage pèse plus que `button, .btn` d'app.css et
   ne tient plus à l'ordre de chargement des feuilles. */
.dashboard-app .dashboard-ajouter-contenu {
  display:none
}
/* Les surtitres de groupe, les entrées, la pastille de compte et le pied de
   la colonne sont habillés dans interface.css (bloc Maison). */
.dashboard-app .mast-nav {
  display:flex;
  flex-direction:column;
  align-items:stretch;
  border:0;
  padding:0;
  margin:0;
  overflow:visible
}
/* La barre du haut (spec Maison 3.1) : 88 px sur un filet, à droite de la
   colonne. Sa marque, sa recherche et son monogramme sont habillés dans
   interface.css. */
.dashboard-app .ears {
  width:calc(100% - var(--colonne));
  max-width:none;
  margin:0 0 0 var(--colonne);
  padding:0 calc(36px + max(0px,100% - var(--colonne) - 1460px)) 0 36px;
  min-height:88px;
  border:0;
  border-bottom:1px solid var(--hair-2);
  background:transparent;
  color:var(--ink);
  flex-wrap:nowrap;
  gap:22px
}
/* La date reste jusqu'à 721 px : la barre du haut est sa seule place depuis
   RF-07. La barre tient sur une rangée à toute largeur : la marque et la
   date gardent leur mesure, c'est la recherche qui se resserre. */
.dashboard-app .ears-date {
  flex:none;
  text-transform:none;
  font-size:12px;
  letter-spacing:0;
  white-space:nowrap
}
.dashboard-app .ears-right {
  flex:0 1 auto;
  min-width:0;
  flex-wrap:nowrap;
  gap:22px
}
/* `order` et `flex` répondent au repli d'app.css, qui renvoyait le champ
   ouvert sur sa propre ligne, après le compte. */
.dashboard-app .ears .search {
  position:relative;
  flex:0 1 320px;
  order:0;
  min-width:0;
  width:320px
}
.dashboard-app .compte-menu {
  background:var(--ground-2);
  border:1px solid var(--hair-2);
  border-radius:var(--r-flottant);
  box-shadow:var(--ombre-flottant);
  min-width:185px;
  padding:10px;
  z-index:15
}
.dashboard-app .compte-menu a {
  padding:10px;
  font-size:13px
}
.dashboard-app .suggest {
  background:var(--ground-2);
  border-radius:var(--r-flottant-entree);
  box-shadow:var(--ombre-flottant);
  z-index:12
}
/* La loupe dans le champ (spec Finitions 4, RF-02) : le texte commence
   apres elle. (0,4,1) : passe devant `.dashboard-app .ears .search input`
   et le champ commun de l'espace connecte, (0,3,1) tous deux, quelle que
   soit la feuille. */
.dashboard-app .search .champ-loupe input[type="search"] {
  padding-left:36px
}
.dashboard-app .champ-loupe .loupe {
  stroke:var(--ink-2)
}
/* La page de recherche : le champ a la mesure courte de la charte, le
   bouton a cote avec l'ecart des rangees d'actions ; la rangee passe a la
   ligne quand la place manque (telephone). Le panneau prend la largeur de
   son champ. */
.dashboard-app .recherche-page label {
  margin-bottom:8px
}
.dashboard-app .recherche-rangee {
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:12px
}
.dashboard-app .recherche-rangee .champ-recherche {
  flex:1 1 16rem;
  max-width:var(--mesure-courte)
}
.dashboard-app .recherche-rangee .champ-loupe input[type="search"] {
  width:100%;
  max-width:none
}
.dashboard-app .recherche-page .suggest {
  left:0;
  right:0;
  width:auto
}
/* Au telephone le panneau du haut s'ancre a la barre, d'un bord a l'autre
   de la gouttiere : ancre au champ (58 px du bord a 393 px), il sortait de
   l'ecran par la droite. */
@media(max-width:720px) {
  .dashboard-app .ears {
    position:relative
  }
  .dashboard-app .ears .search,.dashboard-app .ears .champ-recherche {
    position:static
  }
  .dashboard-app .ears .suggest {
    left:16px;
    right:16px;
    width:auto
  }
}
.dashboard-app .content {
  color:var(--ink);
  background:transparent;
  min-height:calc(100vh - 88px)
}
.dashboard-app .content.court>form,.dashboard-app .content.court>h1,.dashboard-app .content.court>p,.dashboard-app .content.court>div {
  max-width:820px
}
/* Un seul axe sur un écran court (spec Finitions 2.4) : titre, chapeau,
   libellés, champs, actions et lien de retour partagent le bord gauche de la
   colonne. app.css centre `.content.court` et recentre ses paragraphes sur
   toute la zone : ici la colonne est posée à gauche, un paragraphe centré
   partait à 300 px de son formulaire. */
.dashboard-app .content.court {
  text-align:left
}
.dashboard-app .content.court>p {
  margin-inline:0
}
/* L'aide sous un champ, en micro-texte discret : jamais plus grosse que le
   libellé qu'elle précise. */
.dashboard-app .helptext {
  display:block;
  font-size:11px;
  color:var(--ink-faint);
  margin-top:4px
}
.dashboard-app .content>h1 {
  margin-top:0
}
.dashboard-app .section-title {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  text-align:left;
  border:0;
  background:none;
  padding:0;
  margin:28px 0 16px;
  font-size:18px;
  min-height:24px
}
.dashboard-app .section-title:before,.dashboard-app .section-title:after {
  display:none
}
.dashboard-app .section-title .compte {
  position:static;
  transform:none;
  font-size:11px;
  font-family:var(--sans);
  letter-spacing:0;
  text-transform:none;
  color:var(--ink-faint)
}
/* Composants (spec du 09/10/2026, piece 11) : le message de page. Une
   ligne sur un filet, sans cadre ni fond : le texte a l'accent lisible pour
   une confirmation, en couleur d'alerte pour un avertissement ou une erreur
   (`alerte`, posee par base.html d'apres le niveau du message). */
.dashboard-app .flash,.dashboard-app .muted.flash {
  margin:0;
  max-width:none;
  padding:16px 0;
  border:0;
  border-bottom:1px solid var(--hair-2);
  border-radius:0;
  background:none;
  color:var(--accent-texte);
  font-size:12px;
  line-height:1.6
}
.dashboard-app .flash.alerte,.dashboard-app .muted.flash.alerte {
  color:var(--danger)
}
/* Revue du lot A : le pictogramme du niveau (coche, triangle d'alerte,
   base.html), au trait, a la couleur du texte, 12 px avant lui. Le message
   court sur toute la colonne du contenu (`max-width:none` ci-dessus ; app.css
   borne un paragraphe du contenu a 78 ch). Le message qui porte un
   pictogramme est une rangee : son texte, dans sa balise, reste un seul
   bloc quand il passe a la ligne. Qui ignore `:has()` garde le pictogramme
   dans la ligne du texte. */
.dashboard-app .flash>.icon {
  width:16px;
  height:16px;
  margin-right:12px;
  vertical-align:-3px;
  stroke:currentColor;
  stroke-width:1.5
}
.dashboard-app .flash:has(>.icon) {
  display:flex;
  align-items:center;
  gap:12px
}
.dashboard-app .flash:has(>.icon)>.icon {
  margin-right:0
}
/* Une rangee de signalement posee seule hors d'une liste (fiche d'un
   intervenant repris, pret en retard) : une ligne sur son filet, comme un
   message de page (Composants, lot C), a l'ecart de ce qui la suit. */
.dashboard-app .filet-row.bandeau {
  margin-bottom:24px
}
.dashboard-metrics {
  display:grid;
  /* Les relevés sont quatre sur le tableau de bord, deux ou trois sur le
     bilan de collection (la carte des recettes paraît avec la première
     recette de l'année), trois sur la fiche d'un intervenant : auto-fit rend
     autant de colonnes que la largeur en porte, là où 1.2fr 1fr 1fr en
     figeait trois. Les replis sur deux colonnes (1150 px et impression)
     étalent la dernière carte d'un groupe impair sur toute la rangée. */
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  /* Composants, lot C (spec du 09/10/2026) : les cartes de chiffres du
     bilan et de la fiche d'un intervenant sont une bande, comme les quatre
     chiffres du tableau de bord. Chaque case trace un filet au-dessus
     d'elle et un a sa gauche ; la bande deborde de 23 px a gauche et rogne
     ce debord : le filet de la premiere case de chaque rangee sort de la
     vue, son texte part du fer, et les filets horizontaux partent du fer
     eux aussi. Un filet ferme la bande. */
  gap:0;
  margin:0 0 28px -23px;
  clip-path:inset(0 0 0 23px);
  border-bottom:1px solid var(--hair-2)
}
.dashboard-card {
  color:var(--ink)
}
.dashboard-card.metric {
  padding:20px 22px;
  border-top:1px solid var(--hair-2);
  border-left:1px solid var(--hair-2)
}
.metric-label {
  display:block;
  color:var(--ink-faint);
  font-size:12px
}
.metric>strong {
  font-size:30px;
  line-height:1.2;
  font-weight:550;
  letter-spacing:-1px;
  display:block;
  margin:6px 0;
  font-variant-numeric:tabular-nums
}
.metric>strong>span {
  font-size:14px;
  letter-spacing:0;
  color:var(--ink-faint)
}
.metric small {
  color:var(--ink-faint);
  font-size:11px;
  line-height:1.6;
  display:block
}
.dashboard-section-head {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:14px;
  margin:0 0 16px
}
.dashboard-section-head h2 {
  margin:0
}
.dashboard-section-head p {
  font-size:11px;
  margin:6px 0 0
}
.dashboard-section-head>a {
  font-size:12px;
  color:var(--accent-texte)
}
/* Sous les filtres de l'échéancier, le repère respire comme sous un titre. */
.filtres+.dashboard-section-head {
  margin-top:18px
}
/* Seul dans son repère (échéances faites), le lien garde le fer de droite. */
.dashboard-section-head>a:only-child {
  margin-left:auto
}
/* Le tableau des echeances est une liste a filets (Composants, lot C) :
   sa forme vient d'interface.css. */
.dashboard-app .deadline-list {
  margin-bottom:28px
}
/* Les mêmes cartes photographiques sur l'accueil et la collection. */ .dashboard-app .vignettes,.dashboard-app .entries {
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:18px;
  border:0;
  margin:0 0 24px;
  padding:0
}
.dashboard-app .vignette,.dashboard-app .entry {
  display:flex;
  flex-direction:column;
  align-items:stretch;
  overflow:hidden;
  padding:0;
  gap:0;
  min-width:0;
  color:var(--ink);
  position:relative
}
.dashboard-app .vignette:hover {
  border-color:var(--accent)
}
.dashboard-app .vignette:before,.dashboard-app .entry:before {
  display:none
}
.dashboard-app .vignette>.plate,.dashboard-app .entry-media {
  display:flex;
  width:100%;
  height:185px;
  min-height:185px;
  align-items:center;
  justify-content:center;
  margin:0;
  padding:0;
  border:0;
  border-radius:0;
  background:var(--plate);
  aspect-ratio:auto;
  overflow:hidden
}
.dashboard-app .vignette>.plate img,.dashboard-app .entry-media img {
  width:100%;
  height:100%;
  object-fit:cover;
  max-height:none
}
.dashboard-app .vignette>.plate img.car-blueprint,.dashboard-app .entry-media img.car-blueprint {
  object-fit:contain;
  padding:12px
}
.dashboard-app .vignette-nom {
  display:block;
  padding:18px 18px 0;
  min-height:0
}
.dashboard-app .vignette-nom>.monogram {
  display:none
}
.dashboard-app .vignette-nom .nom {
  font-family:var(--sans);
  font-size:14px;
  font-weight:600;
  letter-spacing:0;
  line-height:1.4;
  color:var(--ink)
}
.dashboard-app .vignette-spec {
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  padding:8px 18px 18px;
  align-items:center;
  justify-content:space-between
}
.dashboard-app .vignette-spec>.micro {
  font-size:11px;
  color:var(--ink-faint)
}
.dashboard-app .entry-body {
  padding:17px 18px 12px;
  flex:none
}
.dashboard-app .entry-spec {
  font-size:11px;
  color:var(--ink-faint);
  line-height:1.7;
  display:block;
  margin-top:7px
}
.dashboard-app .entry-figures {
  display:flex;
  flex-wrap:wrap;
  gap:8px;
  margin:0 18px;
  padding:12px 0 16px;
  border-top:1px solid var(--hair-2);
  align-items:center;
  justify-content:space-between;
  text-align:left
}
.dashboard-app .entry-figures .micro {
  font-size:10px;
  color:var(--ink-faint)
}
.dashboard-app .entry-figures>.micro:first-child {
  flex-basis:100%
}
.dashboard-app .entry-figures .num {
  font-size:12px
}
/* Composants (spec du 09/10/2026, piece 12) : l'etiquette. Un rectangle a
   coins de 2 px sur le fond doux, sans filet ni point, le texte a la teinte
   de l'etat. Un statut de voiture mele sa teinte a l'encre (55 %) pour
   tenir 4,5 sur le fond doux dans les dix themes ; une etiquette sans
   teinte parle a l'accent lisible. */
.dashboard-app .etat {
  gap:0;
  padding:4px 7px;
  border:0;
  border-radius:var(--r-etiquette);
  background:var(--fond-doux);
  color:var(--accent-texte);
  font-size:11px;
  font-weight:600;
  line-height:1.4;
  letter-spacing:0;
  text-transform:none
}
.dashboard-app .etat:is(.collection,.restauration,.vente,.cede) {
  color:color-mix(in srgb,var(--teinte) 55%,var(--ink))
}
.dashboard-app .etat:before {
  content:none
}
/* Section 4 de la spec : dans les blocs de Maison la pastille d'etat garde
   la base d'avant le lot A (le garage du tableau de bord la regle par-dessus). */
.dashboard-app :where(.masthead,.ears,.installer,.ouverture,.prioritaire,.chiffres,.raccourcis,.journal,.accueil-garage) .etat {
  gap:6px;
  padding:2px 9px;
  border:1px solid var(--teinte,var(--hair-2));
  border-radius:999px;
  background:none;
  color:var(--ink);
  font-size:10px;
  font-weight:inherit;
  letter-spacing:.14em;
  text-transform:uppercase
}
.dashboard-app :where(.masthead,.ears,.installer,.ouverture,.prioritaire,.chiffres,.raccourcis,.journal,.accueil-garage) .etat:before {
  content:"";
  width:5px;
  height:5px
}
.collection-filters {
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  gap:10px;
  margin:23px 0 16px
}
.collection-filters label {
  display:flex;
  flex-direction:column;
  gap:7px;
  flex:1;
  min-width:110px
}
/* La recherche part de 18rem : les menus partant de leur option la plus
   longue, sur une base nulle elle tombait à 110 px à 1 080 px. */
.collection-filters label:first-child {
  flex:1.5 1 18rem
}
/* Devant trois menus (la collection), entre 800 et 1205 px, le champ de
   recherche prend sa rangée entière : avec leur chevron les menus pèsent
   54 px de plus, et sur une seule rangée ils ne laissaient que 209 à
   228 px au champ, où son texte indicatif (246 px avec ses marges) se
   coupait. Les trois menus et « Filtrer » tiennent la rangée suivante
   (524 px). Au-dessus de 1205 px tout tient sur une rangée.
   Maison : la règle part de 721 px. Sous 800 px le champ partageait sa
   rangée avec le premier menu ; à côté du rail, le formulaire plus large
   y logeait un second menu et le texte indicatif se coupait de 7 px. */
@media(min-width:721px) and (max-width:1205px) {
  .collection-filters:has(label:nth-of-type(4)) label:first-child {
    flex-basis:100%
  }
}
/* Un menu part de la largeur de son option la plus longue, et la rangée
   passe à la ligne. Écrasé au partage, « Tous les groupes » se coupait à
   1 080 et à 393 px (spec Finitions 6 bis, point 6). Seul sur sa ligne, il
   se rétrécit à la largeur du formulaire : un plancher en `max-content`
   faisait défiler la page de côté sous un nom de lieu long (menu de 371 px
   à 320 px, revue de qualité du lot E2). Le sélecteur pèse plus que la
   base de 40 % des écrans moyens, qu'il remplace pour les menus. */
.dashboard-app .collection-filters label:has(select) {
  flex:1 1 max-content;
  min-width:0
}
/* « Filtrer » prend la boîte des champs voisins (même retrait, même
   interligne) : à 43 px contre 45, son bord haut tombait 2 px sous celui
   des menus (revue de qualité du lot E2). Élargi au téléphone, il garde
   son libellé au centre. */
/* Seul sur sa rangée (demi-écran de bureau), « Filtrer » se range au bord
   droit, sous la fin des menus. */
.dashboard-app .collection-filters button {
  padding-block:11px;
  line-height:21px;
  justify-content:center;
  margin-left:auto
}
.collection-filters>a {
  min-height:44px;
  display:flex;
  align-items:center;
  font-size:12px
}
.collection-result {
  font-size:12px
}
.dashboard-app .entries[data-presentation="liste"] {
  grid-template-columns:1fr
}
.dashboard-app .entries[data-presentation="liste"] .entry {
  display:grid;
  align-items:center
}
.dashboard-app .valeur.synthese {
  margin:0 0 20px
}
.dashboard-app .valeur .releves {
  gap:22px
}
.dashboard-app .valeur .releves>.micro {
  font-size:12px
}
.dashboard-app .valeur .releves .num {
  font-size:20px;
  display:block;
  margin-top:8px
}
/* Fiche : photos et situation en tête, sections métier existantes dessous. */ .dashboard-app .lot-head {
  border:0;
  padding:0;
  margin:0 0 10px;
  gap:16px
}
.dashboard-app .lot-head>.monogram,.dashboard-app .lot-head>.micro {
  display:none
}
.dashboard-app .lot-head .vname {
  font-size:31px;
  font-family:var(--sans);
  letter-spacing:-.03em
}
.dashboard-app .vsub {
  font-family:var(--sans);
  font-size:12px;
  color:var(--ink-faint);
  margin-top:9px;
  line-height:1.7
}
.dashboard-app .lot-tools {
  margin:0 0 25px;
  padding:0;
  border:0;
  font-size:12px;
  line-height:1.5
}
.situation-facts dt {
  font-size:11px;
  color:var(--ink-faint);
  margin-bottom:8px
}
.situation-facts dd {
  margin:0;
  font-size:15px;
  font-weight:550;
  overflow-wrap:anywhere
}
.dashboard-app .lot {
  display:grid;
  grid-template-columns:minmax(0,1.75fr) minmax(250px,1fr);
  gap:24px
}
.dashboard-app .lot-aside {
  align-self:start
}
.dashboard-app .lot-aside .aside-groupe+.aside-groupe {
  border-color:var(--hair-2)
}
.dashboard-app .lot-aside .fig .num {
  font-size:17px
}
/* La barre passe à la ligne dès que ses neuf onglets ne tiennent pas sur
   une rangée, en écho au repli d'`app.css` réservé sous 720 px : entre 721
   et 900 px (iPad portrait compris) elle défilait
   encore de côté et cachait les quatre derniers onglets. Interligne serré
   (2 px) pour que plusieurs rangs se lisent comme une seule barre ; la
   gouttière de colonne (22 px) reste celle de la ligne unique. */
.dashboard-app .tabs a {
  font:12px var(--sans);
  padding:10px 0 6px;
  min-height:0;
  color:var(--ink-faint);
  border:0;
  border-radius:0;
  letter-spacing:0;
  text-transform:none;
  flex-shrink:0
}
/* Survol : l'encre pleine, distincte de l'accent de l'onglet actif (meme
   regle que la colonne, spec Finitions 3.3). Avant la regle de l'actif, qui
   garde son accent sous le pointeur. */
.dashboard-app .tabs a:hover {
  color:var(--ink)
}
.dashboard-app .tabs a[aria-current="true"] {
  color:var(--accent-texte);
  background:none
}
.dashboard-app .tabs a .num {
  font-size:10px
}
.dashboard-app [data-onglet]>.section-title:first-child {
  margin-top:0
}
.dashboard-app [data-onglet] .section-title {
  flex-wrap:wrap
}
.dashboard-app .situation-facts {
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:25px
}
.dashboard-app .situation-facts dd {
  font-size:14px
}
.dashboard-app .visionneuse {
  background:var(--ground-2);
  color:var(--ink)
}
.dashboard-app .visionneuse-tete {
  background:var(--ground-2);
  color:var(--ink)
}
.dashboard-app .visionneuse .btn-icone {
  width:44px;
  padding:8px
}
.dashboard-app table th,.dashboard-app table td {
  padding:13px 12px;
  font-size:12px;
  border-color:var(--hair-2)
}
.dashboard-app table th {
  font-family:var(--sans);
  font-weight:550;
  letter-spacing:0;
  text-transform:none;
  color:var(--ink-faint)
}
@media(max-width:1150px) {
  .dashboard-app .vignettes,.dashboard-app .entries {
    grid-template-columns:repeat(2,minmax(0,1fr))
  }
  .dashboard-metrics {
    grid-template-columns:1fr 1fr;
    gap:12px
  }
  /* Trois cartes sur deux colonnes (le bilan dès qu'une recette existe, la
     fiche d'un intervenant) : la dernière, de rang impair, prend toute la
     rangée (seule à demi-largeur, elle laissait un trou à sa droite). Deux
     et quatre cartes ont une dernière carte de rang pair, la règle les
     laisse en place. */
  .dashboard-metrics>:last-child:nth-child(odd) {
    grid-column:1/-1
  }
  .metric>strong {
    font-size:25px
  }
  .dashboard-app .lot {
    grid-template-columns:minmax(0,1fr) 240px;
    gap:18px
  }
  .dashboard-app .lot-head .vname {
    font-size:27px
  }
}
@media(max-width:900px) {
  .dashboard-app .lot {
    grid-template-columns:1fr
  }
  .dashboard-app .lot-aside {
    display:block
  }
  .dashboard-app .collection-filters label {
    flex-basis:40%
  }
}
@media(max-width:720px) {
  /* La barre du bas : sa position est posée plus bas dans cette feuille, son
     habit dans interface.css (bloc du téléphone), qui retire aussi les
     surtitres de la liste et le pied de la colonne. */
  .dashboard-app .masthead .wordmark,.dashboard-workspace {
    display:none
  }
  /* L'onglet « Ajouter » de la barre porte déjà le geste du bouton ; celui
     du tableau de bord reparaît. */
  .dashboard-app .dashboard-ajouter {
    display:none
  }
  .dashboard-app .dashboard-ajouter-contenu {
    display:inline-flex
  }
  /* La barre descend en rangée d'onglets (interface.css) et emporte le
     logo long ; la barre du haut du téléphone ne porte pas de marque (spec
     Maison 3.3). Sa largeur, ses marges et sa hauteur sont dans
     interface.css. */
  .dashboard-app .ears {
    gap:12px
  }
  .dashboard-app .ears-right {
    flex:1 1 auto;
    gap:12px
  }
  .dashboard-app .ears .search {
    flex:1 1 auto;
    width:auto
  }
  /* Largeur et marges du contenu : interface.css. */
  .dashboard-app .content {
    min-height:calc(100vh - 140px)
  }
  .dashboard-app h1 {
    font-size:28px
  }
  .dashboard-metrics {
    gap:10px;
    margin-bottom:20px
  }
  .dashboard-card.metric {
    padding:17px
  }
  .metric-label {
    font-size:11px
  }
  .metric>strong {
    font-size:25px
  }
  .metric small {
    font-size:10px
  }
  .dashboard-app .section-title {
    font-size:17px;
    flex-wrap:wrap;
    margin-top:23px
  }
  .dashboard-app .section-title .compte {
    font-size:10px
  }
  .dashboard-app .deadline-list .filet-row {
    --ecart:8px;
    flex-wrap:wrap;
    gap:8px
  }
  .dashboard-app .vignettes,.dashboard-app .entries {
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:12px
  }
  .dashboard-app .vignette>.plate {
    height:145px;
    min-height:145px
  }
  .dashboard-app .vignette-nom {
    padding:13px 13px 0
  }
  .dashboard-app .vignette-nom .nom {
    font-size:13px
  }
  .dashboard-app .vignette-spec {
    padding:9px 13px 15px
  }
  .dashboard-app .vignette-spec>.micro {
    font-size:10px
  }
  .dashboard-app :where(.masthead,.ears,.installer,.ouverture,.prioritaire,.chiffres,.raccourcis,.journal,.accueil-garage) .etat {
    font-size:9px
  }
  .dashboard-app .valeur .releves {
    display:grid;
    gap:15px;
    margin-top:15px
  }
  .dashboard-app .valeur .releves .num {
    font-size:20px
  }
  .collection-filters label:first-child {
    flex-basis:100%
  }
  .collection-filters button {
    flex:1
  }
  .dashboard-app .lot-head .vname {
    font-size:26px
  }
  .dashboard-app .lot-head {
    margin-top:0
  }
  .dashboard-app .lot-tools {
    font-size:11px;
    margin-bottom:17px
  }
  /* Le repli sur plusieurs lignes est posé sur la règle de base
     (`.dashboard-app .tabs` plus haut) : ce bloc ne garde que ce qui lui
     est propre, la gouttière de colonne resserrée à 18 px et la marge
     basse réduite au téléphone. */
  .dashboard-app .tabs {
    column-gap:18px;
    margin-bottom:19px
  }
  /* Cible tactile de 44 px minimum : le texte reste bas dans la cible pour
     que le soulignement de l'actif garde son 6 px de distance au texte. */
  .dashboard-app .tabs a {
    font-size:12px;
    padding:21px 0 6px;
    min-height:44px
  }
  .dashboard-app .situation-facts {
    grid-template-columns:1fr
  }
  .dashboard-app .visionneuse-tete {
    flex-wrap:wrap
  }
  .dashboard-app .visionneuse-titre {
    flex-basis:100%;
    min-width:0
  }
  .dashboard-app .visionneuse-tete button {
    padding:8px;
    min-width:40px
  }
  .dashboard-app .compte-menu {
    right:0
  }
  .dashboard-app .content.court>form {
    width:100%
  }
}
@media(max-width:460px) {
  .dashboard-app .vignettes,.dashboard-app .entries {
    grid-template-columns:1fr;
    gap:16px
  }
  .dashboard-app .vignette>.plate {
    height:205px;
    min-height:205px
  }
  .dashboard-app .vignette-nom {
    padding:17px 18px 0
  }
  .dashboard-app .vignette-nom .nom {
    font-size:15px
  }
  .dashboard-app .vignette-spec {
    padding:10px 18px 18px
  }
  .dashboard-app .vignette-spec>.micro {
    font-size:11px
  }
}
@media print {
  body.dashboard-app {
    background:#fff;
    color:#202a37
  }
  body.dashboard-app:before,.dashboard-app .masthead,.dashboard-app .ears,[data-print] {
    display:none!important
  }
  .dashboard-app .content {
    width:100%;
    margin:0;
    padding:0;
    max-width:none
  }
  .dashboard-app .dashboard-metrics {
    grid-template-columns:1fr 1fr
  }
  /* Même règle que le repli de l'écran : le bilan s'imprime, et sa
     troisième carte sortait seule à demi-largeur sur le papier. */
  .dashboard-app .dashboard-metrics>:last-child:nth-child(odd) {
    grid-column:1/-1
  }
  .dashboard-app .table-scroll {
    overflow:visible
  }
  /* Les tableaux ne se coupent pas (plus bas) : sans cette règle, le
     titre d'une section restait seul au pied d'une page du bilan et son
     tableau partait sur la suivante. */
  .dashboard-app h2 {
    break-after:avoid
  }
  .dashboard-app table {
    width:100%
  }
  .dashboard-app table th,.dashboard-app table td {
    font-size:10px;
    padding:8px
  }
  .dashboard-app .flash {
    display:none
  }
  .dashboard-card,table {
    break-inside:avoid
  }
  @page {
    size:A4;
    margin:18mm
  }
}
/* Ajustements après la première recette sur les données réelles. */ .dashboard-app .lot-head {
  background:none
}
.dashboard-app .lot-head .vname {
  color:var(--ink)
}
.dashboard-app .lot-head .vsub {
  color:var(--ink-faint)
}
.dashboard-app .section-title {
  text-transform:none;
  letter-spacing:-.02em
}
.dashboard-mobile-label {
  display:none
}
@media(max-width:720px) {
  .dashboard-app .masthead {
    position:fixed;
    top:auto;
    bottom:0;
    left:0;
    right:0;
    width:100%;
    border-bottom:0
  }
  .dashboard-mobile-label {
    display:inline
  }
  .dashboard-desktop-label {
    display:none
  }
}
.dashboard-app .ears-right>.compte {
  flex:none
}
.dashboard-app .lot-main .obs-ligne {
  flex-wrap:wrap
}
.dashboard-app .lot-main .obs-ligne .grow {
  flex:1 0 65%
}
.dashboard-app .lot-main .obs-ligne .etat {
  white-space:normal
}
/* Le chevron du carnet se cale au fer droit de la rangée, l'état passé à
   la ligne ou non (revue de qualité du lot E2 : 135 px de vide à 1 080 px,
   90 à 163 px au téléphone). */
.dashboard-app .lot-main .obs-ligne>.chev {
  margin-left:auto
}
@media print {
  html[data-theme],.dashboard-app .content {
    --ground:#fff;
    --ground-2:#fff;
    --ink:#202a37;
    --ink-2:#536173;
    --ink-faint:#536173;
    --hair-2:#dce2e9;
    background:#fff;
    color:#202a37
  }
}

.dashboard-concierge { margin-top: auto; padding: 24px 12px 18px; }
.dashboard-concierge strong { display: block; font-size: 12px; overflow-wrap: anywhere; }
@media (max-width: 720px) { .dashboard-concierge { display: none; } }
/* Une carte de chiffres qui dit un mot (« À renseigner ») le dit à la taille
   d'un titre de carte : au corps des chiffres il se coupait au téléphone
   (spec Finitions 6.3). Sous 440 px les cartes passent sur une colonne :
   à 393 px la demi-carte laisse 138 px, où « À renseigner » et « 12
   véhicules » passaient à la ligne (spec Finitions 6 bis, point 2). */
.metric>strong.valeur-texte {
  font-size:20px;
  letter-spacing:0
}
@media(max-width:439px) {
  .dashboard-app .dashboard-metrics {
    grid-template-columns:1fr
  }
}
/* Bilan au téléphone (spec Finitions 6.3) : sous 600 px le tableau des
   véhicules passe en rangées empilées, le nom en tête, chaque valeur à
   droite de son libellé (lu dans `data-label`) ; les mots fixes (« À
   renseigner ») sont soudés dans le gabarit, un nom de lieu long passe à
   la ligne. */
@media(max-width:600px) {
  .dashboard-app .tableau-empile thead {
    display:none
  }
  .dashboard-app .tableau-empile,.dashboard-app .tableau-empile tbody {
    display:block
  }
  .dashboard-app .tableau-empile tr {
    display:block;
    padding:10px 0;
    border-bottom:1px solid var(--hair-2)
  }
  .dashboard-app .tableau-empile tr:last-child {
    border-bottom:0
  }
  .dashboard-app .tableau-empile td {
    display:flex;
    justify-content:space-between;
    align-items:baseline;
    gap:12px;
    padding:3px 0;
    border:0
  }
  /* Le libelle reste un libelle sur toute rangee, ligne de total comprise
     (sa cellule s'y compose en famille d'apparat, Composants, lot C). */
  .dashboard-app .tableau-empile td[data-label]::before {
    content:attr(data-label);
    color:var(--ink-faint);
    font:400 12px/1.6 var(--sans);
    white-space:nowrap
  }
  .dashboard-app .tableau-empile td[data-label] {
    text-align:right
  }
  .dashboard-app .tableau-empile td:first-child {
    font-weight:600;
    padding-bottom:6px
  }
}
/* Double authentification (spec Finitions 6.8) : le champ du code a la
   largeur de six chiffres, la clé de secours sous son libellé. */
.dashboard-app input.champ-code {
  width:calc(6ch + 38px);
  font-variant-numeric:tabular-nums
}
.dashboard-app .cle-secours .micro {
  display:block;
  color:var(--ink-faint)
}
