/* =============================================================================
   KILOLA - feuille de style partagee par les quatre surfaces
   (landing, app/, bureau/, partenaire/).

   DEUX COULEURS SEULEMENT : Aubergine et Mangue. Plus noir et blanc.
   Les nuances sont des OPACITES de ces quatre couleurs, jamais une cinquieme teinte.

   AUCUNE BORDURE nulle part. On separe par l'espace et des fonds teintes.
   Un box-shadow qui dessine un trait compte comme une bordure : interdit.

   Reference visuelle : docs/cahier-des-charges/kilola-design.html
   ============================================================================= */

/* ---------------------------------------------------------------------------
   1. Tokens
   --------------------------------------------------------------------------- */
:root{
  /* Les deux couleurs */
  --aub:#2E1437;           /* Aubergine : structure, confiance, texte d'action */
  --man:#FFB400;           /* Mangue : energie, couronnes, direct, moments forts */
  --noir:#000;
  --blanc:#fff;

  /* Opacites d'aubergine */
  --aub-04:rgba(46,20,55,.04);
  --aub-08:rgba(46,20,55,.08);
  --aub-14:rgba(46,20,55,.14);
  --aub-40:rgba(46,20,55,.4);
  --aub-70:rgba(46,20,55,.7);

  /* Opacites de mangue. Jamais de texte mangue sur blanc : 1,8:1 seulement. */
  --man-20:rgba(255,180,0,.2);
  --man-40:rgba(255,180,0,.4);

  /* Opacites de noir */
  --n-05:rgba(0,0,0,.05);
  --n-10:rgba(0,0,0,.1);
  --n-40:rgba(0,0,0,.42);
  --n-60:rgba(0,0,0,.62);

  /* Espacements, base 4 */
  --e1:4px; --e2:8px; --e3:12px; --e4:16px; --e5:20px;
  --e6:24px; --e7:32px; --e8:40px; --e9:48px; --e10:64px;

  /* Rayons */
  --r-tag:6px; --r-chip:9px; --r-btn:12px; --r-media:14px; --r-sheet:22px;

  /* Ombres : aucune par defaut. Deux niveaux seulement. */
  --omb1:0 1px 2px rgba(0,0,0,.06);
  --omb2:0 8px 24px rgba(0,0,0,.12);

  /* Motion */
  --courbe:cubic-bezier(.2,.8,.2,1);
  --t-btn:120ms; --t-nav:200ms; --t-sheet:280ms; --t-vote:420ms;

  /* Z-index */
  --z-collant:10; --z-nav:20; --z-menu:30; --z-sheet:40; --z-modale:50; --z-toast:60;

  --f:'Instrument Sans',system-ui,-apple-system,'Segoe UI',Roboto,Arial,sans-serif;

  /* Variables de surface : redefinies par .ombre pour le Mode Ombre. */
  --fg:var(--noir);
  --mut:var(--n-60);
  --tint:var(--aub-08);
  --bg:var(--blanc);
}

/* Mode Ombre : la MEME application, fond aubergine, texte blanc.
   Memes composants, meme grille. On change d'ambiance, pas d'application. */
.ombre{
  --fg:#fff;
  --mut:rgba(255,255,255,.64);
  --tint:rgba(255,255,255,.08);
  --bg:var(--aub);
}

/* ---------------------------------------------------------------------------
   2. Remise a zero
   --------------------------------------------------------------------------- */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:var(--f);
  font-size:14.5px;
  line-height:1.45;
  color:var(--fg);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  padding-top:env(safe-area-inset-top,0);
}
button,input,textarea,select{font:inherit;color:inherit}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}

/* AUCUNE BORDURE. C'est la regle, pas une preference. */
button,input,textarea,select,table,td,th,img,fieldset{border:0}

:focus-visible{outline:3px solid var(--man);outline-offset:2px}

@media (prefers-reduced-motion:reduce){
  *{transition:none !important;animation:none !important}
  html{scroll-behavior:auto}
}

/* ---------------------------------------------------------------------------
   3. Icones bicolores
   Le trait suit `color`, le remplissage suit `--d`.
   --------------------------------------------------------------------------- */
