:root {
  --bg:#0f1216; --panel:#171b21; --panel2:#1d232b; --line:#272f3a;
  --txt:#e6eaf0; --muted:#8a95a5; --accent:#5aa6ff;
  --ok:#3fb86b; --okbg:rgba(63,184,107,.14);
  --bad:#e5564b; --badbg:rgba(229,86,75,.14);
  --warn:#e0a93b; --warnbg:rgba(224,169,59,.14);
}
* { box-sizing:border-box; }
body { margin:0; background:var(--bg); color:var(--txt);
  font:15px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; }
a { color:var(--accent); text-decoration:none; }

.topbar { display:flex; align-items:center; justify-content:space-between;
  padding:14px 22px; background:var(--panel); border-bottom:1px solid var(--line); }
.brand { font-weight:700; letter-spacing:.5px; display:inline-flex; align-items:center; gap:8px; }
.brand img { display:block;
  filter:drop-shadow(0 0 3px rgba(226,238,255,.7)) drop-shadow(0 0 7px rgba(120,175,255,.5)); }
.brand span { opacity:.9; }
.topbar nav { display:flex; align-items:center; gap:10px; }
.navlink { color:var(--muted); padding:6px 10px; border-radius:8px; font-size:14px; }
.navlink:hover { background:var(--panel2); color:var(--txt); }
.navlink.on { color:var(--txt); background:var(--panel2); }
.navmenu { position:relative; }
.navmenu > summary { list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:5px; }
.navmenu > summary::-webkit-details-marker { display:none; }
.navmenu > summary::after { content:"▾"; font-size:10px; opacity:.6; transition:transform .15s; }
.navmenu[open] > summary::after { transform:rotate(180deg); }
.navmenu[open] > summary { color:var(--txt); background:var(--panel2); }
.navmenu-panel { position:absolute; top:calc(100% + 8px); left:0; z-index:50;
  display:flex; flex-direction:column; gap:2px; min-width:170px; padding:6px;
  background:var(--panel); border:1px solid var(--line); border-radius:10px;
  box-shadow:0 10px 30px rgba(0,0,0,.45); }
.navmenu-panel .navlink { display:block; }
.who { color:var(--muted); font-size:13px; margin-left:6px; }
.btn-ghost { border:1px solid var(--line); padding:6px 12px; border-radius:8px; color:var(--txt);
    background:transparent; font:inherit; cursor:pointer; }
.btn-ghost:hover { background:var(--panel2); }
.logout-form { display:contents; }

.wrap { max-width:1080px; margin:0 auto; padding:26px 22px 60px; position:relative; z-index:1; }
.topbar { position:relative; z-index:2; }

/* Nav responsive : inline sur desktop (toujours dans le flux), repliée derrière
   une bascule ☰ (case à cocher CSS, sans JS) sur mobile. */
.nav-cb { display:none; }
.navburger { display:none; cursor:pointer; user-select:none; font-size:20px; line-height:1;
  color:var(--txt); padding:5px 11px; border:1px solid var(--line); border-radius:8px; }

/* Menu compte (e-mail ↗) : Sécurité + Déconnexion. Aligné à droite sur desktop. */
.usermenu .navmenu-panel { left:auto; right:0; }
.usermenu > summary .who-name { display:inline-block; max-width:200px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom; }
.logout-link { width:100%; text-align:left; background:none; border:none;
  font-family:inherit; font-size:14px; color:var(--muted); cursor:pointer; }
.logout-link:hover { background:var(--panel2); color:var(--txt); }

@media (max-width:720px) {
  .navburger { display:inline-block; }
  .topbar nav { position:absolute; top:100%; left:0; right:0; z-index:40;
    flex-direction:column; align-items:stretch; gap:2px; display:none;
    padding:8px; background:var(--panel); border-bottom:1px solid var(--line);
    box-shadow:0 12px 30px rgba(0,0,0,.45); max-height:82vh; overflow-y:auto; }
  .nav-cb:checked ~ nav { display:flex; }
  .topbar nav .navlink { display:block; padding:11px 12px; font-size:15px; }
  /* Sous-menus (Administration / Alcôve) : dépliés en place, pas en flottant. */
  .navmenu { position:static; }
  .navmenu-panel { position:static; box-shadow:none; border:none; min-width:0;
    padding:2px 0 6px 14px; background:transparent; }
  /* Menu compte : e-mail complet + entrées dépliées en place dans le ☰. */
  .usermenu > summary .who-name { max-width:none; }
}
.foot { text-align:center; color:var(--muted); font-size:12px; padding:24px; }

