/* ava-companion — direction artistique "ligne directe".
   Sujet : une présence (Ava), pas un outil de chat. Thème clair par défaut,
   sombre via prefers-color-scheme.
   Signature : la pastille de présence — elle respire en violet quand Ava est
   disponible (.online), et vire au terracotta en pulsant plus vite quand elle
   est occupée (.working). Un seul élément mémorable, tout le reste reste calme.
   Palette ancrée sur LE violet (#7c5cbf, intouchable), posée sur un papier
   blush chaud, relevée d'un terracotta discret (jamais en grande surface). */

/* ---------- polices auto-hébergées (offline-first, aucune requête CDN) ----------
   Fraunces (display, OFL) + Inter (corps, OFL), variables, sous-ensemble latin
   (couvre le français, œ/Œ compris). Fichiers dans ./fonts/, licences à côté. */

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Fraunces-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Fraunces-var-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Inter-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- tokens ---------- */

:root {
  --bg: #fbf5f1;            /* papier blush, chaud et rosé */
  --surface: #fffdfb;
  --ink: #2a2233;           /* aubergine très sombre */
  --muted: #8d8095;
  --accent: #7c5cbf;        /* LE violet — ne pas toucher */
  --accent-deep: #4f3585;   /* contrastes / hover */
  --accent-ink: #ffffff;
  --warm: #c97854;          /* terracotta — par petites touches seulement */
  /* terracotta version texte : assombri vers l'encre pour tenir le contraste
     sur le papier blush (le --warm nu tombe à ~3:1 sur du texte de 13px) */
  --warm-text: color-mix(in srgb, var(--warm) 72%, var(--ink));
  --ava-tint: #f4edf9;      /* lilas recalé sur le papier blush */
  --line: #ecdfd6;          /* filets chauds */
  --ok: #3f9d63;
  --warn: #c98a2b;
  --err: #c04f4f;
  --radius: 16px;
  --display: "Fraunces", "Georgia", serif;
  --body: "Inter", "Cantarell", "Ubuntu", system-ui, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "JetBrains Mono", monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #201a26;          /* aubergine nuit, légèrement chaud */
    --surface: #2a2231;
    --ink: #efe8ef;
    --muted: #9c8fa3;
    --accent: #a88be0;
    --accent-deep: #cdb6f0; /* en sombre, le "deep" devient le clair de contraste */
    --accent-ink: #241c2e;
    --warm: #d98d66;        /* terracotta relevé pour tenir sur fond sombre */
    --warm-text: var(--warm); /* déjà >6:1 sur l'aubergine nuit, rien à corriger */
    --ava-tint: #2e2637;
    --line: #3a3143;
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* L'attribut hidden doit gagner sur nos display de classe (le display:flex de
   .day-hint battait le [hidden] du navigateur : l'invite restait affichée). */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.55 var(--body);
  overflow: hidden;
}

::selection {
  background: color-mix(in srgb, var(--accent) 28%, transparent);
}

/* ---------- header / présence ---------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  -webkit-app-region: drag; /* no-op sous Tauri/WebKitGTK, gardé pour le mode navigateur/Chromium */
}

.presence { display: flex; align-items: center; gap: 13px; min-width: 0; }

/* La pastille : trois états, trois humeurs.
   (défaut = connexion en cours, ambre, statique) */
.dot {
  width: 11px;
  height: 11px;
  flex: none;
  border-radius: 50%;
  background: var(--warn);
  transition: background .3s;
}

/* en ligne, disponible : violet qui respire lentement */
.dot.online {
  background: var(--accent);
  animation: breathe 2.8s ease-in-out infinite;
}

/* hors ligne : rouge, immobile */
.dot.offline { background: var(--err); animation: none; }

/* occupée ("je fais quelque chose") : la respiration s'accélère et la
   couleur bascule du violet au terracotta — le statut se lit sans un mot.
   Classe à piloter par le futur signal d'activité ; rendu prêt dès maintenant. */
.dot.working {
  background: var(--warm);
  animation: working 1.4s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  50%      { box-shadow: 0 0 0 7px transparent; }
}

@keyframes working {
  0%, 100% {
    background: var(--accent);
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--warm) 55%, transparent);
  }
  50% {
    background: var(--warm);
    box-shadow: 0 0 0 6px transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dot.online, .dot.working { animation: none; }
  /* sans animation, l'état "occupée" reste lisible : teinte mi-violet mi-terracotta */
  .dot.working { background: color-mix(in srgb, var(--accent) 45%, var(--warm)); }
}

