/* Landing TimeStray. Portage du CSS de la maquette, sans style en ligne :
   la page est servie sous une CSP stricte (aucun <style>, aucun attribut style). */

/* ── Polices auto-hébergées (sous-ensemble latin) ─────────────────────── */
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/bricolage-grotesque-latin-400-normal.woff2") format("woff2")}
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/bricolage-grotesque-latin-600-normal.woff2") format("woff2")}
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:700;font-display:swap;src:url("fonts/bricolage-grotesque-latin-700-normal.woff2") format("woff2")}
@font-face{font-family:"Bricolage Grotesque";font-style:normal;font-weight:800;font-display:swap;src:url("fonts/bricolage-grotesque-latin-800-normal.woff2") format("woff2")}

/* ── Tokens : seulement ceux que la page utilise ──────────────────────────
   --u vaut 1px jusqu'à 1920px de large, puis grandit avec la fenêtre jusqu'à 2px en 3840px.
   Les tailles de la maquette, écrites « N × --u », restent donc exactes jusqu'en 1920px
   et ne laissent pas un petit bloc de 420px dans un coin d'écran 4K. */
:root{
  color-scheme:dark;
  --u:clamp(1px,calc(100vw / 1920),2px);

  --bg-base:#08090c;
  --text-primary:#eef0f4;
  --text-muted:#9aa0ae;
  --text-subtle:#7f8593;
  --tv-500:#f0574e;
  --tv-600:#e0433a;
  --tv-300:#f5897f;
  --tv-wash-soft:rgba(240,87,78,.06);
  --games-500:#a78bfa;
  --games-300:#c4b1fd;
  --games-wash:rgba(167,139,250,.16);
  --games-wash-soft:rgba(167,139,250,.06);
  --games-edge:rgba(167,139,250,.3);

  --space-2:calc(4 * var(--u));
  --space-3:calc(6 * var(--u));
  --space-7:calc(14 * var(--u));
  --radius-2xl:calc(12 * var(--u));
  --radius-3xl:calc(13 * var(--u));

  --text-2xs:calc(11 * var(--u));
  --text-sm:calc(12.5 * var(--u));
  --text-lg:calc(14.5 * var(--u));
  --text-xl:calc(15 * var(--u));
  --weight-semibold:600;
  --weight-bold:700;
  --weight-black:800;
  --leading-normal:1.5;
  --tracking-snug:calc(-.5 * var(--u));
  --tracking-wide:calc(1.6 * var(--u));
  --font-ui:"Bricolage Grotesque",system-ui,-apple-system,sans-serif;

  --ease-out-soft:cubic-bezier(.4,0,.2,1);
  --duration-instant:.15s;
  --duration-base:.4s;

  --shadow-poster:0 calc(12 * var(--u)) calc(28 * var(--u)) rgba(0,0,0,.45);
  --shadow-accent:0 calc(8 * var(--u)) calc(22 * var(--u)) rgba(240,87,78,.3);
  --shadow-accent-lg:0 calc(10 * var(--u)) calc(26 * var(--u)) rgba(240,87,78,.32);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%}
body{background:var(--bg-base);color:var(--text-primary);font-family:var(--font-ui);-webkit-font-smoothing:antialiased;overflow:hidden}
h1,h2,p{margin:0;font:inherit}

/* Planche de symboles SVG et texte réservé aux lecteurs d'écran : hors du rendu, mais présents. */
.sprite,.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ── Scène ────────────────────────────────────────────────────────────────
   Deux moitiés égales. L'opacité des murs vit dans deux variables. Seule la moitié TV
   réagit au survol et au focus : la moitié Games est visible mais inactive. */
.stage{position:fixed;inset:0;overflow:hidden;--tv-op:.24;--gm-op:.24}
.stage:has(.tv:hover),.stage:has(.tv:focus-within){--tv-op:.45;--gm-op:.18}

