/* ==========================================================================
   IL LABORATORIO DI PLUTO — animazioni del sito (vedi js/anim.js)

   Tenute fuori da site.css apposta: si possono rivedere o spegnere in blocco
   senza toccare lo stile di base. Regole comuni:
   - si muovono solo transform e opacity (fluide anche sui telefoni economici);
   - colori dai token di site.css (pop-art: giallo, rosa, turchese, arancio, verde);
   - "riduci movimento": site.css porta tutte le animazioni CSS a durata zero
     (stato finale subito visibile) e qui sotto si spengono le cose decorative;
     le animazioni in JavaScript controllano matchMedia da sole.
   ========================================================================== */

/* --------------------------------------------- 6. passaggio tra le pagine
   View Transitions tra documenti: il browser tiene la foto della pagina vecchia
   finché la nuova è pronta, quindi la navigazione NON viene mai rallentata.
   Un'onda di tasselli colorati (lo sfondo dello strato di transizione) passa da
   sinistra a destra: davanti scopre la pagina nuova, dietro copre la vecchia.
   Intestazione e barra in basso hanno un nome proprio, così restano ferme.
   Dove non è supportato (o con "riduci movimento") si naviga come sempre. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: testata; }
  .tabbar { view-transition-name: barra; }
  ::view-transition {
    background-color: var(--yellow);
    background-image:
      linear-gradient(135deg, var(--pop-pink) 25%, transparent 25% 50%, var(--pop-teal) 50% 75%, transparent 75%),
      linear-gradient(45deg, var(--pop-orange) 25%, transparent 25% 50%, var(--pop-green) 50% 75%, transparent 75%);
    background-size: 56px 56px, 56px 56px;
    background-position: 0 0, 28px 28px;
  }
  ::view-transition-old(root) { animation: vt-old .46s cubic-bezier(.55, .1, .45, .9) both; }
  ::view-transition-new(root) { animation: vt-new .46s cubic-bezier(.55, .1, .45, .9) both; }
}
/* Bordo a zig-zag: stessi punti in partenza e in arrivo, così il browser li interpola. */
@keyframes vt-old {
  from { clip-path: polygon(-10% 0, 100% 0, 100% 100%, -10% 100%, -4% 87.5%, -10% 75%, -4% 62.5%, -10% 50%, -4% 37.5%, -10% 25%, -4% 12.5%); }
  to { clip-path: polygon(140% 0, 100% 0, 100% 100%, 140% 100%, 146% 87.5%, 140% 75%, 146% 62.5%, 140% 50%, 146% 37.5%, 140% 25%, 146% 12.5%); }
}
@keyframes vt-new {
  from { clip-path: polygon(0 0, -40% 0, -46% 12.5%, -40% 25%, -46% 37.5%, -40% 50%, -46% 62.5%, -40% 75%, -46% 87.5%, -40% 100%, 0 100%); }
  to { clip-path: polygon(0 0, 110% 0, 104% 12.5%, 110% 25%, 104% 37.5%, 110% 50%, 104% 62.5%, 110% 75%, 104% 87.5%, 110% 100%, 0 100%); }
}

/* --------------------------------------------- 1-2. carrello: ciotola e medaglietta */
.bowl .k { opacity: 0; transform: translateY(-7px); transform-box: fill-box; transition: opacity .2s, transform .45s var(--spring); }
.bowl .k.on { opacity: 1; transform: none; }
.medal-fly { position: fixed; left: 0; top: 0; width: 34px; height: 34px; margin: -17px 0 0 -17px; z-index: 160; pointer-events: none; will-change: transform; }
.medal-fly svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 3px 4px rgb(21 21 21 / .25)); }
.is-bark { animation: bark .5s var(--ease); }
.bark-bubble {
  position: absolute; left: 50%; top: -6px; z-index: 3; pointer-events: none; white-space: nowrap;
  background: var(--ink); color: var(--yellow); font-family: var(--font-display); font-weight: 700; font-size: .72rem;
  padding: 1px 7px; border-radius: 999px; animation: bark-bubble .9s var(--ease) forwards;
}
.tabbar .bark-bubble { top: -14px; }
.count.bump { animation: count-bounce .6s var(--spring); }
@keyframes bark { 0%, 100% { transform: none; } 15% { transform: rotate(-14deg) scale(1.12); } 35% { transform: rotate(11deg) scale(1.12); } 55% { transform: rotate(-7deg); } 75% { transform: rotate(4deg); } }
@keyframes bark-bubble { 0% { opacity: 0; transform: translate(-10%, 4px) scale(.4); } 25% { opacity: 1; transform: translate(-10%, -18px) scale(1); } 75% { opacity: 1; transform: translate(-10%, -22px) scale(1); } 100% { opacity: 0; transform: translate(-10%, -30px) scale(.9); } }
@keyframes count-bounce { 0% { transform: scale(.3); } 40% { transform: scale(1.45) translateY(-3px); } 65% { transform: scale(.85); } 85% { transform: scale(1.1); } 100% { transform: none; } }

