/* vibe · socle commun des projets de vibe.nfrancois.fr
   Laboratoire de projets IA : filets d'un pixel, grille discrète, Geist et Geist Mono, et une seule couleur vive, le
   lime du point du i de vibe. Les autres couleurs servent aux données (voir --v-donnee-*).

   Usage dans un projet (page HTML ou app) :
     <link rel="stylesheet" href="https://vibe.nfrancois.fr/kit/vibe.css">   (ou "/kit/vibe.css" sur le même domaine)
   puis les classes préfixées v- ci-dessous. Le socle ne stylise que <html>, <body> et ses propres classes : un projet
   garde la main sur sa mise en page.

   Thèmes : clair par défaut, sombre en option. /kit/theme.js (à charger dans le <head>, sans defer) pose
   data-theme="dark|light" sur <html> avant l'affichage, suit le réglage de l'appareil tant qu'on n'a rien choisi et
   mémorise le choix pour tout le site ; tout bouton portant data-v-theme bascule le thème (voir .v-theme).

   Polices : Geist et Geist Mono (Vercel, SIL Open Font License 1.1, voir fonts/OFL.txt), servies depuis /kit/fonts. */

@font-face { font-family: "Geist"; src: url("fonts/Geist-Variable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("fonts/GeistMono-Variable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; }

/* Thème clair, par défaut : fond blanc cassé, encre, filets gris clair. */
:root {
  /* Fonds et surfaces, du plus profond au plus proche */
  --v-fond: #FAFAF8;
  --v-fond-2: #FFFFFF;
  --v-surface: #F3F3F1;
  --v-surface-2: #ECECEA;
  /* Texte (les trois niveaux passent 4,5:1 sur fond, fond-2 et surface) */
  --v-texte: #1A1A1A;
  --v-texte-2: #5F5F5F;
  --v-texte-3: #6B6B6B;
  /* Filets */
  --v-filet: #EAEAEA;
  --v-filet-fort: #D4D4D4;
  --v-filet-survol: #B5B5B5;
  /* Accent : le lime du point du i de vibe. --v-accent pour les aplats et les surlignages, --v-accent-texte pour du
     texte (le lime pur ne se lit pas sur fond clair), --v-sur-accent pour écrire sur le lime */
  --v-accent: #C6F05A;
  --v-accent-texte: #477209;
  --v-sur-accent: #1A1A1A;
  /* Couleurs de données (graphiques, compteurs), foncées pour rester lisibles sur fond clair */
  --v-donnee-jaune: #E5B300;
  --v-donnee-ardoise: #5B6B82;
  --v-donnee-bleu: #1E6FC2;
  --v-donnee-vert: #15803D;
  --v-donnee-rouge: #B91C1C;
  /* Typographie */
  --v-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --v-mono: "Geist Mono", ui-monospace, Menlo, Consolas, monospace;
  /* Formes et mouvement */
  --v-rayon: 10px;
  --v-rayon-l: 16px;
  --v-colonne: 1200px;
  --v-gouttiere: clamp(20px, 4vw, 48px);
  --v-courbe: cubic-bezier(.2, .7, .2, 1);
  /* Détails qui changent avec le thème */
  --v-degrade-haut: #000000;
  --v-degrade-bas: #6B6B6B;
  --v-clair-survol: #000000;
  color-scheme: light;
}

/* Thème sombre : fond noir profond, texte blanc cassé ; le lime se lit aussi en texte. Sans JavaScript, il suit le
   réglage de l'appareil ; avec, il suit data-theme. */
:root[data-theme="dark"] {
  --v-fond: #0E0E0E; --v-fond-2: #141414; --v-surface: #181818; --v-surface-2: #1E1E1E;
  --v-texte: #EDEDED; --v-texte-2: #A1A1A1; --v-texte-3: #858585;
  --v-filet: #242424; --v-filet-fort: #363636; --v-filet-survol: #474747;
  --v-accent-texte: #C6F05A;
  --v-donnee-jaune: #FFD84D; --v-donnee-ardoise: #9AA8BC; --v-donnee-bleu: #5AAEF5; --v-donnee-vert: #4ADE80; --v-donnee-rouge: #F87171;
  --v-degrade-haut: #FFFFFF; --v-degrade-bas: #9A9A9A; --v-clair-survol: #FFFFFF;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --v-fond: #0E0E0E; --v-fond-2: #141414; --v-surface: #181818; --v-surface-2: #1E1E1E;
    --v-texte: #EDEDED; --v-texte-2: #A1A1A1; --v-texte-3: #858585;
    --v-filet: #242424; --v-filet-fort: #363636; --v-filet-survol: #474747;
    --v-accent-texte: #C6F05A;
    --v-donnee-jaune: #FFD84D; --v-donnee-ardoise: #9AA8BC; --v-donnee-bleu: #5AAEF5; --v-donnee-vert: #4ADE80; --v-donnee-rouge: #F87171;
    --v-degrade-haut: #FFFFFF; --v-degrade-bas: #9A9A9A; --v-clair-survol: #FFFFFF;
    color-scheme: dark;
  }
}