.presence-text h1 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 20px;
  font-weight: 540;
  letter-spacing: .015em;
  line-height: 1.15;
}

.presence-text p {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.server-btn {
  -webkit-app-region: no-drag;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  background: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.server-btn:hover { color: var(--accent-deep); border-color: var(--accent); }

/* Bouton hamburger : masqué sur desktop (la sidebar reste fixe), visible en
   tiroir sur mobile — voir la media query en bas de fichier. */
.menu-btn {
  -webkit-app-region: no-drag;
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.menu-btn svg { width: 20px; height: 20px; }
.menu-btn:hover { background: var(--ava-tint); }

/* Version logicielle du bouton "surprends-moi" (même endpoint que le futur
   ESP32) : discrète comme server-btn, teinte accent pour la distinguer un peu
   d'un simple réglage. Désactivé quelques secondes après l'appui — un feedback
   suffit, pas la peine de permettre le spam. */
.surprise-btn {
  -webkit-app-region: no-drag;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent-deep);
  background: none;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  transition: color .15s, border-color .15s, opacity .15s;
}

.surprise-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.surprise-btn:disabled { opacity: .5; cursor: default; }

/* Ping du bouton physique (futur ESP32, brainstorm du 04/07) : une pilule
   terracotta qui cligne doucement quelques cycles quand un appui vient d'être
   détecté, puis disparaît. Invisible le reste du temps ([hidden]). L'auto
   margin la colle au bouton serveur malgré le space-between de la topbar. */
.press-ping {
  -webkit-app-region: no-drag;
  flex: none;
  margin-left: auto;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--warm-text);
  border: 1px solid color-mix(in srgb, var(--warm) 45%, var(--line));
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
  animation: press-ping .9s ease-in-out 5;
}

@keyframes press-ping {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
  .press-ping { animation: none; }
}

/* ---------- coque : sidebar + vues ----------
   Sous la topbar, une colonne de navigation à gauche et la vue active à
   droite. L'onglet actif reprend le traitement de la voix d'Ava dans le fil
   (fond lilas + filet violet à gauche) : naviguer, c'est déjà chez elle. */

.shell {
  flex: 1;
  display: flex;
  min-height: 0; /* sans quoi le fil ne scrolle pas, il pousse la page */
}

.sidebar {
  width: 208px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 10px 10px 14px;
  border-right: 1px solid var(--line);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  border: none;
  border-left: 2px solid transparent;
  border-radius: 4px 10px 10px 4px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
  text-align: left;
  cursor: pointer;
  transition: background .15s, color .15s;
}

.nav-item svg { width: 17px; height: 17px; flex: none; opacity: .8; }

.nav-item .label {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.nav-item:hover {
  background: color-mix(in srgb, var(--ava-tint) 65%, transparent);
}

.nav-item.active {
  background: var(--ava-tint);
  border-left-color: var(--accent);
  color: var(--accent-deep);
  font-weight: 550;
}

.nav-item.active svg { opacity: 1; }

/* onglets pas encore ouverts : présents mais en retrait */
.nav-item.soon { color: var(--muted); }
.nav-item.soon:hover { color: var(--ink); }
.nav-item.soon.active { color: var(--accent-deep); }

.nav-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Titre de section : même langue que les séparateurs de jour du fil
   (Fraunces italique terracotta, filet qui court vers la droite). */
.nav-section {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 10px 6px;
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 11.5px;
  font-weight: 480;
  letter-spacing: .03em;
  color: var(--warm-text);
}

.nav-section::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.nav-group { display: flex; flex-direction: column; gap: 1px; }

.nav-note {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  padding: 6px 12px;
}

.views {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.view {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* fenêtre étroite : la sidebar se replie en rail d'icônes */
@media (max-width: 680px) {
  .sidebar { width: 54px; padding: 10px 7px 14px; }
  .sidebar .label { display: none; }
  .nav-item { justify-content: center; padding: 8px 0 8px 2px; gap: 0; }
  .nav-section { padding: 12px 4px 6px; }
  .nav-section .txt { display: none; } /* reste le filet, simple respiration */
  .nav-note { padding: 6px 2px; text-align: center; }
}

/* ---------- en-tête de vue (Discord) ---------- */

.view-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 18px;
  border-bottom: 1px solid var(--line);
}

.view-head-text { min-width: 0; }

.view-head h2 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 16px;
  font-weight: 540;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.view-head p {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pill {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
}

.pill.warm {
  color: var(--warm-text);
  border-color: color-mix(in srgb, var(--warm) 45%, var(--line));
}

/* ---------- placeholder des onglets à venir ---------- */

.view.placeholder { align-items: center; justify-content: center; }

.placeholder-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 380px;
  padding: 24px;
  text-align: center;
}

.placeholder-icon svg {
  width: 34px;
  height: 34px;
  color: var(--muted);
  opacity: .55;
}

.placeholder-card h2 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 22px;
  font-weight: 540;
}

.placeholder-card .tagline {
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 14px;
  color: var(--warm-text);
  margin-bottom: 4px;
}

/* ---------- fil de messages ---------- */

.chat {
  flex: 1;
  overflow-y: auto;
  /* plus de padding-top : ce sont les séparateurs de jour (sticky) qui portent
     l'espace du haut, sinon les messages resteraient visibles au-dessus d'eux */
  padding: 0 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

/* Séparateur de jour, façon page de journal : un court trait terracotta,
   le label en Fraunces italique, puis le filet qui court vers la droite. */
.day-hint {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 13px;
  font-weight: 480;
  letter-spacing: .02em;
  color: var(--warm-text);
  padding: 12px 0 10px;
}

/* Variante sticky (insérée par app.js entre deux jours) : le jour de la
   première ligne visible reste collé en haut pendant qu'on remonte le fil.
   Fond opaque + débord sur le padding horizontal : les bulles passent
   dessous proprement, et hors scroll le fond se fond dans la page. */
.day-hint.day-sep {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 0 -18px;
  padding: 12px 18px 10px;
  background: var(--bg);
}

.day-hint::before {
  content: "";
  flex: none;
  width: 26px;
  height: 1px;
  background: color-mix(in srgb, var(--warm) 60%, transparent);
}

.day-hint::after {
  content: "";
  flex: 1;
  min-width: 24px;
  height: 1px;
  background: var(--line);
}

.msg {
  max-width: 78%;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* Résultat d'une quick action (/status, /help) : centré, discret, mono — un
   petit rapport système, pas un message de conversation. */
.qa-result {
  align-self: center;
  max-width: 90%;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 14px;
  text-align: center;
}

.msg time {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--muted);
  margin-top: 4px;
}

/* Nom de l'expéditeur en tête de bulle — Fraunces italique, comme une
   signature de journal ; la couleur suit la voix de chaque côté. */
.msg .sender {
  display: block;
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 11.5px;
  font-weight: 520;
  letter-spacing: .03em;
  margin-bottom: 2px;
}

.msg.me .sender { color: color-mix(in srgb, var(--accent-ink) 80%, transparent); text-align: right; }

.msg.ava .sender { color: var(--accent-deep); }

/* Ravenne : bulle pleine violette, à droite */
.msg.me {
  align-self: flex-end;
  background: linear-gradient(135deg,
    var(--accent),
    color-mix(in srgb, var(--accent) 82%, var(--accent-deep)));
  color: var(--accent-ink);
  padding: 9px 14px;
  border-radius: var(--radius) var(--radius) 5px var(--radius);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--accent-deep) 18%, transparent);
}

@media (prefers-color-scheme: dark) {
  /* en sombre, --accent-deep est clair : on fond vers l'aubergine du fond */
  .msg.me {
    background: linear-gradient(135deg,
      var(--accent),
      color-mix(in srgb, var(--accent) 84%, var(--bg)));
    box-shadow: none;
  }
}

.msg.me time { color: color-mix(in srgb, var(--accent-ink) 65%, transparent); text-align: right; }

/* Ava : pas de bulle, un filet lilas — sa voix fait partie de la page.
   (même traitement dans les archives Discord : sa voix ne change pas de
   costume selon l'endroit) */
.msg.ava {
  align-self: flex-start;
  background: var(--ava-tint);
  border-left: 2px solid var(--accent);
  padding: 9px 14px 9px 15px;
  border-radius: 4px var(--radius) var(--radius) 4px;
}

/* ---------- archives Discord (lecture seule) ---------- */

/* Les autres voix du salon : bulle calme sur surface, signature terracotta —
   des invités sur la page, ni Ava ni Ravenne. */
.msg.peer {
  align-self: flex-start;
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 8px 14px;
  border-radius: var(--radius) var(--radius) var(--radius) 5px;
}

.msg.peer .sender { color: var(--warm-text); }

/* message supprimé côté Discord : gardé dans l'archive, mais en retrait */
.msg.deleted { opacity: .55; }

.msg .empty-content {
  font-style: italic;
  color: var(--muted);
}

.load-more {
  align-self: center;
  flex: none;
  margin: 12px 0 4px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 14px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.load-more:hover:not(:disabled) { color: var(--accent-deep); border-color: var(--accent); }
.load-more:disabled { cursor: default; opacity: .6; }
.load-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.discord-feed { padding-bottom: 16px; }

/* ---------- panneaux en lecture seule (tâches, crons) ----------
   Même conteneur scrollable que le fil (.chat) mais un contenu de page plus
   que de conversation : intro discrète, marques de section dans la langue des
   séparateurs de jour, puis des lignes ou des cartes. */

.panel-scroll { padding-bottom: 18px; gap: 8px; }

.panel-intro {
  max-width: 62ch;
  font-size: 13px;
  color: var(--muted);
  padding-top: 12px;
}

.panel-intro + .panel-intro { padding-top: 0; }

.panel-intro strong { color: var(--ink); font-weight: 600; }

/* Marque de section : le tag #domaine en mono violet, le titre en Fraunces
   italique terracotta — même filet que les séparateurs de jour. */
.section-head { margin-top: 10px; }

.section-tag {
  font-family: var(--mono);
  font-style: normal;
  font-size: 11px;
  font-weight: 550;
  letter-spacing: .02em;
  color: var(--accent-deep);
  background: var(--ava-tint);
  border-radius: 999px;
  padding: 1.5px 9px;
}

/* code inline dans les textes de tâches */
.todo-text code, .panel-intro code {
  font-family: var(--mono);
  font-size: .88em;
  background: color-mix(in srgb, var(--ava-tint) 80%, transparent);
  border-radius: 5px;
  padding: 1px 5px;
}

/* ---------- tâches ---------- */

.todo-item {
  display: flex;
  gap: 11px;
  max-width: 74ch;
  padding: 2px 0;
}

/* la case : cochée = violet plein + coche blanche ; en attente = vide */
.todo-check {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 2px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, var(--line));
  background: var(--surface);
}

.todo-item.done .todo-check {
  background: var(--accent);
  border-color: var(--accent);
}

.todo-check svg { width: 12px; height: 12px; color: var(--accent-ink); stroke-width: 3; }

.todo-text {
  font-size: 13.5px;
  line-height: 1.5;
  overflow-wrap: break-word;
  min-width: 0;
}

/* le fait est acquis : la ligne se retire, sans rature (illisible en pavé) */
.todo-item.done .todo-text { color: var(--muted); }

.todo-item.done .todo-text strong { color: inherit; }

.go-badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 650;
  letter-spacing: .06em;
  line-height: 1;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: 999px;
  padding: 3px 7px;
  vertical-align: 1px;
}

