/* ============================================================================
   mickaelmancini.com
   Palette reprise du dashboard Trading Robot (dark, inspiration GitHub).
   Regle conservee : chiffres et etiquettes en monospace.
   ============================================================================ */

:root{
  color-scheme: dark;

  --bg:    #0d1117;
  --card:  #161b22;
  --card2: #1c232c;
  --line:  #283039;

  --txt:   #e6edf3;
  --dim:   #8b98a5;
  --dim2:  #6e7781;

  --green: #3fb950;
  --red:   #f85149;
  --amber: #d29922;
  --blue:  #58a6ff;

  --mono: ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --sans: system-ui,'Segoe UI',Roboto,sans-serif;

  --radius: 10px;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --measure: 42rem;

  --scroll-thumb:       rgba(110,119,129,0.38);
  --scroll-thumb-hover: rgba(110,119,129,0.62);
}

*, *::before, *::after{ box-sizing: border-box; }

html{
  -webkit-text-size-adjust: 100%;
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
  scroll-behavior: smooth;
}

::-webkit-scrollbar{ width: 10px; height: 10px; }
::-webkit-scrollbar-track{ background: transparent; }
::-webkit-scrollbar-thumb{
  background: var(--scroll-thumb);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover{ background: var(--scroll-thumb-hover); background-clip: padding-box; }

body{
  margin: 0;
  background: var(--bg);
  color: var(--txt);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  overflow-x: hidden;
}

img{ max-width: 100%; height: auto; display: block; }
a{ color: var(--blue); text-underline-offset: .2em; }

.wrap{ max-width: 78rem; margin: 0 auto; padding: 0 var(--gutter); }

/* ---------------------------------------------------------
   En-tete
   --------------------------------------------------------- */

.masthead{
  padding: clamp(3.5rem, 9vw, 6.5rem) 0 clamp(2rem, 4vw, 3rem);
}

.masthead h1{
  margin: 0;
  font-size: clamp(2.25rem, 1.4rem + 4vw, 4.25rem);
  font-weight: 650;
  letter-spacing: -.03em;
  line-height: 1.02;
}

.masthead h1 span{ color: var(--dim2); }

/* Link to the other language (index.html <-> en/index.html), top right of the
   first screen: the sticky menu scrolls sideways on phones and would hide it. */
.masthead .wrap{ position: relative; }
.lang-switch{
  position: absolute;
  top: calc(-1 * clamp(3.5rem, 9vw, 6.5rem) + 1.1rem);
  right: var(--gutter);
  color: var(--dim);
  text-decoration: none;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: color .2s ease;
}
.lang-switch:hover{ color: var(--txt); }

.masthead p{
  max-width: var(--measure);
  margin: 1.25rem 0 0;
  color: var(--dim);
  font-size: clamp(1rem, .95rem + .3vw, 1.15rem);
}

/* ---------------------------------------------------------
   Sommaire
   --------------------------------------------------------- */

.index{
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(13,17,23,.86);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.index .wrap{
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  padding-top: .85rem;
  padding-bottom: .85rem;
}

/* Sept entrees dans une barre collante : sur telephone elles passeraient a la
   ligne trois ou quatre fois et mangeraient la moitie de l'ecran. On defile
   lateralement plutot que d'empiler. */
@media (max-width: 48rem){
  .index .wrap{
    flex-wrap: nowrap;
    gap: 1.15rem;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .index .wrap::-webkit-scrollbar{ display: none; }

  .index a{ flex: 0 0 auto; }
}

.index a{
  color: var(--dim);
  text-decoration: none;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: color .2s ease;
}

.index a:hover{ color: var(--txt); }

/* ---------------------------------------------------------
   Sections
   --------------------------------------------------------- */

.section{ padding: clamp(3rem, 7vw, 5.5rem) 0; border-bottom: 1px solid var(--line); }
.section:last-of-type{ border-bottom: 0; }

.section-head{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem 1rem;
  margin-bottom: 1.75rem;
}

.section-head h2{
  margin: 0;
  font-size: clamp(1.6rem, 1.1rem + 2vw, 2.4rem);
  font-weight: 650;
  letter-spacing: -.02em;
}

.section-head p{
  flex-basis: 100%;
  max-width: var(--measure);
  margin: .35rem 0 0;
  color: var(--dim);
}

/* ---------------------------------------------------------
   Travaux
   --------------------------------------------------------- */

.works{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.work{
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.35rem 1.5rem 1.5rem;
  position: relative;
  transition: border-color .25s ease, transform .25s ease;
}

.work:hover{ border-color: var(--dim2); transform: translateY(-2px); }

.work h3{
  margin: 0;
  font-size: 1.2rem;
  font-weight: 650;
  letter-spacing: -.01em;
}

.work h3 a{ color: var(--txt); text-decoration: none; }
.work-title{ display: inline-flex; align-items: center; gap: .65rem; }
.work-icon{ width: 2.5rem; height: 2.5rem; flex: 0 0 auto; }
/* The title link stretches over its whole card: one link for screen readers, the card as the target. */
.work h3 a::after{ content: ""; position: absolute; inset: 0; border-radius: var(--radius); }
.work h3 a:focus-visible{ outline: none; }
.work h3 a:focus-visible::after{ outline: 2px solid var(--blue); outline-offset: 2px; }
.work:hover h3 a{ color: var(--blue); }

.work-meta{
  margin: .4rem 0 0;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim2);
}

.work p:last-child{ margin: .8rem 0 0; color: var(--dim); font-size: .95rem; }

/* Projet sans page dediee : le dire, pour qu'un titre non cliquable ne
   ressemble pas a un lien casse. */
.work-tag{
  display: inline-block;
  margin-left: .5rem;
  padding: .05rem .5rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--dim2);
  letter-spacing: .06em;
  vertical-align: .05em;
}

/* ---------------------------------------------------------
   Grilles d'images
   --------------------------------------------------------- */

.grid{
  display: grid;
  gap: .9rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.grid--dense{
  gap: .5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(46%, 7.5rem), 1fr));
}

.tile{
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--card);
  cursor: zoom-in;
  transition: border-color .25s ease, transform .25s ease;
}

