/* ==========================================================================
   WS-Frais — styles propres à cette appli.
   Rien ici ne redéfinit un token : tout vient de tokens.css / base.css /
   components.css (copiés depuis WS-Audit, voir docs/design-system.md).
   ========================================================================== */

/* Garde-fou : aucun débordement horizontal, quel que soit l'écran (règle du
   design system, §9 "Responsive" — testée à 560/375/320px). Un seul endroit
   qui pourrait déborder suffit à casser ça sur mobile ; ceinture et
   bretelles. */
html, body { overflow-x: hidden; max-width: 100%; }
body { padding-bottom: env(safe-area-inset-bottom); }

/* --- Topbar : simple barre, pas le shell sidebar+nav de WS-Audit --------- */
.ws-topbar-title {
  flex: 1;
  font-weight: var(--ws-weight-semi);
  /* Titre + badge + bouton logout sur une seule ligne, même sur un écran
     étroit (320px, iPhone SE) : le titre tronque avec "…" plutôt que de
     passer à la ligne et pousser le reste hors du cadre. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ws-topbar-right { display: flex; align-items: center; gap: var(--ws-3); flex: none; }

/* iOS zoome automatiquement la page quand un champ de moins de 16px reçoit
   le focus — comportement du navigateur, pas un bug appli, mais un vrai
   problème sur un formulaire pensé pour être rempli au doigt. Les tokens du
   design system
   (14px, --ws-text-body) restent corrects pour WS-Audit, pensé pour
   ordinateur/tablette (voir design-system.md §9) ; ici la cible est le
   téléphone en priorité, donc on relève juste nos propres champs. */
#form-saisie .ws-input,
#form-saisie .ws-select,
#form-saisie .ws-textarea,
.ws-auth-panel .ws-input {
  font-size: 16px;
}

/* La vraie cause du débordement du champ Date, pas juste un centrage
   cosmétique : un item de grille CSS a par défaut min-width:auto, qui se
   résout au contenu minimum de l'élément. Le <input type="date"> natif de
   Safari a un contenu minimum large (assez pour "12 août 2026" en toutes
   lettres) — même dans une colonne à 1fr, la grille refuse de le rétrécir
   en dessous de ça, et il déborde du conteneur. .ws-field-row--narrow passe
   bien à une seule colonne sous 720px (components.css), mais ça ne suffit
   pas : il faut aussi autoriser l'item à rétrécir. Montant (un simple
   <input type="number">) n'a pas ce problème, son contenu minimum est petit
   — c'est pour ça que seul le champ Date débordait. */
.ws-field-row > .ws-field { min-width: 0; }
/* iOS donne au <input type="date"> une largeur intrinsèque (basée sur son
   contenu natif) qu'il refuse de contraindre par `width:100%` seul — le champ
   déborde à droite. Réinitialiser l'apparence WebKit force le contrôle à se
   comporter comme une vraie boîte qui respecte la largeur de son conteneur. */
input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  max-width: 100%;
  min-width: 0;
}

/* --- Bandeau message de synchro (sous la topbar) ------------------------
   Rempli par app.js (afficherMsgSync). Trois tons repris des couleurs de
   statut du design system — le texte porte le sens, la couleur renforce
   (jamais la couleur seule, cf. design-system §8). */
.ws-sync-msg {
  margin: 0;
  padding: var(--ws-2) var(--ws-4);
  font-size: var(--ws-text-table);
  font-weight: var(--ws-weight-med);
  text-align: center;
}
.ws-sync-msg--ok      { background: var(--ws-ok-wash);     color: var(--ws-ok); }
.ws-sync-msg--erreur  { background: var(--ws-danger-wash); color: var(--ws-danger); }
.ws-sync-msg--neutre  { background: var(--ws-blue-wash);   color: var(--ws-blue-deep); }

/* Bouton sync icône : pendant l'envoi, on montre le spinner À LA PLACE de
   l'icône (sinon les deux se chevaucheraient dans un bouton icône étroit). */
