/*
 * Animations d'Ambrelune : décors vivants, récompenses, combat, finitions de l'interface.
 * Tout est désactivé pour les joueurs qui demandent moins d'animations (réglage du système) :
 * les règles animées sont dans @media (prefers-reduced-motion: no-preference).
 * Les animations n'utilisent que transform et opacity (rapides, calculées par la carte graphique).
 */

/* ---------- Structure (toujours active, sans mouvement) ---------- */
.scene {
  position: relative; overflow: hidden; isolation: isolate;
  width: calc(100% + 2rem); margin: -1rem -1rem .25rem; height: 120px; border-radius: var(--radius) var(--radius) 0 0;
}
.scene > .region-art { width: 100%; height: 100%; margin: 0; border-radius: 0; }
.scene::after { content: ''; position: absolute; left: 0; right: 0; pointer-events: none; z-index: 1; }
.scene::before { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2; opacity: 0; }
.region-card.locked .scene::after, .region-card.locked .scene::before { display: none; }

/* Particules par décor : couleur et motif (le motif se répète tous les 120 px, la hauteur du décor). */
.scene::after {
  top: 0; height: 240px; --pc: rgb(255 214 130 / 85%);
  background-image:
    radial-gradient(2px 2px at 12% 20%, var(--pc), transparent 70%),
    radial-gradient(1.5px 1.5px at 38% 65%, var(--pc), transparent 70%),
    radial-gradient(2.5px 2.5px at 61% 35%, var(--pc), transparent 70%),
    radial-gradient(1.5px 1.5px at 83% 80%, var(--pc), transparent 70%),
    radial-gradient(2px 2px at 93% 15%, var(--pc), transparent 70%);
  background-size: 170px 120px;
}
.scene[data-scene='dark_forest']::after { --pc: rgb(170 255 150 / 85%); }
.scene[data-scene='abandoned_mines']::after { --pc: rgb(140 210 255 / 90%); }
.scene[data-scene='forgotten_desert']::after { --pc: rgb(255 226 160 / 55%); background-size: 120px 40px; }
.scene[data-scene='volcanic_lands']::after, .scene[data-scene='black_fortress']::after { --pc: rgb(255 140 60 / 95%); }
.scene[data-scene='frozen_tundra']::after { --pc: rgb(255 255 255 / 90%); background-size: 90px 60px; }
.scene[data-scene='sunken_city']::after {
  --pc: rgb(190 235 255 / 70%);
  background-image:
    radial-gradient(circle at 15% 30%, transparent 2px, var(--pc) 2.5px, transparent 3.5px),
    radial-gradient(circle at 55% 75%, transparent 1.5px, var(--pc) 2px, transparent 3px),
    radial-gradient(circle at 80% 20%, transparent 2.5px, var(--pc) 3px, transparent 4px);
}
.scene[data-scene='sky_citadel']::after { --pc: rgb(200 215 255 / 45%); background-image: linear-gradient(100deg, transparent 48%, var(--pc) 50%, transparent 52%); background-size: 30px 40px; }
.scene[data-scene='elder_lair']::after, .scene[data-scene='bottomless_abyss']::after { --pc: rgb(200 130 255 / 90%); }
.scene[data-scene='forgotten_crypts']::after { --pc: rgb(255 200 110 / 60%); }
.scene[data-scene='sky_citadel']::before { background: rgb(220 230 255 / 55%); }