.todo-item.done .go-badge { opacity: .5; }

/* ---------- kanban tâches ---------- */
/* Colonnes par statut plutôt que par tag/topic, scroll horizontal si ça
   déborde. Chaque carte reprend .todo-text (déjà stylée) + un petit badge
   pour le tag d'origine (le regroupement par topic n'a pas disparu, il est
   juste secondaire à la carte plutôt que structurant toute la vue). */

.kanban-board {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 6px;
  align-items: flex-start;
}

.kanban-col {
  flex: none;
  width: 220px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.kanban-col-head {
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 12.5px;
  color: var(--warm-text);
  padding: 4px 2px 8px;
  border-bottom: 1px solid var(--line);
}

.kanban-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px;
}

.kanban-card-tag {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--muted);
  background: var(--ava-tint);
  border-radius: 999px;
  padding: 1.5px 8px;
  margin-bottom: 6px;
}

/* ---------- crons ---------- */

.cron-card {
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
}

.cron-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.cron-head h3 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 15px;
  font-weight: 540;
}

.cron-schedule {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent-deep);
  background: var(--ava-tint);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}

.cron-desc { font-size: 13px; color: var(--ink); margin-top: 2px; }

.cron-runs {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  margin-top: 6px;
  white-space: pre-wrap;
}

