/* Le bandeau ET le fond du site, pour les pages qui ne sont pas la landing.
 *
 * Ces regles sont la copie fidele de celles qui vivent en ligne dans
 * `templates/landing.html` (bloc `.app-icon` / `.brand` / `.nav*` /
 * `.lang-*` / `.btn*`). Elles y restent parce que la landing porte tout son
 * style en ligne pour n'avoir qu'une requete au premier affichage ; ici on
 * en a besoin sur une autre page, et le fichier evite de tout recopier dans
 * chaque gabarit.
 *
 * Si tu touches au bandeau de la landing, touche aussi a celui-ci : ce sont
 * deux exemplaires du meme dessin, et rien ne les tient ensemble tout seul.
 */

.app-icon {
  width: 38px; height: 38px; border-radius: 12px; position: relative; overflow: hidden; flex-shrink: 0;
  background: linear-gradient(160deg, #0a3245 0%, #05121c 70%);
  border: 1px solid rgba(255,255,255,.1);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 20px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.08);
}
.app-icon .split-mark { width: 64%; height: 64%; overflow: visible; }
.app-icon .split-mark .sm-left { fill: var(--accent); filter: drop-shadow(0 0 3px rgba(0,194,255,.75)); }
.app-icon .split-mark .sm-right { fill: var(--accent-2); opacity: .45; }

.brand { display: flex; align-items: center; gap: 11px; font-size: 21px; text-decoration: none; cursor: pointer; color: inherit; }
.brand .word {
  font-family: var(--font-body); font-weight: 900; font-style: italic;
  letter-spacing: -.02em; color: var(--ink); white-space: nowrap;
}
.brand .word span { display: inline-block; }
.brand .word .word-only { font-weight: 500; color: var(--ink-dim); letter-spacing: -.01em; }
.brand .word .word-shorts {
  background: linear-gradient(100deg, var(--accent) 0%, var(--accent-2) 30%, var(--teal) 55%, var(--accent-2) 80%, var(--accent) 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: accentShimmer 5s linear infinite;
  filter: drop-shadow(0 0 12px rgba(0,194,255,.5));
/* Le degrade est peint sur la boite du texte, et l'italique deborde de
   cette boite : sans ce souffle a droite, la jambe du "s" final se
   retrouvait coupee net. */
padding-right: .09em; margin-right: -.04em;
}
@keyframes accentShimmer { 0% { background-position: 0% 50%; } 100% { background-position: 300% 50%; } }
@media (prefers-reduced-motion: reduce) { .brand .word .word-shorts { animation: none; } }

/* Les 14 px au-dessus de la barre, en clair.
 *
 * Sur la landing, ils ne sont ecrits nulle part : la bande perforee fait
 * 7 px, et `position: sticky; top: 14px` colle la barre a 14 des le premier
 * pixel de defilement -- donc au repos aussi. Compter sur cet effet de bord
 * ailleurs, c'est parier que la chaine de parents se comporte pareil ; la
 * marge le dit, et le resultat est le meme dans les deux cas (7 + 7 = 14,
 * et le collage a 14 ne bouge plus rien). */
.nav-wrap { position: sticky; top: 14px; z-index: 20; padding: 0; margin-top: 7px; margin-bottom: 0; }
.nav {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 9px 10px 9px 18px; border-radius: 999px;
  background: var(--nav-bg); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border: 1px solid var(--card-border); box-shadow: 0 14px 40px rgba(0,0,0,.35);
}
.nav-links { position: relative; display: flex; align-items: center; gap: 2px; font-size: 13.5px; color: var(--ink-dim); }
.nav-links a {
  /* `color: inherit` explicitement : la landing le donne a TOUS ses liens
     dans son style en ligne, pas cette feuille -- sans lui, les onglets
     sortaient en bleu-violet de navigateur, et en violet une fois visites. */
  position: relative; z-index: 1; padding: 8px 15px; border-radius: 999px; text-decoration: none;
  color: inherit; transition: color .2s;
  /* Un libelle en deux mots -- "En direct", "A faire" -- se coupait en deux
     lignes des que la barre serrait : l'onglet doublait de hauteur, la barre
     entiere grandissait, et la pastille glissante restait a l'ancienne
     mesure. Les onglets se serrent, ils ne se plient pas. */
  white-space: nowrap;
}
.nav-links a:hover { color: var(--ink); }
.nav-links a.active { color: var(--ink); font-weight: 600; }
.nav-right { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.nav .btn { white-space: nowrap; }

.lang-toggle {
  position: relative; font-family: var(--font-body); font-size: 12px; letter-spacing: .04em;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-dim);
  border-radius: 999px; padding: 7px 4px; cursor: pointer; display: flex; gap: 2px;
}
.lang-toggle span[data-lang] { position: relative; z-index: 1; padding: 3px 9px; border-radius: 999px; transition: color .2s; }
.lang-toggle span[data-lang].active { color: var(--ink); font-weight: 600; }
.lang-pill {
  position: absolute; top: 3px; height: calc(100% - 6px); border-radius: 999px;
  background: linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.03));
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.14); box-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 4px 16px rgba(0,0,0,.25);
  transition: left .22s cubic-bezier(.2,0,.1,1), width .22s cubic-bezier(.2,0,.1,1); opacity: 0;
}
.lang-glow {
  position: absolute; bottom: -6px; height: 2px; border-radius: 2px; background: var(--accent);
  box-shadow: 0 0 5px 1px rgba(0,194,255,.55);
  transition: left .22s cubic-bezier(.2,0,.1,1), width .22s cubic-bezier(.2,0,.1,1), opacity .2s;
  opacity: 0; pointer-events: none;
}