.half{position:absolute;top:0;bottom:0;width:50%;overflow:hidden}
.half.tv{left:0;background:var(--tv-wash-soft)}
.half.tv.is-link{cursor:pointer}
.half.games{right:0;background:var(--games-wash-soft);cursor:default}

/* ── Murs d'affiches ──────────────────────────────────────────────────────
   Grilles droites et régulières, qui débordent de 40px de chaque côté de leur moitié. */
.wall{position:absolute;top:0;width:calc(100% + 80px);display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-7);align-content:start;will-change:transform;transition:opacity var(--duration-base) var(--ease-out-soft)}
/* Un mur reste à 0 jusqu'à ce que ses tuiles soient toutes posées (poser() dans landing.js), puis un seul fondu. */
.wall{opacity:0}
.wall.tvw{left:-40px}
.wall.gmw{right:-40px}
.wall.tvw.revele{opacity:var(--tv-op)}
.wall.gmw.revele{opacity:var(--gm-op)}
.wall.fondu{transition-duration:.3s}
.poster{border-radius:var(--radius-3xl);box-shadow:var(--shadow-poster);display:flex;flex-direction:column;justify-content:space-between;padding:calc(12 * var(--u)) calc(13 * var(--u));overflow:hidden}
.tvw .poster{aspect-ratio:2/3}
.gmw .poster{aspect-ratio:3/4}
.poster b{font-weight:var(--weight-black);font-size:var(--text-xl);letter-spacing:var(--tracking-snug);color:var(--text-primary);opacity:.85}
.poster span{font-size:var(--text-2xs);font-weight:var(--weight-semibold);color:var(--text-primary);opacity:.6}
/* L'image couvre sa tuile une fois décodée, sans en changer la taille : le mur garde sa hauteur. Le clic passe au travers. */
.poster img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;pointer-events:none}
.a-affiche{position:relative}
.a-affiche b,.a-affiche span{visibility:hidden}

@keyframes up{from{transform:translateY(0)}to{transform:translateY(-50%)}}
@keyframes down{from{transform:translateY(-50%)}to{transform:translateY(0)}}

/* ── La faille : une déchirure d'énergie dessinée sur un canvas (voir le script) ── */
#rift{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;mix-blend-mode:screen}
.panel{z-index:3}
.masthead{z-index:4}

/* ── Protection : le texte reste lisible par-dessus les murs ──────────── */
.shade{position:absolute;inset:0;pointer-events:none}
.fade{position:absolute;inset:0;pointer-events:none;opacity:.7}
.tv .fade{background:linear-gradient(to left,transparent 0,transparent 30%,var(--bg-base) 100%)}
.games .fade{background:linear-gradient(to right,transparent 0,transparent 30%,var(--bg-base) 100%)}
.tv .shade{background:linear-gradient(to bottom,var(--bg-base) 0,transparent calc(150 * var(--u))),radial-gradient(110% 70% at 0% 100%,var(--bg-base) 30%,transparent 80%)}
.games .shade{background:linear-gradient(to bottom,var(--bg-base) 0,transparent calc(150 * var(--u))),radial-gradient(110% 70% at 100% 100%,var(--bg-base) 30%,transparent 80%)}

/* ── Contenu ──────────────────────────────────────────────────────────── */
.panel{position:absolute;bottom:calc(56 * var(--u));display:flex;flex-direction:column;gap:var(--space-7);max-width:calc(420 * var(--u));pointer-events:none}
.tv .panel{left:calc(56 * var(--u));align-items:flex-start}
.games .panel{right:calc(56 * var(--u));align-items:flex-end;text-align:right}
.eyebrow{font-size:var(--text-sm);font-weight:var(--weight-bold);letter-spacing:var(--tracking-wide);text-transform:uppercase}
.tv .eyebrow{color:var(--tv-300)}
.games .eyebrow{color:var(--games-300)}
.mark{height:calc(46 * var(--u));display:flex;align-items:center}
.mark>.brand{transform:scale(1.5)}
.tv .mark>.brand{transform-origin:left center}
.games .mark>.brand{transform-origin:right center}
.blurb{font-size:var(--text-lg);font-weight:400;line-height:var(--leading-normal);color:var(--text-muted);max-width:36ch}

