/* =====================================================================
   PARTYFINDER — la feuille de style commune
   ---------------------------------------------------------------------
   Noir et blanc, une seule touche de couleur : le rose de la marque. Il ne
   sert qu'à trois choses — ce sur quoi on va appuyer, le montant à payer,
   l'endroit où on se trouve. Partout ailleurs, du blanc sur du noir.

   ÉCRIT POUR LE WEBVIEW D'USINE DES NEXGO (Android 8, Chromium 58-61).
   C'est la contrainte qui décide de la syntaxe, pas le goût :
     · `gap` n'existe pas en flex → marges, ou grille avec `grid-gap` ;
     · pas de `clamp()`, `min()`, `max()`, `aspect-ratio`, `inset`, `:is()` ;
     · `env(safe-area-inset-*)` seulement en bonus, jamais pour tenir la mise
       en page (un iPhone en profite, le N86 s'en passe).
   Le premier écran cible fait 360 × 720 : tout tient dedans SANS ascenseur.
   ===================================================================== */

@font-face {
  font-family: 'Manrope';
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/manrope-latin.woff2') format('woff2');
}

:root {
  --pf-bg: #08080A;
  --pf-bg2: #0D0D11;
  --pf-card: #141419;
  --pf-card2: #1B1B22;
  --pf-line: rgba(255, 255, 255, .09);
  --pf-line2: rgba(255, 255, 255, .18);
  --pf-txt: #FFFFFF;
  --pf-dim: #8C8C97;
  --pf-dim2: #5C5C66;
  --pf-accent: #FF2D6F;      /* le rose Partyfinder — la seule couleur */
  --pf-accent-sombre: #C81E54;
  --pf-ok: #2FD07B;
  --pf-ko: #FF4B4B;
  --pf-r: 18px;              /* le rayon de la maison */
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  background: var(--pf-bg);
  color: var(--pf-txt);
  font-family: 'Manrope', 'Roboto', 'Segoe UI', system-ui, sans-serif;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* Sur un terminal, la sélection de texte ne sert à rien et gêne : un appui
   maintenu sur un chiffre surlignait le clavier au lieu d'encaisser.
   Les champs de saisie, eux, restent sélectionnables (voir plus bas). */
body.pf-tactile { user-select: none; -webkit-user-select: none; }
body.pf-tactile input, body.pf-tactile textarea { user-select: text; -webkit-user-select: text; }

h1, h2, h3, h4 { margin: 0; font-weight: 800; letter-spacing: -.02em; }
p { margin: 0; }
button { font: inherit; color: inherit; }

/* Les chiffres qui se lisent en colonne : même largeur, jamais de sautillement
   quand un total passe de 9 à 10. */
.pf-num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ---------------------------------------------------------------------
   LA MARQUE
   Le disque noir et son triangle blanc, dessinés en SVG dans la page :
   net à toutes les tailles, et pas une requête de plus au démarrage.
   --------------------------------------------------------------------- */
.pf-mark { display: block; }
.pf-word {
  font-weight: 800; letter-spacing: -.045em; line-height: 1;
}

/* ---------------------------------------------------------------------
   LES BOUTONS
   --------------------------------------------------------------------- */
.pf-btn {
  display: block; width: 100%;
  border: 0; border-radius: 14px;
  padding: 15px 18px;
  background: var(--pf-card2);
  color: var(--pf-txt);
  font-weight: 700; font-size: 16px;
  text-align: center; text-decoration: none;
  cursor: pointer;
  /* Voir « LA RÉPONSE AU DOIGT » en bas de ce fichier : l'appui ne fait pas
     rétrécir, il éclaire — et il éclaire tout de suite. */
  transition: background .18s ease, opacity .15s ease;
}
.pf-btn:active { transition: none; background: #22222A; }
.pf-btn[disabled] { opacity: .4; cursor: default; }
.pf-btn.plein { background: var(--pf-accent); color: #fff; }
.pf-btn.plein:active { transition: none; background: var(--pf-accent-sombre); }
.pf-btn.blanc { background: #fff; color: #000; }
.pf-btn.blanc:active { transition: none; background: #D9D9DE; }
.pf-btn.contour { background: transparent; border: 1px solid var(--pf-line2); }
.pf-btn.contour:active { transition: none; background: rgba(255, 255, 255, .09); }
.pf-btn.fantome { background: transparent; color: var(--pf-dim); font-weight: 600; }
.pf-btn.fantome:active { transition: none; background: rgba(255, 255, 255, .07); }
.pf-btn.danger { background: transparent; border: 1px solid rgba(255, 75, 75, .35); color: var(--pf-ko); }
.pf-btn.danger:active { transition: none; background: rgba(255, 75, 75, .14); }
.pf-btn.petit { padding: 10px 14px; font-size: 14px; border-radius: 11px; }

/* ---------------------------------------------------------------------
   LES CHAMPS
   Taille de police 16 px minimum : en dessous, Android zoome tout seul à la
   mise au point et l'écran part de travers.
   --------------------------------------------------------------------- */
.pf-champ { display: block; margin-bottom: 14px; }
.pf-champ > span {
  display: block; margin-bottom: 6px;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--pf-dim);
}
.pf-champ input, .pf-champ select, .pf-champ textarea {
  display: block; width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--pf-line2); border-radius: 12px;
  background: var(--pf-bg2); color: var(--pf-txt);
  font: inherit; font-size: 16px;
  -webkit-appearance: none; appearance: none;
  /* Sans ça, un champ de date garde sa largeur naturelle (près de 200 px)
     et pousse sa colonne de grille au-delà de l'écran. */
  min-width: 0;
}
.pf-champ input:focus, .pf-champ select:focus, .pf-champ textarea:focus {
  outline: 0; border-color: var(--pf-accent);
}
.pf-champ select {
  /* La flèche : dessinée, pas une image à charger. */
  background-image: linear-gradient(45deg, transparent 50%, var(--pf-dim) 50%),
                    linear-gradient(135deg, var(--pf-dim) 50%, transparent 50%);
  background-position: calc(100% - 19px) 22px, calc(100% - 14px) 22px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 36px;
}
/* DEUX CHAMPS CÔTE À CÔTE — SANS DÉBORDER (corrigé le 26/08/2026, relevé
   sur un écran de 360 px).
   `1fr` vaut `minmax(auto, 1fr)` : la colonne ne peut PAS devenir plus
   étroite que le contenu minimum de son champ. Or un `datetime-local`
   réclame près de 200 px à lui seul — deux d'entre eux forçaient donc la
   boîte à 468 px sur un écran qui en fait 360, et le formulaire partait
   hors de l'écran, vers la droite.
   Deux remèdes, l'un pour l'autre : `minmax(0, 1fr)` autorise la colonne à
   rétrécir, et sous 460 px les deux champs passent l'un sous l'autre —
   parce qu'une date écrasée sur 150 px ne se lit plus. */
.pf-deux {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-gap: 0 12px;
}
/* Le seuil est 620 px et non 460 : entre les deux, deux champs de date se
   partagent 200 px chacun et leur contenu (« 28/08/2026 19:00 » plus l'icône
   du calendrier) se fait rogner À L'INTÉRIEUR du champ. Un texte coupé n'est
   pas un gain de place. */
@media (max-width: 620px) { .pf-deux { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------
   LES MESSAGES
   --------------------------------------------------------------------- */
.pf-erreur {
  margin-bottom: 14px; padding: 11px 14px;
  border-radius: 12px;
  background: rgba(255, 75, 75, .12);
  border: 1px solid rgba(255, 75, 75, .3);
  color: #FFB3B3; font-size: 14px; font-weight: 600;
}
.pf-info {
  padding: 11px 14px; border-radius: 12px;
  background: var(--pf-card); border: 1px solid var(--pf-line);
  color: var(--pf-dim); font-size: 14px;
}
.pf-vide { padding: 34px 16px; text-align: center; color: var(--pf-dim2); font-size: 14px; }

/* ---------------------------------------------------------------------
   LE VOILE (attente de paiement, boîtes de dialogue)
   --------------------------------------------------------------------- */
/* UN POPUP EST CENTRÉ, TOUJOURS (remarque de Jonathan, 26/08/2026).
   Deux précautions, parce que « centré » et « lisible » se disputent dès que
   la boîte devient plus haute que l'écran :
     · `margin: auto` sur la boîte EN PLUS de `align-items: center` — quand
       elle déborde, un enfant centré par `align-items` se fait rogner PAR LE
       HAUT et devient impossible à remonter ; avec `margin: auto`, le
       débordement se répartit et le voile peut le faire défiler ;
     · `overflow-y: auto` sur le voile, pour que ce défilement existe.
   Résultat : centré quand ça tient, entièrement atteignable quand ça ne
   tient pas — sur un terminal de 720 pixels comme sur un grand écran. */
/* Tant qu'un popup est ouvert, la page derrière ne défile plus (voir
   `figer()` dans pf.js) : un seul ascenseur à l'écran, jamais deux. */
html.pf-fige, html.pf-fige body { overflow: hidden; }

.pf-voile {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  z-index: 800;
  background: rgba(4, 4, 6, .82);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.pf-boite {
  width: 100%; max-width: 380px;
  margin: auto;
  padding: 24px 22px;
  border-radius: var(--pf-r);
  background: var(--pf-card);
  border: 1px solid var(--pf-line);
  text-align: center;
}
.pf-boite h3 { font-size: 19px; margin-bottom: 8px; }
.pf-boite p { color: var(--pf-dim); font-size: 14px; line-height: 1.5; }
.pf-boite .pf-btn { margin-top: 16px; }

/* =====================================================================
   SUR UN PETIT ÉCRAN, UN POPUP PREND TOUT (demande de Jonathan,
   26/08/2026 : « lorsque je suis sur smartphone ou terminal de paiement,
   les popups doivent être full screen »)
   ---------------------------------------------------------------------
   À 360 pixels, une carte flottante au milieu d'un voile, c'est trois
   marges perdues de chaque côté et un texte qui se replie en accordéon —
   pour rien, puisqu'il n'y a rien derrière qu'on ait besoin de voir.
   L'écran entier devient donc la boîte : plus de bord, plus de coin
   arrondi, et le contenu centré verticalement dans toute la hauteur.

   LE SEUIL EST 900 px — le MÊME que celui du back-office (barre d'onglets
   en bas / colonne de navigation à gauche). Une seule frontière entre « le
   mode téléphone » et « le mode ordinateur » : deux seuils différents
   donnaient un back-office en mode mobile avec des popups en mode bureau.

   Et une seconde condition, `max-height: 620px`, pour le téléphone COUCHÉ :
   800 × 360 passe le test de largeur mais n'a plus aucune hauteur — une
   carte flottante y est illisible.

   Pas d'`env(safe-area-inset-*)` dans le `padding` : le WebView d'Android 8
   ne connaît pas `env()`, et une déclaration invalide fait tomber TOUT le
   `padding` — la boîte se collerait aux bords sur le N86. Une marge basse
   fixe est plus sûre que la bonne marge qui n'arrive jamais.
   ===================================================================== */
@media (max-width: 900px), (max-height: 620px) {
  .pf-voile { padding: 0; align-items: stretch; }
  .pf-boite {
    width: 100%; max-width: none; margin: 0;
    min-height: 100%;
    /* Plein écran veut dire plein écran : rien ne dépasse sur le côté. */
    overflow-x: hidden;
    border: 0; border-radius: 0;
    padding: 26px 20px 30px;
    background: var(--pf-bg);
    display: flex; flex-direction: column; justify-content: center;
  }
  .pf-boite h3 { font-size: 22px; }
  /* Un formulaire, lui, commence en HAUT : centré, ses premiers champs
     sortiraient de l'écran dès que le clavier virtuel monte. */
  .bo-modale .pf-boite { justify-content: flex-start; max-height: none; }
  /* Une liste a maintenant tout l'écran : autant s'en servir. */
  .pf-liste { max-height: 62vh; }
}

/* LES TROIS ÉCRANS QUI COMPTENT VRAIMENT (26/08/2026) :
     Nexgo N86   360 × 720
     Nexgo N96   360 × 640
     téléphone   360 × 800 (ou 390 × 844)
   Le plus dur est le N96 : 640 pixels de haut, et le pavé du code doit y
   tenir ENTIER, sans un geste de défilement — on tape un code à quatre
   chiffres d'une main, on ne fait pas glisser l'écran d'abord.
   On resserre donc le rythme vertical au lieu de laisser déborder. */
@media (max-width: 900px) and (max-height: 680px) {
  .pf-boite { padding: 18px 18px 22px; }
  .pf-boite h3 { font-size: 19px; margin-bottom: 6px; }
  .pf-boite p { font-size: 13px; line-height: 1.45; }
  .pf-boite .pf-btn { margin-top: 11px; }
  .pf-points { margin: 4px 0 12px; }
  .pf-liste { max-height: 54vh; }
}

/* Le rond qui tourne — trois traits de CSS, aucune image. */
.pf-tourne {
  width: 34px; height: 34px; margin: 0 auto 16px;
  border: 3px solid var(--pf-line2);
  border-top-color: var(--pf-accent);
  border-radius: 50%;
  animation: pf-rot 900ms linear infinite;
}
@keyframes pf-rot { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------
   LE BANDEAU HORS LIGNE
   Il ne bloque RIEN : la vente part dans la file d'attente du terminal et
   remonte toute seule. Le bandeau dit seulement combien attendent.
   --------------------------------------------------------------------- */
.pf-hors {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  padding: 9px 14px;
  background: #3A2A00; color: #FFD98A;
  font-size: 13px; font-weight: 700; text-align: center;
  border-top: 1px solid rgba(255, 217, 138, .25);
}

/* =====================================================================
   L'ÉCRAN DE CONNEXION
   ===================================================================== */
.pf-login {
  min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 28px 22px;
  /* La seule fantaisie de toute l'application : une lueur rose très basse,
     derrière le logo. Sur un écran de terminal, elle sépare l'écran de
     connexion du noir de l'appareil éteint. */
  background:
    radial-gradient(120% 55% at 50% 0%, rgba(255, 45, 111, .17) 0%, rgba(255, 45, 111, 0) 62%),
    var(--pf-bg);
}
.pf-login-boite { width: 100%; max-width: 340px; }
.pf-login .pf-mark { margin: 0 auto 18px; }
.pf-login h1 { font-size: 27px; text-align: center; margin-bottom: 4px; }
.pf-login .sous { text-align: center; color: var(--pf-dim); font-size: 14px; margin-bottom: 26px; }
.pf-login form { margin-bottom: 18px; }
.pf-login .pf-btn.plein { margin-top: 6px; }
.pf-pied { text-align: center; color: var(--pf-dim2); font-size: 12px; }

/* =====================================================================
   LE CLAVIER À CHIFFRES — partout le même
   ---------------------------------------------------------------------
   Trois colonnes, des touches carrées et hautes. `grid-gap` (et non `gap`)
   parce que le WebView d'Android 8 ne connaît que ce nom-là.
   ===================================================================== */
.pf-clavier { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 10px; }
.pf-touche {
  display: flex; align-items: center; justify-content: center;
  height: 66px;
  border: 1px solid var(--pf-line); border-radius: 16px;
  background: var(--pf-card);
  font-size: 28px; font-weight: 700;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}
.pf-touche:active { transition: none; background: #26262F; border-color: var(--pf-line2); }
.pf-touche.choisie { background: var(--pf-accent); border-color: var(--pf-accent); color: #fff; }
.pf-touche.plus { font-size: 24px; color: var(--pf-accent); font-weight: 800; }
.pf-touche.action { font-size: 15px; font-weight: 700; color: var(--pf-dim); }

@media (min-height: 760px) { .pf-touche { height: 74px; } }
@media (max-height: 640px) { .pf-touche { height: 56px; font-size: 25px; } .pf-clavier { grid-gap: 8px; } }

/* =====================================================================
   LES TABLEAUX (back-office)
   Ils débordent DANS leur boîte, jamais la page : sur 360 pixels on fait
   glisser le tableau, on ne déplace pas l'écran entier.
   ===================================================================== */
.pf-table-boite { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.pf-table { width: 100%; border-collapse: collapse; font-size: 14px; }
table.pf-table th, table.pf-table td {
  padding: 11px 12px; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--pf-line);
}
table.pf-table th {
  font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--pf-dim2);
}
table.pf-table td.droite, table.pf-table th.droite { text-align: right; }
table.pf-table tr:last-child td { border-bottom: 0; }

/* =====================================================================
   UN TABLEAU DE HUIT COLONNES SUR 360 PIXELS N'EST PLUS UN TABLEAU
   ---------------------------------------------------------------------
   (26/08/2026 : « fait le tour de CHAQUE page … optimisé pour la taille
   d'un N86 ».)

   Le journal des ventes fait 8 colonnes, l'équipe en fait 5. Sur un
   terminal, ça tenait grâce à un ascenseur horizontal — c'est-à-dire qu'il
   fallait TIRER le tableau de côté pour lire la recette d'un employé. Une
   main sur le terminal, une file devant : personne ne fait ça.

   Sous 620 px, chaque LIGNE devient donc une petite fiche : le premier
   champ en titre, les autres en « libellé … valeur » sur une ligne
   chacun. Le libellé vient de `data-l` par `content: attr()` — le HTML est
   le même pour les deux mises en page, il n'y a rien à maintenir en
   double, et un simple redimensionnement rebascule.

   `attr()` dans `content` et `display: block` sur des éléments de tableau :
   les deux existent depuis toujours, WebView d'Android 8 compris.
   ===================================================================== */
@media (max-width: 620px) {
  .pf-table-boite { overflow-x: visible; }
  table.pf-table, table.pf-table tbody, table.pf-table tr, table.pf-table td { display: block; width: 100%; }
  table.pf-table thead { display: none; }

  table.pf-table tr {
    padding: 12px 16px;
    border-bottom: 1px solid var(--pf-line);
  }
  table.pf-table tr:last-child { border-bottom: 0; }

  table.pf-table td {
    display: flex; align-items: baseline;
    padding: 2px 0; border: 0;
    white-space: normal; text-align: right;
  }
  /* Le libellé, à gauche, en petit : c'est l'en-tête de colonne qui vient
     se coucher à côté de sa valeur. `margin-right: auto` plutôt que
     `justify-content: space-between` — space-between écarterait AUSSI deux
     morceaux de valeur l'un de l'autre, alors qu'ils doivent se lire
     ensemble (« Carte (hors appareil) »). */
  table.pf-table td::before {
    content: attr(data-l);
    flex: 0 0 auto; margin-right: auto; padding-right: 16px;
    font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--pf-dim2);
    text-align: left;
  }
  /* La première cellule est le TITRE de la fiche : pas de libellé, elle se
     lit seule (un nom d'employé, une heure de vente, un nom de soirée). */
  table.pf-table td.titre {
    display: block; text-align: left;
    font-size: 15px; font-weight: 700; margin-bottom: 6px;
  }
  table.pf-table td.titre::before { content: none; }
  table.pf-table td:empty { display: none; }
}

/* Les pastilles d'état — une couleur, un mot. */
.pf-pastille {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.pf-pastille.ouverte { background: rgba(47, 208, 123, .16); color: var(--pf-ok); }
.pf-pastille.prevue { background: rgba(255, 255, 255, .09); color: var(--pf-dim); }
.pf-pastille.fermee { background: rgba(255, 255, 255, .05); color: var(--pf-dim2); }
.pf-pastille.paye { background: rgba(47, 208, 123, .16); color: var(--pf-ok); }
.pf-pastille.refuse { background: rgba(255, 75, 75, .16); color: var(--pf-ko); }
.pf-pastille.annule { background: rgba(255, 255, 255, .07); color: var(--pf-dim); }
.pf-pastille.rose { background: rgba(255, 45, 111, .16); color: var(--pf-accent); }

/* =====================================================================
   LA RÉPONSE AU DOIGT (remarque de Jonathan, 26/08/2026 : « ça rétrécit un
   peu puis remet normal et change de page »)
   ---------------------------------------------------------------------
   Une touche qui RÉTRÉCIT à l'appui puis reprend sa taille pendant que
   l'écran change, ça fait deux mouvements pour un seul geste — et le
   second, on ne l'a pas demandé. Sur un bouton qui change de page, c'est
   pire : l'animation de retour se joue par-dessus le nouvel écran.

   Donc AUCUN `transform` à l'appui, nulle part. La réponse est un
   ÉCLAIRCISSEMENT, et elle obéit à deux règles :

     · à l'appui, `transition: none` — la couleur change à l'instant même
       où le doigt touche, sans les 80 millisecondes qui donnaient
       l'impression d'un appareil lent ;
     · au relâchement, la transition normale reprend et la couleur
       redescend en douceur — mais elle ne déplace rien, donc si l'écran a
       changé entre-temps, personne ne la voit.

   Une couleur qui s'allume ne bouge pas la mise en page : c'est la seule
   forme de retour tactile qui ne peut pas entrer en concurrence avec une
   navigation.
   ===================================================================== */