.btn {
  display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-body); font-weight: 600;
  font-size: 14px; padding: 11px 18px; border-radius: 999px; text-decoration: none;
  border: 1px solid transparent; cursor: pointer; color: inherit;
}
.btn-accent {
  position: relative; overflow: hidden; border: 0;
  background: radial-gradient(circle at 30% 30%, var(--accent-2), var(--accent) 75%);
  color: #fff; box-shadow: 0 0 26px rgba(0,194,255,.4), inset 0 1px 0 rgba(255,255,255,.2);
}
.btn-ghost { background: var(--surface-2); border: 1px solid var(--card-border); color: var(--ink); }
.btn-ghost:hover { border-color: rgba(0,194,255,.45); }

/* Les memes ruptures que la landing : sous 860 px les onglets disparaissent,
   sous 540 la barre se resserre pour tenir sur une ligne. */
@media (min-width: 861px) and (max-width: 1020px) {
  .nav { gap: 10px; padding-left: 14px; }
  .nav-links { font-size: 13px; }
  .nav-links a { padding: 8px 9px; }
}
/* Le cran du dessous. Les pages d'administration portent sept onglets, la
   landing cinq : c'est entre 861 et 960 que les sept ne tenaient plus, et
   comme ils ne se plient plus (white-space ci-dessus), il faut leur faire
   la place pour de bon. */
@media (min-width: 861px) and (max-width: 960px) {
  .nav { gap: 7px; padding: 9px 8px 9px 12px; }
  .nav-links { font-size: 12.5px; gap: 0; }
  .nav-links a { padding: 8px 6px; }
  .brand { font-size: 16.5px; gap: 8px; }
  .brand .app-icon { width: 30px; height: 30px; border-radius: 9px; }
  .nav-right { gap: 8px; }
}
@media (max-width: 860px) { .nav-links { display: none; } }
@media (max-width: 540px) {
  .nav { flex-wrap: nowrap; gap: 8px; padding: 7px 7px 7px 11px; }
  .brand { font-size: 16.5px; gap: 8px; }
  .brand .app-icon { width: 30px; height: 30px; border-radius: 9px; }
  .nav-right { margin-left: auto; gap: 7px; }
  .lang-toggle { font-size: 10.5px; padding: 5px 3px; }
  .lang-toggle span[data-lang] { padding: 3px 6px; }
  .nav .btn { padding: 10px 14px; font-size: 12.5px; }
}


/* ------------------------------------------------------------- le fond ---
 * Exactement celui de la landing : le meme degre de bleu, le meme grain, les
 * memes halos qui derivent. Passer d'une page a l'autre ne doit rien changer
 * a ce qu'on a sous les yeux.
 */
.grain-overlay {
  position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none;
  opacity: var(--grain-opacity); mix-blend-mode: overlay; z-index: 0;
}
/* Fond vivant : des halos flous qui derivent (lente boucle) ET reagissent
   au defilement (parallaxe -- chaque halo se deplace a sa propre vitesse
   via --scroll-shift, pousse par JS), plus des formes qui "respirent"
   (border-radius anime) pour un mouvement moins geometrique qu'un simple
   cercle. Recolore dans la palette rouge de OnlyShorts. */
