/* =============================================================================
   CoreAI — feuille de style commune (console MSP + portail client)
   Charte : navy #0a2540, cyan #00d2ff, dégradé #00f2fe→#0077ff,
   Montserrat (marque) + JetBrains Mono (données). Écrans en thème clair.
   ============================================================================= */

@font-face{font-family:'Montserrat';src:url('fonts/montserrat.woff2') format('woff2');
           font-weight:400 900;font-display:swap}
@font-face{font-family:'JetBrains Mono';src:url('fonts/jetbrains-mono.woff2') format('woff2');
           font-weight:400 700;font-display:swap}

:root{
  --navy:#0a2540;
  --navy-deep:#132f4c;
  --cyan:#00d2ff;
  --mint:#4ecdc4;
  --grad-a:#00f2fe;
  --grad-b:#0077ff;
  --grad:linear-gradient(135deg,var(--grad-a) 0%,var(--grad-b) 100%);
  --green:#2f9e5f;
  --green-bg:#e4f6ec;
  --amber:#a9791a;
  --amber-bg:#fdf1dc;
  --red:#c0392b;
  --red-bg:#fbe4e4;

  --bg:#f4f7fa;
  --surface:#ffffff;
  --line:#e6edf3;
  --line-soft:#eff3f7;
  --txt:#0a2540;
  /* Les deux gris secondaires portent presque tout le texte d'explication de
     l'interface. L'ancien #8ba0b1 tombait à 2,7:1 sur blanc, sous le seuil
     lisible : les légendes de cartes, les aides de formulaire et les mentions
     de bas de page devenaient difficiles à lire. Ces valeurs tiennent 4,8:1 et
     7:1, tout en gardant une hiérarchie visible entre les deux. */
  --txt-mute:#42566a;
  --txt-faint:#5f7689;

  --sans:'Montserrat','Segoe UI',system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --r:12px;
  --shadow:0 1px 2px rgba(10,37,64,.04),0 6px 18px -12px rgba(10,37,64,.18);
  --sidebar:262px;
}

*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--txt);font-family:var(--sans);font-weight:500;
     line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
svg{display:block}
::selection{background:var(--cyan);color:var(--navy)}

h1{font-size:1.32rem;font-weight:800;letter-spacing:-.01em;text-transform:uppercase}
h2{font-size:1.05rem;font-weight:800;letter-spacing:-.01em;text-transform:uppercase}
h3{font-size:.95rem;font-weight:800;letter-spacing:-.01em}
.mono{font-family:var(--mono);letter-spacing:-.02em}
.muted{color:var(--txt-mute)}
.faint{color:var(--txt-faint)}
.num,th.num,td.num{text-align:right;font-family:var(--mono);letter-spacing:-.02em;white-space:nowrap}

/* ---------- Structure ---------- */
.shell{display:grid;grid-template-columns:var(--sidebar) 1fr;min-height:100vh}
@media(max-width:900px){.shell{grid-template-columns:1fr}}

aside.nav{background:var(--surface);border-right:1px solid var(--line);
          display:flex;flex-direction:column;padding:0 14px 18px}
@media(max-width:900px){aside.nav{border-right:0;border-bottom:1px solid var(--line);padding-bottom:10px}}

.brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:1.4rem;
       letter-spacing:-.03em;height:76px;padding-left:8px;flex-shrink:0}
.brand svg{width:34px;height:34px;flex-shrink:0}
/* Le logo du prestataire garde ses proportions : seule la hauteur est imposée,
   la largeur suit. Forcer un carré écrasait les logos horizontaux, qui sont la
   règle. La borne de largeur évite qu'un logo très allongé ne pousse la
   navigation hors de la barre latérale. */
.brand img.logo-msp{height:36px;width:auto;max-width:186px;object-fit:contain;flex-shrink:0}
.brand .cy{color:var(--cyan)}

aside.nav a.item{padding:11px 13px;border-radius:9px;color:var(--txt-mute);font-weight:600;
                 font-size:.9rem;display:flex;align-items:center;gap:11px;margin-bottom:2px;
                 transition:.16s}
