/* ==========================================================================
   CARILLON MOBILE TERRAIN — Refonte 2026-07 (dossier design CarillonPro)
   Maquette de référence : maquettes/mobile/15-planche-mobile-terrain.png
   Chargée APRÈS carillon-ui.css ; ne cible QUE l'expérience téléphone
   (body.phone-mode + media ≤ 800px). Quatre gestes : voir la mission,
   appeler le client, documenter l'intervention, valider.
   Contraintes : boutons ≥ 48px, texte courant ≥ 16px, une main,
   aucun tableau large, titres jamais tronqués, 360 → 430px.
   ========================================================================== */

/* La carte mission n'existe qu'au téléphone. */
#mobileMissionCard { display: none; }

@media (max-width: 800px) {

  /* ------------------------------------------------------------------
     1. EN-TÊTE BLEU NUIT — cloche | CarillonPro.fr centré | profil
     ------------------------------------------------------------------ */
  body.ui-revolution .sidebar,
  body .sidebar {
    display: flex;
    flex-direction: row; /* la sidebar bureau est une colonne */
    align-items: center;
    gap: 4px;
    height: 64px;
    padding: 8px 10px;
    background: var(--carillon-nuit);
    border-bottom: none;
  }

  body .sidebar .brand {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    min-width: 0;
    margin: 0;
    padding: 0;
  }

  /* Maquette : cloche à gauche, wordmark centré, profil à droite.
     La cloche de la coquille (à droite du wordmark au bureau) passe
     devant, le wordmark prend le centre. */
  body .brand .brand-bell {
    order: -1;
    position: relative;
    flex: none;
    width: 48px;
    height: 48px;
    color: #ffffff;
  }
  body .brand .brand-bell svg { width: 24px; height: 24px; }
  body .brand .brand-bell .notification-count {
    position: absolute;
    top: 2px;
    right: 2px;
    display: grid;
    place-items: center;
    min-width: 19px;
    height: 19px;
    padding: 0 4px;
    background: var(--carillon-rouge);
    border: 2px solid var(--carillon-nuit);
    border-radius: 999px;
    color: #ffffff;
    font-size: 0.72rem;
    font-weight: 800;
  }
  body .brand > div {
    order: 0;
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
  }

  /* La cloche de la barre supérieure est remplacée par celle du header. */
  body.ui-revolution .topbar #topNotificationsBtn,
  body #topNotificationsBtn { display: none; }

  body.ui-revolution .brand strong.brand-wordmark,
  body .brand strong.brand-wordmark {
    font-size: 1.4rem;
    line-height: 1;
  }

  /* Le « .fr » vermillon du wordmark (une vieille règle mobile masque
     les span du brand) */
  body.ui-revolution .brand strong.brand-wordmark span.brand-fr,
  body .brand strong.brand-wordmark span.brand-fr {
    display: inline;
    /* CONF-02 : cette règle ré-écrasait la teinte AA posée dans carillon-ui.css
       (chargée avant, même spécificité) et ramenait le « .fr » à 4.07:1. On reprend
       la teinte vermillon éclaircie dédiée (5.0:1) — token global inchangé. */
    color: #f4515f;
    font-size: inherit;
    font-weight: inherit;
    vertical-align: baseline;
  }

  /* Cloche et profil déplacés dans l'en-tête par app.js (phone-mode) */
  body .sidebar .topbar-icon-btn,
  body .sidebar #topNotificationsBtn {
    position: relative;
    flex: none;
    width: 48px;
    height: 48px;
    background: transparent;
    border: none;
    color: #ffffff;
  }
  body .sidebar #topNotificationsBtn svg { width: 24px; height: 24px; stroke: #ffffff; }

  body .sidebar .topbar-profile {
    flex: none;
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    padding: 0;
    border-left: none;
    color: #ffffff;
  }
  body .sidebar .topbar-profile img { width: 34px; height: 34px; border: 1.5px solid rgba(255, 255, 255, 0.7); }
  body .sidebar .topbar-profile span { display: none; }
  /* L'avatar ouvre les Réglages : il doit se comporter comme un bouton. */
  body .sidebar .topbar-profile { cursor: pointer; border-radius: 50%; }
  body .sidebar .topbar-profile:focus-visible { box-shadow: var(--focus-ring); outline: none; }

  /* Le sélecteur d'établissement quitte l'en-tête : rangée sous l'en-tête,
     réservée à l'installateur (le patron n'a qu'un établissement). */
  body .sidebar > .field {
    order: 99;
    flex: 1 1 100%;
    margin: 0;
  }
  body.patron-session .sidebar > .field { display: none !important; }
  body:not(.patron-session).phone-mode .sidebar { height: auto; flex-wrap: wrap; }

  /* ------------------------------------------------------------------
     2. TITRES DE PAGE — sérif éditoriale, jamais tronqués
     (spécificité body.ui-revolution : la topbar sticky crème de
     theme-final gagnait sinon) ------------------------------------- */
  /* NC-035 : la .topbar gardait la grille bureau `minmax(0,1fr) auto` (app.css
     6771 / ui-revolution 1745), dont la piste `auto` + les marges négatives
     rognaient tout contrôle au bord droit. Source unique en phone : flex-wrap,
     marges nulles → chaque zone se replie proprement, rien n'est coupé. */
  body.ui-revolution .topbar,
  body .topbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    position: static;
    top: auto;
    background: transparent;
    border-bottom: none;
    margin: 0;
    padding: 14px 4px 4px;
    min-height: 0;
    box-shadow: none;
  }

  /* Le bouton « menu » (repli de la sidebar bureau) n'a pas de sens au
     téléphone où l'en-tête bleu EST la navigation. */
  body.phone-mode .sidebar-toggle-btn { display: none; }

  body.ui-revolution .topbar h1,
  body .topbar h1 {
    font-family: var(--font-titres);
    font-size: 2.05rem;
    font-weight: 600;
    color: var(--carillon-nuit);
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }

  /* La maquette n'a rien au-dessus du titre : l'eyebrow doublonne le h1. */
  body.ui-revolution .topbar .eyebrow,
  body .topbar .eyebrow { display: none; }

  /* Le sous-titre porte la date du jour (mercredi 21 mai). */
  body.ui-revolution .topbar .subtitle,
  body .topbar .subtitle,
  body #clientSubtitle {
    display: block;
    font-size: 1rem;
    color: var(--muted);
  }

  /* NC-029 — Contexte d'établissement lisible au téléphone.
     Le patron n'a qu'UN commerce. On ne montre pas un select tronqué (cap
     220px de la barre bureau) ni un masquage total qui laissait le patron
     sans repère : on affiche son NOM en clair, en badge de contexte, tout
     en haut du bloc titre — sous l'en-tête bleu, au-dessus de « Ma journée ».
     Le <select> à option unique est neutralisé en étiquette (pas de chevron,
     pas de troncature). L'installateur multi-établissements garde le vrai
     sélecteur (règles bureau + .sidebar > .field ci-dessus). */
  body.phone-mode.patron-session .topbar-etab {
    display: flex;
    align-items: center;
    gap: 8px;
    width: fit-content;
    max-width: 100%;
    min-height: 44px;
    margin: 2px 4px 10px;
    padding: 8px 14px;
    background: var(--surface-douce);
    border: 1px solid var(--line);
    border-radius: 999px;
  }
  body.phone-mode.patron-session .topbar-etab > svg {
    width: 18px;
    height: 18px;
    color: var(--carillon-bleu);
    flex: none;
  }
  body.phone-mode.patron-session .topbar-etab select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    min-width: 0;
    max-width: 100%;
    min-height: 0;
    padding: 0;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--carillon-nuit);
    text-overflow: ellipsis;
  }

  /* La maquette réserve la zone titre au titre : le back-office
     n'existe pas au téléphone. */
  body.phone-mode #workshopModeBtn { display: none !important; }

  /* NC-007 : la zone du titre ne doit porter QUE le titre. Les outils
     secondaires (Signaler, Mettre à jour, statut autopilote) débordaient
     à côté du titre → déplacés dans « Plus » (voir buildMobileMoreGrid).
     Le sélecteur d'établissement et la recherche globale ne s'affichent
     pas non plus dans la zone titre au téléphone. */
  body.phone-mode .topbar-actions,
  body.phone-mode .global-command-shell { display: none; }
  /* Sous flex-wrap (NC-035) : le titre occupe sa propre rangée pleine
     largeur ; le badge établissement reste une pastille sur la rangée du
     dessus (flex:0 0 auto). L'installateur multi-établissements garde un
     vrai sélecteur mais borné à la largeur écran (plus de coupe, cf. NC-035). */
  body.phone-mode .topbar-title { flex: 1 1 100%; min-width: 0; }
  body.phone-mode .topbar-etab { flex: 0 0 auto; max-width: 100%; min-width: 0; }

  /* ------------------------------------------------------------------
     3. CARTE MISSION « MA JOURNÉE » (markup posé par app.js)
     ------------------------------------------------------------------ */
  /* NC-002 : « Ma journée » ne doit PAS empiler le tableau de bord DESKTOP
     sous la carte mission (planche 15 = carte mission + barre basse). La
     carte mission est la SOURCE UNIQUE en phone ; le rendu desktop de
     l'accueil (greeting, priority-card, pilotage, action-strip, tagline…)
     est masqué. Le :has() garantit qu'on ne masque QUE si la carte existe
     (sinon page blanche au 1er rendu). */
  body.phone-mode .tab-panel[data-panel="overview"]:has(#mobileMissionCard) > *:not(#mobileMissionCard) {
    display: none;
  }

  body.phone-mode #mobileMissionCard {
    display: grid;
    gap: 14px;
    margin-bottom: 14px;
  }

  .mission-card {
    display: grid;
    gap: 10px;
    padding: 18px 16px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
  }

  .mission-urgent {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    justify-self: start;
    padding: 6px 12px;
    background: #fdecee;
    border-radius: 999px;
    color: var(--carillon-rouge);
    font-size: 0.8rem;
    font-weight: 800;
    letter-spacing: 0.04em;
  }
  .mission-urgent svg { width: 15px; height: 15px; stroke: var(--carillon-rouge); }

  .mission-time {
    font-family: var(--font-titres);
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--carillon-nuit);
    font-variant-numeric: tabular-nums;
  }
  .mission-card.is-urgent .mission-time { color: var(--carillon-rouge); }

  .mission-title {
    font-family: var(--font-titres);
    font-size: 1.7rem;
    font-weight: 600;
    line-height: 1.15;
    color: var(--carillon-nuit);
    white-space: normal;
  }

  .mission-place {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: var(--carillon-nuit);
    font-size: 1rem;
    line-height: 1.35;
  }
  .mission-place svg { flex: none; width: 18px; height: 18px; margin-top: 2px; stroke: var(--carillon-nuit); }

  .mission-chip {
    justify-self: start;
    padding: 6px 12px;
    background: var(--surface-douce);
    border-radius: 999px;
    color: #47536b;
    font-size: 0.88rem;
    font-weight: 650;
  }

  .mission-note { color: var(--muted); font-size: 1rem; line-height: 1.45; }

  .mission-empty { color: var(--muted); font-size: 1rem; }

  /* Boutons du geste : appeler (secondaire) puis démarrer (énorme). */
  .mission-call {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 56px;
    background: var(--surface);
    border: 1.5px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--carillon-bleu);
    font-size: 1.05rem;
    font-weight: 750;
    text-decoration: none;
  }
  .mission-call svg { width: 20px; height: 20px; stroke: var(--carillon-bleu); }

  .mission-start {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    min-height: 72px;
    background: var(--carillon-bleu);
    border: none;
    border-radius: var(--radius);
    color: #ffffff;
    font-size: 1.35rem;
    font-weight: 800;
  }
  .mission-start:hover { background: var(--carillon-bleu-fonce); }
  .mission-start svg { width: 22px; height: 22px; stroke: #ffffff; fill: #ffffff; }

  /* ------------------------------------------------------------------
     4. NAVIGATION BASSE — blanche, 4 gestes, actif bleu France
     ------------------------------------------------------------------ */
  body.ui-revolution .nav,
  body .nav {
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 18px rgba(7, 28, 59, 0.07);
  }

  /* Les cinq gestes quotidiens restent directement accessibles : journée,
     planning, intervention, messages et le reste. Le stock passe dans « Plus ». */
  /* « Messages » est le seul libellé long. On lui réserve quelques pixels
     pris sur « Plus » afin d'éviter toute ellipse à 320 px, sans réduire la
     taille du texte ni la zone tactile des cinq gestes. */
  body.ui-revolution.phone-mode .sidebar .nav {
    display: grid;
    grid-template-columns:
      minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr)
      minmax(0, 1.15fr) minmax(0, 0.85fr);
  }
  body.ui-revolution .nav-btn[data-tab="planning"]:not(.sector-hidden-tab) { display: grid; }
  body.ui-revolution .nav-btn[data-tab="inventory"] { display: none; }
  body.ui-revolution .nav-btn[data-tab="production"]:not(.sector-hidden-tab) { display: grid; }
  /* Messages est un geste central pour TOUS les métiers : on annule le
     masquage hérité du mode métier salon/artisan (app.css). */
  body.ui-revolution.workshop-mode.sector-salon .nav .nav-btn[data-tab="requests"],
  body.ui-revolution.workshop-mode.sector-artisan .nav .nav-btn[data-tab="requests"] { display: grid; }
  body.ui-revolution .nav > .nav-btn[data-tab="overview"] { order: 1; }
  body.ui-revolution .nav > .nav-btn[data-tab="planning"] { order: 2; }
  body.ui-revolution .nav > .nav-btn[data-tab="production"] { order: 3; }
  body.ui-revolution .nav > .nav-btn[data-tab="requests"] { order: 4; }
  body.ui-revolution .nav > .mobile-more-btn { order: 9; }

  /* Cinq gestes maximum. Les pages secondaires restent accessibles dans
     « Plus » : elles ne doivent jamais comprimer la barre basse. */
  body.phone-mode .nav > .nav-btn:not([data-tab="overview"]):not([data-tab="planning"]):not([data-tab="production"]):not([data-tab="requests"]):not(.mobile-more-btn) {
    display: none !important;
  }

  body.phone-mode .nav > .nav-btn {
    min-width: 0;
    overflow: hidden;
  }

  body.phone-mode .nav > .nav-btn span {
    display: block;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  body.phone-mode .nav > .nav-group-label {
    display: none !important;
  }

  body.ui-revolution .nav-btn,
  body .nav-btn { color: #47536b; }
  body .nav .nav-btn .nav-icon { stroke: #47536b; }

  /* La maquette n'a pas de pilule : l'actif passe au bleu France. */
  body .nav .nav-btn.active,
  body[class*="sector-"] .nav .nav-btn.active,
  body.ui-revolution[class*="sector-"] .nav .nav-btn.active {
    background: transparent !important;
    border-color: transparent !important;
    color: var(--carillon-bleu) !important;
    box-shadow: none;
  }
  body .nav .nav-btn.active .nav-icon { stroke: var(--carillon-bleu) !important; }

  /* ------------------------------------------------------------------
     5. GESTE « INTERVENTION » — fiche de la préparation (modale op)
     ------------------------------------------------------------------ */
  body #opDetailModal .modal-card h2,
  body #productionModal .modal-card h2 {
    font-family: var(--font-titres);
    font-size: 1.45rem;
  }

  /* Étapes/matières : lignes aérées, coche verte à gauche. */
  body #opDetailModal .modal-card li,
  body #opDetailModal .prep-material-row,
  body #productionModal .production-ingredient-row {
    min-height: 44px;
    font-size: 1rem;
  }

  /* Le geste final occupe toute la largeur, 56px. */
  body #opDetailModal .modal-actions .btn.primary,
  body #productionModal .modal-actions .btn.primary {
    flex: 1 1 100%;
    min-height: 56px;
    font-size: 1.1rem;
  }

  /* Checklist horodatée (planche 15) : coche verte + heure à droite. */
  .mission-check {
    display: grid;
    gap: 8px;
    padding: 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
  }
  .mission-check > strong {
    font-family: var(--font-titres);
    font-size: 1.15rem;
    color: var(--carillon-nuit);
  }
  .mission-check ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
  .mission-check li {
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    font-size: 1rem;
  }
  .mission-check-icon {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1.5px solid var(--line);
    color: #ffffff;
  }
  .mission-check li.done .mission-check-icon {
    background: var(--carillon-vert);
    border-color: var(--carillon-vert);
  }
  .mission-check-icon svg { width: 13px; height: 13px; }
  .mission-check li.todo .mission-check-label { color: var(--muted); }
  .mission-check-time {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-weight: 650;
  }

  /* Bloc Photos avant/après (planche 15) : deux cadres arrondis,
     flèche en pastille blanche entre les deux. */
  .mission-photos {
    display: grid;
    gap: 10px;
    padding: 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
  }
  .mission-photos > strong {
    font-family: var(--font-titres);
    font-size: 1.15rem;
    color: var(--carillon-nuit);
  }
  .mission-photos-row {
    position: relative;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
  }
  .mission-photos-row figure { margin: 0; display: grid; gap: 6px; }
  .mission-photos-row figcaption {
    color: var(--muted);
    font-size: 0.9rem;
    font-weight: 650;
  }
  .mission-photos-row img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 12px;
    border: 1px solid var(--line);
  }
  .mission-photos-arrow {
    position: absolute;
    top: 55%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 50%;
    color: var(--carillon-nuit);
    box-shadow: var(--shadow-hover);
  }
  .mission-photos-arrow svg { width: 18px; height: 18px; }
  .mission-photos > small { color: var(--muted); font-size: 0.85rem; }

  /* Photos produits du dossier sur les cartes catalogue. */
  body.phone-mode .production-product-card .product-visual .product-photo {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 12px;
    display: block;
  }

  /* Bandeau « fournée en attente » : le bouton sortait de l'écran
     (flex nowrap) — il replie en pleine largeur. */
  body.phone-mode .fournil-priority { flex-wrap: wrap; }
  body.phone-mode .fournil-priority .btn { flex: 1 1 100%; max-width: 100%; }

  /* Catalogue des prestations : la grille implicite hachait la
     catégorie dans la colonne icône (56px) et la puce marge sortait
     de la carte. Icône + titre en tête, le reste pleine largeur. */
  body.phone-mode .production-product-card {
    grid-template-columns: 48px minmax(0, 1fr);
    align-items: center;
    gap: 8px 12px;
    padding: 14px;
  }
  body.phone-mode .production-product-card > strong {
    font-size: 1.05rem;
    line-height: 1.25;
    text-align: left;
  }
  body.phone-mode .production-product-card > span:not(.product-visual):not(.margin-chip) {
    grid-column: 1 / -1;
    width: auto;
    font-size: 0.85rem;
    color: var(--muted);
    text-align: left;
  }
  body.phone-mode .production-product-card small {
    grid-column: 1 / -1;
    text-align: left;
  }
  body.phone-mode .production-product-card .margin-chip {
    grid-column: 1 / -1;
    justify-self: start;
    max-width: 100%;
    white-space: normal;
  }
  /* Un coût à compléter est un brouillon : gris, pas orange. */
  body.phone-mode .margin-chip.warn {
    background: var(--surface-douce);
    color: #47536b;
  }

  /* ------------------------------------------------------------------
     6. GESTE « VALIDATION » — devis ligne à ligne, total TTC bleu
     ------------------------------------------------------------------ */
  body.phone-mode .billing-card,
  body.phone-mode .quote-line-row {
    font-size: 1rem;
  }

  /* Lignes du constructeur de devis : libellé à gauche, prix à droite. */
  body.phone-mode #quoteModal .quote-line-row,
  body.phone-mode .quote-lines-table tr {
    border-bottom: 1px solid var(--surface-douce);
  }

  body.phone-mode .quote-totals strong,
  body.phone-mode .billing-total,
  body.phone-mode #quoteTotalTtc {
    color: var(--carillon-bleu);
    font-family: var(--font-titres);
    font-size: 1.4rem;
    font-variant-numeric: tabular-nums;
  }

  /* Modifier / Valider côte à côte, mêmes largeurs. */
  body.phone-mode .billing-card .item-actions,
  body.phone-mode .order-card .item-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  body.phone-mode .billing-card .item-actions .btn,
  body.phone-mode .order-card .item-actions .btn {
    min-height: 52px;
    font-size: 1rem;
  }
  /* Trois actions et plus : la dernière prend toute la largeur. */
  body.phone-mode .order-card .item-actions .btn:nth-child(3):last-child {
    grid-column: 1 / -1;
  }

  /* NC-033 (arbitrage NC-021) : la bande défilante horizontale comptait un
     scrollWidth 402 > 324 clientWidth = « débordement » pour l'audit patron.
     On revient donc à un REPLI sur 2 rangées (grille 2×2) : aucun onglet
     coupé, AUCUN débordement horizontal, cibles tactiles 48px conservées.
     Vérifié sur les 7 profils à 324/360/390/402/430 px. */
  body.phone-mode .billing-tabs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow-x: visible;
    gap: 6px;
  }
  body.phone-mode .billing-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 48px;                     /* cible tactile >= 48px */
    white-space: nowrap;
  }
  body.phone-mode .billing-followups { margin: 10px 0; padding: 10px; border-radius: 12px; }
  body.phone-mode .billing-followups-head { align-items: flex-start; }
  body.phone-mode .billing-followups-list { grid-template-columns: 1fr; }
  body.phone-mode .billing-followup { min-height: 56px; }
  body.phone-mode .billing-payment-summary { display: grid; grid-template-columns: 1fr; justify-content: stretch; }

  /* ------------------------------------------------------------------
     7. GESTE « MESSAGE CLIENT » — reçu, compris, réponse, envoi
     ------------------------------------------------------------------ */
  body.phone-mode #messageList .item-card {
    padding: 16px;
    font-size: 1rem;
  }

  /* Le message du client : bulle bleue douce. */
  body.phone-mode #messageList .item-card blockquote,
  body.phone-mode #messageList .message-body {
    margin: 6px 0;
    padding: 12px 14px;
    background: #e8f0fb;
    border: none;
    border-radius: 12px;
    color: var(--carillon-nuit);
    font-size: 1rem;
    line-height: 1.45;
  }

  /* « Compris par Carillon » : la ligne d'analyse passe au vert confirmé. */
  body.phone-mode #messageList .badge.ok,
  body.phone-mode #messageList .analysis-line {
    color: var(--carillon-vert);
    background: #e9f5ef;
    border-color: #cdebdc;
  }

  /* La réponse proposée : carte crème distincte. */
  body.phone-mode #messageList .proposed-reply,
  body.phone-mode #messageList .draft-reply,
  body.phone-mode #messageList pre {
    padding: 14px;
    background: var(--blanc-chaud);
    border: 1px solid var(--line);
    border-radius: 12px;
    color: var(--carillon-nuit);
    font-size: 1rem;
    line-height: 1.5;
    white-space: pre-wrap;
  }

  /* Valider et envoyer : pleine largeur. */
  body.phone-mode #messageList .item-actions .btn.primary,
  body.phone-mode .validation-card .item-actions .btn.primary {
    flex: 1 1 100%;
    min-height: 56px;
    font-size: 1.05rem;
  }

  /* ------------------------------------------------------------------
     8. FONDATIONS TÉLÉPHONE — tailles minimales du dossier
     ------------------------------------------------------------------ */
  body.phone-mode .tab-panel.active { font-size: 16px; }

  body.phone-mode .btn,
  body.ui-revolution.phone-mode .btn { min-height: 48px; }

  body.phone-mode .item-card p,
  body.phone-mode .item-card span:not(.badge):not(.chip-time),
  body.phone-mode .panel p {
    font-size: max(1rem, 1em);
  }

  /* Cartes : rayons du dossier partout au téléphone. */
  body.phone-mode .item-card,
  body.phone-mode .panel { border-radius: var(--radius); }

  /* Le fond de page reste blanc chaud sous la barre. */
  body.phone-mode main { background: var(--blanc-chaud); }

  /* ------------------------------------------------------------------
     9. CIBLES TACTILES < 44px (punch-list) — carillon-mobile est chargee
        en dernier : ces regles gagnent sur theme-final au doigt.
     ------------------------------------------------------------------ */
  /* Segmenté Jour / Semaine / Mois du planning : 34px -> 48px, pleine
     largeur (3 cibles egales et confortables) ; le segment prend sa
     propre ligne dans la toolbar (flex-wrap) quand la place manque. */
  body.phone-mode .view-segment {
    display: flex;
    flex: 1 1 100%;
    width: 100%;
  }
  body.phone-mode .view-segment button {
    flex: 1 1 0;
    min-height: 48px;
  }

  /* NC-022 — Fleches precedent/suivant du planning ecrasees a ~19px de
     large. Cause : theme-final pose .planning-icon-btn { width:36px } en
     GLOBAL (bat le .icon-btn 44px du @media <= 800px) et, dans
     .calendar-nav (flex sur une ligne : fleche + « Aujourd'hui » + fleche
     + titre + date), le flex-shrink comprime les fleches jusqu'a la
     largeur de leur icone. On force un carre 48px insecable (min-width
     bat le shrink, la double classe bat .planning-icon-btn) et on
     autorise le bandeau a passer sur 2 lignes. */
  body.phone-mode .calendar-nav {
    flex-wrap: wrap;
    row-gap: 8px;
  }
  /* Le titre prend sa propre ligne (ne vole plus la largeur aux fleches). */
  body.phone-mode .calendar-nav h2 {
    flex: 1 1 100%;
    order: 9;
    margin: 2px 0 0;
  }
  body.phone-mode .calendar-nav .planning-icon-btn {
    width: 48px;
    min-width: 48px;
    height: 48px;
    flex: 0 0 auto;
  }
  body.phone-mode .calendar-nav .planning-icon-btn svg {
    width: 22px;
    height: 22px;
  }

  /* Champ date du planning : 38px -> 44px (specificite ID pour battre
     body .calendar-nav #planningDateInput). */
  body.phone-mode .calendar-nav #planningDateInput {
    min-height: 44px;
  }

  /* NC-008 — KPI du planning : theme-final force 3 colonnes sous 800px
     (body .planning-stats), les libelles se tronquent des 390px. On
     repasse a 2 colonnes ; meme specificite (0,1,1) que theme-final mais
     carillon-mobile est charge apres -> gagne par ordre source. Le
     passage a 1 colonne sous 360px est traite hors de ce bloc. */
  body .planning-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* ------------------------------------------------------------------
     10. BARRE D'ACTIONS DE PAGE — les actions du bandeau desktop
         (.page-hero-actions dans .page-desktop, masqué en phone) sont
         reproposées ici en proxys visibles (Actualiser / Nouveau devis…).
     ------------------------------------------------------------------ */
  body.phone-mode .mobile-page-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 4px 0 2px;
    /* NC-006 : le bandeau (enfant supplémentaire de la .topbar) tombait dans
       une piste de 0px et était peint SOUS .topbar-actions → « Nouveau devis »/
       « Actualiser » injoignables au tap réel (le .click() JS marchait). Sous
       la topbar flex (NC-035), il prend sa propre rangée pleine largeur. */
    flex: 1 1 100%;
    width: 100%;
  }
  body.phone-mode .mobile-page-actions[hidden] { display: none; }

  body.phone-mode .mobile-page-action {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 16px;
    background: var(--surface);
    border: 1.5px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--carillon-bleu);
    font-size: 0.95rem;
    font-weight: 750;
  }
  body.phone-mode .mobile-page-action.primary {
    background: var(--carillon-bleu);
    border-color: var(--carillon-bleu);
    color: #ffffff;
  }
  body.phone-mode .mobile-page-action svg {
    width: 19px;
    height: 19px;
    stroke: currentColor;
    fill: none;
  }
}