/* --------------------------------------------- 3. conferma d'ordine in festa */
.thanks.has-party .thanks__icon { display: none; }
.party { width: min(340px, 86vw); margin: -10px auto 14px; }
.party svg { width: 100%; height: auto; display: block; overflow: visible; }
.party__dog { transform-box: fill-box; transform-origin: 50% 100%; animation: party-dog 1.6s .1s var(--spring) both; }
.party__gift { transform-box: fill-box; transform-origin: 50% 100%; animation: party-gift .6s .25s var(--spring) both; }
.party__cord { stroke-dasharray: 1 1; stroke-dashoffset: 1; animation: draw .55s var(--ease) forwards; }
.party__cord--v { animation-delay: .75s; } .party__cord--h { animation-delay: 1.15s; }
.party__braid { opacity: 0; animation: fade-in .3s forwards; }
.party__braid--v { animation-delay: 1.2s; } .party__braid--h { animation-delay: 1.6s; }
.party__bow { transform-box: fill-box; transform-origin: 50% 80%; animation: bow-tie .7s 1.6s var(--spring) both; }
.party__shard { transform-box: fill-box; transform-origin: center; opacity: 0; animation: shard 1.9s calc(2.05s + var(--dl, 0s)) cubic-bezier(.15, .7, .3, 1) forwards; }
@keyframes party-dog { 0% { transform: scale(.4); opacity: 0; } 30% { transform: none; opacity: 1; } 78% { transform: none; } 86% { transform: translateY(-14px) rotate(-3deg); } 94% { transform: none; } 100% { transform: none; opacity: 1; } }
@keyframes party-gift { from { transform: translateY(-80px) scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fade-in { to { opacity: 1; } }
@keyframes bow-tie { 0% { transform: scale(0) rotate(-60deg); } 60% { transform: scale(1.25) rotate(10deg); } 80% { transform: scale(.92) rotate(-4deg); } 100% { transform: none; } }
@keyframes shard { 0% { opacity: 1; transform: translate(0, 0) scale(.2) rotate(0); } 35% { opacity: 1; transform: translate(var(--tx), var(--ty)) scale(1) rotate(calc(var(--r) * .5)); } 100% { opacity: 0; transform: translate(var(--tx), calc(var(--ty) + 150px)) scale(.8) rotate(var(--r)); } }

/* --------------------------------------------- 4. "Conferma l'ordine" a guinzaglio
   Durante l'invio il pulsante è disabilitato: dalla maniglia a sinistra un
   guinzaglio in paracord si tende verso destra, fino al moschettone. */
.checkout [data-submit][disabled] { opacity: 1; position: relative; overflow: hidden; padding-bottom: 1.15em; }
.checkout [data-submit][disabled]::before {
  content: ''; position: absolute; left: 12px; bottom: 5px; width: 18px; height: 14px; border: 4px solid var(--ink); border-radius: 50%; z-index: 1;
}
.checkout [data-submit][disabled]::after {
  content: ''; position: absolute; left: 26px; right: 14px; bottom: 9px; height: 6px; border-radius: 999px;
  background:
    radial-gradient(circle at calc(100% - 6px) 50%, var(--card) 0 3px, var(--ink) 3.5px 6px, transparent 6.5px),
    repeating-linear-gradient(-60deg, var(--pop-teal) 0 5px, var(--ink) 5px 7px, var(--pop-orange) 7px 12px, var(--ink) 12px 14px);
  background-size: 100% 12px, auto; background-position: right center, 0 0; background-repeat: no-repeat, repeat;
  transform: translateX(-100%); animation: leash 2.6s var(--ease) forwards, leash-tug .5s 2.6s ease-in-out infinite alternate;
}
@keyframes leash { 0% { transform: translateX(-100%); } 70% { transform: translateX(-12%); } 100% { transform: translateX(0); } }
@keyframes leash-tug { to { transform: translateX(-2%); } }

/* --------------------------------------------- 5. codice sconto: l'osso dorato */
.bone-pop {
  position: fixed; left: 50%; top: 42%; z-index: 170; width: 240px; margin-left: -120px; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  animation: bone-pop 2.8s var(--ease) forwards;
}
.bone-pop svg { width: 220px; height: auto; overflow: visible; }
.bone-pop .bone__l, .bone-pop .bone__r { transform-box: view-box; transform-origin: 100px 40px; }
.bone-pop .bone__l { animation: bone-l 1s .45s var(--spring) forwards; }
.bone-pop .bone__r { animation: bone-r 1s .45s var(--spring) forwards; }
.bone-pop .bone__all { transform-box: view-box; transform-origin: 100px 40px; animation: bone-shake .45s ease-in-out; }
.bone__val {
  margin-top: -78px; font-family: var(--font-display); font-weight: 700; font-size: 1.9rem; color: var(--ink);
  background: var(--card); border: 3px solid var(--ink); border-radius: 14px; padding: 0 .5em; transform: scale(0);
  animation: bone-val .5s .6s var(--spring) forwards;
}
.bone__lbl { margin-top: 44px; font-family: var(--font-script); font-weight: 700; font-size: 1.6rem; background: var(--yellow); border-radius: 999px; padding: 0 .7em; opacity: 0; animation: fade-in .3s .8s forwards; }
@keyframes bone-pop { 0% { opacity: 0; transform: scale(.6); } 10% { opacity: 1; transform: none; } 85% { opacity: 1; } 100% { opacity: 0; transform: translateY(-20px); } }
@keyframes bone-shake { 0%, 100% { transform: none; } 25% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } 75% { transform: rotate(-3deg); } }
@keyframes bone-l { to { transform: translate(-46px, 8px) rotate(-24deg); } }
@keyframes bone-r { to { transform: translate(46px, 8px) rotate(24deg); } }
@keyframes bone-val { to { transform: none; } }

/* --------------------------------------------- 7. impronte durante il caricamento
   Al posto del luccichio grigio: una fila di impronte che avanza a passi. */
.skeleton { position: relative; overflow: hidden; background: var(--card); animation: none; box-shadow: inset 0 0 0 2px var(--line); }
.skeleton::before {
  content: ''; position: absolute; top: 50%; left: 0; width: calc(100% + 96px); height: 56px; margin-top: -28px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 56'%3E%3Cg fill='%23a9b8e8'%3E%3Cg transform='translate(8 2) scale(.36) rotate(80 32 32)'%3E%3Cellipse cx='20' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='44' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='9' cy='33' rx='6' ry='7.5'/%3E%3Cellipse cx='55' cy='33' rx='6' ry='7.5'/%3E%3Cpath d='M32 30c-9 0-17 10-17 18 0 6 5 9 10 8 3-.5 5-2 7-2s4 1.5 7 2c5 1 10-2 10-8 0-8-8-18-17-18Z'/%3E%3C/g%3E%3Cg transform='translate(56 30) scale(.36) rotate(100 32 32)'%3E%3Cellipse cx='20' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='44' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='9' cy='33' rx='6' ry='7.5'/%3E%3Cellipse cx='55' cy='33' rx='6' ry='7.5'/%3E%3Cpath d='M32 30c-9 0-17 10-17 18 0 6 5 9 10 8 3-.5 5-2 7-2s4 1.5 7 2c5 1 10-2 10-8 0-8-8-18-17-18Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") repeat-x 0 0 / 96px 56px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 25%, #000 60%, transparent 85%);
  mask-image: linear-gradient(90deg, transparent 0, #000 25%, #000 60%, transparent 85%);
  animation: paws-walk 1.6s steps(2) infinite;
}
@keyframes paws-walk { from { transform: translateX(-96px); } to { transform: translateX(0); } }

/* --------------------------------------------- 8. fondo pagina: il cane saluta */
.peek {
  position: fixed; left: 10px; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) - 4px); z-index: 65;
  width: 112px; height: 104px; overflow: hidden; pointer-events: none;
}
@media (min-width: 900px) { .peek { bottom: 0; left: 24px; width: 140px; height: 130px; } }
.has-buybar .peek { bottom: calc(76px + env(safe-area-inset-bottom)); }
.peek__in { position: absolute; inset: 0; transform: translateY(105%); transition: transform .55s var(--spring); }
.peek.is-up .peek__in { transform: translateY(6%); }
.peek svg { position: absolute; display: block; }
.peek__dog { left: 0; top: 0; width: 100%; height: 100%; }
.peek__paw { right: -2px; top: 26%; width: 34%; transform-origin: 50% 95%; }
.peek.is-up .peek__paw { animation: wave .5s .5s ease-in-out 4 alternate; }
@keyframes wave { from { transform: rotate(-22deg); } to { transform: rotate(18deg); } }

