/* Le système de Film 36, réduit à ce dont le web a besoin.
   Les mêmes trois couleurs que l'app : la nuit où l'on photographie,
   le papier où l'on découvre, et le jaune qui ne sert qu'à l'action. */

:root {
  --nuit: #101014;
  --papier: #E7E8F0;
  --flash: #FFEF46;
  --encre: #101014;
  --encre-60: #6C6D78;
  --surface: #FFFFFF;
  --surface-terne: #D8D9E2;
  --marge: 22px;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  background: var(--papier);
  color: var(--encre);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

/* Une seule vue à la fois : le web reproduit ici la logique d'écrans de
   l'app plutôt qu'un défilement de page. */
.ecran { display: none; min-height: 100dvh; flex-direction: column; }
.ecran[data-actif] { display: flex; }
.ecran.nuit { background: var(--nuit); color: var(--papier); }

h1 { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
h2 { font-size: 21px; font-weight: 700; letter-spacing: -0.01em; }
p { font-size: 16px; line-height: 1.45; color: var(--encre-60); }
.nuit p { color: #9A9BA6; }

.marque {
  font-weight: 800; font-size: 15px; letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------ accueil */

.accueil { padding: var(--marge); gap: 26px; justify-content: center; }
.accueil .bandeau { text-align: center; display: grid; gap: 12px; }

.champs { display: grid; gap: 12px; }

input {
  width: 100%; border: 0; border-radius: 16px; padding: 17px 18px;
  font-size: 17px; font-family: inherit; background: var(--surface);
  color: var(--encre); outline: 2px solid transparent; transition: outline-color .15s;
}
input:focus { outline-color: var(--encre); }
input::placeholder { color: var(--encre-60); }

#code {
  text-transform: uppercase; letter-spacing: 0.42em; text-align: center;
  font-weight: 700; font-size: 25px; padding-left: 0.42em; /* recentre l'interlettrage */
}

button {
  font-family: inherit; font-size: 17px; font-weight: 700; border: 0;
  border-radius: 999px; padding: 17px 22px; cursor: pointer;
  background: var(--flash); color: var(--encre); transition: transform .1s;
}
button:active { transform: scale(.97); }
button[disabled] { opacity: .45; cursor: default; }
button.discret { background: transparent; color: var(--encre-60); text-decoration: underline; }
.nuit button.discret { color: #9A9BA6; }

.erreur { color: #C2384A; font-size: 15px; min-height: 20px; text-align: center; }

/* Le pont vers l'app, réservé à iOS. Discret par construction : quelqu'un
   qui a ouvert ce lien voulait justement éviter d'installer quoi que ce
   soit. On propose, on ne barre pas la route — le formulaire reste au
   -dessus et fonctionne sans jamais passer par là. */
.pont {
  display: grid; gap: 12px; text-align: center;
  padding-top: 20px; border-top: 1px solid var(--surface-terne);
}
.pont p { font-size: 14px; }
button.secondaire {
  background: var(--surface); color: var(--encre);
  font-size: 16px; padding: 15px 22px;
}

/* ------------------------------------------------------------- viseur */

.viseur { position: relative; background: #000; }

/* Le cadre occupe tout ce qui reste : un jetable n'a pas de marges. */
.cadre { position: relative; flex: 1; overflow: hidden; background: #000; }
.cadre video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Le voile blanc du déclenchement.
   C'est le seul retour visuel : rien d'autre ne confirme la prise, puisque
   la photo ne s'affiche jamais. Sans lui, on redéclenche par doute. */
.voile {
  position: absolute; inset: 0; background: #fff; opacity: 0;
  pointer-events: none;
}
.voile.declenche { animation: eclair .22s ease-out; }
@keyframes eclair { from { opacity: .85; } to { opacity: 0; } }

.compteur {
  position: absolute; top: 18px; left: 18px;
  background: rgba(16,16,20,.62); backdrop-filter: blur(8px);
  padding: 8px 14px; border-radius: 999px;
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 15px;
  color: var(--papier); letter-spacing: .04em;
}

.commandes {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px var(--marge) calc(20px + env(safe-area-inset-bottom));
  background: var(--nuit);
}

.declencheur {
  width: 74px; height: 74px; border-radius: 50%; padding: 0;
  background: var(--papier); border: 5px solid var(--nuit);
  box-shadow: 0 0 0 3px var(--papier);
}
.declencheur:disabled { background: var(--encre-60); box-shadow: 0 0 0 3px var(--encre-60); }

.icone {
  width: 46px; height: 46px; border-radius: 50%; padding: 0;
  background: rgba(255,255,255,.12); color: var(--papier); font-size: 19px;
}

/* ------------------------------------------------------------ attente */

.centre {
  flex: 1; display: grid; place-content: center; gap: 16px;
  text-align: center; padding: var(--marge);
}
.grand-nombre {
  font-size: 62px; font-weight: 800; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ galerie */

.galerie { padding: var(--marge); gap: 18px; }
.grille { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.grille img {
  width: 100%; aspect-ratio: 3/4; object-fit: cover;
  border-radius: 12px; background: var(--surface-terne); display: block;
}

/* --------------------------------------------------- navigateur intégré */

.alerte { padding: var(--marge); gap: 20px; justify-content: center; text-align: center; }
.alerte .pastille {
  justify-self: center; width: 58px; height: 58px; border-radius: 50%;
  background: var(--flash); display: grid; place-content: center; font-size: 27px;
}

/* --- Hauteur réelle, mesurée plutôt que déclarée ---------------------
   Chrome sur iOS ment sur `100dvh` : ses barres d'outils **recouvrent**
   la page au lieu d'en réduire la hauteur. Le viseur dépassait donc par
   le bas et le déclencheur passait sous le pli — inatteignable au moment
   précis où l'on veut photographier.
   `visualViewport` donne la hauteur vraiment visible ; un script la
   reporte dans `--hauteur` à chaque changement. */
:root { --hauteur: 100dvh; }
.ecran { min-height: var(--hauteur); }
/* Le viseur ne défile jamais : il tient dans l'écran ou il n'est pas un
   viseur. Le cadre prend ce qui reste, les commandes gardent leur place. */
.viseur { height: var(--hauteur); max-height: var(--hauteur); overflow: hidden; }
.cadre { min-height: 0; flex: 1 1 auto; }
.commandes { flex: 0 0 auto; }
.galerie, .accueil { overflow-y: auto; }

/* ------------------------------------------------------- visionneuse */

.visionneuse {
  position: fixed; inset: 0; z-index: 50; background: #000;
  display: grid; place-items: center; overflow: hidden;
  /* `none` et non `pinch-zoom` : le zoom de page est désactivé par le
     `viewport` (sans quoi le viseur se déplacerait sous les doigts), donc
     le pincement est reconstruit ici. Laisser le navigateur intercepter
     les gestes lui ferait avaler ceux qu'on veut traiter. */
  touch-action: none;
}
.visionneuse[hidden] { display: none; }
.visionneuse img {
  max-width: 100%; max-height: 100%; display: block;
  transform-origin: 0 0; will-change: transform;
}
.visionneuse .fermer {
  position: absolute; top: calc(14px + env(safe-area-inset-top)); right: 14px;
  background: rgba(255,255,255,.16);
}
.grille img { cursor: zoom-in; }

/* La croix de fermeture, sur fond opaque.
   Elle était en blanc translucide : invisible dès qu'une photo claire
   passait dessous — c'est-à-dire la plupart du temps. Un disque plein,
   cerclé de blanc et ombré, tient sur n'importe quelle image, sombre
   comme claire. 48 px pour rester au-dessus du minimum tactile. */
.visionneuse .fermer {
  width: 48px; height: 48px; font-size: 21px; line-height: 1;
  background: rgba(16, 16, 20, .82);
  color: #fff;
  border: 1.5px solid rgba(255, 255, 255, .45);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
}

/* Le viseur au format du tirage.
   Il montrait tout le champ de la caméra alors que la capture est rognée
   en 3:4 : on cadrait donc sur une image plus large que la photo obtenue.
   Le cadre adopte le rapport final, et le noir autour dit franchement où
   s'arrête la pose. */
.cadre { aspect-ratio: 3 / 4; flex: 0 1 auto; align-self: center; width: 100%; }
.viseur { justify-content: center; }