.tile:hover{ border-color: var(--dim2); transform: translateY(-2px); }
.tile:focus-visible{ outline: 2px solid var(--blue); outline-offset: 2px; }

.tile img{
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--card2);
}

.grid--dense .tile img{ aspect-ratio: 1; }
.grid--dense .tile{ border-radius: 8px; }

.tile figcaption{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .6rem;
  padding: .6rem .75rem .7rem;
  border-top: 1px solid var(--line);
  text-align: left;
}

.tile-title{ font-size: .9rem; color: var(--txt); }
.tile-sci{ font-size: .82rem; color: var(--dim); }

.tile-note{
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--dim2);
}

/* Bloc « voir plus » de la collection */
.more{
  display: block;
  margin: 1.25rem auto 0;
  padding: .7rem 1.4rem;
  background: var(--card);
  color: var(--txt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: border-color .2s ease, background .2s ease;
}

.more:hover{ border-color: var(--dim2); background: var(--card2); }

/* ---------------------------------------------------------
   Video
   --------------------------------------------------------- */

.film{ margin: 0; max-width: 56rem; }
.grid + .film{ margin-top: 2rem; }

.film-frame{
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--card2);
  cursor: pointer;
}

.film-frame img{ width: 100%; height: 100%; object-fit: cover; opacity: .85; transition: opacity .3s ease, transform .6s ease; }
.film-frame:hover img{ opacity: 1; transform: scale(1.02); }
.film-frame iframe{ position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.film-play{
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%,-50%);
  width: 4.25rem; aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(13,17,23,.82);
  border: 1px solid var(--line);
  transition: transform .25s ease, border-color .25s ease;
}

.film-play::after{
  content: "";
  position: absolute;
  left: 54%; top: 50%;
  transform: translate(-50%,-50%);
  border-style: solid;
  border-width: .5rem 0 .5rem .85rem;
  border-color: transparent transparent transparent var(--txt);
}

.film-frame:hover .film-play{ transform: translate(-50%,-50%) scale(1.06); border-color: var(--dim2); }

.film figcaption{
  display: flex;
  flex-wrap: wrap;
  gap: .35rem .9rem;
  align-items: baseline;
  padding-top: .8rem;
  color: var(--dim);
  font-size: .9rem;
}

/* ---------------------------------------------------------
   Pied
   --------------------------------------------------------- */

.colophon{
  border-top: 1px solid var(--line);
  padding: clamp(2.5rem, 6vw, 4rem) 0 clamp(3rem, 7vw, 5rem);
  color: var(--dim2);
  font-size: .88rem;
}

.colophon p{ margin: 0 0 .45rem; }

/* ---------------------------------------------------------
   Visionneuse
   --------------------------------------------------------- */