/* --------------------------------------------- 9. menu: voci che si incastrano */
.menu-sheet[open] li { animation: tile-in .5s var(--spring) both; animation-delay: calc(60ms + var(--i, 0) * 55ms); }
.menu-sheet[open] li:nth-child(2) { --i: 1; } .menu-sheet[open] li:nth-child(3) { --i: 2; } .menu-sheet[open] li:nth-child(4) { --i: 3; }
.menu-sheet[open] li:nth-child(5) { --i: 4; } .menu-sheet[open] li:nth-child(6) { --i: 5; } .menu-sheet[open] li:nth-child(7) { --i: 6; }
.menu-sheet[open] li:nth-child(8) { --i: 7; } .menu-sheet[open] li:nth-child(9) { --i: 8; }
.menu-sheet[open] li:nth-child(odd) { --from: -40px; --rot: -7deg; }
.menu-sheet[open] li:nth-child(even) { --from: 40px; --rot: 7deg; }
.menu-sheet[open] > .btn { animation: tile-in .5s .55s var(--spring) both; --from: 0px; --rot: 0deg; }
@keyframes tile-in { from { opacity: 0; transform: translateX(var(--from, -40px)) rotate(var(--rot, -6deg)) scale(.86); } 70% { opacity: 1; } to { opacity: 1; transform: none; } }

