/* Biscuit & Will — conversation animée. Tokens partagés dans ../shared/tokens.css */

:root {
  --bubble-dog: var(--biscuit);
  --bubble-human: var(--paper);
  --avatar: 36px;
  --gap: 8px;
  /* Deux courbes : un ease-out pur, et un ressort très léger (dépassement ~2 %) */
  --ease-soft: cubic-bezier(.22, 1, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.25, .64, 1);
}

/* Hauteur DÉFINIE (pas min-height) : c'est ce qui permet au fil de scroller
   à l'intérieur du cadre sur mobile au lieu de faire grandir la page. */
body {
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ── Cadre : plein écran sur mobile, panneau « téléphone » centré au-delà ──── */
.phone {
  position: relative; /* l'écran d'intro se pose par-dessus */
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--ground);
}
@media (min-width: 640px) {
  body {
    background: var(--ground-deep);
    display: grid;
    place-items: center;
    padding: 24px;
    box-sizing: border-box;
    overflow: hidden;
  }
  .phone {
    flex: none;
    width: 430px;
    max-width: 100%;
    height: min(860px, calc(100dvh - 48px));
    border-radius: 40px;
    overflow: hidden;
    box-shadow:
      0 40px 90px -40px rgb(var(--shadow-rgb) / .5),
      0 0 0 1px rgb(var(--shadow-rgb) / .06);
  }
}

/* ── Écran d'accueil : heure, date, et la notification qui descend ────────── */
.intro {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16vh 20px 0;
  padding-top: max(16vh, env(safe-area-inset-top));
  background: linear-gradient(180deg, var(--ground) 0%, var(--ground-deep) 100%);
  cursor: pointer;
  touch-action: none;   /* on gère le swipe nous-mêmes */
  user-select: none;
  -webkit-user-select: none;
  transition: transform 560ms cubic-bezier(.32, .72, 0, 1); /* la courbe de déverrouillage iOS */
}
.intro.leave {
  transform: translateY(-100%);
  pointer-events: none;
}
.intro[hidden] { display: none; }
.intro-time {
  margin: 0;
  font-size: 4.4rem;
  font-weight: 500;
  letter-spacing: -.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.intro-date {
  margin: 8px 0 0;
  color: var(--ink-soft);
  font-weight: 700;
}
.intro-date::first-letter { text-transform: uppercase; }
.notif {
  margin-top: 48px;
  width: 100%;
  max-width: 380px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px 16px 14px;
  border: 0;
  border-radius: 26px;
  background: rgb(255 249 240 / .94);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 1px 2px rgb(var(--shadow-rgb) / .08), 0 18px 40px -18px rgb(var(--shadow-rgb) / .45);
  opacity: 0;
  transform: translateY(-48px) scale(.9);
  transition: opacity 450ms ease-out, transform 700ms var(--ease-spring);
}
.notif.show {
  opacity: 1;
  transform: none;
  animation: invite 2.6s ease-in-out 1.4s infinite;
}
.notif:focus-visible { outline: none; }
.notif:active { transform: scale(.98); }
@keyframes invite {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.025); }
}
.notif-icon {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 17px;
  background: var(--leaf);
  color: #fff;
}
.notif-icon svg { width: 30px; height: 30px; }
.badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: #D9534F;
  color: #fff;
  font-size: .78rem;
  font-weight: 800;
  line-height: 20px;
  text-align: center;
  box-shadow: 0 0 0 2px rgb(255 249 240 / .94);
}
.notif-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.notif-body small { color: var(--ink-soft); font-size: .8rem; font-weight: 700; }
.notif-body strong { font-size: 1.12rem; font-weight: 800; line-height: 1.2; text-wrap: balance; }
.notif-body span { color: var(--ink-soft); font-size: .95rem; font-weight: 500; }

/* Les deux conseils en bas : « Appuie sur l'écran », puis la barre d'accueil et le swipe */
.wake-hint,
.swipe-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: max(22px, env(safe-area-inset-bottom));
  margin: 0;
  text-align: center;
  color: var(--ink-soft);
  font-size: .85rem;
  font-weight: 700;
  transition: opacity 500ms ease-out;
}
.wake-hint { animation: pulse-hint 2.4s ease-in-out infinite; }
.wake-hint.gone { opacity: 0; animation: none; }
@keyframes pulse-hint {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}
.swipe-hint { opacity: 0; }
.swipe-hint.show { opacity: 1; }
.home-bar {
  display: block;
  width: 120px;
  height: 5px;
  margin: 12px auto 0;
  border-radius: 999px;
  background: rgb(var(--shadow-rgb) / .35);
}