/* la limite connue, dite en face : pas de fausse donnée */
.cron-limitation {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  max-width: 560px;
  border: 1px dashed color-mix(in srgb, var(--warm) 45%, var(--line));
  border-radius: var(--radius);
  padding: 12px 16px;
}

.cron-limitation p { font-size: 13px; color: var(--muted); }

/* ---------- mémoire ----------
   Le sommaire MEMORY.md : chaque entrée est un <details> — fermé, une ligne
   de sommaire (titre Fraunces + description discrète) ; ouvert, le fichier
   entier dans un encart lilas, la voix d'Ava (c'est elle qui se souvient). */

.mem-entry {
  max-width: 74ch;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  padding: 2px 0 8px;
}

.mem-entry summary {
  list-style: none;
  cursor: pointer;
  border-radius: 8px;
  padding: 6px 8px;
  margin: 0 -8px;
  transition: background .15s;
}

.mem-entry summary::-webkit-details-marker { display: none; }

.mem-entry summary:hover {
  background: color-mix(in srgb, var(--ava-tint) 65%, transparent);
}

.mem-entry summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.mem-title {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 14.5px;
  font-weight: 540;
  color: var(--ink);
}

/* petit chevron dessiné, qui pivote à l'ouverture */
.mem-entry summary .mem-title::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 10px;
  border-right: 1.6px solid var(--muted);
  border-bottom: 1.6px solid var(--muted);
  transform: rotate(-45deg) translateY(-2px);
  transition: transform .15s;
}