/* ── Marque : mot-symbole et pictogramme, dessinés par les symboles de index.html.
   Le sablier et le triangle du mot lisent --dot et --play, hérités à travers <use>. ── */
.brand{display:flex;align-items:center;gap:calc(11 * var(--u))}
.brand--suite{--dot:var(--tv-500);--play:var(--games-500)}
.brand--tv{--dot:var(--tv-500);--play:var(--tv-500)}
.brand--games{--dot:var(--games-500);--play:var(--games-500)}
.wordmark{display:block;flex:0 0 auto;height:calc(30 * var(--u));width:calc(157 * var(--u));color:var(--text-primary)}
.wm-dot{fill:var(--dot)}
.wm-play{fill:var(--play)}
.picto-tv{display:block;flex:0 0 auto;height:calc(29 * var(--u));width:calc(29 * var(--u));color:var(--tv-500)}
/* Les épaules arrondies de la manette laissent du vide dans sa boîte : on la rapproche d'environ 10 % de la hauteur. */
.picto-games{display:block;flex:0 0 auto;height:calc(25 * var(--u));width:calc(31.3 * var(--u));margin-left:calc(-3 * var(--u));color:var(--games-500)}

/* ── Boutons : gabarit « lg » du Button du design system ──────────────── */
.cta{pointer-events:auto;margin-top:var(--space-2)}
.cta a,.cta button{display:inline-flex;align-items:center;justify-content:center;gap:calc(8 * var(--u));height:calc(50 * var(--u));padding:0 calc(20 * var(--u));border-radius:var(--radius-2xl);font-family:var(--font-ui);font-size:var(--text-xl);font-weight:var(--weight-bold);line-height:1}
.cta a:focus-visible,.cta button:focus-visible{outline:2px solid var(--text-primary);outline-offset:3px}
.cta svg{display:block;flex:0 0 auto;width:calc(17 * var(--u));height:calc(17 * var(--u))}

/* Lien TV : encre sombre sur l'accent (blanc sur tv-500 ne fait que 3.4:1, bg-base 5.9:1). */
.cta a{color:var(--bg-base);background:linear-gradient(135deg,var(--tv-500),var(--tv-600));border:0;box-shadow:var(--shadow-accent);text-decoration:none;cursor:pointer;transition:transform var(--duration-instant) var(--ease-out-soft),filter var(--duration-instant) var(--ease-out-soft),box-shadow var(--duration-instant) var(--ease-out-soft)}
/* Survoler la moitié soulève un peu le bouton ; le viser lui-même le soulève davantage. */
.half.tv:hover .cta a{filter:brightness(1.06);transform:translateY(-1px)}
.half.tv .cta a:hover,.half.tv .cta a:focus-visible{filter:brightness(1.14);transform:translateY(-2px);box-shadow:var(--shadow-accent-lg)}
.half.tv .cta a:hover{box-shadow:var(--shadow-accent-lg),0 0 0 1px var(--tv-300)}
.cta a svg{transition:transform var(--duration-instant) var(--ease-out-soft)}
.cta a:hover svg,.cta a:focus-visible svg{transform:translateX(3px)}
.half.tv .cta a:active{transform:translateY(0);filter:brightness(1)}

/* Bouton Games, inactif : fond opaque (voile games sur bg-base), pour que le contraste
   ne dépende pas du mur en dessous. Pas d'opacity : le texte doit rester lisible. */
.cta button{color:var(--games-300);background:linear-gradient(var(--games-wash),var(--games-wash)),var(--bg-base);border:1px solid var(--games-edge);cursor:not-allowed}