/* --------------------------------------------- 10. torna su: la pallina */
.ball-top {
  position: fixed; right: 14px; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 14px); z-index: 66;
  width: 52px; height: 52px; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer;
  opacity: 0; transform: translateY(20px) scale(.6); pointer-events: none; transition: opacity .25s, transform .35s var(--spring);
}
.ball-top.is-on { opacity: 1; transform: none; pointer-events: auto; }
.ball-top svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 4px 6px rgb(21 21 21 / .25)); }
.ball-top:hover svg { animation: ball-wiggle .5s ease-in-out; }
@media (min-width: 900px) { .ball-top { bottom: 24px; right: 24px; } }
.has-buybar .ball-top { bottom: calc(84px + env(safe-area-inset-bottom)); }
@keyframes ball-wiggle { 50% { transform: rotate(25deg) translateY(-4px); } }
.fetch-dog { position: fixed; right: 0; top: calc(var(--header-h) + 8px); z-index: 59; width: 120px; pointer-events: none; transform: translateX(110%); }
.fetch-dog svg { width: 100%; height: auto; display: block; }
.fetch-dog.is-in { animation: fetch-in 1.9s var(--ease) forwards; }
@keyframes fetch-in { 0% { transform: translateX(110%); } 22% { transform: translateX(8%) rotate(-6deg); } 30% { transform: translateX(10%) rotate(3deg); } 38% { transform: translateX(8%) rotate(-2deg); } 75% { transform: translateX(8%); } 100% { transform: translateX(110%); } }