.viewer{
  width: min(96vw, 88rem);
  max-width: none;
  max-height: 96vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--txt);
  overflow: hidden;
}

.viewer::backdrop{ background: rgba(1,4,9,.88); }

.viewer img{
  width: 100%;
  max-height: 84vh;
  object-fit: contain;
  background: var(--bg);
}

.viewer-bar{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .6rem .9rem;
  border-top: 1px solid var(--line);
}

.viewer-caption{
  margin: 0;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim2);
}

.viewer-close{
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: .3rem .7rem;
  background: var(--card2);
  color: var(--dim);
  cursor: pointer;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.viewer-close:hover{ color: var(--txt); border-color: var(--dim2); }

/* ---------------------------------------------------------
   Chat : bulle en bas a droite, panneau lateral.
   Plein ecran sur telephone, ou un panneau de 24rem n'a pas la place.
   --------------------------------------------------------- */

.masthead .masthead-chat{ margin-top: .6rem; }

.chat-bubble{
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .7rem 1.05rem .7rem .9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card2);
  color: var(--txt);
  font: inherit;
  font-size: .92rem;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(1,4,9,.55);
  transition: border-color .15s, transform .15s;
}

.chat-bubble:hover{ border-color: var(--dim2); transform: translateY(-1px); }
.chat-bubble svg{ width: 1.15rem; height: 1.15rem; fill: var(--blue); flex: none; }

.chat-dot{
  position: absolute;
  top: .2rem;
  right: .2rem;
  width: .6rem;
  height: .6rem;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 2px var(--card2);
}

.chat{
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 40;
  width: min(24rem, calc(100vw - 2.5rem));
  height: min(38rem, calc(100vh - 2.5rem));
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 16px 48px rgba(1,4,9,.6);
  overflow: hidden;
}

.chat[hidden], .chat-bubble[hidden], .chat [hidden]{ display: none; }

.chat-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .7rem .9rem;
  border-bottom: 1px solid var(--line);
}

.chat-head h2{
  margin: 0;
  font-family: var(--mono);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dim);
}

