/* ============================================================
   PORTFOLIO v2 — BŁAŻEJ LUBERA
   Direction : « console d'infrastructure » — fond encre, grille
   blueprint, typographie éditoriale Geist + Geist Mono,
   un seul accent ambre signal (+ un vert d'état).

   Ce fichier contient ce que Tailwind ne fait pas :
   les fontes, les jetons de couleur, les keyframes,
   et quelques composants signature (grille, halo, révélation).
   Tout le reste est en utilitaires Tailwind dans le HTML/JS.
   ============================================================ */

/* ---------- 1. Fontes auto-hébergées (aucune requête externe) ---------- */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geist-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geist-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geistmono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geistmono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- 2. Jetons de couleur (triplets RGB pour Tailwind) ----------
   Thème sombre par défaut : c'est la direction artistique du site.
   Le thème clair est une transposition complète, pas un repli. */
:root,
:root[data-theme="dark"] {
  --c-bg:        8   9  11;   /* encre profonde                      */
  --c-surface:  15  17  20;   /* cartes                              */
  --c-surface2: 21  24  29;   /* cartes surelevees, champs           */
  --c-line:     35  40  47;   /* filets                              */
  --c-line2:    52  59  68;   /* filets marques (survol)             */
  --c-text:    236 238 241;   /* texte principal                     */
  --c-muted:   142 149 159;   /* texte secondaire                    */
  --c-faint:   122 130 141;   /* metadonnees — 4.9:1 sur les surfaces */
  --c-accent:  255 176  32;   /* ambre signal — un seul accent       */
  --c-on-accent: 12  13  15;  /* texte pose sur l'ambre              */
  --c-live:     52 211 153;   /* vert d'etat : « en ligne »          */
  --grid-line: rgba(255, 255, 255, .045);
  --glow: rgba(255, 176, 32, .10);
  color-scheme: dark;
}

:root[data-theme="light"] {
  --c-bg:      247 246 243;
  --c-surface: 255 255 255;
  --c-surface2:250 249 246;
  --c-line:    226 223 216;
  --c-line2:   199 195 186;
  --c-text:     18  20  24;
  --c-muted:    92  96 104;
  --c-faint:   106 111 120;   /* 4.7:1 sur le fond clair              */
  --c-accent:  150  87   0;   /* ambre assombri : 5.3:1 sur le fond,
                                 5.7:1 en texte blanc posé dessus     */
  --c-on-accent: 255 255 255;
  --c-live:      4 120  87;
  --grid-line: rgba(20, 22, 26, .05);
  --glow: rgba(150, 87, 0, .07);
  color-scheme: light;
}

/* ---------- 3. Base ---------- */
* { -webkit-tap-highlight-color: transparent; }

html { scroll-behavior: smooth; }

body {
  background: rgb(var(--c-bg));
  color: rgb(var(--c-text));
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: rgb(var(--c-accent)); color: rgb(var(--c-on-accent)); }

:focus-visible {
  outline: 2px solid rgb(var(--c-accent));
  outline-offset: 3px;
  border-radius: 4px;
}

/* Barre de defilement discrete, accordee au theme */
* { scrollbar-width: thin; scrollbar-color: rgb(var(--c-line2)) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: rgb(var(--c-line2));
  border: 3px solid rgb(var(--c-bg));
  border-radius: 99px;
}

/* ---------- 4. Decor : grille blueprint + halo qui suit le curseur ----------
   La grille est une paire de degrades repetes : zero image, zero requete. */
.blueprint {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(ellipse 100% 70% at 50% 0%, #000 35%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 100% 70% at 50% 0%, #000 35%, transparent 78%);
}

/* Halo : pilote par --mx / --my mis a jour au pointeur (v2-app.js). */
.spotlight {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    520px circle at var(--mx, 50%) var(--my, 30%),
    var(--glow),
    transparent 70%
  );
}

/* Filet horizontal qui s'estompe aux extremites */
.hairline {
  height: 1px;
  background: linear-gradient(to right, transparent, rgb(var(--c-line)) 12%, rgb(var(--c-line)) 88%, transparent);
}

/* ---------- 5. Revelation au defilement ----------
   Ajoutee par IntersectionObserver ; --d porte le decalage de la cascade. */
.reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity .7s cubic-bezier(.22, .61, .36, 1) var(--d, 0ms),
    transform .7s cubic-bezier(.22, .61, .36, 1) var(--d, 0ms);
  will-change: opacity, transform;
}
.reveal.is-in { opacity: 1; transform: none; }

/* ---------- 6. Composants signature ---------- */

