/* Figurines Bobble (mêmes calques que l'app, Canon.swift) et particules des réactions.
   Partagé par la landing (index.html) et la page d'invitation (api/invite.js) ; en bas, l'île (js/island.js). */
/* Figurines v2 (mêmes calques que l'app) : contours → tête arrière → corps → visage → bras levé */
.fig:focus{outline:none}.fig:focus-visible{outline:3px solid var(--lemon);outline-offset:4px;border-radius:12px}
.fig{position:relative;cursor:pointer;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;touch-action:pan-y;filter:drop-shadow(0 6px 7px rgba(23,19,31,.16));transform-origin:50% 100%;flex:none}
.fig .cv{position:absolute}
.fig img{position:absolute;display:block;user-select:none;-webkit-user-drag:none;pointer-events:none}
.fig .hc{transform-origin:50% 56%;animation:idle 3.6s ease-in-out infinite;animation-delay:var(--d);rotate:var(--flick,0deg);translate:0 0}
.fig.pop .bc{animation:pop .32s cubic-bezier(.3,1.6,.5,1)}
@keyframes pop{0%{transform:scale(1.04,.93)}100%{transform:none}}
.fig .bc{transform-origin:50% 98%}
@keyframes idle{0%,100%{transform:rotate(-1.2deg)}50%{transform:rotate(1.2deg)}}
.head{position:relative;flex:none}
.head .cv{position:absolute}.head img{position:absolute;display:block;pointer-events:none}
/* Scènes des réactions (tempo de l'app ×1,3) */
.fig.a-hype{animation:hops 1.5s cubic-bezier(.3,1.4,.5,1)}
.fig.a-hype .hc{animation:headbang 1.5s ease-in-out}
@keyframes hops{0%,100%{transform:none}8%{transform:scale(1.06,.9)}22%{transform:translateY(-7%) scale(.97,1.05)}34%{transform:none}46%{transform:scale(1.04,.92)}60%{transform:translateY(-4.5%) scale(.98,1.04)}74%{transform:none}}
@keyframes headbang{0%,100%{transform:none}10%{transform:scale(1.06)}25%{transform:rotate(7deg)}40%{transform:rotate(-7deg)}55%{transform:rotate(6deg)}70%{transform:rotate(-4deg)}}
.fig.a-kiss{animation:shrug 2.4s ease-in-out}
.fig.a-kiss .hc{animation:shy 2.4s cubic-bezier(.3,1.2,.5,1)}
@keyframes shrug{0%,100%{transform:none}15%{transform:scale(.95)}30%{transform:scale(.95) rotate(2.5deg)}45%{transform:scale(.95) rotate(-2.5deg)}60%{transform:scale(.95) rotate(2deg)}75%{transform:scale(.95) rotate(-1.5deg)}}
@keyframes shy{0%,100%{transform:none}18%{transform:rotate(-18deg) scale(.9)}35%{transform:rotate(-11deg) scale(.9)}52%{transform:rotate(-19deg) scale(.9)}68%{transform:rotate(-13deg) scale(.9)}82%{transform:rotate(-15deg) scale(.88)}}
.fig.a-slap .hc{animation:slap 1.75s cubic-bezier(.2,1.4,.4,1)}
@keyframes slap{0%{transform:none}7%{transform:rotate(-34deg) scale(1.16)}22%{transform:rotate(18deg) scale(1.05)}38%{transform:rotate(6deg)}56%{transform:rotate(-6deg)}74%{transform:rotate(4deg)}100%{transform:none}}
.fig.a-wave{animation:sway 1.95s ease-in-out}
.fig.a-wave .hc{animation:follow 1.95s ease-in-out}
@keyframes sway{0%,100%{transform:none}20%{transform:rotate(9deg)}42%{transform:rotate(-9deg)}64%{transform:rotate(6deg)}84%{transform:rotate(-3deg)}}
@keyframes follow{0%,100%{transform:none}8%{transform:scale(1.07)}28%{transform:rotate(-5deg)}50%{transform:rotate(6deg)}70%{transform:rotate(-5deg)}88%{transform:rotate(3deg)}}
/* Particules en stickers plats (comme ReactionFX dans l'app) */
.fx{position:absolute;pointer-events:none;user-select:none;-webkit-user-select:none;width:var(--s,20px);height:var(--s,20px);filter:drop-shadow(0 2px 2.5px rgba(23,19,31,.18))}
.fx svg{display:block;width:100%;height:100%;overflow:visible}
.fx.spark{animation:spark .9s cubic-bezier(.2,.8,.4,1) forwards}
@keyframes spark{0%{transform:translate(0,0) scale(.2) rotate(var(--rot,0deg))}35%{transform:translate(calc(var(--bx)*.7),calc(var(--by)*.7)) scale(1.15) rotate(var(--rot,0deg))}100%{transform:translate(var(--bx),var(--by)) scale(0) rotate(var(--rot,0deg))}}
.fx.heart{left:0;top:0}
.fx.star{animation:orbit 1.6s linear forwards}
@keyframes orbit{0%{transform:rotate(var(--a)) translateX(var(--r)) rotate(calc(-1*var(--a))) scale(.3)}15%{transform:rotate(calc(var(--a) + 60deg)) translateX(var(--r)) rotate(calc(-1*var(--a) - 60deg)) scale(1)}85%{transform:rotate(calc(var(--a) + 330deg)) translateX(var(--r)) rotate(calc(-1*var(--a) - 330deg)) scale(1)}100%{transform:rotate(calc(var(--a) + 380deg)) translateX(var(--r)) rotate(calc(-1*var(--a) - 380deg)) scale(0)}}
.fx.hi{width:auto;height:auto;font-family:"Gochi Hand",cursive;font-size:var(--s);color:var(--ink);background:#fff;border-radius:.55em;padding:.02em .45em .1em;transform-origin:0 100%;animation:hi 1.9s cubic-bezier(.3,1.5,.5,1) forwards}
.fx.hi:after{content:"";position:absolute;left:.5em;bottom:-.22em;width:.45em;height:.45em;background:#fff;transform:rotate(45deg);border-radius:1px}
@keyframes hi{0%{transform:scale(0) rotate(-12deg)}15%{transform:scale(1.1) rotate(-6deg)}25%,85%{transform:scale(1) rotate(-6deg)}100%{transform:scale(0) rotate(-6deg)}}
.fx.hand{width:auto;height:auto;font-size:var(--s);line-height:1;filter:none;animation:smack .5s cubic-bezier(.3,1.6,.5,1) forwards}
@keyframes smack{0%{transform:translate(-50%,-50%) scale(.3) rotate(-25deg)}30%{transform:translate(-50%,-50%) scale(1.15) rotate(8deg)}75%{transform:translate(-50%,-50%) scale(1)}100%{transform:translate(-50%,-50%) scale(0)}}
/* Pluie des séries de gifles (js/figures.js, StreakRain) : par-dessus toute la page, jamais sous le doigt */
.rain{position:fixed;inset:0;pointer-events:none;z-index:60;overflow:hidden}
.rain .drop{position:absolute;left:0;top:0;transform:scale(0);filter:drop-shadow(0 2px 2.5px rgba(23,19,31,.18))}
.rain .drop svg{display:block;width:100%;height:100%;overflow:visible}
/* L'île « what are your friends doing? » (js/island.js ; landing, invitation), la même que la Live Activity de l'app.
   Tailles par variables, posées par la page : --iw0 / --ih0 pilule fermée, --iw / --ihx ouverte, --ihs + --sw (mesurée)
   une annonce seule, --hp / --hx têtes (en px). La page place l'île (top, left) ; .narrow = colonnes étroites. */
.isle{position:absolute;left:50%;width:var(--iw0,140px);height:var(--ih0,42px);margin-left:calc(var(--iw0,140px) / -2);border-radius:calc(var(--ih0,42px) / 2);background:#000;color:#fff;overflow:hidden;cursor:pointer;text-align:left;-webkit-tap-highlight-color:transparent;touch-action:manipulation;user-select:none;-webkit-user-select:none;
  transition:width .62s var(--spr,cubic-bezier(.32,1.22,.45,1)),height .62s var(--spr,cubic-bezier(.32,1.22,.45,1)),margin-left .62s var(--spr,cubic-bezier(.32,1.22,.45,1)),border-radius .62s var(--spr,cubic-bezier(.32,1.22,.45,1)),transform .35s cubic-bezier(.3,1.8,.5,1)}
.isle.peek,.isle.open{width:var(--iw);margin-left:calc(var(--iw) / -2);height:var(--ihx,150px);border-radius:40px}
.isle.say{width:var(--sw,260px);margin-left:calc(var(--sw,260px) / -2);height:var(--ihs,52px);border-radius:calc(var(--ihs,52px) / 2)}
.isle:focus-visible{outline:3px solid var(--lemon);outline-offset:4px}
.isle.press{transform:scale(1.035)}
@media (hover:hover){.isle:not(.peek):not(.open):hover{transform:scale(1.06)}}
.isle.nudge{animation:inudge .9s cubic-bezier(.3,1.6,.5,1)}
@keyframes inudge{0%,100%{transform:none}30%{transform:scale(1.04,1.06)}60%{transform:scale(.99)}}
.isle .ping{position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 3px #fff;pointer-events:none;opacity:0}
.isle .ping.go{animation:iping 1.3s cubic-bezier(.2,.8,.3,1)}
@keyframes iping{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.12,1.4)}}
/* Fermée : têtes + pastilles de statut à gauche, sticker de l'événement à droite */
.isle .ipill{position:absolute;left:50%;top:0;pointer-events:none;width:var(--iw0,140px);margin-left:calc(var(--iw0,140px) / -2);height:var(--ih0,42px);display:flex;align-items:center;justify-content:space-between;padding:0 8px 0 13px;transition:opacity .25s .2s}
.isle.peek .ipill,.isle.open .ipill{opacity:0;transition:opacity .1s}
.isle .iheads{display:flex;align-items:center;gap:4px}
.isle .iph{position:relative;height:var(--hp,28px);display:grid;place-items:center}
.isle .iph img{height:var(--hp,28px)}
.isle .idot{position:absolute;right:-4px;bottom:-3px;width:14px;height:14px;border-radius:50%;background:#fff;box-shadow:0 0 0 1.5px #000;display:grid;place-items:center;font-size:8px;font-style:normal;line-height:1}
.isle .istk{width:calc(var(--ih0,42px) - 14px);height:calc(var(--ih0,42px) - 14px);border-radius:50%;background:var(--lemon);box-shadow:inset 0 0 0 2.5px #fff;display:grid;place-items:center;font-size:15px;line-height:1;transform:rotate(-10deg) scale(0);transition:transform .45s cubic-bezier(.3,1.8,.5,1)}
.isle .istk.on{transform:rotate(-10deg)}.isle .istk.irl{background:var(--mint)}
/* Ouverte : une colonne par ami (3 au plus, centrées) ; le contenu garde sa largeur d'île ouverte, l'île le découpe en grandissant */
.isle .icols{position:absolute;left:50%;top:0;width:var(--iw);margin-left:calc(var(--iw) / -2);height:var(--ihx,150px);display:grid;grid-template-columns:repeat(var(--n,3),minmax(0,calc((var(--iw) - 36px) / 3)));justify-content:center;gap:6px;padding:14px 12px 0;opacity:0;scale:.72;transition:opacity .14s,scale .3s}
.isle.peek .icols,.isle.open .icols{opacity:1;scale:1;transition:opacity .28s .12s,scale .5s cubic-bezier(.3,1.4,.5,1) .08s}
.isle.say .icols{opacity:0;transition:opacity .1s}
.isle .icol{position:relative;display:grid;grid-template-rows:var(--bh,28px) auto auto auto;justify-items:center;min-width:0}
.isle .icol .bub{align-self:end}   /* une bulle sur deux lignes grandit vers le haut : les têtes restent alignées */
.isle .bub{position:relative;max-width:100%;height:28px;padding:0 11px;border:0;border-radius:14px;background:#fff;color:var(--ink);font:600 13px/28px Parkinsans,sans-serif;white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .25s,transform .3s cubic-bezier(.3,1.9,.5,1)}
.isle .bub>span{display:block;overflow:hidden;text-overflow:ellipsis}
.isle .bub:after{content:"";position:absolute;left:50%;bottom:-5px;width:12px;height:6px;margin-left:-6px;background:inherit;clip-path:polygon(0 0,100% 0,50% 100%)}   /* la pointe, vers la tête */
.isle .bub.ev{background:var(--lemon)}.isle .bub.irl{background:var(--mint)}
.isle .bub .hand{font:400 16px/28px 'Gochi Hand',cursive}
.isle .bub b{font:400 12px 'Dela Gothic One',sans-serif;color:var(--cobalt)}
.isle .bub:active{transform:scale(.92)}
@media (hover:hover){.isle .bub:hover{transform:scale(1.06)}}
.isle .ihd{margin-top:9px;height:var(--hx,52px);border:0;padding:0;background:none;cursor:pointer;display:grid;place-items:center;-webkit-tap-highlight-color:transparent}
.isle .ihd img{height:var(--hx,52px)}
.isle .ihd.p-slap{animation:islap .9s cubic-bezier(.2,1.4,.4,1)}.isle .ihd.p-hype{animation:ihype .9s ease-in-out}.isle .ihd.p-kiss{animation:ikiss 1.2s cubic-bezier(.3,1.2,.5,1)}.isle .ihd.p-wave{animation:iwave 1s ease-in-out}
@keyframes islap{0%{rotate:0deg;scale:1}10%{rotate:-26deg;scale:1.14}30%{rotate:14deg}50%{rotate:-6deg;scale:1}75%{rotate:3deg}100%{rotate:0deg}}
@keyframes ihype{0%,100%{rotate:0deg;translate:0 0}15%{translate:0 -6px}30%{rotate:8deg;translate:0 0}50%{rotate:-8deg;translate:0 -4px}70%{rotate:5deg;translate:0 0}}
@keyframes ikiss{0%,100%{rotate:0deg;scale:1}25%{rotate:-14deg;scale:.92}60%{rotate:-10deg;scale:.92}}
@keyframes iwave{0%,100%{rotate:0deg}20%{rotate:-8deg;scale:1.06}45%{rotate:8deg}70%{rotate:-5deg}}
.isle .ipop{position:absolute;top:36px;left:50%;font-size:22px;line-height:1;pointer-events:none;animation:ipop .8s cubic-bezier(.3,1.6,.5,1) forwards}
@keyframes ipop{0%{transform:translate(8px,10px) scale(.3) rotate(-20deg);opacity:1}35%{transform:translate(20px,-4px) scale(1.15) rotate(8deg)}75%{opacity:1}100%{transform:translate(24px,-10px) scale(1);opacity:0}}
.isle .inm{margin-top:5px;font:400 13px/16px 'Dela Gothic One',sans-serif;letter-spacing:0;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.isle .isn{font-size:11px;line-height:14px;font-weight:500;color:rgba(255,255,255,.6);white-space:nowrap}
/* Colonnes étroites (téléphone, invitation) : la bulle passe sur deux lignes plutôt que de couper « sent you a kiss » */
.isle.narrow .icols{gap:4px;padding:10px 8px 0;--bh:38px}
.isle.narrow .icol .bub{height:auto;min-height:24px;padding:4px 9px;border-radius:12px;font-size:12px;line-height:15px;white-space:normal;text-align:center}
.isle.narrow .icol .bub>span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.isle.narrow .icol .bub .hand{font-size:15px;line-height:15px}
.isle.narrow .ihd{margin-top:8px}.isle.narrow .inm{margin-top:4px;font-size:12px;line-height:15px}
/* Annonce qui n'est pas d'un ami (la machine, un score, une invitation) : une seule bulle citron au centre */
.isle .isay{position:absolute;inset:0;pointer-events:none;display:grid;place-items:center;opacity:0;transition:opacity .12s}
.isle.say .isay{opacity:1;transition:opacity .25s .12s}
.isle .isay .bub{height:32px;padding:0 14px;border-radius:16px;font-size:14px;line-height:32px;pointer-events:none}
.isle .isay .bub:after{display:none}
.isle .swap{animation:iswap .5s cubic-bezier(.3,1.6,.5,1)}
@keyframes iswap{0%{transform:scale(.6)}100%{transform:none}}
.isle .istk.swap{animation-name:iswaps}
@keyframes iswaps{0%{transform:rotate(14deg) scale(.5)}100%{transform:rotate(-10deg)}}