/* Centre d'alertes mobile -------------------------------------------------- */
.mobile-notification-sheet {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: grid;
  align-items: end;
}

.mobile-notification-sheet.hidden,
.mobile-notification-onboarding.hidden {
  display: none !important;
}

.mobile-notification-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(18, 27, 24, 0.46);
  backdrop-filter: blur(3px);
}

.mobile-notification-card {
  position: relative;
  z-index: 1;
  width: min(100%, 560px);
  max-height: min(88vh, 760px);
  margin-inline: auto;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  background: var(--surface, #fff);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -18px 50px rgba(18, 27, 24, 0.18);
}

.mobile-notification-head,
.mobile-notification-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--line, #e7ece9);
}

.mobile-notification-head h2 {
  margin: 2px 0 0;
  font-size: 1.2rem;
  overflow-wrap: anywhere;
}

.mobile-notification-head > div {
  min-width: 0;
}

.mobile-notification-summary {
  padding: 12px 18px;
  background: #f3f8f5;
  color: #315244;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.mobile-notification-list {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px;
  display: grid;
  gap: 10px;
}

.mobile-alert-card {
  border: 1px solid var(--line, #dde6e1);
  border-radius: 18px;
  padding: 14px;
  background: #fff;
  display: grid;
  gap: 10px;
}

.mobile-alert-card.is-due {
  border-color: #dfb46c;
  box-shadow: 0 7px 18px rgba(126, 86, 28, 0.09);
}

.mobile-alert-card.is-critical {
  border-color: #d78b8b;
}

.mobile-alert-head {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
}

.mobile-alert-icon {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: #e8f3ed;
  color: #206347;
}

.mobile-alert-icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mobile-alert-copy {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.mobile-alert-copy strong,
.mobile-alert-copy span {
  overflow-wrap: anywhere;
}

.mobile-alert-copy span {
  color: var(--muted, #63716a);
  font-size: 0.9rem;
}

.mobile-alert-steps {
  margin: 0;
  padding-left: 22px;
  display: grid;
  gap: 4px;
  color: #45564e;
  font-size: 0.88rem;
}

.mobile-alert-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
}

.mobile-alert-actions .btn {
  min-height: 44px;
}

.mobile-alert-dismiss {
  grid-column: 1 / -1;
  justify-self: start;
  min-height: 36px;
}

.mobile-alert-target {
  outline: 3px solid #2a7a59;
  outline-offset: 3px;
  animation: mobile-alert-focus 1s ease-in-out 2;
}

@keyframes mobile-alert-focus {
  50% {
    outline-color: #d89a24;
    box-shadow: 0 0 0 7px rgba(216, 154, 36, 0.18);
  }
}

.mobile-notification-footer {
  border-top: 1px solid var(--line, #e7ece9);
  border-bottom: 0;
  justify-content: stretch;
  padding-bottom: calc(14px + env(safe-area-inset-bottom));
}

.mobile-notification-footer .btn {
  width: 100%;
}

.mobile-notification-onboarding {
  position: fixed;
  z-index: 1250;
  left: 12px;
  right: 12px;
  bottom: calc(82px + env(safe-area-inset-bottom));
  max-width: 520px;
  margin-inline: auto;
  padding: 16px;
  border: 1px solid #cfe1d8;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 18px 50px rgba(18, 27, 24, 0.22);
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  gap: 12px;
}

.mobile-notification-onboarding-icon {
  width: 42px;
  height: 42px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  background: #e8f3ed;
  color: #206347;
}

.mobile-notification-onboarding-icon svg {
  width: 22px;
  height: 22px;
}

.mobile-notification-onboarding > div:nth-child(2) {
  display: grid;
  gap: 4px;
}

.mobile-notification-onboarding > div:nth-child(2) span {
  color: var(--muted, #63716a);
  font-size: 0.9rem;
}

.mobile-notification-onboarding-actions {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
}

.notification-settings-panel {
  display: grid;
  gap: 16px;
}

.notification-device-card,
.notification-preference-row {
  border: 1px solid var(--line, #dde6e1);
  border-radius: 16px;
  background: #fff;
}

.notification-device-card {
  padding: 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.notification-device-card > div,
.notification-preference-row > span {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.notification-device-card span,
.notification-preference-row small {
  color: var(--muted, #63716a);
  overflow-wrap: anywhere;
}

.notification-preference-list {
  display: grid;
  gap: 8px;
}

.notification-preference-row {
  padding: 13px 14px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  cursor: pointer;
}

.notification-preference-row input {
  width: 22px;
  height: 22px;
  accent-color: var(--primary, #206347);
}

.notification-timing-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 801px) {
  .mobile-notification-sheet {
    align-items: start;
    justify-items: end;
    padding: 70px 20px 20px;
  }

  .mobile-notification-card {
    width: 460px;
    max-height: calc(100vh - 90px);
    margin: 0;
    border-radius: 22px;
  }

  .mobile-notification-onboarding {
    bottom: 24px;
  }
}

@media (max-width: 600px) {
  .mobile-notification-card {
    width: 100%;
    max-height: calc(100dvh - env(safe-area-inset-top));
  }

  body.phone-mode .settings-subnav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
  }

  body.phone-mode .settings-subnav > button,
  body.phone-mode .settings-more,
  body.phone-mode .settings-more-grid,
  body.phone-mode .settings-more-grid > button {
    min-width: 0;
    max-width: 100%;
    width: 100%;
  }

  body.phone-mode .settings-subnav > button,
  body.phone-mode .settings-more-grid > button {
    justify-content: flex-start;
    padding-inline: 12px;
    border-radius: 12px;
    white-space: normal;
    overflow-wrap: anywhere;
  }

  body.phone-mode .settings-more {
    grid-column: 1 / -1;
  }

  body.phone-mode .settings-more > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 8px 12px;
    border: 1px solid var(--line, #dde6e1);
    border-radius: 12px;
    cursor: pointer;
    font-weight: 750;
  }

  body.phone-mode .settings-more-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    padding-top: 6px;
  }

  .notification-device-card {
    align-items: stretch;
    flex-direction: column;
  }

  .notification-device-card .btn {
    width: 100%;
  }

  .notification-timing-grid {
    grid-template-columns: 1fr;
  }

  body.phone-mode .msg-status-compact .msg-filter,
  body.phone-mode .msg-channel-details .msg-filter {
    min-height: 44px;
  }
}

/* Hors phone-mode : le proxy n'existe pas (le vrai bandeau est visible). */
.mobile-page-actions { display: none; }

/* NC-008 (suite) — tres petits ecrans : sous 360px, 2 colonnes restent
   trop etroites pour les libelles KPI planning -> passage a 1 colonne.
   Ce bloc est apres le bloc <=800px : a specificite egale il gagne par
   ordre source, donc 1 col sous 360, 2 col entre 360 et 800, 3 col au
   dela (desktop, non regresse). */
@media (max-width: 360px) {
  body .planning-stats {
    grid-template-columns: minmax(0, 1fr);
  }

  .mobile-more-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mobile-more-tile span {
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
  }

  .mobile-alert-actions,
  .mobile-notification-onboarding-actions {
    grid-template-columns: minmax(0, 1fr);
  }

  .mobile-alert-dismiss {
    grid-column: auto;
    min-height: 44px;
  }

  .mobile-notification-onboarding-actions .btn,
  .mobile-notification-onboarding-actions .link-btn {
    width: 100%;
    min-height: 44px;
  }
}

/* ============================================================
   COHERENCE MOBILE 25/07 — audit patron « incoherences et
   chevauchements ». 3 defauts confirmes au banc (hit-testing
   scrollIntoView+elementFromPoint, 7 profils x 360/390/430).
   ============================================================ */
@media (max-width: 800px) {
  /* D3 — Planning plombier : la regle takeover AUD-14 (colonnes fluides
     minmax(0,1fr) pleine largeur, pensee pour le bureau plein ecran)
     s'applique aussi au telephone -> colonnes de ~39px, libelles des jours
     empiles lettre a lettre, grille illisible et rien a faire defiler.
     Au telephone on restaure le contrat de base du module (plombier.css
     .plb-week : min-width max-content + minmax(132px,1fr)) : la grille
     redevient lisible et DEFILE horizontalement dans son cadre
     .plb-week-wrap (deja overflow:auto). Specificite : la classe
     .phone-mode ajoutee bat la regle takeover chargee apres cette feuille. */
  body.phone-mode.plb-planning-takeover .plb-planning-host .plb-week {
    min-width: max-content;
    grid-template-columns: 64px repeat(var(--plb-days, 7), minmax(132px, 1fr));
  }

  /* D2 — Table « Reassort conseille » (stock fournil) : 4 colonnes en
     nowrap forcent ~640px -> moitie droite coupee a l'ecran (l'aside
     defile mais rien ne l'indique). Au telephone : en-tetes autorises a
     passer a la ligne + paddings et corps compactes -> la table tient
     dans la carte des 360px ; le defilement de l'aside reste en filet. */
  body.phone-mode .fournil-reassort-table { font-size: 0.84rem; }
  body.phone-mode .fournil-reassort-table th,
  body.phone-mode .fournil-reassort-table td {
    white-space: normal;
    padding: 7px 8px;
  }
  body.phone-mode .reassort-article { white-space: normal; }
  /* L'ancien filet « ruban » (carillon-ui.css : min-width 640px + aside
     defilant) datait d'avant la compaction ci-dessus : il maintenait la
     table a 640px et donc sa moitie droite hors ecran, sans indice de
     defilement. Compactee, la table tient dans la carte : on rend la
     main a la largeur naturelle (meme specificite, source posterieure). */
  body.phone-mode .fournil-reassort-table { min-width: 0; }

  /* D4 — Fin de page sous la barre 4 gestes : le degagement bas venait de
     theme-final (88px, body.ui-revolution main) et laissait le dernier
     bouton (« Imprimer », Devis 430px) sous la barre meme a scroll max.
     Meme specificite mais cette feuille charge apres -> 112px partout. */
  body.phone-mode main {
    padding-bottom: calc(112px + env(safe-area-inset-bottom, 0px));
  }
}