/* Bannière d'accueil : l'image passe dans un calque à part pour pouvoir bouger. */
.hero-banner { isolation: isolate; background: none; }
.hero-banner::before {
  content: ''; position: absolute; inset: 0; z-index: -2;
  background: var(--hero) center / cover; transform-origin: 70% 40%;
}
.hero-banner::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgb(10 6 18 / 85%) 0%, rgb(10 6 18 / 35%) 55%, transparent 100%);
}
.hero-fx { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.hero-fx::before { /* halo de lune */
  content: ''; position: absolute; width: 46%; aspect-ratio: 1; right: 6%; top: -12%; border-radius: 50%;
  background: radial-gradient(circle, rgb(255 210 122 / 28%), rgb(255 190 90 / 10%) 40%, transparent 70%);
  mix-blend-mode: screen;
}
.hero-fx::after { /* lucioles */
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 200%; --pc: rgb(255 214 130 / 90%);
  background-image:
    radial-gradient(2.5px 2.5px at 10% 30%, var(--pc), transparent 70%), radial-gradient(2px 2px at 30% 70%, var(--pc), transparent 70%),
    radial-gradient(3px 3px at 55% 45%, var(--pc), transparent 70%), radial-gradient(2px 2px at 75% 85%, var(--pc), transparent 70%),
    radial-gradient(2.5px 2.5px at 90% 20%, var(--pc), transparent 70%);
  background-size: 320px 50%;
}

/* Récompenses */
.fx-layer { position: fixed; inset: 0; pointer-events: none; z-index: 60; overflow: hidden; }
.fx-spark {
  position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  background: radial-gradient(circle, #fff6d8, var(--c, #f2b84b) 55%, transparent 70%);
  box-shadow: 0 0 8px var(--c, #f2b84b);
}
.fx-spark.star { border-radius: 0; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%); width: 14px; height: 14px; margin: -7px 0 0 -7px; }
.fx-banner {
  position: fixed; left: 50%; top: 22%; z-index: 61; pointer-events: none; text-align: center; transform: translateX(-50%);
  font-family: var(--font-display); font-size: clamp(1.6rem, 6vw, 3rem); line-height: 1.1; white-space: nowrap;
  background: linear-gradient(180deg, #fff6d8, #f2b84b 55%, #a8641a); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 4px 12px rgb(0 0 0 / 70%)) drop-shadow(0 0 20px rgb(242 184 75 / 50%));
}
.fx-banner small { display: block; font-family: var(--font-title); font-size: .4em; letter-spacing: .08em; }
.fx-vignette { position: fixed; inset: 0; z-index: 59; pointer-events: none; box-shadow: inset 0 0 120px rgb(220 60 60 / 55%); opacity: 0; }

/* Combat */
.duel { display: flex; align-items: center; justify-content: center; gap: .9rem; margin: .4rem 0; --beat: 1.8s; }
.duel-hero, .duel-foe {
  width: 46px; height: 46px; border-radius: 50%; border: 2px solid rgb(244 210 138 / 45%); background: rgb(0 0 0 / 30%);
  display: grid; place-items: center; font-size: 1.5rem; box-shadow: 0 0 10px rgb(0 0 0 / 40%);
}
.duel-foe { border-color: rgb(230 90 90 / 60%); }
.duel-clash { position: relative; width: 1.6rem; height: 1.6rem; display: grid; place-items: center; font-size: 1.1rem; opacity: .25; }
.bar-hp { position: relative; }
.bar-hp > .bar-ghost { position: absolute; left: 0; top: 0; bottom: 0; background: rgb(255 120 90 / 55%); border-radius: inherit; z-index: 0; }
.bar-hp > span { position: relative; z-index: 1; }
.bar-hp > em { z-index: 2; }
.fx-float {
  position: absolute; z-index: 3; left: 50%; top: -.4rem; transform: translateX(-50%); pointer-events: none; white-space: nowrap;
  font-family: var(--font-title); font-weight: 800; font-size: 1.25rem; color: #ffb38a; text-shadow: 0 2px 6px rgb(0 0 0 / 80%);
}

/* ---------- Animations (seulement si le joueur ne demande pas moins d'animations) ---------- */
@media (prefers-reduced-motion: no-preference) {

  /* 1. Décors vivants */
  .scene > .region-art { transition: transform 6s ease-out, filter .4s; }
  .region-card:not(.locked):hover .scene > .region-art { transform: scale(1.08) translateX(-2%); }
  .scene::after { animation: fx-float 7s ease-in-out infinite alternate; }
  .scene[data-scene='volcanic_lands']::after, .scene[data-scene='black_fortress']::after,
  .scene[data-scene='elder_lair']::after, .scene[data-scene='sunken_city']::after { animation: fx-rise 9s linear infinite; }
  .scene[data-scene='sunken_city']::after { animation-duration: 12s; }
  .scene[data-scene='frozen_tundra']::after { top: -120px; animation: fx-fall 8s linear infinite; }
  .scene[data-scene='sky_citadel']::after { top: -120px; animation: fx-fall .9s linear infinite; }
  .scene[data-scene='sky_citadel']::before { animation: fx-lightning 9s steps(1) infinite; }
  .scene[data-scene='forgotten_desert']::after { left: -120px; animation: fx-drift 6s linear infinite; }
  .scene[data-scene='bottomless_abyss']::after { animation: fx-rise 14s linear infinite reverse; }
  .scene[data-scene='forgotten_crypts'] > .region-art { animation: fx-candle 3.2s ease-in-out infinite; }

  .hero-banner::before { animation: fx-kenburns 32s ease-in-out infinite alternate; }
  .hero-fx::before { animation: fx-moon 6s ease-in-out infinite alternate; }
  .hero-fx::after { animation: fx-rise 26s linear infinite; }
  .hero-title { animation: fx-title 4s ease-in-out infinite alternate; }

  /* 2. Récompenses */
  .loot-grid .loot { animation: fx-pop .5s cubic-bezier(.2, 1.6, .4, 1) both; animation-delay: calc(var(--i, 0) * 70ms + 150ms); }
  .loot.rarity-epic, .loot.rarity-legendary, .item-row.rarity-legendary { position: relative; overflow: hidden; }
  .loot.rarity-epic::after, .loot.rarity-legendary::after, .item-row.rarity-legendary::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 35%) 50%, transparent 65%);
    transform: translateX(-120%); animation: fx-shine 3.5s ease-in-out infinite; animation-delay: calc(var(--i, 0) * 70ms + 900ms);
  }
  .loot.rarity-legendary { animation-name: fx-pop, fx-glow; animation-duration: .5s, 2.4s; animation-iteration-count: 1, infinite;
    animation-direction: normal, alternate; animation-timing-function: cubic-bezier(.2, 1.6, .4, 1), ease-in-out; }
  .fx-spark { animation: fx-spark var(--d, 900ms) cubic-bezier(.2, .7, .3, 1) forwards; }
  .fx-banner { animation: fx-banner 2.4s cubic-bezier(.2, 1.4, .4, 1) forwards; }
  .fx-vignette { animation: fx-vignette .9s ease-out forwards; }
  .toast { animation: fx-toast-in .35s cubic-bezier(.2, 1.4, .4, 1); }
  .toast-rare { animation: fx-toast-in .35s cubic-bezier(.2, 1.4, .4, 1), fx-glow 1.2s ease-in-out 3 alternate; }
  .gold-pill.is-up { animation: fx-bump .5s ease-out; }
  .is-shaking { animation: fx-shake .45s ease-in-out; }

  /* 3. Combat */
  .duel-hero { animation: fx-lunge var(--beat) ease-in-out infinite; }
  .duel-foe { animation: fx-hit var(--beat) ease-in-out infinite; }
  .duel-clash { animation: fx-clash var(--beat) ease-out infinite; }
  .bar-hp > span, .bar-hp > .bar-ghost { transition: width .7s cubic-bezier(.3, .8, .3, 1); }
  .bar-hp > .bar-ghost { transition-duration: 1.2s; transition-delay: .6s; }
  .fx-float { animation: fx-float-up 1.8s ease-out forwards; }

  /* 4. Finitions de l'interface */
  .btn { position: relative; overflow: hidden; }
  .btn:active { transform: translateY(1px) scale(.97); }
  .btn-primary::after, .btn-green::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; transform: translateX(-120%);
    background: linear-gradient(105deg, transparent 30%, rgb(255 255 255 / 45%) 50%, transparent 70%);
  }
  .btn-primary:hover::after, .btn-green:hover::after { transition: transform .6s ease; transform: translateX(120%); }
  .bar:not(.js-unit) > span { transition: width .7s cubic-bezier(.3, .8, .3, 1); }
  .region-card, .worker-card, .resource-card, .item-row, .expedition-card { transition: transform .2s ease, box-shadow .2s ease, border-color .2s; }
  .region-card:not(.locked):hover, .resource-card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgb(0 0 0 / 40%), 0 0 0 1px rgb(244 210 138 / 25%); }

  /* Apparition en fondu au défilement (navigateurs récents ; ailleurs, tout s'affiche normalement). */
  @supports (animation-timeline: view()) {
    .content .panel, .content .region-card, .content .resource-card, .public-main .panel, .public-main .news-card {
      animation: fx-reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 35%;
    }
  }

  /* Changement de page en fondu (le menu et la barre du haut restent en place). */
  @view-transition { navigation: auto; }
  .sidebar { view-transition-name: sidebar; }
  .topbar { view-transition-name: topbar; }
  ::view-transition-old(root) { animation: fx-page-out .16s ease-in both; }
  ::view-transition-new(root) { animation: fx-page-in .26s ease-out both; }
}