/* ── En-tête façon messagerie ─────────────────────────────────────────────── */
.bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  padding-top: max(10px, env(safe-area-inset-top));
  border-bottom: 1px solid rgb(var(--shadow-rgb) / .08);
}
.back {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-left: -10px;
  border-radius: var(--radius-control);
  color: var(--leaf);
  transition: background-color 150ms ease-out;
}
.back:hover { background: rgb(var(--shadow-rgb) / .06); }
.back:active { background: rgb(var(--shadow-rgb) / .1); }
.back svg {
  width: 24px;
  height: 24px;
  margin-left: -3px; /* alignement optique du chevron */
}
.back:focus-visible,
button:focus-visible {
  outline: 3px solid var(--leaf);
  outline-offset: 2px;
}
.who {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
/* Bouton muet : même gabarit que le retour, à droite */
.mute {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}
.mute:hover { background: rgb(var(--shadow-rgb) / .06); }
.mute:active { background: rgb(var(--shadow-rgb) / .1); }
.mute svg { width: 22px; height: 22px; }
.mute .icon-off { display: none; }
.mute[aria-pressed="true"] .icon-on { display: none; }
.mute[aria-pressed="true"] .icon-off { display: block; }
.mute[hidden] { display: none; }
.who strong {
  display: block;
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.15;
}
.who small {
  display: block;
  color: var(--ink-soft);
  font-size: .8rem;
  font-weight: 700;
}

/* ── Avatars ──────────────────────────────────────────────────────────────── */
.avatar {
  display: inline-grid;
  place-items: center;
  width: var(--avatar);
  height: var(--avatar);
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: var(--biscuit);
  color: rgb(var(--shadow-rgb) / .55);
  box-shadow: inset 0 0 0 1px rgb(var(--shadow-rgb) / .1);
}
.avatar svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}
.avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.who .avatar { --avatar: 40px; }

/* ── Fil : c'est lui qui scrolle, pas la page ─────────────────────────────── */
.thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none; /* le fil scrolle, mais sans barre visible (Windows/Linux) */
  padding: 20px 16px 24px;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}
.thread::-webkit-scrollbar { display: none; }
.row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  flex: none;
}
.row-human { flex-direction: row-reverse; }
.row-cont { margin-top: calc(3px - var(--gap)); } /* bulles d'un même groupe : serrées */
.slot {
  width: var(--avatar);
  flex: none;
}

.bubble {
  max-width: 78%;
  box-sizing: border-box;
  padding: 10px 15px;
  border-radius: var(--radius-bubble);
  font-size: 1.02rem;
  font-weight: 500;
  line-height: 1.4;
  text-wrap: pretty;
  overflow-wrap: anywhere;
  box-shadow: 0 1px 1px rgb(var(--shadow-rgb) / .05), 0 6px 18px -8px rgb(var(--shadow-rgb) / .22);
  transform-origin: bottom left;
}
.row-dog .bubble {
  background: var(--bubble-dog);
  font-weight: 700;
}
.row-human .bubble {
  background: var(--bubble-human);
  transform-origin: bottom right;
}
/* Coin « queue » côté avatar */
.row-dog .bubble { border-bottom-left-radius: 6px; }
.row-human .bubble { border-bottom-right-radius: 6px; }

/* Sticker envoyé comme une photo : pas de bulle, juste l'image détourée et son ombre */
.bubble.sticker {
  max-width: 70%;
  padding: 0;
  background: none;
  box-shadow: none;
}
.bubble.sticker img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 46vh;
  filter: drop-shadow(0 8px 16px rgb(var(--shadow-rgb) / .25));
}
.row-human .bubble.sticker img { margin-left: auto; }

/* Image opaque envoyée comme une photo : cadre arrondi, sans le coin « queue » */
.bubble.photo {
  max-width: 58%;
  padding: 0;
  overflow: hidden;
  border-radius: 18px !important;
  background: var(--paper);
}
.bubble.photo img {
  display: block;
  width: 100%;
  height: auto;
}

/* Le choix : deux réponses côté Madline, une seule possible */
.choices {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  max-width: 82%;
  transform-origin: bottom right;
}
.choice {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 1rem;
  font-weight: 800;
  min-height: 44px;
  padding: 10px 20px;
  border: 0;
  border-radius: var(--radius-control);
  background: var(--leaf);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 1px 2px rgb(var(--shadow-rgb) / .15), 0 10px 22px -10px rgb(46 125 87 / .6);
  transition-property: transform, background-color, box-shadow;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
}
.choice:hover { background: #29704E; }
.choice:active { transform: scale(.97); }
.choice.locked {
  background: var(--paper);
  color: var(--ink-soft);
  cursor: not-allowed;
  box-shadow: inset 0 0 0 1.5px rgb(var(--shadow-rgb) / .15);
}
.choice.locked:hover { background: var(--paper); }
.choice.locked:active { transform: none; }
.choice.locked svg { width: 16px; height: 16px; flex: none; }
@keyframes nope {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-5px); }
  40%      { transform: translateX(5px); }
  60%      { transform: translateX(-3px); }
  80%      { transform: translateX(3px); }
}
.choice.locked.nope { animation: nope 380ms ease-out; }

/* La révélation du cadeau : même bulle, un halo doux autour */
.bubble.gift {
  background: var(--paper);
  box-shadow:
    0 0 0 1.5px rgb(46 125 87 / .35),
    0 0 28px rgb(46 125 87 / .22),
    0 6px 18px -8px rgb(var(--shadow-rgb) / .22);
}