.mem-entry[open] summary .mem-title::before {
  transform: rotate(45deg) translateY(-2px);
  border-color: var(--accent);
}

.mem-desc {
  font-size: 12.5px;
  color: var(--muted);
  margin: 1px 0 0 17px;
}

/* entrées du sommaire pointant hors du dossier mémoire : présentes, en retrait */
.mem-entry.external { padding: 8px 0; }

.mem-entry.external .mem-title { color: var(--muted); }

.mem-external-note {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--muted);
  border: 1px dashed var(--line);
  border-radius: 999px;
  padding: 1.5px 8px;
  margin-left: 10px;
  vertical-align: 1px;
  white-space: nowrap;
}

.mem-entry.external .mem-desc { margin-left: 0; }

/* le fichier déplié : encart dans la voix d'Ava (lilas, filet violet) */
.mem-file {
  margin: 8px 0 6px 17px;
  background: var(--ava-tint);
  border-left: 2px solid var(--accent);
  border-radius: 4px var(--radius) var(--radius) 4px;
  padding: 12px 16px;
  font-size: 13.5px;
  line-height: 1.55;
}

.mem-file-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.mem-type {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .05em;
  color: var(--accent-deep);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  border-radius: 999px;
  padding: 2px 9px;
  text-transform: uppercase;
}

.mem-type-feedback { color: var(--warm-text); border-color: color-mix(in srgb, var(--warm) 45%, var(--line)); }

.mem-file-name {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
}

.mem-file-desc {
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 13px;
  color: var(--accent-deep);
  margin-bottom: 8px;
}

/* ---------- rendu Markdown minimal (corps des fichiers mémoire) ---------- */

.md-p { white-space: pre-wrap; overflow-wrap: break-word; }

.md-p + .md-p, .md-p + .md-list, .md-list + .md-p,
.md-pre + .md-p, .md-p + .md-pre, .md-quote + .md-p, .md-p + .md-quote {
  margin-top: 8px;
}

.md-h {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-weight: 560;
  margin: 12px 0 4px;
}

.md-h1 { font-size: 16px; }
.md-h2 { font-size: 15px; }
.md-h3, .md-h4 { font-size: 13.5px; }

.md-list { margin: 4px 0 4px 4px; padding-left: 16px; }

.md-list li { margin: 2px 0; white-space: pre-wrap; overflow-wrap: break-word; }

.md-list li::marker { color: var(--accent); }

.md-list li.nested { margin-left: 16px; }

.md-quote {
  white-space: pre-wrap;
  overflow-wrap: break-word;
  border-left: 2px solid color-mix(in srgb, var(--warm) 55%, var(--line));
  padding-left: 12px;
  color: var(--muted);
  font-style: italic;
  margin: 6px 0;
}

.md-pre {
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.5;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  overflow-x: auto;
  margin: 6px 0;
}

.md-hr {
  height: 1px;
  background: var(--line);
  margin: 12px 0;
}