#btn-sync[data-busy] svg { display: none; }

/* Indicateur réseau : PHP ne peut pas savoir si le téléphone a du réseau,
   le badge est donc vide au rendu serveur et rempli par app.js. Tant qu'il
   est vide, on le masque entièrement — sinon `.ws-badge` afficherait sa
   pastille toute seule, un point coloré sans texte à côté du titre. */
#net-status:empty { display: none; }

/* --- Contenu, mobile-first, plafonné en large pour rester lisible --------
   padding-bottom généreux : sert à la fois à dégager le bouton "+" flottant
   (liste.php) et à ce que le dernier élément d'un formulaire (le lien
   "Annuler", sur ajouter.php) ne finisse jamais collé sous la barre d'outils
   de Safari mobile — cette barre n'est PAS couverte par
   env(safe-area-inset-bottom) (elle ne couvre que l'encoche/le trait
   d'accueil), donc une marge fixe généreuse est la seule protection fiable. */
.ql-page {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--ws-4);
  padding-bottom: calc(var(--ws-12) + var(--ws-8) + env(safe-area-inset-bottom));
}

/* ==========================================================================
   Direction « Journal » — navigation basse, liste chronologique par jour.

   Le seul écart assumé au système WS-Audit, pensé pour l'ordinateur et la
   tablette : ici la navigation est EN BAS. QuickLog se remplit debout, à une
   main, et le pouce n'atteint pas le haut d'un téléphone moderne.

   Tout le reste (palette, échelle de 4 px, rayons ≤ 6 px, une seule ombre)
   reste celui du système : la modernité vient de la hiérarchie et de
   l'atteignabilité, pas de coins plus arrondis.
   ========================================================================== */

/* --- Contenu ------------------------------------------------------------
   Le padding bas dégage le bouton "+" flottant ET la barre d'outils de
   Safari mobile, qui n'est PAS couverte par env(safe-area-inset-bottom)
   (celui-ci ne couvre que l'encoche et le trait d'accueil). */
.ql-main {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--ws-4);
  padding-bottom: calc(88px + var(--ws-8) + env(safe-area-inset-bottom));
}

/* --- En-tête de journée -------------------------------------------------
   « Aujourd'hui · 6h30 · 45.90 CHF ». Collant : en faisant défiler une
   longue journée, on garde sous les yeux de quel jour il s'agit. */
.ql-jour-tete {
  position: sticky;
  top: 0;
  z-index: var(--ws-z-sticky);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ws-3);
  margin: 0;
  padding: var(--ws-3) var(--ws-1) var(--ws-2);
  background: var(--ws-bg);
  font-size: var(--ws-text-table);
}
.ql-jour-nom { font-weight: var(--ws-weight-semi); color: var(--ws-ink); }
.ql-jour-total { color: var(--ws-muted); white-space: nowrap; }

.ql-journee + .ql-journee { margin-top: var(--ws-2); }

/* --- Liste : filets, pas de cartes (règle du système) ------------------- */
.ql-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--ws-surface);
  border: var(--ws-border);
  border-radius: var(--ws-radius-box);
  overflow: hidden;
}
.ql-liste > li + li .ql-ligne { border-top: var(--ws-border); }

.ql-ligne {
  display: flex;
  align-items: center;
  gap: var(--ws-3);
  padding: var(--ws-3);
  min-height: var(--ws-touch-min);
  color: inherit;
  text-decoration: none;
  transition: background var(--ws-motion);
}
a.ql-ligne:hover { background: var(--ws-row-hover); }
a.ql-ligne:focus-visible { outline: var(--ws-focus); outline-offset: -2px; }

/* Marqueur de type : c'est lui qui distingue une heure d'un frais dans une
   liste mêlée. Forme + couleur, jamais la couleur seule (système §8). */
.ql-marque {
  flex: none;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: var(--ws-radius-field);
  background: var(--ws-blue-wash);
  color: var(--ws-blue);
}
.ql-marque--frais { background: var(--ws-warn-wash); color: var(--ws-warn); }