@keyframes fx-float { from { transform: translate(0, 0); opacity: .45; } to { transform: translate(-10px, -14px); opacity: 1; } }
@keyframes fx-rise { from { transform: translateY(0); } to { transform: translateY(-120px); } }
@keyframes fx-fall { from { transform: translateY(0); } to { transform: translateY(120px); } }
@keyframes fx-drift { from { transform: translateX(0); } to { transform: translateX(120px); } }
@keyframes fx-lightning { 0%, 91%, 93%, 95%, 100% { opacity: 0; } 92%, 94% { opacity: 1; } }
@keyframes fx-candle { 0%, 100% { filter: brightness(1); } 30% { filter: brightness(1.12); } 55% { filter: brightness(.94); } 75% { filter: brightness(1.08); } }
@keyframes fx-kenburns { from { transform: scale(1) translate(0, 0); } to { transform: scale(1.1) translate(-2%, 1%); } }
@keyframes fx-moon { from { opacity: .55; transform: scale(.94); } to { opacity: 1; transform: scale(1.06); } }
@keyframes fx-title { from { filter: drop-shadow(0 4px 10px rgb(0 0 0 / 60%)); } to { filter: drop-shadow(0 4px 10px rgb(0 0 0 / 60%)) drop-shadow(0 0 18px rgb(242 184 75 / 45%)); } }
@keyframes fx-pop { from { opacity: 0; transform: scale(.4) translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes fx-shine { 0% { transform: translateX(-120%); } 35%, 100% { transform: translateX(120%); } }
@keyframes fx-glow { from { box-shadow: 0 0 0 rgb(242 184 75 / 0%); } to { box-shadow: 0 0 18px rgb(242 184 75 / 55%); } }
@keyframes fx-spark {
  0% { opacity: 1; transform: translate(0, 0) scale(.6) rotate(0); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.1) rotate(var(--r, 180deg)); }
}
@keyframes fx-banner {
  0% { opacity: 0; transform: translateX(-50%) scale(.5); }
  15% { opacity: 1; transform: translateX(-50%) scale(1.08); }
  25%, 80% { opacity: 1; transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-20px) scale(1); }
}
@keyframes fx-vignette { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-toast-in { from { opacity: 0; transform: translateX(30px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes fx-bump { 0% { transform: scale(1); } 40% { transform: scale(1.12); filter: brightness(1.3); } 100% { transform: scale(1); } }
@keyframes fx-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-6px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(2px); } }
@keyframes fx-lunge { 0%, 30%, 100% { transform: translateX(0); } 42% { transform: translateX(14px) rotate(6deg); } 55% { transform: translateX(0); } }
@keyframes fx-hit { 0%, 40%, 100% { transform: translateX(0); filter: none; } 46% { transform: translateX(6px); filter: brightness(2) saturate(.3); } 60% { transform: translateX(0); filter: none; } 80% { transform: translateX(-10px); } 88% { transform: translateX(0); } }
@keyframes fx-clash { 0%, 38% { opacity: .2; transform: scale(.6); } 44% { opacity: 1; transform: scale(1.5) rotate(15deg); } 70%, 100% { opacity: .2; transform: scale(.8); } }
@keyframes fx-float-up { 0% { opacity: 0; transform: translate(-50%, 10px) scale(.7); } 15% { opacity: 1; transform: translate(-50%, 0) scale(1.15); } 100% { opacity: 0; transform: translate(-50%, -40px) scale(1); } }
@keyframes fx-reveal { from { opacity: 0; transform: translateY(24px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes fx-page-out { to { opacity: 0; } }
@keyframes fx-page-in { from { opacity: 0; transform: translateY(8px); } }

/* Jour et nuit (heure locale, voir fx.js) : le fond de la carte du monde et le plan du domaine prennent la teinte de
   l'heure. Les repères de la carte restent vifs (comme des lumières dans la nuit). */
.wmap-bg { transition: filter 2s ease; }
[data-daytime="dawn"] .wmap-bg { filter: sepia(.25) saturate(1.1) hue-rotate(-12deg) brightness(.97); }
[data-daytime="dusk"] .wmap-bg { filter: sepia(.4) saturate(1.2) hue-rotate(-25deg) brightness(.82); }
[data-daytime="night"] .wmap-bg { filter: saturate(.7) hue-rotate(15deg) brightness(.55) contrast(1.05); }
.domain-grid { position: relative; }
.domain-grid::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; opacity: 0;
  mix-blend-mode: multiply; transition: opacity 2s ease;
}
[data-daytime="dawn"] .domain-grid::after { opacity: 1; background: linear-gradient(180deg, rgb(255 190 200 / 35%), rgb(255 220 180 / 15%)); }
[data-daytime="dusk"] .domain-grid::after { opacity: 1; background: linear-gradient(180deg, rgb(255 140 70 / 40%), rgb(140 80 160 / 30%)); }
[data-daytime="night"] .domain-grid::after { opacity: 1; background: radial-gradient(ellipse at 50% 40%, rgb(90 110 190 / 55%), rgb(25 35 90 / 80%)); }