.section { margin-bottom:38px; }
.section-head { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.section-head.sub { margin-top:26px; }
h2 { font-size:20px; margin:0 0 6px; }
h3 { font-size:15px; margin:22px 0 8px; color:var(--txt); }
.muted { color:var(--muted); }
.tiny { font-size:11px; color:var(--muted); }
.center { text-align:center; }
.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; }
.nowrap { white-space:nowrap; }

.ranges, .chip { display:inline-flex; gap:6px; }
.chip { padding:5px 12px; border:1px solid var(--line); border-radius:20px;
  color:var(--muted); font-size:13px; }
.chip.on { background:var(--accent); border-color:var(--accent); color:#06101f; font-weight:600; }

.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:12px; margin:16px 0 8px; }
.card { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:16px; }
.card .k { font-size:28px; font-weight:700; }
.card .l { color:var(--muted); font-size:13px; margin-top:2px; }
.card.ok .k { color:var(--ok); }
.card.bad .k { color:var(--bad); }

.tbl { width:100%; border-collapse:collapse; margin:10px 0 4px; background:var(--panel);
  border:1px solid var(--line); border-radius:12px; overflow:hidden; }
.tbl th, .tbl td { text-align:left; padding:9px 12px; border-bottom:1px solid var(--line); vertical-align:top; }
.tbl th { background:var(--panel2); color:var(--muted); font-weight:600; font-size:12px;
  text-transform:uppercase; letter-spacing:.4px; }
.tbl tr:last-child td { border-bottom:none; }
.tbl .msg { color:var(--muted); font-size:13px; max-width:320px; }
.row-alert { background:rgba(229,86,75,.05); }

.badge { display:inline-block; padding:2px 9px; border-radius:20px; font-size:12px; font-weight:600; }
.badge.ok { background:var(--okbg); color:var(--ok); }
.badge.bad { background:var(--badbg); color:var(--bad); }
.badge.warn { background:var(--warnbg); color:var(--warn); }
.badge.muted { background:var(--panel2); color:var(--muted); }
.tag { display:inline-block; padding:1px 8px; border:1px solid var(--line); border-radius:6px;
  font-size:12px; color:var(--muted); }

.alert { background:var(--badbg); border:1px solid var(--bad); color:#ffd9d5;
  padding:10px 14px; border-radius:10px; margin:12px 0; font-size:14px; }