.bg-drift { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; overflow: hidden; }
/* La forme organique est figee au lieu d'etre animee : "border-radius"
   est la seule propriete ici qui ne peut pas etre composee sur le GPU,
   donc l'animer forcait la repeinture ET le reflou a 70px de cinq
   calques de 400 a 620px, a chaque image, defilement compris. Le rendu
   ne change pas : le degrade est deja transparent avant d'atteindre le
   bord, donc la decoupe des coins ne se voyait pas. */
.bg-drift .blob {
  position: absolute; filter: blur(70px); will-change: transform;
  border-radius: 51% 49% 49% 51% / 49% 53% 47% 52%;
  transform: translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1)));
}
.bg-drift .blob.b1 { width: 620px; height: 620px; left: -180px; top: -220px; --parallax: 0.25; background: radial-gradient(circle, rgba(0,194,255,.55), transparent 70%); animation: blobA 22s ease-in-out infinite alternate; }
.bg-drift .blob.b2 { width: 540px; height: 540px; right: -160px; top: 8%; --parallax: -0.4; background: radial-gradient(circle, rgba(92,219,255,.45), transparent 70%); animation: blobB 28s ease-in-out infinite alternate; }
.bg-drift .blob.b3 { width: 520px; height: 520px; left: 8%; top: 60%; --parallax: 0.55; background: radial-gradient(circle, rgba(0,120,180,.5), transparent 70%); animation: blobC 25s ease-in-out infinite alternate; }
.bg-drift .blob.b4 { width: 420px; height: 420px; right: 10%; top: 120%; --parallax: -0.3; background: radial-gradient(circle, rgba(95,227,192,.35), transparent 70%); animation: blobD 30s ease-in-out infinite alternate; }
.bg-drift .blob.b5 { width: 480px; height: 480px; left: 30%; top: 190%; --parallax: 0.4; background: radial-gradient(circle, rgba(0,194,255,.4), transparent 70%); animation: blobA 26s ease-in-out infinite alternate; }
@keyframes blobA { from { transform: translate(0,0) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1); } to { transform: translate(90px, 60px) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1.15); } }
@keyframes blobB { from { transform: translate(0,0) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1); } to { transform: translate(-70px, 90px) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1.1); } }
@keyframes blobC { from { transform: translate(0,0) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1); } to { transform: translate(80px, -60px) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1.2); } }
@keyframes blobD { from { transform: translate(0,0) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1); } to { transform: translate(-60px, -70px) translateY(calc(var(--scroll-shift, 0px) * var(--parallax, 1))) scale(1.12); } }
.bg-drift .spark {
  position: absolute; width: 3px; height: 3px; border-radius: 50%; background: #fff;
  box-shadow: 0 0 10px 3px rgba(200,240,255,.85); opacity: 0; animation: sparkle 5s ease-in-out infinite;
}


.shell { max-width: 1120px; margin: 0 auto; padding: 0 28px; }
@media (max-width: 620px) { .shell { padding: 0 14px; } }
@media (max-width: 380px) { .shell { padding: 0 10px; } }
.shell { position: relative; z-index: 1; }


/* --- la bande perforee du haut : c'est elle qui donne l'ecart sous
   lequel la barre vient se coller. --- */
.sprockets {
  height: 7px;
  background-image: radial-gradient(circle, var(--ground) 2.1px, transparent 2.2px);
  background-size: 20px 7px;
  background-repeat: repeat-x;
  background-position: 8px center;
  background-color: rgba(0,194,255,.4);
}