/* --------------------------------------------- 11. foto prodotto: rivelazione a tasselli */
.tiles { position: absolute; inset: 0; z-index: 1; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr); pointer-events: none; }
.tiles i { background: var(--stone); transform-origin: center; }
.tiles i:nth-child(3n) { background: var(--sky-2); } .tiles i:nth-child(5n + 1) { background: var(--yellow-2); }
.tiles i:nth-child(7n + 2) { background: color-mix(in srgb, var(--pop-pink) 45%, var(--stone)); }
.tiles i:nth-child(11n + 4) { background: color-mix(in srgb, var(--pop-teal) 45%, var(--stone)); }
.tiles.go i { animation: tile-out .5s var(--ease) forwards; animation-delay: calc(var(--i) * 55ms); }
@keyframes tile-out { 0% { transform: none; } 30% { transform: scale(1.04) rotate(4deg); } 100% { transform: scale(0) rotate(45deg); opacity: .4; } }

/* --------------------------------------------- 12. colori del paracord che scorrono */
.braid { width: min(240px, 70%); height: 16px; margin: -.2rem 0 .8rem; border-radius: 999px; overflow: hidden; box-shadow: 0 0 0 2px var(--ink); background: var(--ink); }
.braid__strip { height: 100%; background-repeat: repeat-x; background-size: auto 100%; animation: braid-run 2.2s linear infinite; }
@keyframes braid-run { to { transform: translateX(calc(-1 * var(--p, 24px))); } }

/* --------------------------------------------- 13. "Pezzo unico" che luccica */
.tag:not(.tag--sold) { overflow: hidden; }
.tag:not(.tag--sold)::after {
  content: ''; position: absolute; top: -20%; bottom: -20%; left: 0; width: 45%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / .95) 45%, rgb(246 207 63 / .55) 55%, transparent);
  transform: translateX(-150%) skewX(-18deg); animation: shine 5.5s 1.2s ease-in-out infinite; pointer-events: none;
}
.pcard:nth-child(3n + 2) .tag::after { animation-delay: 2.6s; } .pcard:nth-child(3n) .tag::after { animation-delay: 4s; }
@keyframes shine { 0%, 72% { transform: translateX(-150%) skewX(-18deg); } 88%, 100% { transform: translateX(330%) skewX(-18deg); } }

/* --------------------------------------------- 14. articolo venduto: timbro "Adottato!" */
.pcard.is-sold .pcard__media::after {
  content: 'Adottato!'; position: absolute; left: 50%; top: 50%; z-index: 2; padding: .15em .55em .15em 1.75em;
  font-family: var(--font-display); font-weight: 700; font-size: clamp(1rem, 4.6vw, 1.45rem); color: var(--pop-pink); white-space: nowrap;
  border: 3px solid currentColor; border-radius: 10px; background: rgb(253 253 251 / .82) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cg fill='%23ec3f8c'%3E%3Cellipse cx='20' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='44' cy='18' rx='6.5' ry='8.5'/%3E%3Cellipse cx='9' cy='33' rx='6' ry='7.5'/%3E%3Cellipse cx='55' cy='33' rx='6' ry='7.5'/%3E%3Cpath d='M32 30c-9 0-17 10-17 18 0 6 5 9 10 8 3-.5 5-2 7-2s4 1.5 7 2c5 1 10-2 10-8 0-8-8-18-17-18Z'/%3E%3C/g%3E%3C/svg%3E") no-repeat .35em 50% / 1.1em;
  transform: translate(-50%, -50%) rotate(-12deg); opacity: 0;
}
.pcard.is-sold.is-visible .pcard__media::after, .no-io .pcard.is-sold .pcard__media::after { animation: stamp .55s .35s cubic-bezier(.3, 1.4, .6, 1) forwards; }
@keyframes stamp { 0% { opacity: 0; transform: translate(-50%, -50%) rotate(-30deg) scale(2.4); } 60% { opacity: 1; transform: translate(-50%, -50%) rotate(-10deg) scale(.92); } 100% { opacity: 1; transform: translate(-50%, -50%) rotate(-12deg) scale(1); } }