.alert.soft { background:var(--warnbg); border-color:var(--warn); color:#f1dcae; }
.notice { background:var(--panel2); border:1px solid var(--line); color:var(--muted);
  padding:10px 14px; border-radius:10px; margin:12px 0; font-size:14px; }

.logs { margin:8px 0 4px; }
.logs summary { cursor:pointer; color:var(--muted); font-size:13px; padding:6px 0; }
.logs pre { background:#0b0e12; border:1px solid var(--line); border-radius:10px;
  padding:12px; overflow:auto; font-size:12px; max-height:320px; }

/* Hub / page d'accueil */
/* Filigrane : la porte du logo (Portes de la Moria) intégrée au fond de
   l'accueil. Élément fixe, décoratif (aria-hidden), derrière le contenu. */
.hub-door { position:fixed; z-index:0; pointer-events:none;
  right:max(-70px, -6vw); top:50%; transform:translateY(-50%);
  width:min(52vw, 560px); aspect-ratio:314/338; opacity:.16;
  /* Luminescence « clair de lune » : halos froids autour des traits. */
  filter:drop-shadow(0 0 2px rgba(226,238,255,.8))
         drop-shadow(0 0 12px rgba(150,192,255,.5))
         drop-shadow(0 0 30px rgba(96,150,255,.32)); }
/* Les traits sont « peints » par masquage : la couleur n'apparaît que sur le
   tracé de la porte. ::before = lueur douce constante ; ::after = bande de
   lumière qui balaie le tracé (le trait s'illumine au passage). */
.hub-door::before, .hub-door::after {
  content:""; position:absolute; inset:0;
  -webkit-mask:url(/assets/hub-door.png) center/contain no-repeat;
          mask:url(/assets/hub-door.png) center/contain no-repeat; }
.hub-door::before { background:rgba(220,234,255,.45); }
.hub-door::after {
  background:linear-gradient(115deg, transparent 40%,
    rgba(233,242,255,.95) 50%, transparent 60%);
  background-size:200% 200%;
  animation:door-sweep 12s ease-in-out infinite alternate; }
/* Course resserrée et symétrique : la bande est centrée sur l'arche au milieu
   du cycle. Va-et-vient doux (alternate) : la lumière remonte puis redescend
   le tracé sans saut de retour. */
@keyframes door-sweep {
  from { background-position:88% 88%; }
  to   { background-position:12% 12%; }
}
@media (prefers-reduced-motion:reduce) { .hub-door::after { animation:none; opacity:0; } }
@media (max-width:720px) {
  .hub-door { right:50%; transform:translate(50%, -50%); width:min(120vw, 560px); opacity:.10; }
  .hub-door::after { animation:none; opacity:0; }
}

.hub-hero { margin:6px 0 34px; }
.hub-date { text-transform:uppercase; letter-spacing:.6px; font-size:12px; color:var(--muted); margin:0 0 8px; }
.hub-hero h1 { font-size:30px; line-height:1.15; margin:0; font-weight:750; letter-spacing:-.5px; }
.hub-hero h1 .accent { color:var(--accent); }
.hub-hero .sub { color:var(--muted); margin:8px 0 0; font-size:15px; }

.hub-group { margin-bottom:34px; }
.hub-group > h2 { font-size:12px; text-transform:uppercase; letter-spacing:.7px; color:var(--muted);
  font-weight:700; margin:0 0 14px; }

.tiles { display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:14px; }
.tiles.tiles-sm { grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); }

.tile { position:relative; background:var(--panel); border:1px solid var(--line); border-radius:14px;
  padding:18px; transition:border-color .15s ease, transform .15s ease, background .15s ease; }
.tile:hover { border-color:var(--accent); transform:translateY(-2px); background:var(--panel2); }
.tile-ico { display:block; font-size:26px; line-height:1; }
.tile-ico-img { display:block; width:44px; height:44px; border-radius:11px; object-fit:cover;
  box-shadow:0 2px 8px rgba(0,0,0,.35); }
.tile h3 { margin:12px 0 3px; font-size:16px; color:var(--txt); }
.tile p { margin:0; color:var(--muted); font-size:13px; }
.tile .ext { position:absolute; top:15px; right:16px; color:var(--muted); font-size:14px; z-index:1; }

/* Tuile entièrement cliquable (projets / outils) */
a.tile-link { color:inherit; display:block; }
a.tile-link:hover { color:inherit; }

/* Tuile app : lien principal étiré + pied cliquable au-dessus */
.tile-main { display:block; color:inherit; }
.tile-main:hover { color:inherit; }
.tile-main::after { content:""; position:absolute; inset:0; border-radius:14px; }
.tile-foot { position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between;
  margin-top:14px; padding-top:13px; border-top:1px solid var(--line); }
.tile-foot a { font-size:13px; color:var(--muted); }
.tile-foot a:hover { color:var(--accent); }

.dot { display:inline-flex; align-items:center; gap:8px; font-size:12px; color:var(--muted); }
.dot::before { content:""; width:9px; height:9px; border-radius:50%; background:var(--muted); flex:none; }
.dot.ok::before { background:var(--ok); box-shadow:0 0 0 3px var(--okbg); }
.dot.warn::before { background:var(--warn); box-shadow:0 0 0 3px var(--warnbg); }
.dot.bad::before { background:var(--bad); box-shadow:0 0 0 3px var(--badbg); }

/* Bouton inline (formulaires de gestion) */
.btn-inline { border:none; border-radius:9px; background:var(--accent); color:#06101f;
  font-weight:700; font-size:14px; padding:9px 16px; cursor:pointer; }
.btn-inline:hover { filter:brightness(1.08); }
button.chip { background:none; cursor:pointer; font-family:inherit; }
.tbl input[type=checkbox] { width:17px; height:17px; accent-color:var(--accent); cursor:pointer; }

/* Login */
.login-card { max-width:360px; margin:8vh auto 0; background:var(--panel);
  border:1px solid var(--line); border-radius:16px; padding:28px;
  animation:login-card-in .7s cubic-bezier(.16,1,.3,1) both; }