i.ph-duotone{
  --d:var(--man);
  color:var(--aub);
  font-style:normal;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;
  width:1em;height:1em;flex:none;vertical-align:-.14em;
}
i.ph-duotone svg{display:block;width:100%;height:100%;fill:currentColor;overflow:visible}
.ombre i.ph-duotone,.inv i.ph-duotone{color:#fff}
/* Etat inactif : trait noir 62 %, remplissage noir 10 %. */
.mute i.ph-duotone,i.ph-duotone.mute{color:var(--n-60);--d:var(--n-10)}

/* ---------------------------------------------------------------------------
   4. Typographie
   Instrument Sans, une seule famille, deux largeurs.
   Etroite (78 %) = voix de la marque. Normale = tout le reste.
   Casse de phrase, jamais de capitales.
   --------------------------------------------------------------------------- */
.d   {font-stretch:78%;font-weight:700;font-size:40px;line-height:.98;letter-spacing:-.015em}
.h1  {font-size:26px;line-height:1.15;font-weight:700;letter-spacing:-.01em}
.h2  {font-size:21px;line-height:1.2;font-weight:650}
.h3  {font-size:17px;line-height:1.3;font-weight:650}
.h4  {font-size:15px;line-height:1.3;font-weight:650}
.bl  {font-size:16px;line-height:1.5}
.bs  {font-size:13px;line-height:1.4}
.cap {font-size:12px;line-height:1.35;color:var(--mut)}
.lab {font-size:12.5px;font-weight:600;color:var(--mut)}
.mutc{color:var(--mut)}
.num {font-variant-numeric:tabular-nums}

/* L'identifiant KILOLA : 13 caracteres, etroit, tabulaire, interlettrage 6 %. */
.kid{font-variant-numeric:tabular-nums;letter-spacing:.06em;font-weight:700;font-stretch:84%}

/* Le wordmark. Le point est mangue, toujours. */
.wm{font-stretch:76%;font-weight:700;letter-spacing:-.01em;color:var(--aub)}
.wm b{display:inline-block;width:.26em;height:.26em;border-radius:50%;background:var(--man);margin-left:.05em}
.ombre .wm,.inv .wm{color:#fff}

/* Echelle responsive : Display et H1 grandissent, le corps ne bouge pas. */
@media(min-width:840px){ .d{font-size:48px} .h1{font-size:31px} }
@media(min-width:1024px){ .d{font-size:54px} .h1{font-size:35px} }

/* ---------------------------------------------------------------------------
   5. Boutons
   Une seule action principale par ecran : un seul bouton plein.
   --------------------------------------------------------------------------- */
.btn{
  height:50px;min-height:44px;border-radius:var(--r-btn);padding:0 18px;
  font-weight:650;font-size:15px;
  display:flex;align-items:center;justify-content:center;gap:var(--e2);
  width:100%;cursor:pointer;background:none;
  transition:transform var(--t-btn) var(--courbe),opacity var(--t-btn) var(--courbe);
}
.btn:active{transform:scale(.98)}
.btn i{font-size:20px}
.btn.p{background:var(--aub);color:#fff}
.btn.p i.ph-duotone{color:#fff}
.ombre .btn.p{background:#fff;color:var(--aub)}
.ombre .btn.p i.ph-duotone{color:var(--aub)}
.btn.m{background:var(--man);color:var(--aub)}   /* vote, couronne : usage rare */
.btn.m i.ph-duotone{color:var(--aub);--d:#fff}
.btn.g{background:var(--tint);color:var(--fg)}
.btn.o{background:transparent;color:var(--fg);
       text-decoration:underline;text-decoration-color:var(--man);
       text-decoration-thickness:2px;text-underline-offset:4px}
.btn.t{background:transparent;color:var(--fg);height:44px}
.btn.x{background:var(--n-05);color:var(--n-40);cursor:not-allowed}
.btn.sm{height:36px;font-size:13.5px;width:auto;padding:0 14px;border-radius:var(--r-chip)}
.btn.sm i{font-size:17px}

/* Chips : filtres, categories. Zone tactile 34 px, cible reelle elargie par le padding. */
.chips{display:flex;gap:var(--e2);overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
.chips::-webkit-scrollbar{display:none}
.chip{
  height:34px;padding:0 13px;border-radius:var(--r-chip);
  font-size:13px;font-weight:550;
  display:inline-flex;align-items:center;gap:6px;
  white-space:nowrap;flex:none;background:var(--tint);cursor:pointer;
}
.chip i{font-size:17px}
.chip.on{background:var(--aub);color:#fff}
.chip.on i.ph-duotone{color:#fff}
.ombre .chip.on{background:#fff;color:var(--aub)}
.ombre .chip.on i.ph-duotone{color:var(--aub)}

/* ---------------------------------------------------------------------------
   6. Champs
   Erreur : fond mangue 20 %, icone et texte aubergine. Jamais de rouge.
   --------------------------------------------------------------------------- */
.in{display:flex;flex-direction:column;gap:6px}
.in label{font-size:13px;font-weight:600}
.in .f{
  height:50px;border-radius:var(--r-btn);background:var(--tint);
  display:flex;align-items:center;gap:10px;padding:0 14px;font-size:15px;
}
.in .f input,.in .f select{flex:1;background:none;min-width:0;height:100%}
.in .f i{font-size:20px}
.in.focus .f{background:var(--man-20)}
.in.err .f{background:var(--man-20)}
.in .h{font-size:12.5px;color:var(--mut);display:flex;gap:6px;align-items:center}
.in.err .h,.in.ok .h{color:var(--aub);font-weight:600}
.ta{border-radius:var(--r-btn);background:var(--tint);padding:14px;font-size:15px;min-height:120px;width:100%}

/* Cases OTP : 6 cases, chiffres larges. */
.otp{display:flex;gap:var(--e2)}
.otp span{flex:1;height:56px;border-radius:var(--r-btn);background:var(--tint);
          display:grid;place-items:center;font-size:22px;font-weight:700}
.otp span.on{background:var(--man-20)}

/* Bascules, cases, radios : jamais de bordure, le fond fait la forme. */
.tog{width:44px;height:26px;border-radius:13px;background:var(--n-10);position:relative;flex:none;
     transition:background var(--t-btn) var(--courbe);cursor:pointer}
.tog::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
            background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.2);transition:left var(--t-btn) var(--courbe)}
.tog.on{background:var(--aub)}
.tog.on::after{left:21px}

.radio,.check{width:22px;height:22px;flex:none;background:var(--tint);position:relative;cursor:pointer}
.radio{border-radius:50%}
.check{border-radius:var(--r-tag);display:grid;place-items:center}
.radio.on{background:var(--aub)}
.radio.on::after{content:"";position:absolute;inset:7px;border-radius:50%;background:#fff}
.check.on{background:var(--aub)}
.check.on::after{content:"";width:12px;height:9px;background:#fff;
                 clip-path:polygon(0 52%,14% 38%,38% 62%,86% 0,100% 14%,38% 100%)}

/* ---------------------------------------------------------------------------
   7. Listes - LES LISTES AVANT LES CARTES
   Le feed, les classements, les notifications et les tableaux sont des listes
   separees par l'espace et un fond alterne. Un conteneur arrondi n'existe que
   s'il regroupe reellement quelque chose.
   --------------------------------------------------------------------------- */
.row{display:flex;gap:var(--e3);align-items:center;padding:11px var(--e5);min-height:44px}
.row .tx{flex:1;min-width:0}
.row .t{font-weight:600;font-size:14.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .s{font-size:12.5px;color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .ri{font-size:22px}
.row .k{font-size:20px;font-weight:700;width:26px;text-align:center;font-stretch:80%}
.liste .row:nth-child(even){background:var(--aub-04)}

.sh{display:flex;justify-content:space-between;align-items:baseline;padding:var(--e5) var(--e5) var(--e2)}
.sh h3{font-size:17px;font-weight:650}
.sh a{font-size:13px;font-weight:600;color:var(--aub);cursor:pointer}
.ombre .sh a{color:var(--man)}

/* ---------------------------------------------------------------------------
   8. Identite : avatars et sigles
   L'ECOLE SE RECONNAIT PAR SON SIGLE, PAS PAR SA COULEUR.
   Monogramme typographique sur fond aubergine. Les couleurs des ecoles
   n'entrent jamais dans l'interface.
   --------------------------------------------------------------------------- */
.av{border-radius:50%;background:var(--tint);color:var(--aub);
    display:flex;align-items:center;justify-content:center;font-weight:700;flex:none;position:relative}
.ombre .av{color:#fff}
.av.m{background:var(--aub);color:#fff}
.av.sh{background:var(--aub);color:var(--man)}       /* avatar d'ombre */
.ombre .av.sh{background:rgba(255,255,255,.1)}
.av.r::after{content:"";position:absolute;right:-1px;bottom:-1px;
             width:30%;height:30%;min-width:10px;min-height:10px;border-radius:50%;background:var(--man)}
.av i.ph-duotone{font-size:1.45em;width:1em;height:1em}

.sig{border-radius:10px;background:var(--aub);color:#fff;
     display:grid;place-items:center;font-stretch:80%;font-weight:700;flex:none;letter-spacing:.01em}
.sig.l{background:var(--tint);color:var(--aub)}

/* Pastille de certification. Icone ET texte : jamais la couleur seule. */
.cert{display:inline-flex;gap:4px;align-items:center;font-size:12px;font-weight:600;color:var(--aub)}
.cert i{font-size:16px}
.ombre .cert{color:#fff}

/* ---------------------------------------------------------------------------
   9. Conteneurs
   --------------------------------------------------------------------------- */
.box{border-radius:var(--r-media);background:var(--tint)}
.band{background:var(--man);color:var(--aub);border-radius:var(--r-media)}
.band i.ph-duotone{color:var(--aub);--d:#fff}
.aubbox{background:var(--aub);color:#fff;border-radius:16px}
.aubbox i.ph-duotone{color:#fff}
.aubbox .cap,.aubbox .mutc{color:rgba(255,255,255,.66)}

.media{border-radius:var(--r-media);background:var(--aub-08);
       display:grid;place-items:center;color:var(--aub-40);font-size:40px;overflow:hidden;position:relative}
.media i.ph-duotone{color:var(--aub-40);--d:var(--aub-14)}
.media .tag{position:absolute;left:10px;top:10px;font-size:11.5px;font-weight:650;
            background:var(--aub);color:#fff;border-radius:var(--r-tag);padding:3px 8px}
.media .tag.m{background:var(--man);color:var(--aub)}

/* ---------------------------------------------------------------------------
   10. Etats - SANS TROISIEME COULEUR
   Pas de vert pour le succes ni de rouge pour l'erreur. L'etat est porte par
   une ICONE et un TEXTE ; la couleur ne fait que renforcer.
   --------------------------------------------------------------------------- */
.etat{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;
      padding:4px 10px;border-radius:var(--r-tag)}
.etat i{font-size:15px}
.etat.succes{background:var(--aub-08);color:var(--aub)}
.etat.erreur{background:var(--man-20);color:var(--aub)}
.etat.alerte{background:var(--man);color:var(--aub)}
.etat.info{background:var(--aub-08);color:var(--aub)}
.etat.off{background:var(--n-05);color:var(--n-40)}

/* Pastille d'etat dans une liste. Toujours accompagnee d'un texte. */
.st{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;white-space:nowrap}
.st s{width:8px;height:8px;border-radius:50%;background:var(--aub);display:inline-block;text-decoration:none}
.st s.m{background:var(--man)}
.st s.g{background:var(--n-10)}
.st s.o{background:var(--tint)}

/* Barre de progression. Le remplissage est mangue : c'est un moment fort. */
.bar{height:6px;background:var(--tint);border-radius:3px;overflow:hidden}
.bar span{display:block;height:100%;background:var(--man);border-radius:3px;
          transition:width var(--t-nav) var(--courbe)}
.bar.a span{background:var(--aub)}
.ombre .bar.a span{background:#fff}

/* Etapes d'un parcours (inscription, certification). */
.steps{display:flex;gap:5px}
.steps span{flex:1;height:4px;border-radius:2px;background:var(--tint)}
.steps span.on{background:var(--aub)}

/* Squelettes de chargement. AFFICHES APRES 300 ms SEULEMENT, jamais avant. */
.sk{background:var(--aub-08);border-radius:var(--r-tag);animation:kil-pulse 1.4s ease-in-out infinite}
@keyframes kil-pulse{0%,100%{opacity:1}50%{opacity:.5}}

/* Verrou 18 plus. Icone ET texte. */
.lock{display:inline-flex;gap:6px;align-items:center;font-size:12px;font-weight:650;
      background:var(--man);color:var(--aub);padding:3px 8px;border-radius:var(--r-tag)}
.lock i.ph-duotone{color:var(--aub);--d:#fff}

/* ---------------------------------------------------------------------------
   11. Surcouches : sheet, modale, toast
   Seuls endroits ou une ombre est autorisee (niveau 2).
   --------------------------------------------------------------------------- */
.ov{position:fixed;inset:0;background:rgba(0,0,0,.44);z-index:var(--z-modale)}
.sheet{position:fixed;left:0;right:0;bottom:0;background:var(--bg);
       border-radius:var(--r-sheet) var(--r-sheet) 0 0;
       padding:10px var(--e5) calc(30px + env(safe-area-inset-bottom,0));
       box-shadow:var(--omb2);z-index:var(--z-sheet);
       animation:kil-monte var(--t-sheet) var(--courbe)}
@keyframes kil-monte{from{transform:translateY(100%)}to{transform:none}}
.grab{width:40px;height:5px;border-radius:3px;background:var(--n-10);margin:0 auto var(--e4)}

.modale{position:fixed;left:var(--e4);right:var(--e4);top:50%;transform:translateY(-50%);
        max-width:420px;margin:0 auto;background:var(--bg);border-radius:18px;
        padding:var(--e6);box-shadow:var(--omb2);z-index:calc(var(--z-modale) + 1)}
.modale h3{font-size:19px;font-weight:700;margin-bottom:var(--e2)}
.modale p{color:var(--mut);margin-bottom:var(--e5)}
.modale .actions{display:flex;flex-direction:column;gap:var(--e2)}

.toast{position:fixed;left:var(--e4);right:var(--e4);
       bottom:calc(92px + env(safe-area-inset-bottom,0));
       background:var(--aub);color:#fff;border-radius:var(--r-btn);padding:12px 14px;
       display:flex;gap:10px;align-items:center;font-size:13.5px;font-weight:550;
       box-shadow:var(--omb2);z-index:var(--z-toast)}
.toast i.ph-duotone{color:#fff}

/* ---------------------------------------------------------------------------
   12. App etudiante : coquille
   --------------------------------------------------------------------------- */
.ab{display:flex;align-items:center;gap:6px;height:54px;flex:none;padding:0 10px;
    position:sticky;top:env(safe-area-inset-top,0);background:var(--bg);z-index:var(--z-collant)}
.ab h1{font-size:17px;font-weight:650;flex:1;padding-left:6px;
       white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ib{width:44px;height:44px;display:grid;place-items:center;border-radius:var(--r-btn);
    font-size:23px;position:relative;flex:none;cursor:pointer}
.ib .dot{position:absolute;top:9px;right:9px;width:9px;height:9px;border-radius:50%;background:var(--man)}

/* Barre du bas : 76 px dont 16 px de zone gestuelle.
   Sans le safe-area, le dernier onglet passe sous la barre de geste de l'iPhone. */
.nav{
  height:76px;flex:none;display:grid;grid-template-columns:repeat(5,1fr);
  padding-bottom:calc(16px + env(safe-area-inset-bottom,0));
  background:var(--tint);position:sticky;bottom:0;z-index:var(--z-nav);
}
.nav a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
       font-size:11px;font-weight:500;color:var(--mut)}
.nav a i{font-size:25px}
.nav a:not(.on) i.ph-duotone{color:var(--n-60);--d:var(--n-10)}
.nav a.on{color:var(--aub);font-weight:650}
.nav a.on i.ph-duotone{color:var(--aub);--d:var(--man)}
.ombre .nav a:not(.on) i.ph-duotone{color:rgba(255,255,255,.6);--d:rgba(255,255,255,.12)}
.ombre .nav a.on{color:#fff}
.ombre .nav a.on i.ph-duotone{color:#fff;--d:var(--man)}

.pad{padding-left:var(--e5);padding-right:var(--e5)}
.fill{flex:1}

/* Onglets en segments. */
.tabs{display:flex;gap:4px;padding:4px;margin:0 var(--e4);border-radius:var(--r-btn);
      background:var(--tint);flex:none;overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs span{padding:8px 12px;font-size:14px;font-weight:500;color:var(--mut);
           white-space:nowrap;border-radius:var(--r-chip);cursor:pointer}
.tabs span.on{color:var(--fg);font-weight:650;background:var(--bg)}

/* ---------------------------------------------------------------------------
   13. La carte KILOLA
   Le seul objet spectaculaire de toute l'application.
   --------------------------------------------------------------------------- */
.card-k{background:var(--aub);color:#fff;border-radius:var(--r-sheet);
        padding:22px;position:relative;overflow:hidden}
.card-k .top{display:flex;justify-content:space-between;align-items:flex-start}
.card-k .wm{font-size:24px;color:#fff}
.card-k .id{font-size:30px;color:var(--man);margin-top:18px}
.card-k .strip{position:absolute;left:0;top:0;bottom:0;width:6px;background:var(--man)}

.qrw{background:#fff;border-radius:16px;padding:14px;display:inline-block;box-shadow:var(--omb1)}
.ombre .qrw{box-shadow:none}

/* ---------------------------------------------------------------------------
   14. Bureau et Partenaire : coquille dense
   Le Partenaire est un Bureau restreint a un perimetre : meme layout.
   --------------------------------------------------------------------------- */
.dk{display:grid;grid-template-columns:244px 1fr;min-height:100vh;background:#fff;font-size:13.5px}
.side{background:var(--aub);color:#fff;padding:18px 12px;display:flex;flex-direction:column;gap:1px;
      overflow:auto;position:sticky;top:0;height:100vh}
.side .lg{font-stretch:76%;font-weight:700;font-size:25px;padding:2px 10px 4px;color:#fff}
.side .lg b{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--man);margin-left:2px}
/* Le bloc de contexte dit EN PERMANENCE de quel etablissement on parle.
   C'est ce qui evite qu'un representant publie pour la mauvaise ecole. */
.side .ctx{margin:10px 4px 8px;padding:10px;border-radius:10px;background:rgba(255,255,255,.08);
           display:flex;gap:10px;align-items:center}
.side .ctx .sig{width:34px;height:34px;background:var(--man);color:var(--aub);font-size:13px}
.side .ctx b{display:block;font-size:13px}
.side .ctx span{font-size:11.5px;color:rgba(255,255,255,.62)}
.side .gp{font-size:11.5px;font-weight:600;color:rgba(255,255,255,.5);padding:12px 10px 4px}
.side a{display:flex;align-items:center;gap:10px;height:34px;padding:0 10px;border-radius:8px;
        font-size:13.5px;color:rgba(255,255,255,.8)}
.side a i{font-size:19px}
.side a i.ph-duotone{color:#fff}
.side a.on{background:rgba(255,255,255,.12);color:#fff;font-weight:600}
.side a em{margin-left:auto;font-style:normal;font-size:11px;font-weight:700;
           background:var(--man);color:var(--aub);border-radius:5px;padding:1px 6px}
.side .usr{margin-top:auto;display:flex;gap:10px;align-items:center;padding:10px}
.side .usr .av{width:32px;height:32px;background:rgba(255,255,255,.14);color:#fff;font-size:12px}

.mn{display:flex;flex-direction:column;min-width:0}
.bt{height:62px;flex:none;display:flex;align-items:center;gap:var(--e3);padding:0 28px;background:var(--aub-04)}
.bt h1{font-size:19px;font-weight:700;flex:1}
.bt .crumb{font-size:12px;color:var(--n-60);font-weight:500;display:block}
.srch{height:38px;border-radius:10px;background:var(--aub-08);display:flex;align-items:center;gap:8px;
      padding:0 12px;color:var(--n-40);width:260px;font-size:13px}
.bb{padding:22px 28px;flex:1;display:flex;flex-direction:column;gap:18px}

.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.kpis > div{background:var(--aub-04);border-radius:var(--r-btn);padding:16px 18px}
.kpis .l{font-size:12.5px;color:var(--n-60);font-weight:550}
.kpis .v{font-size:27px;font-weight:700;font-stretch:84%;font-variant-numeric:tabular-nums;
         line-height:1.1;margin-top:4px}
.kpis .d{font-size:12px;font-weight:600;color:var(--aub);margin-top:4px;
         display:flex;align-items:center;gap:4px}

table.t{width:100%;border-collapse:collapse;font-size:13px}
table.t th{font-size:12px;color:var(--n-60);font-weight:600;text-align:left;padding:9px 12px;
           white-space:nowrap;background:var(--aub-08)}
table.t th:first-child{border-radius:8px 0 0 8px}
table.t th:last-child{border-radius:0 8px 8px 0}
table.t td{padding:10px 12px;vertical-align:middle}
table.t tbody tr:nth-child(even) td{background:var(--aub-04)}
table.t tr.sel td{background:var(--aub-08)}

.pane{background:var(--aub-04);border-radius:var(--r-media);padding:16px 18px;min-width:0}
.pane h4{font-size:14px;font-weight:650;margin-bottom:var(--e3);
         display:flex;justify-content:space-between;align-items:center}
.hr{display:flex;gap:18px}
.hr > *{flex:1;min-width:0}

/* Graphiques sobres et bicolores : aubergine, et UNE seule barre mangue. */
.bars{display:flex;align-items:flex-end;gap:8px;height:150px;padding-top:8px}
.bars div{flex:1;background:var(--aub-14);border-radius:4px 4px 0 0;position:relative}
.bars div.on{background:var(--aub)}
.bars div.m{background:var(--man)}
.bars div span{position:absolute;bottom:-20px;left:0;right:0;text-align:center;
               font-size:11px;color:var(--n-60)}

/* Matrice de permissions (BS03). */
.perm td:not(:first-child){text-align:center}
.perm .c{display:inline-block;width:18px;height:18px;border-radius:5px;
         vertical-align:middle;background:var(--n-10)}
.perm .c.on{background:var(--aub)}
.perm .c.pa{background:var(--man)}

@media(max-width:1023px){
  .dk{grid-template-columns:1fr}
  .side{position:fixed;left:0;top:0;width:244px;transform:translateX(-100%);
        transition:transform var(--t-nav) var(--courbe);z-index:var(--z-menu)}
  .side.ouvert{transform:none}
  .bb{padding:18px var(--e4)}
  .kpis{grid-template-columns:repeat(2,1fr)}
}

/* ---------------------------------------------------------------------------
   15. Desktop de l'app (W01)
   Contrairement a OUIDAYS, on ne renvoie pas l'ordinateur vers une page QR :
   la vie de campus se consulte aussi depuis la salle informatique.
   --------------------------------------------------------------------------- */
@media(min-width:1024px){
  .app-shell{display:grid;grid-template-columns:248px minmax(0,600px) 1fr;
             gap:var(--e7);max-width:1400px;margin:0 auto}
  .app-shell .nav{display:none}
  .app-shell .lat{display:flex}
}
.app-shell .lat{display:none;flex-direction:column;position:sticky;top:0;height:100vh;padding:var(--e5)}
@media(min-width:1440px){ .app-shell .aside{display:block} }
.app-shell .aside{display:none}

/* ---------------------------------------------------------------------------
   16. Utilitaires de mise en page
   --------------------------------------------------------------------------- */
.col{display:flex;flex-direction:column}
.lig{display:flex;align-items:center}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:var(--e3)}
.g3{display:grid;grid-template-columns:repeat(3,1fr);gap:3px}
.sep{flex:1}
.sp-1{height:var(--e1)} .sp-2{height:var(--e2)} .sp-3{height:var(--e3)}
.sp-4{height:var(--e4)} .sp-5{height:var(--e5)} .sp-6{height:var(--e6)}
.sp-7{height:var(--e7)} .sp-8{height:var(--e8)}
[hidden]{display:none !important}

/* Bandeau hors ligne. */
.offbar{position:fixed;left:0;right:0;bottom:0;z-index:var(--z-toast);
        background:var(--aub);color:#fff;padding:10px var(--e4);
        padding-bottom:calc(10px + env(safe-area-inset-bottom,0));
        display:flex;gap:10px;align-items:center;font-size:13px;font-weight:550}
.offbar i.ph-duotone{color:#fff}

/* ---------------------------------------------------------------------------
   17. Carte des campus (E08) - assets/kilola-map.js
   Tuiles OpenStreetMap en <img>. Une epingle est aubergine ; elle passe en
   mangue SEULEMENT si le point est en direct.
   --------------------------------------------------------------------------- */
.kmap{position:relative;overflow:hidden;background:var(--aub-04);touch-action:none;
      border-radius:var(--r-media);cursor:grab}
.kmap.kmap-drag{cursor:grabbing}
.kmap-monde{position:absolute;inset:0;will-change:transform}
.kmap-tuile{position:absolute;width:256px;height:256px;user-select:none;pointer-events:none;
            filter:saturate(.35) contrast(.95)}
.kmap-pin{position:absolute;transform:translate(-50%,-100%);
          width:38px;height:38px;border-radius:50% 50% 50% 4px;rotate:-45deg;
          background:var(--aub);display:grid;place-items:center;cursor:pointer;padding:0;
          box-shadow:var(--omb1)}
.kmap-pin > *{rotate:45deg}
.kmap-pin i.ph-duotone{color:#fff;--d:var(--man);font-size:19px}
.kmap-pin .sg{color:#fff;font-stretch:78%;font-weight:700;font-size:10px;letter-spacing:.01em}
.kmap-pin .n{color:var(--aub);font-weight:700;font-size:14px;font-variant-numeric:tabular-nums}
.kmap-pin.groupe{background:var(--man);border-radius:50%}
.kmap-pin.groupe > *{rotate:0deg}
.kmap-pin.groupe{rotate:0deg}
.kmap-pin.direct{background:var(--man)}
.kmap-pin.direct i.ph-duotone{color:var(--aub);--d:#fff}
.kmap-pin:focus-visible{outline:3px solid var(--man);outline-offset:3px}
.kmap-ctrl{position:absolute;right:10px;top:10px;display:flex;flex-direction:column;gap:6px}
.kmap-ctrl button{width:36px;height:36px;border-radius:10px;background:var(--blanc);
                  color:var(--aub);font-size:18px;font-weight:700;display:grid;place-items:center;
                  cursor:pointer;box-shadow:var(--omb1)}
.kmap-ctrl button i.ph-duotone{font-size:17px}
.kmap-att{position:absolute;left:8px;bottom:6px;font-size:10.5px;color:var(--n-60);
          background:rgba(255,255,255,.78);padding:2px 6px;border-radius:4px}

/* ---------------------------------------------------------------------------
   18. Pile de cartes a glisser (O07) - assets/kilola-swipe.js
   Le voile « passer » est aubergine, le voile « choisir » est mangue : la
   mangue ne sort que sur le geste positif, qui est le moment fort.
   --------------------------------------------------------------------------- */
.kswipe{position:relative;width:100%;max-width:360px;margin:0 auto;
        height:520px;touch-action:pan-y;outline:none}
.kswipe-carte{position:absolute;inset:0;border-radius:var(--r-sheet);overflow:hidden;
              background:var(--aub);color:#fff;display:flex;flex-direction:column;
              transform-origin:50% 100%;will-change:transform;box-shadow:var(--omb2);
              user-select:none;-webkit-user-select:none}
.kswipe-media{flex:1;display:grid;place-items:center;background:var(--aub);
              font-size:90px;overflow:hidden}
.kswipe-media img{width:100%;height:100%;object-fit:cover}
.kswipe-media i.ph-duotone{color:rgba(255,255,255,.35);--d:rgba(255,255,255,.12)}
.kswipe-info{padding:var(--e5);background:linear-gradient(transparent,rgba(46,20,55,.92) 38%);
             margin-top:-72px;position:relative}
.kswipe-info .cap{color:rgba(255,255,255,.66)}
.kswipe-voile{position:absolute;inset:0;z-index:2;opacity:0;pointer-events:none;
              display:flex;flex-direction:column;align-items:center;justify-content:center;
              gap:var(--e3);font-size:19px;font-weight:700;transition:opacity 120ms linear}
.kswipe-voile i.ph-duotone{font-size:64px}
.kswipe-voile.non{background:rgba(46,20,55,.82);color:#fff}
.kswipe-voile.non i.ph-duotone{color:#fff;--d:rgba(255,255,255,.3)}
.kswipe-voile.oui{background:rgba(255,180,0,.88);color:var(--aub)}
.kswipe-voile.oui i.ph-duotone{color:var(--aub);--d:#fff}
.kswipe-actions{position:absolute;left:0;right:0;bottom:-74px;z-index:5;
                display:flex;justify-content:center;gap:var(--e6)}
.kswipe-btn{width:60px;height:60px;border-radius:50%;display:grid;place-items:center;
            cursor:pointer;box-shadow:var(--omb1)}
.kswipe-btn i.ph-duotone{font-size:28px}
.kswipe-btn.non{background:var(--tint)}
.kswipe-btn.non i.ph-duotone{color:var(--aub);--d:var(--n-10)}
.kswipe-btn.oui{background:var(--man)}
.kswipe-btn.oui i.ph-duotone{color:var(--aub);--d:#fff}
.kswipe-fin{position:absolute;inset:0;display:flex;flex-direction:column;
            align-items:center;justify-content:center;gap:var(--e2);text-align:center;
            padding:var(--e6);background:var(--tint);border-radius:var(--r-sheet)}

/* ---------------------------------------------------------------------------
   19. Combobox filtrable - assets/kilola-select.js
   AUCUN <select> natif visible dans KILOLA.
   --------------------------------------------------------------------------- */
.ksel{position:relative}
.ksel-champ{height:50px;min-height:44px;border-radius:var(--r-btn);background:var(--tint);
            display:flex;align-items:center;gap:10px;padding:0 14px;font-size:15px;
            cursor:pointer;width:100%;text-align:left}
.ksel-champ .val{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ksel-champ .val.vide{color:var(--n-40)}
.ksel.ouvert .ksel-champ{background:var(--man-20)}
.ksel-liste{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:var(--z-menu);
            background:var(--bg);border-radius:var(--r-btn);box-shadow:var(--omb2);
            max-height:280px;overflow:auto;padding:6px}
.ksel-rech{width:100%;height:42px;border-radius:var(--r-chip);background:var(--tint);
           padding:0 12px;margin-bottom:6px;font-size:14px}
.ksel-opt{padding:11px 12px;border-radius:var(--r-chip);cursor:pointer;font-size:14.5px;
          display:flex;align-items:center;gap:10px;min-height:44px}
.ksel-opt:hover,.ksel-opt.actif{background:var(--tint)}
.ksel-opt.choisi{font-weight:650}
.ksel-vide{padding:14px 12px;color:var(--mut);font-size:13.5px}