/* --------------------------------------------- 16. il segno giallo come paracord intrecciato */
.mark::after {
  height: .36em; transform: none; border-radius: 999px;
  background: var(--yellow) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 12'%3E%3Cpath d='M-2 13 L8 -1 M6 13 L16 -1 M14 13 L24 -1' stroke='%23e0ad1c' stroke-width='3.2'/%3E%3Cpath d='M-2 13 L8 -1 M6 13 L16 -1 M14 13 L24 -1' stroke='%23fde89a' stroke-width='1.1' transform='translate(-1.2 0)'/%3E%3C/svg%3E") repeat-x 0 50% / auto 100%;
  clip-path: inset(0 100% 0 0 round 999px); animation: braid-draw 1s .3s var(--ease) forwards;
}
@keyframes braid-draw { to { clip-path: inset(0 0 0 0 round 999px); } }

/* --------------------------------------------- 17. materiali: il nodo cobra legato allo scorrimento */
.knot-card { background: var(--sky); border-radius: var(--r-lg); padding: clamp(20px, 4vw, 40px); display: grid; gap: 14px; overflow: hidden; }
@media (min-width: 900px) { .knot-card { grid-template-columns: 1fr 1.5fr; align-items: center; } }
.knot-card .lead { margin: .5rem 0 0; }
.knot-svg { width: 100%; height: auto; display: block; overflow: visible; }
.knot-meter { font-family: var(--font-script); font-weight: 700; font-size: 1.4rem; color: var(--ink-2); margin: 0; }

/* --------------------------------------------- 18. guida alle misure */
.measure-art.is-anim .tape { opacity: 0; }
.measure-art.is-anim .tape-run { fill: none; stroke: var(--yellow); stroke-width: 11; stroke-linecap: round; stroke-dasharray: 100 100; stroke-dashoffset: 100; }
.measure-art.go .tape-run { animation: tape-wrap 1.1s var(--ease) forwards; animation-delay: var(--dl, 0s); }
.measure-art.go .tape { animation: fade-in .3s forwards, tape-cm 1.4s linear infinite; animation-delay: calc(var(--dl, 0s) + .9s), calc(var(--dl, 0s) + .9s); }
.measure-art .cm { font-family: var(--font-display); font-weight: 700; font-size: 22px; fill: var(--ink); }
@keyframes tape-wrap { to { stroke-dashoffset: 0; } }
@keyframes tape-cm { to { stroke-dashoffset: -30; } }

/* --------------------------------------------- 19. fiere ed eventi: la mappa */
.ev-map { display: grid; gap: 12px; background: var(--sky); border-radius: var(--r-lg); padding: clamp(16px, 4vw, 32px); margin-bottom: 20px; }
@media (min-width: 800px) { .ev-map { grid-template-columns: minmax(260px, 380px) 1fr; align-items: center; } }
.ev-map svg { width: 100%; max-width: 380px; height: auto; display: block; margin-inline: auto; overflow: visible; }
.ev-map .italia { fill: var(--card); stroke: var(--ink); stroke-width: 2.5; stroke-linejoin: round; }
.ev-map .tratto { fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-dasharray: 2 6; stroke-linecap: round; }
.ev-map .citta circle { fill: var(--pop-pink); stroke: var(--ink); stroke-width: 2; }
.ev-map .citta text { font-family: var(--font-display); font-weight: 700; font-size: 13px; fill: var(--ink); paint-order: stroke; stroke: var(--card); stroke-width: 4px; stroke-linejoin: round; }
.ev-map .citta.is-on circle { fill: var(--yellow); }
.ev-map .zampa { will-change: transform; }
.ev-map ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; counter-reset: tappa; }
.ev-map li { display: flex; gap: 10px; align-items: baseline; font-weight: 700; font-size: .95rem; padding: 6px 10px; border-radius: var(--r-sm); transition: background .3s; }
.ev-map li::before { counter-increment: tappa; content: counter(tappa); flex: none; width: 24px; height: 24px; border-radius: 50%; background: var(--card); display: grid; place-items: center; font-size: .8rem; }
.ev-map li.is-on { background: var(--card); }
.ev-map li small { display: block; color: var(--ink-3); font-weight: 600; }