.login-card h1 { margin:0 0 4px; font-size:22px; }

/* Logo — entrée douce (fondu + montée + zoom léger) puis lueur qui respire */
.login-logo { display:flex; justify-content:center; margin:0 0 18px; }
.login-logo img { width:96px; height:96px; border-radius:22px; display:block;
  animation:login-logo-in .9s cubic-bezier(.16,1,.3,1) both,
            login-logo-glow 5s ease-in-out 1s infinite; }

@keyframes login-card-in {
  from { opacity:0; transform:translateY(14px) scale(.985); }
  to   { opacity:1; transform:none; }
}
@keyframes login-logo-in {
  from { opacity:0; transform:translateY(10px) scale(.88); filter:blur(6px); }
  to   { opacity:1; transform:none; filter:blur(0); }
}
@keyframes login-logo-glow {
  0%,100% { box-shadow:0 0 0 1px rgba(90,166,255,.08), 0 6px 22px rgba(90,166,255,.10); }
  50%     { box-shadow:0 0 0 1px rgba(90,166,255,.18), 0 10px 34px rgba(90,166,255,.28); }
}

/* Respect des préférences d'accessibilité : pas d'animation superflue */
@media (prefers-reduced-motion:reduce) {
  .login-card, .login-logo img { animation:none; }
}
.login-card label { display:block; margin:14px 0 0; font-size:13px; color:var(--muted); }
.login-card input { width:100%; margin-top:5px; padding:10px 12px; border-radius:9px;
  border:1px solid var(--line); background:var(--panel2); color:var(--txt); font-size:15px; }
.btn { width:100%; margin-top:20px; padding:11px; border:none; border-radius:9px;
  background:var(--accent); color:#06101f; font-weight:700; font-size:15px; cursor:pointer; }
.btn:hover { filter:brightness(1.08); }

/* Bloc « Notifications » (Supervision). */
.push-setup { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:14px 16px; }
.push-head { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.push-head h2 { margin:0; font-size:16px; }
.push-actions { display:flex; gap:8px; }
.push-setup .push-hint { font-size:12px; margin:4px 0 0; }
#push-msg { margin:8px 0 0; }

/* Tables défilables horizontalement sur petit écran. */
.tbl-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; }

/* Actions d'incident (fiche utilisateur) : cibles tactiles, danger explicite. */
.act-row { display:flex; gap:10px; flex-wrap:wrap; }
.act-btn { border:1px solid var(--line); background:var(--panel2); color:var(--txt);
  padding:11px 16px; border-radius:10px; font-size:15px; font-weight:600; cursor:pointer; }
.act-btn:hover { filter:brightness(1.08); }
.act-btn.danger { border-color:var(--bad); color:var(--bad); }
.act-btn.danger:hover { background:var(--badbg); }

/* Approbation de connexion (2FA push) : attente + page d'approbation. */
.wait-spin { width:34px; height:34px; margin:20px auto 4px; border-radius:50%;
  border:3px solid var(--line); border-top-color:var(--accent); animation:spin 1s linear infinite; }
@keyframes spin { to { transform:rotate(360deg); } }
#login-wait.done .wait-spin { display:none; }
.approve-detail { margin:14px 0; border:1px solid var(--line); border-radius:10px; overflow:hidden; }
.approve-detail > div { display:flex; justify-content:space-between; gap:12px; padding:9px 12px;
  border-bottom:1px solid var(--line); font-size:14px; }
.approve-detail > div:last-child { border-bottom:none; }
.approve-detail .k { color:var(--muted); }
.approve-actions { display:flex; flex-direction:column; gap:10px; margin-top:16px; }
.approve-actions .btn { margin-top:0; }

/* Bandeau global « connexion à approuver » (affiché tant qu'une demande est en attente). */
.approve-banner { display:flex; align-items:center; gap:10px; text-decoration:none;
  padding:11px 22px; background:var(--warnbg); color:var(--txt);
  border-bottom:1px solid var(--warn); font-size:14px; }
.approve-banner .ab-ico { font-size:18px; }
.approve-banner .ab-txt { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.approve-banner .ab-go { font-weight:700; color:var(--warn); white-space:nowrap; }
.approve-banner:hover { filter:brightness(1.06); }