/* --- la pluie de formats courts et les etincelles --- */
.shorts-field { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.short-float {
  position: absolute; top: 0; width: 30px; height: 45px; color: var(--accent);
  filter: blur(1.1px) drop-shadow(0 0 7px rgba(0,194,255,.45));
  will-change: transform, opacity;
  animation: shortFall linear infinite;
}
/* Chute lente, legere derive laterale et rotation : 9 profils differents
   pour qu'aucune trajectoire ne se repete visiblement. */
@keyframes shortFall {
  0%   { transform: translate3d(0, -18vh, 0) rotate(-10deg); opacity: 0; }
  12%  { opacity: var(--peak, .17); }
  88%  { opacity: var(--peak, .17); }
  100% { transform: translate3d(var(--drift, 40px), 116vh, 0) rotate(14deg); opacity: 0; }
}
.short-float:nth-child(1) { left: 6%;  --drift: 46px;  --peak: .17; transform: scale(1);    animation-duration: 27s; animation-delay: -3s; }
.short-float:nth-child(2) { left: 19%; --drift: -34px; --peak: .12; width: 22px; height: 33px; animation-duration: 34s; animation-delay: -14s; }
.short-float:nth-child(3) { left: 31%; --drift: 30px;  --peak: .2;  width: 38px; height: 57px; animation-duration: 22s; animation-delay: -8s; }
.short-float:nth-child(4) { left: 44%; --drift: -48px; --peak: .1;  width: 20px; height: 30px; animation-duration: 38s; animation-delay: -21s; }
.short-float:nth-child(5) { left: 57%; --drift: 38px;  --peak: .18; animation-duration: 25s; animation-delay: -11s; }
.short-float:nth-child(6) { left: 69%; --drift: -28px; --peak: .13; width: 24px; height: 36px; animation-duration: 31s; animation-delay: -6s; }
.short-float:nth-child(7) { left: 80%; --drift: 44px;  --peak: .2;  width: 36px; height: 54px; animation-duration: 24s; animation-delay: -17s; }
.short-float:nth-child(8) { left: 90%; --drift: -36px; --peak: .11; width: 21px; height: 32px; animation-duration: 36s; animation-delay: -2s; }
.short-float:nth-child(9) { left: 50%; --drift: 26px;  --peak: .09; width: 18px; height: 27px; animation-duration: 41s; animation-delay: -29s; }
@media (prefers-reduced-motion: reduce) { .shorts-field { display: none; } }
/* Sur mobile, la moitie suffit : moins de calques flous a composer. */
@media (max-width: 640px) {
  .short-float:nth-child(even) { display: none; }
}
@keyframes sparkle { 0%, 100% { opacity: 0; transform: scale(.5); } 50% { opacity: .9; transform: scale(1.4); } }
@media (prefers-reduced-motion: reduce) {
  .bg-drift .blob, .bg-drift .spark { animation: none; transform: none; }
}

/* --- le verre : fond flou, filet lumineux qui suit le curseur --- */
.glass-card {
  position: relative; overflow: hidden; border-radius: 20px;
  background: var(--glass-bg); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border: 1px solid var(--card-border); box-shadow: var(--card-shadow);
}
.glass-card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.45), transparent 60%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity .35s; pointer-events: none;
}
.glass-card::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.07), transparent 60%);
  opacity: 0; transition: opacity .35s; pointer-events: none;
}
.glass-card:hover::before, .glass-card:hover::after { opacity: 1; }

/* Les deux jetons que le verre attend, aux valeurs de la landing. */
:root { --glass-bg: rgba(255,255,255,0.035); --card-shadow: 0 30px 80px rgba(0,0,0,.5); }


/* ---- bouton compte du bandeau ----
   Visible seulement une fois connecte ; il remplace alors l'appel a
   l'action, qui ne s'adresse qu'aux visiteurs. */
.account { position: relative; }
.account[hidden] { display: none; }
.account-btn {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px 4px 4px;
  background: var(--surface-2); border: 1px solid var(--card-border); border-radius: 999px;
  color: var(--ink-dim); cursor: pointer; transition: border-color .2s, color .2s;
}
.account-btn:hover, .account-btn[aria-expanded="true"] { border-color: rgba(0,194,255,.45); color: var(--ink); }
.account-avatar {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--accent-2), var(--accent) 75%);
  color: #03151f; font-size: 11.5px; font-weight: 700; letter-spacing: .02em;
}
.account-chev { width: 14px; height: 14px; transition: transform .2s; }
.account-btn[aria-expanded="true"] .account-chev { transform: rotate(180deg); }
.account-menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60; width: 268px;
  background: linear-gradient(180deg, rgba(16,30,39,.98), rgba(8,16,22,.98));
  border: 1px solid var(--card-border); border-radius: 16px; box-shadow: var(--card-shadow);
  padding: 14px; display: flex; flex-direction: column; gap: 12px; text-align: left;
}
.account-menu[hidden] { display: none; }
.account-name { font-size: 14px; font-weight: 600; color: var(--ink); }
.account-mail { font-size: 11.5px; color: var(--ink-dim); overflow-wrap: anywhere; }
.account-block { display: flex; flex-direction: column; gap: 7px; }
.account-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.account-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-dim);
}
.account-link {
  display: block; width: 100%; text-align: left; padding: 7px 8px; border-radius: 8px;
  background: none; border: 0; cursor: pointer; font-family: var(--font-body);
  font-size: 13px; color: var(--ink); text-decoration: none; transition: background .18s;
}
.account-link:hover { background: rgba(255,255,255,.06); }
.account-actions { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--card-border); padding-top: 10px; }
.account-link-quiet { color: var(--ink-dim); }
@media (max-width: 560px) { .account-menu { width: min(268px, calc(100vw - 32px)); } }