/* --------------------------------------------- 20. recensioni: medagliette e nome scritto a mano */
.review__stars.medals { display: flex; gap: 4px; letter-spacing: 0; }
.medal { width: 22px; height: 26px; display: block; transform-origin: 50% 2px; }
.medal .m-disc { fill: var(--line); stroke: var(--line-2); stroke-width: 1.5; }
.medal .m-star { fill: var(--card); }
.medal .m-ring { fill: none; stroke: #b8bcc4; stroke-width: 1.6; }
.medal.on .m-disc { fill: var(--yellow); stroke: var(--ink); }
.medal.on .m-star { fill: var(--pop-orange); }
.review.lit-wait .medal.on .m-disc { fill: var(--line); stroke: var(--line-2); }
.review.lit-wait .medal.on .m-star { fill: var(--card); }
.review.is-lit .medal.on { animation: jingle .9s var(--ease) both; animation-delay: calc(var(--i) * 170ms); }
.review.is-lit .medal.on .m-disc, .review.is-lit .medal.on .m-star { animation: light-on .25s both; animation-delay: calc(var(--i) * 170ms); }
@keyframes jingle { 0% { transform: scale(.6) rotate(0); } 20% { transform: scale(1.15) rotate(24deg); } 40% { transform: rotate(-16deg); } 60% { transform: rotate(9deg); } 80% { transform: rotate(-4deg); } 100% { transform: none; } }
@keyframes light-on { from { fill: var(--line); } }
.pet-name { font-family: var(--font-script); font-weight: 700; font-size: 1.55rem; line-height: 1; display: inline-block; }
.review.lit-wait .pet-name { clip-path: inset(-10% 100% -20% 0); }
.review.is-lit .pet-name { animation: write 1s calc(5 * 170ms) steps(14, end) both; }
@keyframes write { from { clip-path: inset(-10% 100% -20% 0); } to { clip-path: inset(-10% -5% -20% 0); } }

/* --------------------------------------------- 21-22. temi stagionali e compleanno */
.season-bar { position: relative; overflow: hidden; background: var(--th-bg, var(--sky)); color: var(--th-fg, var(--ink)); }
.season-bar__in { position: relative; z-index: 1; display: flex; align-items: center; gap: 12px; min-height: 64px; padding-block: 6px; }
.season-bar__dog { flex: none; width: 54px; height: 54px; border: 0; padding: 0; background: var(--card); border-radius: 50%; box-shadow: 0 0 0 3px var(--ink); cursor: pointer; overflow: hidden; }
.season-bar__dog svg { width: 100%; height: 100%; display: block; }
.season-bar__dog:hover svg, .season-bar__dog:focus-visible svg { animation: ball-wiggle .5s ease-in-out; }
.season-bar__msg { flex: 1; margin: 0; font-weight: 800; font-size: .95rem; line-height: 1.25; }
.season-bar__msg b { display: block; font-family: var(--font-script); font-size: 1.35rem; font-weight: 700; }
.season-bar__x { flex: none; width: 40px; height: 40px; border: 0; border-radius: 50%; background: rgb(253 253 251 / .7); color: var(--ink); cursor: pointer; font-size: 1.1rem; font-weight: 900; }
.season-bar__deco { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .5; }
.season-bar__deco svg { position: absolute; }
.season-bar__deco .d-sway { animation: sway 3s ease-in-out infinite alternate; transform-origin: 50% 0; transform-box: fill-box; }
.season-bar__deco .d-run { animation: run-x 6s linear infinite; }
@keyframes sway { from { transform: rotate(-6deg); } to { transform: rotate(6deg); } }
@keyframes run-x { to { transform: translateX(-50%); } }
.brand { position: relative; }
.season-sticker { position: absolute; left: 22px; top: -9px; width: 36px; height: 30px; pointer-events: none; transform: rotate(12deg); }
.menu-sheet .season-sticker { display: none; }
@media (min-width: 1000px) { .season-sticker { left: 28px; top: -6px; width: 42px; height: 34px; } }
.hero__badge .season-dog { width: 52px; height: 52px; flex: none; }
.season-fx { position: fixed; inset: 0; z-index: 55; pointer-events: none; overflow: hidden; }
.season-fx > * { position: absolute; top: 0; left: 0; will-change: transform; }
.fx-fall { animation: fx-fall var(--du, 7s) var(--dl, 0s) linear both; }
.fx-fall > svg { display: block; animation: sway 1.4s ease-in-out infinite alternate; }
.fx-rise { animation: fx-rise var(--du, 7s) var(--dl, 0s) linear both; }
.fx-fly { animation: fx-fly var(--du, 6s) var(--dl, 0s) linear both; }
.fx-fly > svg { display: block; animation: flap .25s ease-in-out infinite alternate; }
.fx-boom { animation: fx-boom 1.4s var(--dl, 0s) cubic-bezier(.1, .8, .3, 1) both; }
@keyframes fx-fall { from { transform: translate(var(--x), -60px) rotate(0); } to { transform: translate(calc(var(--x) + var(--dx, 40px)), 105vh) rotate(var(--r, 360deg)); } }
@keyframes fx-rise { 0% { opacity: 0; transform: translate(var(--x), 100vh) scale(.6); } 10% { opacity: 1; } 90% { opacity: 1; } 100% { opacity: 0; transform: translate(calc(var(--x) + var(--dx, 30px)), -10vh) scale(1); } }
@keyframes fx-fly { from { transform: translate(-80px, var(--y)); } 50% { transform: translate(50vw, calc(var(--y) - 40px)); } to { transform: translate(110vw, var(--y)); } }
@keyframes flap { from { transform: scaleY(1); } to { transform: scaleY(.45); } }
@keyframes fx-boom { 0% { opacity: 0; transform: translate(var(--x), var(--y)) scale(.1); } 15% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--x), calc(var(--y) + 30px)) scale(1); } }