html, body { margin: 0; background: var(--v-fond); color: var(--v-texte); }
body { font-family: var(--v-sans); font-size: 16px; line-height: 1.6; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-variant-numeric: tabular-nums; }
::selection { background: var(--v-accent); color: var(--v-sur-accent); }
:focus-visible { outline: 2px solid var(--v-accent-texte); outline-offset: 3px; }

@keyframes v-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--v-accent) 55%, transparent); } 70% { box-shadow: 0 0 0 6px transparent; } }

/* ── Logo vibe (SVG inline, voir README) : lettres manuscrites pleines à la couleur du texte, point du i lime ── */
.vibe { display: block; width: auto; overflow: visible; color: var(--v-texte); }
.vibe__lettres { fill: currentColor; }
.vibe__point { fill: var(--v-accent); transform-box: fill-box; transform-origin: center; }

/* ── Barre vibe : en haut de chaque projet, retour au hub ── */
.v-bar { position: sticky; top: 0; z-index: 50; background: color-mix(in srgb, var(--v-fond) 72%, transparent); -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%); border-bottom: 1px solid var(--v-filet); font-family: var(--v-sans); }
.v-bar__in { max-width: calc(var(--v-colonne) + 2px); margin: 0 auto; height: 56px; padding-inline: var(--v-gouttiere); display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.v-bar__fil { display: flex; align-items: center; gap: 12px; min-width: 0; }
.v-bar__home { display: inline-flex; color: var(--v-texte); }
.v-bar__home .vibe { height: 32px; }
.v-bar__sep { color: var(--v-filet-fort); font-size: 20px; font-weight: 300; }
.v-bar__nom { font-family: var(--v-mono); font-size: 13px; color: var(--v-texte); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v-bar__liens { display: flex; align-items: center; gap: 20px; }
.v-bar__lien { font-size: 14px; color: var(--v-texte-2); text-decoration: none; transition: color .2s var(--v-courbe); }
.v-bar__lien:hover { color: var(--v-texte); }
/* Sur mobile, le logo suffit pour revenir au hub : les liens d'ancre et le bouton de retour (.v-bar__retour) s'effacent */
@media (max-width: 560px) { .v-bar .v-bar__lien, .v-bar .v-bar__retour { display: none; } }

/* ── Boutons : pilule claire (action principale) ou sombre bordée ── */
.v-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0 20px; border-radius: 999px; font: 500 15px/1 var(--v-sans); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color .2s var(--v-courbe), border-color .2s var(--v-courbe), color .2s var(--v-courbe); }
.v-btn svg { width: 16px; height: 16px; flex: none; transition: transform .25s var(--v-courbe); }
.v-btn--clair { background: var(--v-texte); color: var(--v-fond); border: 1px solid var(--v-texte); }
.v-btn--clair:hover { background: var(--v-clair-survol); border-color: var(--v-clair-survol); }
.v-btn--sombre { background: var(--v-fond); color: var(--v-texte); border: 1px solid var(--v-filet-fort); }
.v-btn--sombre:hover { background: var(--v-surface); border-color: var(--v-filet-survol); }
.v-btn--petit { height: 34px; padding: 0 14px; font-size: 14px; }
.v-btn--petit svg { width: 14px; height: 14px; }

/* ── Pastille d'état et point lumineux ── */
.v-pill { display: inline-flex; align-items: center; gap: 10px; height: 32px; padding: 0 14px 0 12px; border: 1px solid var(--v-filet-fort); border-radius: 999px; background: color-mix(in srgb, var(--v-surface) 80%, transparent); font-family: var(--v-mono); font-size: 12px; letter-spacing: .02em; color: var(--v-texte-2); }
.v-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--v-texte-3); flex: none; }
.v-dot--vif { background: var(--v-accent); box-shadow: 0 0 10px color-mix(in srgb, var(--v-accent) 70%, transparent); }
@media (prefers-reduced-motion: no-preference) { .v-dot--vif { animation: v-pulse 2.4s ease-out infinite; } }

/* ── Étiquettes ── */
.v-label { font-family: var(--v-mono); font-size: 12px; font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--v-texte-3); }
.v-tag { display: inline-flex; align-items: center; height: 26px; padding: 0 10px; border: 1px solid var(--v-filet-fort); border-radius: 6px; background: var(--v-fond); font-family: var(--v-mono); font-size: 12px; color: var(--v-texte-2); }

/* ── Carte : surface bordée ── */
.v-card { background: var(--v-fond-2); border: 1px solid var(--v-filet); border-radius: var(--v-rayon-l); }