/* Voix off de la communicatrice : centrée, en italique, sans bulle */
.row-note {
  justify-content: center;
  padding: 8px 12px;
}
.bubble.note {
  max-width: 90%;
  padding: 4px 8px;
  background: none;
  box-shadow: none;
  color: var(--ink-soft);
  font-size: .92rem;
  font-style: italic;
  font-weight: 500;
  line-height: 1.5;
  text-align: center;
  transform-origin: bottom center;
}

/* ── Indicateur « écrit… » : trois points qui respirent ───────────────────── */
.bubble.typing {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 15px 16px;
}
.bubble.typing i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgb(var(--shadow-rgb) / .45);
  animation: breathe-dot 1100ms ease-in-out infinite;
}
.row-dog .bubble.typing i { animation-duration: 900ms; }
.bubble.typing i:nth-child(2) { animation-delay: 150ms; }
.bubble.typing i:nth-child(3) { animation-delay: 300ms; }
@keyframes breathe-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: .5; }
  30%           { transform: translateY(-3px); opacity: 1; }
}
/* Le chien « écrit » avec trois croquettes (dessin SVG, ou l'image de dialogue.js).
   La rotation est sur l'enfant : le parent garde l'animation translateY. */
.bubble.typing .kibble {
  width: 13px;
  height: 13px;
  background: none;
}
.kibble span,
.kibble svg,
.kibble img {
  display: block;
  width: 100%;
  height: 100%;
}
.kibble img { object-fit: contain; }
.kibble:nth-child(1) span { transform: rotate(-24deg); }
.kibble:nth-child(2) span { transform: rotate(12deg); }
.kibble:nth-child(3) span { transform: rotate(-8deg); }

/* ── Apparition : fondu + légère montée. Le chien a un soupçon de ressort ── */
@keyframes pop-human {
  from { opacity: 0; transform: translateY(8px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes pop-dog {
  from { opacity: 0; transform: translateY(10px) scale(.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.pop { animation: pop-human 420ms var(--ease-soft) both; }
.row-dog .pop { animation: pop-dog 520ms var(--ease-spring) both; }

/* ── Le texte arrive lettre à lettre : fondu + flou qui se dissipe ────────── */
/* Les lettres restent « inline » (pas de transform possible, mais le flou marche
   et surtout les mots continuent de se couper aux espaces, pas au milieu). */
.ch {
  opacity: 0;
  animation: letter 320ms ease-out both; /* durée reprise dans script.js (LETTER_MS) */
}
@keyframes letter {
  from { opacity: 0; filter: blur(3px); }
  to   { opacity: 1; filter: blur(0); }
}
/* Tap pendant l'animation : le texte est complet tout de suite */
.bubble.done .ch {
  animation: none;
  opacity: 1;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── L'avatar respire quand sa bulle arrive ───────────────────────────────── */
@keyframes breathe {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}
.avatar.breathe { animation: breathe 480ms ease-in-out; }

/* ── Pied : le conseil « Appuie pour continuer », puis « Rejouer » ────────── */
/* Bande réservée en permanence : rien ne saute quand l'un ou l'autre apparaît. */
.foot {
  flex: none;
  display: grid;
  place-items: center;
  min-height: 76px;
  padding: 8px 16px;
  padding-bottom: max(16px, env(safe-area-inset-bottom));
}
.foot > * { grid-area: 1 / 1; }
.hint {
  margin: 0;
  color: var(--ink-soft);
  font-size: .85rem;
  font-weight: 700;
  opacity: 0;
  visibility: hidden;
  transition: opacity 400ms ease-out, visibility 0s linear 400ms;
}
.hint.show {
  opacity: 1;
  visibility: visible;
  transition: opacity 400ms ease-out;
}
.replay {
  font: inherit;
  font-size: 1rem;
  font-weight: 800;
  min-height: 44px;
  padding: 12px 26px;
  border: 0;
  border-radius: var(--radius-control);
  background: var(--leaf);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 1px 2px rgb(var(--shadow-rgb) / .15), 0 10px 22px -10px rgb(46 125 87 / .6);
  transition-property: transform, background-color, box-shadow;
  transition-duration: 150ms;
  transition-timing-function: ease-out;
  animation: pop-dog 600ms var(--ease-spring) both;
}
.replay[hidden] { display: none; }
.replay:hover { background: #29704E; }
.replay:active { transform: scale(.97); }

/* ── Mouvement réduit : tout devient un simple fondu ──────────────────────── */
@media (prefers-reduced-motion: reduce) {
  @keyframes fade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes blink { 50% { opacity: .35; } }
  .pop, .row-dog .pop, .replay { animation: fade 160ms ease-out both; }
  .avatar.breathe { animation: none; }
  .choice.locked.nope { animation: none; }
  .notif.show { animation: none; }
  .wake-hint { animation: none; opacity: .8; }
  .ch { animation: none; opacity: 1; }
  .bubble.typing i { animation: blink 1s ease-in-out infinite; }
}