/* --------------------------------------------- 23. negozio chiuso: il cane che sonnecchia */
.nap { width: min(270px, 70vw); }
.nap svg { width: 100%; height: auto; display: block; overflow: visible; }
.nap__dog { transform-box: view-box; transform-origin: 243px 509px; animation: nap-breathe 3.6s ease-in-out infinite; }
.nap__bubble { transform-box: fill-box; transform-origin: 85% 15%; animation: snore 3.6s ease-in-out infinite; fill: rgb(207 216 243 / .7); stroke: var(--sky-3); stroke-width: 4; }
.nap__z { font-family: var(--font-display); font-weight: 700; fill: var(--ink); opacity: 0; animation: nap-z 3.6s ease-in-out infinite; }
.nap__z:nth-of-type(2) { animation-delay: 1.2s; } .nap__z:nth-of-type(3) { animation-delay: 2.4s; }
@keyframes nap-breathe { 0%, 100% { transform: rotate(0) scale(1); } 50% { transform: rotate(-1.6deg) scale(1.025, 1.035); } }
@keyframes snore { 0%, 15% { transform: scale(.15); opacity: 0; } 50% { transform: scale(1); opacity: 1; } 62% { transform: scale(1.06); opacity: 1; } 66%, 100% { transform: scale(.2); opacity: 0; } }
@keyframes nap-z { 0% { opacity: 0; transform: translate(0, 0) scale(.6); } 25% { opacity: 1; } 100% { opacity: 0; transform: translate(60px, -90px) scale(1.2); } }

/* --------------------------------------------- riduci movimento: via le decorazioni in movimento */
@media (prefers-reduced-motion: reduce) {
  .skeleton::before { animation: none; transform: translateX(-48px); }
  .tag::after, .season-fx, .tiles, .medal-fly, .bone-pop, .fetch-dog { display: none !important; }
  .braid__strip, .season-bar__deco * { animation: none !important; }
  .mark::after { clip-path: none; }
  .nap__z { opacity: 1; }
  .nap__z:nth-of-type(1) { transform: translate(10px, -10px); } .nap__z:nth-of-type(2) { transform: translate(30px, -40px); } .nap__z:nth-of-type(3) { transform: translate(50px, -70px); }
}