/* ── Grille de fond qui s'estompe (à poser en absolu derrière un héros) ── */
.v-grille { position: absolute; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to right, var(--v-filet) 1px, transparent 1px), linear-gradient(to bottom, var(--v-filet) 1px, transparent 1px); background-size: 64px 64px; background-position: -1px -1px; -webkit-mask-image: radial-gradient(ellipse 70% 80% at 30% 20%, #000 20%, transparent 75%); mask-image: radial-gradient(ellipse 70% 80% at 30% 20%, #000 20%, transparent 75%); opacity: .7; }

/* ── Titre en dégradé (encre vers gris), mot accentué surligné en lime, texte encre, dans les deux thèmes ── */
.v-degrade { background: linear-gradient(180deg, var(--v-degrade-haut) 30%, var(--v-degrade-bas) 120%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.v-accent { color: var(--v-sur-accent); -webkit-text-fill-color: var(--v-sur-accent); background: linear-gradient(transparent 14%, var(--v-accent) 14%, var(--v-accent) 96%, transparent 96%); -webkit-background-clip: border-box; background-clip: border-box; padding: 0 .08em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }

/* ── Bascule de thème : bouton rond, soleil en sombre (passer au clair), lune en clair (passer au sombre) ── */
.v-theme { display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0; border: 1px solid var(--v-filet-fort); border-radius: 999px; background: transparent; color: var(--v-texte-2); cursor: pointer; transition: color .2s var(--v-courbe), border-color .2s var(--v-courbe), background-color .2s var(--v-courbe); }
.v-theme:hover { color: var(--v-texte); border-color: var(--v-filet-survol); background: var(--v-surface); }
.v-theme svg { width: 16px; height: 16px; grid-area: 1 / 1; transition: transform .35s var(--v-courbe), opacity .2s var(--v-courbe); }
.v-theme__soleil { opacity: 0; transform: rotate(60deg) scale(.6); }
:root[data-theme="dark"] .v-theme__soleil { opacity: 1; transform: none; }
:root[data-theme="dark"] .v-theme__lune { opacity: 0; transform: rotate(-60deg) scale(.6); }
/* Changement de thème en fondu (classe posée un instant par theme.js) */
.v-transition, .v-transition *, .v-transition *::before, .v-transition *::after { transition: background-color .3s var(--v-courbe), color .3s var(--v-courbe), border-color .3s var(--v-courbe), fill .3s var(--v-courbe), stroke .3s var(--v-courbe) !important; }

/* ── Pied de page du site : le même sur le hub et dans chaque projet (balisage dans le README). Ce qui concerne un
   projet va dans le projet, au-dessus. ── */
.v-pied { border-top: 1px solid var(--v-filet); font-family: var(--v-sans); font-size: 14px; }
.v-pied__in { max-width: calc(var(--v-colonne) + 2px); margin: 0 auto; padding: 32px var(--v-gouttiere) 40px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px 32px; }
.v-pied__liens { display: flex; flex-wrap: wrap; gap: 12px 28px; margin: 0; padding: 0; list-style: none; }
.v-pied__liens a { display: inline-flex; align-items: center; gap: 4px; color: var(--v-texte-2); text-decoration: none; transition: color .2s var(--v-courbe); }
.v-pied__liens a:hover { color: var(--v-texte); }
.v-pied__liens svg { width: 12px; height: 12px; flex: none; opacity: .7; }
.v-pied__copy { margin: 0; font-family: var(--v-mono); font-size: 12px; color: var(--v-texte-3); }
@media (max-width: 640px) {
  .v-pied__in { flex-direction: column; align-items: stretch; padding-block: 28px 32px; }
  .v-pied__liens { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 20px; }
  .v-pied__copy { padding-top: 20px; border-top: 1px solid var(--v-filet); }
}

/* Texte réservé aux lecteurs d'écran (ex. « (nouvel onglet) » dans le pied de page) */
.v-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* Images doublées selon le thème : <img class="v-si-sombre"> et <img class="v-si-clair"> */
.v-si-sombre { display: none !important; }
:root[data-theme="dark"] .v-si-sombre { display: block !important; }
:root[data-theme="dark"] .v-si-clair { display: none !important; }

/* ── Chiffre : mono, unité plus petite et grisée ── */
.v-num { font-family: var(--v-mono); font-weight: 600; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.v-num small { font-size: .45em; font-weight: 500; letter-spacing: 0; color: var(--v-texte-2); margin-left: .3em; }

/* ── Compteur : une carte par indicateur, filet de couleur en tête (--v-c), lueur discrète ── */
.v-meter { --v-c: var(--v-accent); position: relative; background: var(--v-fond-2); border: 1px solid var(--v-filet); border-radius: var(--v-rayon-l); overflow: hidden; }
.v-meter::before { content: ""; position: absolute; inset: 0 0 auto; height: 2px; background: var(--v-c); box-shadow: 0 0 24px 2px color-mix(in srgb, var(--v-c) 60%, transparent); }
.v-meter::after { content: ""; position: absolute; inset: 0 0 auto; height: 90px; background: linear-gradient(to bottom, color-mix(in srgb, var(--v-c) 10%, transparent), transparent); pointer-events: none; }

/* ── Ticket : lignes en pointillés façon reçu, chiffres en mono ── */
.v-ticket { font-family: var(--v-mono); border-top: 1px dashed var(--v-filet-fort); border-bottom: 1px dashed var(--v-filet-fort); }
.v-ticket > * + * { border-top: 1px solid var(--v-filet); }

@media (prefers-reduced-motion: reduce) { .v-btn, .v-btn svg, .v-bar__lien, .v-theme, .v-theme svg, .v-pied__liens a { transition: none; } .v-transition, .v-transition * { transition: none !important; } }