/* ── Bandeau ──────────────────────────────────────────────────────────── */
.masthead{position:absolute;top:calc(30 * var(--u));left:0;right:0;text-align:center;pointer-events:none;text-shadow:0 0 calc(10 * var(--u)) var(--bg-base),0 0 calc(22 * var(--u)) var(--bg-base),0 0 calc(36 * var(--u)) var(--bg-base)}
.masthead .name{display:flex;justify-content:center;filter:drop-shadow(0 0 calc(8 * var(--u)) var(--bg-base)) drop-shadow(0 0 calc(18 * var(--u)) var(--bg-base))}
.masthead .sub{margin-top:var(--space-3);font-size:var(--text-2xs);font-weight:var(--weight-bold);letter-spacing:var(--tracking-wide);color:var(--text-subtle)}

/* ── Sources : une ligne dans la bande libre sous les panneaux (56 × --u). Le voile tient le contraste au-dessus d'une
   affiche claire, du survol (--tv-op) ou de la faille : à .82, un pixel blanc en dessous donne encore 4,67:1 ; à .80, 4,34:1. ── */
.sources{position:absolute;z-index:3;left:calc(50 * var(--u));bottom:calc(5 * var(--u));max-width:calc(100% - 100 * var(--u));padding:calc(3 * var(--u)) calc(6 * var(--u));border-radius:calc(6 * var(--u));background:rgba(8,9,12,.82);font-size:var(--text-2xs);line-height:1.25;color:var(--text-muted)}
.sources a{color:inherit;text-decoration:underline}
/* Les mentions légales ne font pas partie de la phrase : un peu d'air les en détache, et elles ne se coupent pas. */
.sources .legal{margin-left:calc(6 * var(--u));white-space:nowrap}
.sources a:focus-visible{outline:2px solid var(--text-primary);outline-offset:2px}

/* ── Panneau de mesure : n'existe qu'avec ?perf=1 (voir assets/perf.js) ── */
.perf-panneau{position:fixed;top:calc(12 * var(--u));left:calc(12 * var(--u));z-index:10;max-width:calc(100vw - 24px);padding:calc(10 * var(--u)) calc(12 * var(--u));border-radius:var(--radius-2xl);background:rgba(8,9,12,.92);border:1px solid var(--text-subtle);font-size:var(--text-2xs);line-height:var(--leading-normal)}
.perf-panneau pre{margin:0;font:inherit;white-space:pre-wrap}
.perf-actions{display:flex;gap:var(--space-3);margin-top:var(--space-3)}
.perf-actions button{font:inherit;color:var(--text-primary);background:transparent;border:1px solid var(--text-subtle);border-radius:var(--space-2);padding:var(--space-2) var(--space-3);cursor:pointer}

@media (prefers-reduced-motion:reduce){.wall{animation:none!important}.wall.fondu{transition:none}}

/* ── Écrans étroits : moitiés empilées ; le canvas trace la faille à l'horizontale entre elles ── */
@media (max-width:760px){
  body{overflow:auto}
  .stage{position:relative;min-height:100vh}
  .half{position:relative;width:100%;height:50vh;min-height:360px}
  .masthead{position:absolute;top:22px;z-index:2}
  .tv .panel,.games .panel{left:24px;right:24px;bottom:32px;align-items:flex-start;text-align:left}
  .tv .panel{bottom:84px}
  .games .mark>.brand{transform-origin:left center}
  /* Avec les mentions légales, le texte tient sur 3 lignes en 390px mais sur 4 (61px) dès 360px, et ne tient pas dans
     les 32px du panneau Games : celui-ci monte de 42px, assez pour 4 lignes et un écart de 7px. */
  .games .panel{bottom:calc(74px + env(safe-area-inset-bottom,0px))}
  .sources{left:18px;right:18px;bottom:calc(6px + env(safe-area-inset-bottom,0px));max-width:none}
}