.md-p code, .md-list code, .md-quote code, .md-h code {
  font-family: var(--mono);
  font-size: .88em;
  background: color-mix(in srgb, var(--surface) 85%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  border-radius: 5px;
  padding: 1px 5px;
}

/* référence [[mémoire]] : chip discret, non cliquable (pas de navigation) */
.md-ref {
  font-family: var(--mono);
  font-size: .85em;
  color: var(--accent-deep);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-radius: 5px;
  padding: 1px 6px;
}

/* lien Markdown rendu comme texte (la cible vit sur le Pi, pas ici) */
.md-link {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  text-underline-offset: 2px;
}

/* ---------- skills ---------- */

.skill-card {
  max-width: 560px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
}

.skill-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.skill-head h3 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 15px;
  font-weight: 540;
}

.skill-flag {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .05em;
  color: var(--accent-deep);
  background: var(--ava-tint);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

.skill-desc { font-size: 13px; color: var(--ink); margin-top: 2px; }

.skill-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}

.skill-tool {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.5px 7px;
}

.skill-foot {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  margin-top: 8px;
}

/* ---------- bouton rafraîchir (onglets d'usage) ---------- */

.refresh-btn {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  transition: color .15s, border-color .15s;
}

.refresh-btn:hover { color: var(--accent-deep); border-color: var(--accent); }
.refresh-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---------- cartes chiffres (stats, usage) ----------
   Une grille de tuiles sobres : un grand nombre en Fraunces, un libellé
   discret, un sous-titre en mono. La sévérité (usage/système) teinte le filet
   gauche et le nombre — terracotta en alerte, rouge en critique. */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  max-width: 620px;
  padding-top: 6px;
}

.stat-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 14px 16px;
}

.stat-num {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 30px;
  font-weight: 560;
  line-height: 1.05;
  color: var(--accent-deep);
  overflow-wrap: break-word;
}

.stat-label {
  font-size: 12.5px;
  color: var(--ink);
  margin-top: 4px;
}

.stat-sub {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  margin-top: 5px;
}

.stat-card.sev-warning { border-left-color: var(--warm); }
.stat-card.sev-warning .stat-num { color: var(--warm-text); }
.stat-card.sev-critical { border-left-color: var(--err); }
.stat-card.sev-critical .stat-num { color: var(--err); }

/* ---------- mini graphiques en barres (stats) ----------
   Une teinte, pas de légende (un seul jeu de données) — le titre dit ce qui
   est tracé. Axe réduit à trois repères (début/milieu/fin), jamais un par
   barre ; bulle au survol plutôt que des valeurs plaquées partout. */

.chart-wrap {
  max-width: 620px;
  margin-top: 18px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.chart-title {
  font-family: var(--display);
  font-style: italic;
  font-optical-sizing: auto;
  font-size: 13px;
  color: var(--warm-text);
  margin-bottom: 8px;
}

.chart-plot { position: relative; }

.chart-svg { display: block; width: 100%; height: 120px; }

.chart-baseline { stroke: var(--line); stroke-width: 1; }

.chart-bar { transition: opacity .12s; cursor: default; }
.chart-bar:hover { opacity: .78; }

.chart-tip {
  position: absolute;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 6px;
  padding: 3px 9px;
  font-family: var(--mono);
  font-size: 11px;
  white-space: nowrap;
  color: var(--accent-ink);
  background: var(--ink);
  border-radius: 6px;
  pointer-events: none;
}

.chart-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
}

/* ---------- activité (état courant + timeline en RAM) ---------- */

.activity-now {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 560px;
  margin-top: 8px;
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--ava-tint);
  border-left: 3px solid var(--accent);
}

.activity-now.working { border-left-color: var(--warm); }

.activity-now-state {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 24px;
  font-weight: 560;
  color: var(--accent-deep);
}

.activity-now.working .activity-now-state { color: var(--warm-text); }

.activity-now-detail { font-size: 13px; color: var(--ink); }

.activity-now-since {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  margin-top: 2px;
}

.activity-row {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 560px;
  padding: 5px 0;
}

.activity-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
}

.activity-row.working .activity-dot { background: var(--warm); }

.activity-label {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--ink);
  overflow-wrap: break-word;
}

.activity-detail { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }

.activity-time {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
}

/* ---------- composer ----------
   Pilule flottante sur le papier : plus de barre pleine largeur, le champ et
   le bouton d'envoi vivent dans une même capsule qui s'illumine au focus. */