.ql-ligne-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
/* min-width:0 sur le parent + ellipsis ici : sans quoi un nom de client long
   pousse la valeur hors de l'écran au lieu d'être tronqué. */
.ql-ligne-client {
  font-weight: var(--ws-weight-med);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ql-ligne-detail {
  font-size: var(--ws-text-table);
  color: var(--ws-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ql-ligne-val { flex: none; font-weight: var(--ws-weight-semi); }

/* --- Bloc « En attente d'envoi » (rempli par app.js) -------------------- */
.ql-attente { margin-bottom: var(--ws-4); }
.ql-attente .ql-jour-nom { color: var(--ws-warn); }
.ql-attente .ql-liste { border-color: var(--ws-warn); }
.ql-attente-photo {
  width: 28px; height: 28px; flex: none;
  border-radius: var(--ws-radius-field);
  object-fit: cover;
  border: var(--ws-border);
}

/* --- Menu latéral ---------------------------------------------------------
   Réutilise .ws-nav (base.css) : déjà un drawer hors-écran sous 1024px,
   inutile de redessiner quoi que ce soit ici, seulement le déclencheur —
   voir topbar.php pour pourquoi body[data-nav] et pas .ws-shell[data-nav]. */
.ql-nav-overlay {
  display: none;
  position: fixed; inset: 0;
  z-index: calc(var(--ws-z-overlay) - 1);
  background: rgba(22, 33, 43, .45);
}
body[data-nav="open"] .ws-nav { transform: none; }
body[data-nav="open"] .ql-nav-overlay { display: block; }
/* .ws-nav vient de WS-Audit (desktop/tablette), positionné avec
   `top: var(--ws-topbar-h)` + `bottom: 0` — censé s'étirer entre les deux.
   En pratique, ça a laissé un vide en bas dans plusieurs navigateurs
   (`dvh - topbar-h` n'a pas suffi non plus, essayé avant). Plus robuste :
   `inset: 0` — le panneau prend TOUJOURS la vraie hauteur de l'écran, sans
   dépendre d'un calcul — et un padding-top pousse son contenu sous la
   topbar au lieu de faire dépendre la position du panneau d'une hauteur
   qui peut se désynchroniser. */
.ws-nav {
  top: 0;
  padding: 0;
  padding-bottom: env(safe-area-inset-bottom);
  /* Colonne : en-tête, liens, pied (nom + déconnexion) poussé tout en bas —
     pas de grand vide sous 2 liens. */
  display: flex;
  flex-direction: column;
}
.ws-nav ul { flex: 1; padding: var(--ws-3) var(--ws-2); }

.ql-nav-tete {
  display: flex; align-items: center; justify-content: space-between;
  min-height: var(--ws-topbar-h);
  padding: 0 var(--ws-2) 0 var(--ws-4);
  border-bottom: var(--ws-border);
}
.ql-nav-titre { font-weight: var(--ws-weight-semi); }

.ql-nav-pied {
  padding: var(--ws-3) var(--ws-2);
  border-top: var(--ws-border);
}
.ql-nav-nom {
  display: block;
  padding: 0 var(--ws-2);
  margin-bottom: var(--ws-1);
  font-size: var(--ws-text-meta);
  color: var(--ws-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ql-nav-logout {
  display: flex; align-items: center; gap: var(--ws-2);
  min-height: var(--ws-touch-min);
  padding: 0 var(--ws-2);
  border-radius: var(--ws-radius-field);
  color: var(--ws-ink);
  text-decoration: none;
  font-size: var(--ws-text-body);
  transition: background var(--ws-motion);
}
.ql-nav-logout:hover { background: var(--ws-row-hover); }
.ql-nav-logout svg { color: var(--ws-muted); flex: none; }

/* --- Bouton d'ajout flottant ----------------------------------------------
   Remplace l'ancienne barre à 2 boutons : la navigation Heures/Frais vit
   maintenant dans le menu latéral, il ne reste que l'ajout à porter en bas.
   Fixe en bas-droite : le pouce y arrive sans changer la prise du téléphone. */
.ql-fab-wrap {
  position: fixed;
  right: var(--ws-4);
  bottom: calc(var(--ws-4) + env(safe-area-inset-bottom));
  z-index: var(--ws-z-sticky);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--ws-2);
}
.ql-fab {
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border: none; /* sinon la bordure système du <button> reste visible */
  border-radius: 50%;
  background: var(--ws-blue);
  color: #fff;
  cursor: pointer;
  box-shadow: var(--ws-shadow-overlay);
  transition: background var(--ws-motion), transform var(--ws-motion);
}
.ql-fab:hover { background: var(--ws-blue-deep); }
.ql-fab:focus-visible { outline: var(--ws-focus); outline-offset: 2px; }
/* Le "+" devient un "×" à l'ouverture — retour visuel gratuit, sans texte
   ni deuxième icône à charger. */
.ql-fab-wrap[data-open="true"] .ql-fab { transform: rotate(45deg); }

/* Heures / Frais : masqués tant que le "+" n'est pas ouvert. display:none
   plutôt qu'opacité seule — sinon ils restent dans l'ordre de tabulation. */
.ql-fab-item {
  display: none;
  align-items: center;
  gap: var(--ws-2);
  height: 44px;
  padding: 0 var(--ws-4);
  border-radius: var(--ws-radius-field);
  background: var(--ws-surface);
  color: var(--ws-ink);
  border: var(--ws-border);
  box-shadow: var(--ws-shadow-overlay);
  text-decoration: none;
  font-size: var(--ws-text-body);
  font-weight: var(--ws-weight-med);
  white-space: nowrap;
}
.ql-fab-item svg { color: var(--ws-blue); flex: none; }
.ql-fab-wrap[data-open="true"] .ql-fab-item { display: flex; }

/* --- Raccourcis de durée -------------------------------------------------
   0h30 / 1h / 2h / 4h / 8h : la saisie courante se fait en un geste, sans
   ouvrir le clavier. `flex-wrap` parce que cinq boutons ne tiennent pas sur
   une ligne à 320 px. */
.ql-raccourcis {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ws-2);
  margin-bottom: var(--ws-2);
}
.ql-raccourcis .ws-btn { flex: 1 1 auto; min-width: 60px; }

/* --- Formulaire de saisie (heures ou frais) ------------------------------
   <form class="ws-panel"> sans .ws-panel-body (pas besoin d'un <div>
   supplémentaire juste pour porter le padding) : on le porte ici. Sans ça,
   les champs touchent le bord du panneau — l'effet "boîte dans la boîte". */
#form-saisie { padding: var(--ws-4); }

/* --- Page détail d'un frais (frais.php) ---------------------------------- */
.ws-detail {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--ws-2) var(--ws-4);
  margin: 0;
}
.ws-detail dt {
  color: var(--ws-muted);
  font-size: var(--ws-text-table);
  font-weight: var(--ws-weight-med);
}
.ws-detail dd { margin: 0; }
/* Sous 400px, label au-dessus de la valeur plutôt que côte à côte (sinon un
   commentaire long est écrasé dans une colonne étroite). */
@media (max-width: 400px) {
  .ws-detail { grid-template-columns: 1fr; gap: var(--ws-1); }
  .ws-detail dd { margin-bottom: var(--ws-3); }
}

.ws-detail-photo { margin-top: var(--ws-4); }
.ws-detail-photo .ws-label { display: block; margin-bottom: var(--ws-2); }
.ws-detail-photo img {
  width: 100%;
  border: var(--ws-border);
  border-radius: var(--ws-radius-field);
}

/* --- Notice d'installation (installer.php) -------------------------------
   Page publique, lue une seule fois, souvent sur un téléphone qu'on tient
   d'une main : plus d'air que le reste de l'appli, et des étapes numérotées
   assez espacées pour qu'on ne perde pas sa ligne en levant les yeux. */
.ql-notice { padding-top: var(--ws-6); }
.ql-notice .ws-title-page { margin-bottom: var(--ws-2); }
.ql-notice .ws-subtitle { color: var(--ws-muted); margin-bottom: var(--ws-6); }

.ql-notice-bloc { padding: var(--ws-4); margin-bottom: var(--ws-4); }
.ql-notice-bloc .ws-title-section {
  display: flex;
  align-items: center;
  gap: var(--ws-2);
  margin-bottom: var(--ws-3);
}
/* Une icône en tête de panneau marque la section : elle porte donc le bleu
   de marque, contrairement à une icône de label (design-system §7). */
.ql-notice-bloc .ws-title-section > svg { flex: none; color: var(--ws-blue); }

/* Les étapes gardent la numérotation native de <ol> : elle porte du sens
   (un ordre à suivre), inutile de la redessiner. */
.ql-etapes { margin: 0; padding-left: var(--ws-6); }
.ql-etapes li { margin-bottom: var(--ws-3); }
.ql-etapes li:last-child { margin-bottom: 0; }

.ql-liste-simple { margin: 0; padding-left: var(--ws-6); }
.ql-liste-simple li { margin-bottom: var(--ws-2); }
.ql-liste-simple li:last-child { margin-bottom: 0; }

/* Précision secondaire : présente pour qui la cherche, jamais concurrente
   de l'étape elle-même. */
.ql-note {
  display: block;
  margin-top: var(--ws-1);
  font-size: var(--ws-text-meta);
  color: var(--ws-muted);
}

.ql-notice-bloc p { margin-bottom: var(--ws-2); }
.ql-notice-bloc p:last-child { margin-bottom: 0; }
.ql-notice-pied { margin-top: var(--ws-6); }
.ql-notice-pied .ws-btn { width: 100%; }

/* --- Connexion : panneau centré, pas de shell --------------------------- */
.ws-auth {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ws-4);
}
.ws-auth-panel {
  width: 100%;
  max-width: 360px;
  padding: var(--ws-6);
}

/* --- Champ photo : 2 boutons (caméra / galerie) + aperçu -----------------
   Remplace le <input type="file"> natif (rendu "bouton système" moche,
   pensé pour un clavier/souris — voir components.css .ws-file, gardé pour
   d'autres projets mais pas utilisé ici). Les vrais <input type="file">
   existent toujours dans le DOM (accessibilité, fonctionnement de base
   garanti même si JS échoue à charger) mais restent cachés (`hidden`) —
   voir app.js pour le déclenchement au clic. */
.ws-photo-boutons {
  display: flex;
  gap: var(--ws-2);
}
.ws-photo-boutons .ws-btn {
  flex: 1;
  white-space: normal; /* "Prendre une photo" peut passer sur 2 lignes sur un très petit écran plutôt que déborder */
}

.ws-photo-apercu {
  display: flex;
  align-items: center;
  gap: var(--ws-3);
  margin-top: var(--ws-3);
  padding: var(--ws-2);
  border: var(--ws-border);
  border-radius: var(--ws-radius-field);
}
.ws-photo-apercu img {
  width: 64px; height: 64px;
  object-fit: cover;
  border-radius: var(--ws-radius-field);
  flex: none;
}
.ws-photo-apercu .ws-btn { margin-left: auto; }

/* --- Petit téléphone (iPhone SE et pareils, ~320-380px) ------------------
   La topbar (24px de marge de chaque côté par défaut, cf. base.css) est
   pensée pour un shell desktop/tablette. Resserrée ici pour laisser de la
   place au badge réseau + bouton déconnexion sans que le titre s'écrase. */
@media (max-width: 380px) {
  .ws-topbar { padding: 0 var(--ws-4); gap: var(--ws-2); }
  .ql-page { padding: var(--ws-3); padding-bottom: calc(var(--ws-12) + var(--ws-8) + env(safe-area-inset-bottom)); }
}