/* 6.1 Point d'etat pulsant (« disponible », « en ligne ») */
.dot-live {
  position: relative;
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 99px;
  background: rgb(var(--c-live));
  flex: none;
}
.dot-live::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 99px;
  border: 1px solid rgb(var(--c-live) / .55);
  animation: ping 2.4s cubic-bezier(0, 0, .2, 1) infinite;
}
@keyframes ping {
  0%   { transform: scale(.7); opacity: .9; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* 6.2 Bandeau technologies : defilement continu, pause au survol */
.marquee { display: flex; width: max-content; animation: slide 44s linear infinite; }
.marquee-wrap:hover .marquee,
.marquee-wrap:focus-within .marquee { animation-play-state: paused; }
@keyframes slide { to { transform: translate3d(-50%, 0, 0); } }

/* 6.3 Lien a soulignement balaye (navigation, liens de texte) */
.sweep { position: relative; }
.sweep::after {
  content: "";
  position: absolute;
  left: 0; bottom: -3px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .32s cubic-bezier(.65, 0, .35, 1);
}
.sweep:hover::after,
.sweep[aria-current="true"]::after { transform: scaleX(1); transform-origin: left; }

/* 6.4 Rangee de projet : le filet se remplit, le titre avance, la fleche entre */
.row-proj { position: relative; }
.row-proj::before {
  content: "";
  position: absolute;
  left: 0; bottom: -1px;
  height: 1px; width: 100%;
  background: rgb(var(--c-accent));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .55s cubic-bezier(.65, 0, .35, 1);
}
.row-proj:hover::before { transform: scaleX(1); }
.row-proj .row-title { transition: transform .4s cubic-bezier(.22, .61, .36, 1); }
.row-proj:hover .row-title { transform: translateX(10px); }
.row-proj .row-go { opacity: 0; transform: translateX(-8px); transition: transform .4s cubic-bezier(.22, .61, .36, 1), opacity .3s; }
.row-proj:hover .row-go { transform: translateX(0); opacity: 1; }
.row-proj .row-num { transition: color .35s ease; }
.row-proj:hover .row-num { color: rgb(var(--c-accent)); }

/* 6.5 Vignette qui suit le curseur au survol d'une rangee (desktop) */
.hover-peek {
  position: fixed;
  z-index: 40;
  width: 300px;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-50%, -50%, 0) scale(.94) rotate(-2.5deg);
  transition: opacity .25s ease, transform .35s cubic-bezier(.22, .61, .36, 1);
  will-change: transform, opacity;
}
.hover-peek.is-on { opacity: 1; transform: translate3d(-50%, -50%, 0) scale(1) rotate(-2.5deg); }

/* 6.6 Retour tactile uniforme sur tous les controles */
.tap { transition: transform .12s cubic-bezier(.4, 0, .2, 1); }
.tap:active { transform: scale(.97); }

/* 6.7 Carte : elevation douce au survol */
.card-lift {
  transition: transform .35s cubic-bezier(.22, .61, .36, 1),
              border-color .35s ease,
              background-color .35s ease;
}
.card-lift:hover { transform: translateY(-4px); }

/* 6.8 Visionneuse d'images */
.lightbox {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  padding: 5vmin;
  background: rgb(var(--c-bg) / .93);
  backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity .25s ease;
}
/* Indispensable : le `display: grid` ci-dessus est une regle d'auteur, il
   ecrase le `display: none` que le navigateur applique a [hidden]. Sans cette
   ligne, la visionneuse reste posee sur toute la page — invisible (opacity 0)
   mais bien presente — et intercepte tous les clics. */
.lightbox[hidden] { display: none; }

.lightbox[data-open="true"] { opacity: 1; }
.lightbox img {
  max-width: 100%; max-height: 100%;
  border-radius: 12px;
  border: 1px solid rgb(var(--c-line));
  transform: scale(.97);
  transition: transform .3s cubic-bezier(.22, .61, .36, 1);
}
.lightbox[data-open="true"] img { transform: scale(1); }

/* 6.9 Entree du heros : cascade jouee une fois au chargement */
.hero-in { opacity: 0; transform: translate3d(0, 22px, 0); animation: rise .85s cubic-bezier(.22,.61,.36,1) forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* 6.10 Accordeon des competences (fiche projet) */
.acc-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .4s cubic-bezier(.22,.61,.36,1); }
.acc-body > div { overflow: hidden; }
details[open] .acc-body { grid-template-rows: 1fr; }
details summary::-webkit-details-marker { display: none; }
details[open] .acc-caret { transform: rotate(180deg); }
.acc-caret { transition: transform .3s cubic-bezier(.22,.61,.36,1); }

/* ---------- 7. Accessibilite : tout le mouvement se neutralise ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .hero-in { opacity: 1; transform: none; }
  .hover-peek { display: none; }
}

/* ---------- 8. Impression ---------- */
@media print {
  .no-print { display: none !important; }
  body { background: #fff; color: #000; }
  .blueprint, .spotlight { display: none; }
}