.composer {
  display: flex;
  align-items: flex-end;
  padding: 8px 14px 14px;
}

.field {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 5px 5px 5px 16px;
  box-shadow: 0 2px 12px color-mix(in srgb, var(--accent-deep) 7%, transparent);
  transition: border-color .15s, box-shadow .15s;
}

.field:hover { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }

/* le halo violet de la capsule sert d'indicateur de focus du champ */
.field:focus-within {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--line));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}

@media (prefers-color-scheme: dark) {
  .field { box-shadow: none; } /* l'ombre portée ne se lit pas sur fond nuit */
}

.composer textarea {
  flex: 1;
  min-width: 0;
  resize: none;
  max-height: 130px;
  border: none;
  outline: none; /* remplacé par le focus-within de la capsule */
  padding: 8px 0;
  font: inherit;
  color: var(--ink);
  background: none;
}

.composer textarea::placeholder { color: var(--muted); }

.server-btn:focus-visible,
.composer button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.composer button[type="submit"] {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: linear-gradient(135deg,
    var(--accent),
    color-mix(in srgb, var(--accent) 82%, var(--accent-deep)));
  color: var(--accent-ink);
  cursor: pointer;
  transition: filter .15s, transform .15s;
}

.composer button[type="submit"]:hover:not(:disabled) {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.composer button[type="submit"]:active:not(:disabled) { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .composer button[type="submit"]:hover:not(:disabled) { transform: none; }
}

.composer button[type="submit"]:disabled { opacity: .45; cursor: default; }

/* ---------- alertes (journal de supervision Checkmk) ----------
   Des lignes sobres, pas des cartes : le journal se lit d'un œil comme un log.
   La sévérité vient de l'emoji du texte (🔴/🟡/✅), reprise sur un filet gauche
   discret — le rouge/ambre ne s'étale jamais en grande surface. */

.alert-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  max-width: 640px;
  padding: 5px 10px 5px 8px;
  border-left: 2px solid transparent;
}

.alert-row.critical { border-left-color: var(--err); }
.alert-row.warning  { border-left-color: var(--warn); }
.alert-row.ok       { border-left-color: var(--ok); }

.alert-ico {
  flex: none;
  width: 18px;
  text-align: center;
  font-size: 11px;
  color: var(--muted); /* le "·" des lignes sans emoji ; les emojis s'imposent */
}

.alert-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.alert-time {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
}

/* ---------- recherche Discord (archives, plein texte) ----------
   Une capsule discrète dans l'en-tête de la vue : champ + périmètre. Les
   résultats remplacent visuellement le fil (conteneur jumeau) et se lisent
   comme un log : une ligne par message, extrait avec les termes marqués. */

.discord-search {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 4px 3px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}

.discord-search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.discord-search input {
  width: 170px;
  border: none;
  background: none;
  color: var(--ink);
  font: 12.5px var(--body);
}

.discord-search input:focus { outline: none; }
.discord-search input::placeholder { color: var(--muted); }

.discord-search select {
  border: none;
  border-radius: 999px;
  padding: 3px 6px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  color: var(--accent-deep);
  font: 11px var(--mono);
  cursor: pointer;
}

/* une ligne de résultat : auteur, extrait marqué, heure — le jour vient des
   séparateurs sticky partagés avec le fil */
.search-hit {
  display: flex;
  align-items: baseline;
  gap: 10px;
  max-width: 640px;
  padding: 5px 10px;
}

.hit-body {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  overflow-wrap: break-word;
}

.hit-who {
  margin-right: 8px;
  font-family: var(--display);
  font-style: italic;
  font-size: 12.5px;
  color: var(--accent-deep);
}

.hit-chat {
  margin-right: 8px;
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--warm-text);
  white-space: nowrap;
}

.hit-excerpt mark {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: inherit;
  border-radius: 4px;
  padding: 0 2px;
}

.hit-time {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
}

/* ---------- git (digest multi-repos) ----------
   Un groupe par repo : nom + branche en en-tête, puis une ligne par commit
   façon `git log --oneline`, hash en mono discret pour ne pas rivaliser avec
   le sujet du commit qui porte l'info utile. */

.git-repo-group { margin-bottom: 18px; }
.git-repo-group:last-child { margin-bottom: 0; }

.git-repo-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 10px;
}

.git-repo-name {
  font-family: var(--display);
  font-style: italic;
  font-size: 14px;
  color: var(--accent-deep);
}