aside.nav a.item:hover{background:#f3f7fa;color:var(--txt)}
aside.nav a.item.on{background:#e6f7f6;color:var(--navy);font-weight:700}
aside.nav a.item svg{width:18px;height:18px;stroke-width:1.8;flex-shrink:0;opacity:.75}
aside.nav a.item.on svg{opacity:1;color:var(--mint)}
/* Le libellé tient sur une ligne, quitte à rétrécir : replié, il changeait la
   hauteur du menu d'un écran à l'autre et faisait sauter toutes les entrées
   suivantes à chaque navigation. */
aside.nav a.item span.lbl{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
aside.nav a.item .tag{margin-left:auto;font-size:.68rem;color:var(--mint);font-weight:700;
                      flex-shrink:0}
@media(max-width:1100px) and (min-width:901px){
  aside.nav a.item{font-size:.84rem;padding:10px 11px;gap:9px}
}
.nav-foot{margin-top:auto;padding:14px 12px 0;border-top:1px solid var(--line-soft);
          font-size:.72rem;color:var(--txt-faint);line-height:1.5}
.nav-foot a.out{display:flex;align-items:center;gap:9px;font-size:.82rem;font-weight:700;
                color:var(--txt-mute);transition:color .15s}
.nav-foot a.out:hover{color:var(--txt)}
.nav-foot a.out svg{width:18px;height:18px;stroke-width:1.8;flex-shrink:0}
@media(max-width:900px){.nav-foot{display:none}}

/* Cibles tactiles. Sur écran tactile il n'y a pas de curseur pour viser : une
   commande haute de 21 px se rate une fois sur trois. On élargit la zone
   sensible sans changer la taille apparente des éléments. */
@media(max-width:900px){
  .topbar .ico{width:42px;height:42px}
  .btn.sm{min-height:38px}
  table a.nm{display:inline-block;padding:8px 0}
  .actions .btn{min-height:38px}
}

.pane{min-width:0;display:flex;flex-direction:column}
.topbar{background:var(--surface);border-bottom:1px solid var(--line);height:76px;
        display:flex;align-items:center;justify-content:flex-end;gap:18px;padding:0 28px;flex-shrink:0}
.topbar .ico{color:var(--txt-mute);position:relative;display:grid;place-items:center}
.topbar .ico svg{width:21px;height:21px;stroke-width:1.7}
.topbar .ico .dot{position:absolute;top:-1px;right:-1px;width:8px;height:8px;border-radius:50%;
                  background:#e0457b;border:2px solid var(--surface)}
.topbar .who{display:flex;align-items:center;gap:8px;font-weight:700;font-size:.9rem}
.topbar .who svg{width:14px;height:14px;color:var(--txt-mute)}
@media(max-width:600px){.topbar{padding:0 16px;height:64px}}

main{padding:26px 28px 60px;min-width:0;flex:1}
@media(max-width:640px){main{padding:20px 16px 44px}}
.head{display:flex;justify-content:space-between;align-items:center;gap:18px;
      flex-wrap:wrap;margin-bottom:20px}
.head .sub{color:var(--txt-mute);font-size:.85rem;margin-top:5px;text-transform:none;
           font-weight:500;letter-spacing:0}

/* ---------- Cartes ---------- */
.grid{display:grid;gap:15px}
/* Un élément de grille refuse par défaut de descendre sous la largeur
   intrinsèque de son contenu. Sans cela, un tableau large ou un graphique en
   SVG élargit la page entière au lieu de défiler dans son propre cadre — le
   symptôme est une page qui défile latéralement sur téléphone. */
.grid>*,.row>*{min-width:0}
.g2{grid-template-columns:1fr 1fr}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1120px){.g4{grid-template-columns:1fr 1fr}}
@media(max-width:940px){.g3{grid-template-columns:1fr}.g2{grid-template-columns:1fr}}
@media(max-width:620px){.g4{grid-template-columns:1fr}}

.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
      padding:18px 20px;box-shadow:var(--shadow)}
.card > h2,.card > h3{margin-bottom:14px}
.card-head{display:flex;justify-content:space-between;align-items:center;gap:12px;
           flex-wrap:wrap;margin-bottom:14px}
.card-head h2,.card-head h3{margin:0}

.kpi .lbl{font-size:.9rem;color:var(--txt);font-weight:700;line-height:1.35}
.kpi .val{font-family:var(--mono);font-size:1.6rem;font-weight:700;letter-spacing:-.035em;
          margin:8px 0 2px;line-height:1.1}
.kpi .sub{font-size:.76rem;color:var(--txt-faint)}
.up{color:var(--green)}
.down{color:var(--red)}

/* ---------- Tableaux ---------- */
table{width:100%;border-collapse:collapse;font-size:.87rem}
thead th{text-align:left;font-size:.78rem;color:var(--txt-mute);font-weight:600;
         padding:0 12px 12px;border-bottom:1px solid var(--line);white-space:nowrap;line-height:1.3}
tbody td{padding:13px 12px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:#fafcfd}
/* Un tableau plus large que son cadre défile — encore faut-il que cela se
   voie. Sans ce dégradé, un tableau tronqué sur téléphone passe pour un
   tableau amputé, et l'on ne va pas chercher les colonnes manquantes. Le voile
   s'efface dès que la fin est atteinte, grâce au fond opaque en arrière-plan. */
.table-wrap{overflow-x:auto;
  background:
    linear-gradient(to right, var(--surface) 30%, rgba(255,255,255,0)) left center / 28px 100% no-repeat,
    linear-gradient(to left,  var(--surface) 30%, rgba(255,255,255,0)) right center / 28px 100% no-repeat,
    radial-gradient(farthest-side at 0 50%, rgba(10,37,64,.14), transparent) left center / 12px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(10,37,64,.14), transparent) right center / 12px 100% no-repeat;
  background-attachment:local, local, scroll, scroll}
.empty{padding:36px 12px;text-align:center;color:var(--txt-faint);font-size:.87rem}

/* Pastille d'identité client : initiale sur fond dérivé du nom. */
.who-cell{display:flex;align-items:center;gap:10px;min-width:0}
.avatar{width:30px;height:30px;border-radius:7px;display:grid;place-items:center;
        font-weight:800;font-size:.82rem;color:#fff;flex-shrink:0}
.who-cell .nm{font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---------- Éléments ---------- */
.pill{display:inline-flex;align-items:center;gap:6px;font-size:.76rem;font-weight:700;
      padding:5px 13px;border-radius:8px;white-space:nowrap}
.pill.ok{background:var(--green-bg);color:var(--green)}
.pill.warn{background:var(--amber-bg);color:var(--amber)}
.pill.off{background:var(--red-bg);color:var(--red)}
.pill.neutral{background:#eef3f7;color:var(--txt-mute)}
.pill.mult{background:#e6f7f6;color:#0d7d75;font-family:var(--mono)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
     padding:10px 18px;border-radius:9px;font-weight:700;font-size:.85rem;
     border:1px solid transparent;cursor:pointer;transition:.18s;white-space:nowrap}
.btn.primary{background:var(--navy-deep);color:#fff}
.btn.primary:hover{background:#0d233a}
.btn.grad{background:var(--grad);color:#02121f}
.btn.grad:hover{filter:brightness(1.05)}
.btn.mint{background:#5fd9d0;color:#04322f}
.btn.mint:hover{background:#4ecdc4}
.btn.soft{background:#fbe0e2;color:#b23a3a}
.btn.soft:hover{background:#f7d0d3}
.btn.ghost{border-color:#d9e4ec;background:var(--surface);color:var(--txt)}
.btn.ghost:hover{border-color:var(--mint);background:#f2fbfa}
.btn.danger{border-color:rgba(192,57,43,.3);color:var(--red);background:var(--surface)}
.btn.danger:hover{background:var(--red-bg)}
.btn.sm{padding:7px 13px;font-size:.79rem;border-radius:8px}
.actions{display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}

label{display:block;font-size:.79rem;font-weight:700;color:var(--txt-mute);margin-bottom:6px}
input[type=text],input[type=email],input[type=password],input[type=number],select,textarea{
  width:100%;padding:10px 13px;border:1px solid #d9e4ec;border-radius:9px;
  background:var(--surface);font-size:.88rem;transition:.16s}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--mint);
  box-shadow:0 0 0 3px rgba(78,205,196,.18)}
.field{margin-bottom:16px}
.field .hint{font-size:.74rem;color:var(--txt-faint);margin-top:6px;line-height:1.45}
.row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:620px){.row{grid-template-columns:1fr}}

.flash{padding:12px 16px;border-radius:9px;font-size:.86rem;margin-bottom:18px;font-weight:600}
.flash.ok{background:var(--green-bg);color:var(--green);border:1px solid rgba(47,158,95,.22)}
.flash.err{background:var(--red-bg);color:var(--red);border:1px solid rgba(192,57,43,.22)}
/* Ni succès ni échec : un état à régulariser, que l'exploitant doit voir sans
   croire à une panne. */
.flash.warn{background:var(--amber-bg);color:var(--amber);border:1px solid rgba(169,121,26,.24)}

.key{font-family:var(--mono);font-size:.79rem;background:#f2f7fa;border:1px solid var(--line);
     border-radius:6px;padding:3px 9px;letter-spacing:-.02em;display:inline-block}
.secret{font-family:var(--mono);font-size:.86rem;background:var(--navy);color:#7fe9ff;
        padding:14px 16px;border-radius:9px;word-break:break-all;line-height:1.6}

/* ---------- Graphiques ---------- */
.chart{width:100%;max-width:100%;height:170px;overflow:visible}
.chart .bar{fill:var(--navy);transition:fill .18s}
.chart .bar:hover{fill:var(--cyan)}
.chart .axis{stroke:var(--line);stroke-width:1}
.chart .grid-l{stroke:var(--line-soft);stroke-width:1}
.chart .lbl{font-family:var(--mono);font-size:7px;fill:var(--txt-faint)}
/* Un SVG mis à l'échelle réduit son texte dans la même proportion : sur un
   écran de 390 px, un graphique dessiné pour 720 rend ses libellés à trois
   pixels. On les agrandit dans le repère du dessin pour compenser. */
@media(max-width:760px){.chart .lbl{font-size:15px}}
@media(max-width:480px){.chart .lbl{font-size:19px}}
.chart .l-rev{fill:none;stroke:var(--mint);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart .l-cost{fill:none;stroke:#e2756f;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart .a-rev{fill:rgba(78,205,196,.14)}
.chart .a-cost{fill:rgba(226,117,111,.12)}
.chart .pt-rev{fill:var(--mint)}
.chart .pt-cost{fill:#e2756f}
.legend{display:flex;gap:20px;flex-wrap:wrap;font-size:.78rem;color:var(--txt-mute);
        margin-top:12px;justify-content:center}
.legend span{display:flex;align-items:center;gap:7px}
.legend i{width:16px;height:3px;border-radius:2px;display:block}

.bar-row{display:flex;align-items:center;gap:11px;margin-bottom:10px}
.bar-row .nm{font-size:.83rem;min-width:130px;font-weight:600}
.bar-row .track{flex:1;height:8px;background:#edf2f6;border-radius:99px;overflow:hidden}
.bar-row .fill{height:100%;background:var(--grad);border-radius:99px}
.bar-row .amt{font-family:var(--mono);font-size:.79rem;min-width:92px;text-align:right;
              letter-spacing:-.02em}

.meter{height:7px;background:#edf2f6;border-radius:99px;overflow:hidden;min-width:70px}
.meter i{display:block;height:100%;border-radius:99px;background:var(--mint)}
.meter i.hot{background:#e2756f}

/* ---------- Journaux techniques (terminal) ---------- */
.term{background:#0e1b2a;border-radius:10px;overflow:hidden}
.term-bar{display:flex;gap:10px;align-items:center;padding:12px 14px;flex-wrap:wrap;
          border-bottom:1px solid rgba(255,255,255,.07)}
.term-bar .search{flex:1;min-width:180px;display:flex;align-items:center;gap:8px;
                  background:rgba(255,255,255,.05);border-radius:8px;padding:7px 11px}
.term-bar .search svg{width:15px;height:15px;color:#7e94a8;flex-shrink:0}
.term-bar .search input{background:none;border:0;color:#dbe7f0;font-size:.83rem;width:100%;padding:0}
.term-bar .search input:focus{outline:none;box-shadow:none}
.term-bar .search input::placeholder{color:#6f8497}
.term-bar select{width:auto;min-width:130px;background:rgba(255,255,255,.05);
                 border-color:rgba(255,255,255,.12);color:#dbe7f0;font-size:.82rem;padding:7px 11px}
/* La liste déroulante est dessinée par le navigateur sur SON fond, pas sur le
   bandeau sombre : sans couleurs propres, les options héritaient du gris clair
   du contrôle et devenaient illisibles sur blanc. Le contrôle fermé garde sa
   teinte claire, la liste ouverte redevient du texte sombre sur blanc. */
.term-bar select option{color:var(--txt);background:var(--surface)}
.term-bar select option:checked{color:var(--txt);background:#e6f7f6}
.term-body{font-family:var(--mono);font-size:.78rem;line-height:1.85;padding:14px 16px;
           max-height:520px;overflow:auto;color:#9fb6c9}
.term-body .ln{display:flex;gap:12px;white-space:pre;min-width:0}
.term-body .ts{color:#5f7a91;flex-shrink:0}
.term-body .lv{font-weight:700;flex-shrink:0;width:62px}
.term-body .lv.info{color:#4ecdc4}
.term-body .lv.warn{color:#e8b84b}
.term-body .lv.err{color:#ef6f6f}
.term-body .msg{color:#c3d5e2;white-space:pre-wrap;word-break:break-word}
.term-body .empty{color:#6f8497}
/* Sur téléphone, l'horodatage et le niveau consommaient presque toute la
   largeur : le message se retrouvait dans une colonne de ~45 px et se cassait
   lettre par lettre, rendant le journal illisible. On le passe sous son
   en-tête, qui reste sur une ligne. */
@media(max-width:720px){
  .term-body .ln{flex-wrap:wrap;gap:6px 10px}
  .term-body .msg{flex:1 0 100%;padding-left:2px}
}

/* ---------- Connexion ---------- */
.login-page{min-height:100vh;display:grid;place-items:center;padding:24px;
            background:radial-gradient(ellipse at 50% 0%,#12395e,#0a1c2e 62%)}
.login{width:100%;max-width:398px;background:var(--surface);border-radius:16px;
       padding:34px 32px;box-shadow:0 40px 90px -40px rgba(0,0,0,.7)}
.login .brand{justify-content:center;height:auto;padding:0 0 6px;font-size:1.5rem}
.login .tag{text-align:center;color:var(--txt-faint);font-size:.82rem;margin-bottom:24px}
.login .btn{width:100%;margin-top:6px}
.login-foot{text-align:center;font-size:.73rem;color:var(--txt-faint);margin-top:18px;line-height:1.5}

/* ---------- Périodes ---------- */
.periods{display:flex;gap:6px;flex-wrap:wrap}
.periods a{padding:7px 13px;border-radius:8px;font-size:.8rem;font-weight:600;
           color:var(--txt-mute);border:1px solid transparent}
.periods a:hover{background:#eef3f7}
.periods a.on{background:var(--navy-deep);color:#fff;font-weight:700}

@media print{
  aside.nav,.topbar,.periods,.btn{display:none}
  body{background:#fff}
  .card{break-inside:avoid;box-shadow:none;border-color:#ccc}
}