.chat-close, .chat-send, .chat-admin-exit{
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: .3rem .7rem;
  background: var(--card2);
  color: var(--dim);
  cursor: pointer;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.chat-close:hover, .chat-admin-exit:hover{ color: var(--txt); border-color: var(--dim2); }

.chat-scroll{
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .9rem;
}

.chat-list{ list-style: none; margin: 0; padding: 0; }

.chat-msg{ margin: 0 0 .85rem; }
.chat-msg p{ margin: 0; }

.chat-meta{
  display: flex;
  align-items: baseline;
  gap: .5rem;
}

.chat-author{ font-weight: 600; font-size: .88rem; color: var(--txt); }

.chat-when{
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .06em;
  color: var(--dim2);
}

.chat-body{
  color: var(--dim);
  font-size: .92rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.chat-msg--owner{
  padding: .55rem .7rem;
  border-left: 2px solid var(--blue);
  border-radius: 0 6px 6px 0;
  background: var(--card2);
}

.chat-msg--owner .chat-author{ color: var(--blue); }
.chat-msg--owner .chat-body{ color: var(--txt); }
.chat-msg--pinned{ margin-bottom: 1.1rem; }

.chat-delete{
  margin-left: auto;
  border: 0;
  padding: 0 .3rem;
  background: none;
  color: var(--dim2);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.chat-delete:hover{ color: var(--red); }

.chat-form{
  display: grid;
  gap: .5rem;
  padding: .75rem .9rem .85rem;
  border-top: 1px solid var(--line);
}

.chat-form input, .chat-form textarea{
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: .5rem .65rem;
  background: var(--bg);
  color: var(--txt);
  font: inherit;
  font-size: 16px; /* sous 16px, iOS zoome sur le champ */
  resize: none;
}

.chat-form input:focus, .chat-form textarea:focus{ outline: none; border-color: var(--blue); }

.chat-form .chat-hp{
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.chat-turnstile:empty{ display: none; }

.chat-actions{
  display: flex;
  align-items: center;
  gap: .6rem;
}

.chat-status{
  flex: 1;
  margin: 0;
  font-size: .8rem;
  color: var(--dim);
}

.chat-status.is-error{ color: var(--amber); }

.chat-count{
  font-family: var(--mono);
  font-size: .68rem;
  color: var(--dim2);
}

.chat-count.is-low{ color: var(--amber); }

.chat-send{ background: var(--blue); border-color: var(--blue); color: var(--bg); font-weight: 600; }
.chat-send:hover{ filter: brightness(1.1); }
.chat-send:disabled{ opacity: .5; cursor: default; }

.chat-admin{
  margin: 0;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--amber);
}

@media (max-width: 48rem){
  .chat-bubble{ right: 1rem; bottom: 1rem; padding: .8rem; }
  .chat-bubble-label{
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .chat-bubble svg{ width: 1.35rem; height: 1.35rem; }

  .chat{
    inset: 0;
    width: 100%;
    height: 100%;
    height: 100dvh;
    border: 0;
    border-radius: 0;
  }

  /* Le panneau couvre tout l'ecran : la page derriere ne doit pas defiler. */
  .chat-is-open, .chat-is-open body{ overflow: hidden; }
}

/* ---------------------------------------------------------
   Snake and ball
   A fixed layer over the page: it never takes a click and it
   stays under the message bubble (z-index 40).
   --------------------------------------------------------- */

#snake-canvas{
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 30;
}

.snake-best{ font-family: var(--mono); font-size: .78rem; }

/* A button over the resting ball starts the game; its dare, in the colour of
   the ball, sits to its left and starts it too. */
.snake-start{
  position: fixed;
  z-index: 31;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}
.snake-hint{
  position: absolute;
  right: 26px;
  top: 50%;
  transform: translateY(-50%);
  padding: 4px 0;
  white-space: nowrap;
  color: var(--amber);
  font: 600 .78rem/1 var(--mono);
}
/* On a phone the title reaches the ball: the dare goes above it. */
@media (max-width: 48rem){
  .snake-hint{ right: 0; top: auto; bottom: 24px; transform: none; }
}

/* The text cut into letters while a capsule plays with it: words never break
   apart, and a letter can only move once it is a box of its own. */
.snake-w{ white-space: nowrap; }
.snake-letters-move .snake-ch{ display: inline-block; }
.snake-fonts :is(.masthead, .index, main, .colophon),
.snake-fonts :is(.masthead, .index, main, .colophon) *{ font-family: var(--snake-font, inherit); }

/* Capsules that change the look of the page itself. The game layer and its
   start button are siblings of these blocks, so they are never affected.
   Disco and Séisme are driven by the game through two variables rather than
   by a CSS animation, which the reduced-motion rule below would turn into a
   strobe. Each selector starts with the class and a space: the tests look for it. */
.masthead, .index, main, .colophon{ transition: transform .5s ease, filter .5s ease; }
.snake-mod-negative :is(.masthead, .index, main, .colophon){ filter: invert(1) hue-rotate(180deg); }
.snake-mod-mono :is(.masthead, .index, main, .colophon){ filter: grayscale(1) contrast(1.15); }
.snake-mod-blur :is(.masthead, .index, main, .colophon){ filter: blur(3px); }
.snake-mod-disco :is(.masthead, .index, main, .colophon){ filter: hue-rotate(var(--snake-hue, 0deg)) saturate(1.6); transition: none; }
.snake-mod-tilt :is(.masthead, .index, main, .colophon){ transform: rotate(-3deg); }
.snake-mod-zoom :is(.masthead, .index, main, .colophon){ transform: scale(1.08); }
.snake-mod-upside :is(.masthead, .index, main, .colophon){ transform: rotate(180deg); }
.snake-mod-quake :is(.masthead, .index, main, .colophon){ transform: translate(var(--snake-dx, 0), var(--snake-dy, 0)); transition: none; }

/* ---------------------------------------------------------
   Home motion (js/motion-gate.js, js/motion.js): fades only.
   Hidden only while the scripts run: without them, or if they
   fail, the page shows exactly as before.
   --------------------------------------------------------- */

html.motion :is(.masthead h1, .masthead p, .index .wrap > a, .section-head, .tile-wrap, .film, .work):not(.motion-in){ opacity: 0; }

/* A rule across the top of each section in place of the border under the
   previous one. */
html.motion-on .section{ position: relative; border-bottom: 0; }
.motion-rule{
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--line);
}

/* Hover: a blue line under the card. */
html.motion-on .work::before{
  content: "";
  position: absolute;
  left: 1.5rem; right: 1.5rem; bottom: -1px;
  height: 2px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: left;
}
html.motion-on .work:hover::before{ transform: scaleX(1); }

/* ---------------------------------------------------------
   Divers
   --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}