.git-repo-branch {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--muted);
  padding: 1px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
}

.git-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  max-width: 640px;
  padding: 4px 10px;
  font-size: 13px;
}

.git-hash {
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
}

.git-subject {
  flex: 1;
  min-width: 0;
  color: var(--ink);
  overflow-wrap: break-word;
}

.git-commit-meta {
  flex: none;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

/* ---------- modale réglages (serveur + token) ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: color-mix(in srgb, var(--ink) 45%, transparent);
}

.modal {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 20px 50px -15px color-mix(in srgb, var(--ink) 35%, transparent);
}

.modal h2 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-size: 18px;
  font-weight: 560;
}

.modal label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12.5px;
  color: var(--muted);
}

.modal label code {
  font-family: var(--mono);
  font-size: 11px;
}

.modal input {
  font: 14px var(--mono);
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 12px;
}

.modal input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

.modal-actions button {
  font: 13px var(--body);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  border: 1px solid var(--line);
}

.modal-cancel {
  background: none;
  color: var(--muted);
}

.modal-cancel:hover { color: var(--ink); }

.modal-save {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
  font-weight: 550;
}

.modal-save:hover { background: var(--accent-deep); }

/* ---------- mobile : la topbar et les en-têtes de vue ne débordent plus,
   ils passent à la ligne au lieu de chevaucher le contenu en dessous. ---------- */
@media (max-width: 520px) {
  .topbar {
    flex-wrap: wrap;
    row-gap: 8px;
    padding: 10px 12px;
  }

  .presence-text p { white-space: normal; }

  .view-head {
    flex-wrap: wrap;
    row-gap: 8px;
    padding: 10px 12px;
  }

  .discord-search { flex: 1 1 100%; order: 3; }
  .discord-search input { flex: 1; width: auto; }

  .surprise-btn, .server-btn { font-size: 10.5px; padding: 4px 10px; }

  /* Ligne de commit (onglet Git) : sur desktop hash/sujet/méta tiennent sur
     une ligne. Sur mobile, le sujet se retrouve écrasé dans une colonne
     étroite pendant que la méta flotte à droite — on empile plutôt. */
  .git-row { flex-wrap: wrap; }
  .git-commit-meta { flex: 1 1 100%; padding-left: 26px; }

  /* Tout champ de saisie sous 16px déclenche un zoom automatique sur iOS
     Safari au focus (bug historique de WebKit, pas un choix de l'app) — on
     s'aligne sur 16px pile sur mobile pour l'éviter, ailleurs les tailles
     d'origine restent inchangées. */
  .composer textarea,
  .discord-search input,
  .modal input {
    font-size: 16px;
  }

  /* Bouton hamburger visible, sidebar fixe cachée par défaut. */
  .menu-btn { display: flex; }

  .sidebar-backdrop {
    position: fixed;
    inset: 0;
    z-index: 39;
    background: color-mix(in srgb, var(--ink) 40%, transparent);
  }

  /* Tiroir : la sidebar sort du flux normal, se pose par-dessus le contenu,
     et coulisse depuis la gauche. Les labels restent visibles (contrairement
     au rail d'icônes de la media query 680px) puisqu'elle ne partage plus
     la largeur avec le contenu — un tiroir peut se permettre d'être lisible. */
  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    width: 240px;
    max-width: 82vw;
    background: var(--bg);
    box-shadow: 8px 0 30px -12px color-mix(in srgb, var(--ink) 30%, transparent);
    transform: translateX(-100%);
    transition: transform .22s ease;
    padding-top: max(10px, env(safe-area-inset-top));
  }

  .sidebar.open { transform: translateX(0); }

  .sidebar .label { display: inline; } /* annule le rail-icônes de la media query 680px */
  .nav-item { justify-content: flex-start !important; padding: 7px 10px !important; gap: 10px !important; }
  .nav-section .txt { display: inline; }

  /* La modale réglages devient une feuille ancrée en bas plutôt qu'une carte
     flottante centrée — pattern mobile plus naturel, et évite qu'elle se
     retrouve écrasée en hauteur par le clavier virtuel. */
  .modal-overlay { align-items: flex-end; padding: 0; }
  .modal {
    max-width: none;
    width: 100%;
    border-radius: 20px 20px 0 0;
    padding: 18px 18px max(18px, env(safe-area-inset-bottom));
  }
}
