/* Animations de l'interface + composants des pages Mon compte / Paramètres généraux.
   Tout est désactivé si l'utilisateur coupe les animations (Mon compte) ou réduit les animations dans Windows. */

:root { --ease-out: cubic-bezier(.22, 1, .36, 1); --ease-spring: cubic-bezier(.34, 1.56, .64, 1); }

/* --- Entrée des pages : chaque bloc apparaît en glissant, l'un après l'autre --- */
.main.enter > * { animation: rise .5s var(--ease-out) both; }
.main.enter > :nth-child(2) { animation-delay: .05s; }
.main.enter > :nth-child(3) { animation-delay: .1s; }
.main.enter > :nth-child(4) { animation-delay: .15s; }
.main.enter > :nth-child(5) { animation-delay: .2s; }
.main.enter > :nth-child(n+6) { animation-delay: .25s; }
.main.enter .kpi { animation: rise .55s var(--ease-out) both; }
.main.enter .kpi:nth-child(2) { animation-delay: .06s; }
.main.enter .kpi:nth-child(3) { animation-delay: .12s; }
.main.enter .kpi:nth-child(4) { animation-delay: .18s; }
.main.enter .settings-grid > * { animation: rise .5s var(--ease-out) both; }
.main.enter .settings-grid > :nth-child(2) { animation-delay: .06s; }
.main.enter .settings-grid > :nth-child(3) { animation-delay: .12s; }
.main.enter .settings-grid > :nth-child(4) { animation-delay: .18s; }
.main.enter .settings-grid > :nth-child(n+5) { animation-delay: .24s; }

/* Lignes de tableaux et listes : fondu en cascade (indice --i posé par le script). */
.main.enter [style*="--i"] { animation: rise .45s var(--ease-out) both; animation-delay: calc(var(--i) * 30ms + .15s); }
.main.enter .table tbody tr, .main.enter .entries > li, .main.enter .alerts > li, .main.enter .review-list > * {
  animation: fadeSlide .4s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 25ms + .12s);
}

/* Barres des compteurs et jauges : elles se remplissent. */
.main.enter .bar { animation: growX .8s var(--ease-out) both .2s; transform-origin: left; }
.main.enter .bar.neg { transform-origin: right; }
.main.enter .meter span { animation: growX 1s var(--ease-out) both .3s; transform-origin: left; }

/* Planning et calendriers : les pastilles « poppent ». */
.main.enter .pl[class*="k-"], .main.enter .tc { animation: popIn .35s var(--ease-spring) both; animation-delay: calc(var(--d, 0) * 12ms + .2s); }
.main.enter .cal-cell { animation: popIn .35s var(--ease-out) both; animation-delay: calc(var(--d, 0) * 10ms + .1s); }

/* --- Micro-interactions --- */
.card, .kpi { transition: transform .25s var(--ease-out), box-shadow .25s var(--ease-out), border-color .2s; }
.kpi:hover { transform: translateY(-3px); box-shadow: 0 10px 30px rgb(15 23 42 / .12); }
.btn { transition: background .15s, border-color .15s, transform .15s var(--ease-out), box-shadow .2s; }
.btn:active:not(:disabled), .icon-btn:active, .chip-btn:active, .theme-opt:active { transform: scale(.96); }
.btn.primary:hover { box-shadow: 0 6px 18px color-mix(in srgb, var(--primary) 35%, transparent); }
.icon-btn, .chip-btn { transition: background .15s, color .15s, transform .15s var(--ease-out); }
.icon-btn:hover .ic { animation: wiggle .4s var(--ease-out); }
.nav a { position: relative; transition: background .2s, color .2s, padding-left .2s var(--ease-out); }
.nav a:hover { padding-left: 16px; }
.nav a .ic { transition: transform .25s var(--ease-spring); }
.nav a:hover .ic { transform: scale(1.12); }
/* Pastille qui glisse d'un élément actif à l'autre (menu latéral, onglets). */
.has-glide { position: relative; isolation: isolate; }
.glide {
  position: absolute; left: 0; top: 0; z-index: -1; pointer-events: none; border-radius: 10px;
  transition: transform .45s var(--ease-spring), width .45s var(--ease-spring), height .45s var(--ease-spring);
}
.nav .glide { background: var(--primary-soft); }
.nav .glide::before {
  content: ""; position: absolute; left: -14px; top: 8px; bottom: 8px; width: 4px; border-radius: 0 4px 4px 0; background: var(--primary);
}
.nav.has-glide a.active { background: transparent; }
.tabs .glide { border-radius: 8px; background: var(--surface); box-shadow: var(--shadow); }
.tabs.has-glide .tab.on { background: transparent; box-shadow: none; color: var(--primary); }
.tab { transition: color .25s; }

/* Entrée du menu au premier affichage. */
.sidebar .nav a { animation: fadeSlide .45s var(--ease-out) both; }
.sidebar .nav a:nth-child(2) { animation-delay: .04s; } .sidebar .nav a:nth-child(3) { animation-delay: .08s; }
.sidebar .nav a:nth-child(4) { animation-delay: .12s; } .sidebar .nav a:nth-child(5) { animation-delay: .16s; }
.sidebar .nav a:nth-child(n+6) { animation-delay: .2s; }
.layout.ready .sidebar .nav a { animation: none; }
.nav .count { animation: popIn .4s var(--ease-spring); }
.logo { transition: transform .4s var(--ease-spring); }
.brand:hover .logo { transform: rotate(-12deg) scale(1.06); }
.table tbody tr { transition: background .15s; }
.pl, .tc { transition: transform .15s var(--ease-out); }
.pl[class*="k-"]:hover, .tc:hover { transform: scale(1.18); z-index: 1; }
input, select, textarea { transition: border-color .15s, box-shadow .2s; }
input:focus, select:focus, textarea:focus { box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 15%, transparent); }

/* Modales : fond flouté qui s'éclaircit, fenêtre qui rebondit. */
.overlay { animation: fade .2s ease-out; }
.modal { animation: modalIn .35s var(--ease-spring); }
.overlay.closing { animation: fade .18s ease-in reverse forwards; }
.overlay.closing .modal { animation: modalIn .18s ease-in reverse forwards; }

/* Toasts : arrivent depuis la droite avec une barre de temps restant. */
.toast { position: relative; overflow: hidden; animation: toastIn .45s var(--ease-spring); }
.toast::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: currentColor; opacity: .25; transform-origin: left; animation: shrink 4.2s linear forwards;
}
.toast.success::after { background: #4ade80; opacity: .7; }
.toast.error::after { background: #f87171; opacity: .7; }
.toast.out { opacity: 0; transform: translateX(30px); }

/* Cloche : secousse quand une notification arrive. */
.bell.ring .ic { animation: ring .9s var(--ease-out); transform-origin: 50% 10%; }
.bell-count:not([hidden]) { animation: popIn .4s var(--ease-spring); }

/* Chargement : squelettes scintillants à la place de « Chargement… ». */
.skeleton { display: flex; flex-direction: column; gap: 16px; }
.skeleton i {
  display: block; height: 18px; border-radius: 10px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--border) 50%, var(--surface-2) 75%); background-size: 200% 100%;
  animation: shimmer 1.2s linear infinite;
}
.skeleton .sk-title { width: 240px; height: 30px; }
.skeleton .sk-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.skeleton .sk-row i { height: 92px; border-radius: var(--radius); }
.skeleton .sk-block { height: 280px; border-radius: var(--radius); }

/* Connexion : carte qui apparaît, logo qui flotte, secousse sur un code faux. */
.login-card { animation: modalIn .6s var(--ease-spring); }
.login .logo.big { animation: float 4s ease-in-out infinite; }
.login { background-size: 200% 200%; }
.shake { animation: shake .45s cubic-bezier(.36, .07, .19, .97); }
.pulse-once { animation: pulse 1.4s var(--ease-out) .4s 2; }

/* Indicateur d'enregistrement de la journée. */
.saving { animation: breathe 1s ease-in-out infinite; }

/* --- Effets supplémentaires --- */

/* Navigation précédent / suivant : le contenu arrive du côté où l'on va. */
.main.enter.from-right > :not(.page-head) { animation-name: fromRight; }
.main.enter.from-left > :not(.page-head) { animation-name: fromLeft; }

/* Blocs sous la ligne de flottaison : apparaissent quand on fait défiler. */
.reveal { opacity: 0; transform: translateY(26px) scale(.98); transition: opacity .6s var(--ease-out), transform .7s var(--ease-out); }
.reveal.in { opacity: 1; transform: none; }
.main.enter > .reveal { animation: none; }

/* Ondulation au clic. */
.has-ripple { position: relative; overflow: hidden; }
.ripple {
  position: absolute; border-radius: 50%; pointer-events: none; background: currentColor; opacity: .18;
  transform: scale(0); animation: ripple .6s var(--ease-out) forwards;
}
.btn.primary .ripple, .btn.success .ripple, .btn.danger .ripple { background: #fff; opacity: .35; }

/* Confettis. */
.confetti { position: fixed; inset: 0; z-index: 100; pointer-events: none; overflow: hidden; }
.confetti i { position: absolute; display: block; will-change: transform, opacity; }

/* Barre de chargement en haut de l'écran pendant les échanges avec le serveur. */
#loadbar {
  position: fixed; top: 0; left: 0; z-index: 90; height: 3px; width: 0; pointer-events: none;
  background: linear-gradient(90deg, var(--primary), #6a5cff, #22d3ee); box-shadow: 0 0 10px var(--primary);
}
#loadbar.on { animation: load 8s cubic-bezier(.1, .7, .2, 1) forwards; }
#loadbar.done { width: 100%; opacity: 0; transition: width .2s ease-out, opacity .4s .2s; }

/* Chiffre qui vient de changer (ex. après l'enregistrement d'une journée). */
.kpi-value.bump { display: inline-block; animation: bump .6s var(--ease-spring); }
.kpi.flash { animation: flash 1s var(--ease-out); }

/* Journée enregistrée : halo vert bref. */
.saved { animation: savedGlow 1.1s var(--ease-out); }

/* Carte « Compteur » : reflet qui passe de temps en temps. */
.kpi.primary { position: relative; overflow: hidden; }
.kpi.primary::after {
  content: ""; position: absolute; inset: -50% auto -50% -60%; width: 40%; transform: rotate(20deg);
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / .28), transparent); animation: sheen 6s ease-in-out 1.2s infinite;
}
.kpi.primary:hover::after { animation-duration: 1.4s; animation-delay: 0s; }

/* Toasts : coche qui se dessine. */
.toast.success .ic path, .toast.success .ic polyline { stroke-dasharray: 30; stroke-dashoffset: 30; animation: draw .5s .15s var(--ease-out) forwards; }

/* Panneau de notifications : descend, puis les lignes arrivent l'une après l'autre. */
.notif-panel.opening { animation: dropIn .4s var(--ease-spring); transform-origin: top right; }
.notif-panel.opening li { animation: fadeSlide .35s var(--ease-out) both; }
.notif-panel.opening li:nth-child(2) { animation-delay: .04s; } .notif-panel.opening li:nth-child(3) { animation-delay: .08s; }
.notif-panel.opening li:nth-child(4) { animation-delay: .12s; } .notif-panel.opening li:nth-child(n+5) { animation-delay: .16s; }
.notif-panel li { transition: background .15s, transform .2s var(--ease-out); }
.notif-panel li:hover { transform: translateX(3px); }

/* Petits plus au survol. */
.me-btn .avatar { transition: transform .35s var(--ease-spring); }
.me-btn:hover .avatar { transform: rotate(-10deg) scale(1.1); }
.bars li .bar { transition: filter .2s; }
.bars li:hover .bar { filter: brightness(1.2) saturate(1.2); }
.alerts a .ic:last-child { transition: transform .25s var(--ease-out); }
.alerts a:hover .ic:last-child { transform: translateX(4px); }
.empty .ic { animation: float 3.5s ease-in-out infinite; }
.card-head h2 .ic { transition: transform .35s var(--ease-spring); }
.card:hover .card-head h2 .ic { transform: rotate(-12deg) scale(1.15); }
.badge { transition: transform .2s var(--ease-spring); }
.badge:hover { transform: scale(1.06); }
.month-label .ic { transition: transform .4s var(--ease-spring); }
.month:hover .month-label .ic { transform: rotate(-15deg); }

/* Connexion : halos colorés qui dérivent lentement en fond. */
.login { position: relative; overflow: hidden; isolation: isolate; }
.login::before, .login::after {
  content: ""; position: absolute; z-index: -1; width: 46vmax; height: 46vmax; border-radius: 50%; filter: blur(60px); opacity: .45;
}
.login::before { background: var(--primary); top: -20vmax; left: -12vmax; animation: drift 18s ease-in-out infinite; }
.login::after { background: #6a5cff; bottom: -22vmax; right: -14vmax; animation: drift 22s ease-in-out infinite reverse; }
.dev-user { transition: border-color .15s, transform .2s var(--ease-out); }
.dev-user:hover { transform: translateX(4px); }

/* Changement de thème : on laisse l'animation circulaire faire le travail. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* --- Images clés --- */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes fadeSlide { from { opacity: 0; transform: translateX(-8px); } }
@keyframes growX { from { transform: scaleX(0); } }
@keyframes popIn { 0% { opacity: 0; transform: scale(.5); } 100% { opacity: 1; transform: scale(1); } }
@keyframes slideIn { from { transform: scaleY(0); opacity: 0; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(18px) scale(.94); } }
@keyframes toastIn { from { opacity: 0; transform: translateX(60px) scale(.9); } }
@keyframes shrink { to { transform: scaleX(0); } }
@keyframes shimmer { to { background-position: -200% 0; } }
@keyframes float { 50% { transform: translateY(-6px) rotate(-3deg); } }
@keyframes wiggle { 30% { transform: rotate(-12deg); } 60% { transform: rotate(8deg); } }
@keyframes ring { 10%, 50% { transform: rotate(16deg); } 30%, 70% { transform: rotate(-14deg); } 85% { transform: rotate(5deg); } }
@keyframes shake { 15%, 85% { transform: translateX(-2px); } 30%, 70% { transform: translateX(5px); } 45%, 55% { transform: translateX(-8px); } }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 45%, transparent); } 100% { box-shadow: 0 0 0 10px transparent; } }
@keyframes breathe { 50% { opacity: .6; } }
@keyframes fromRight { from { opacity: 0; transform: translateX(40px); } }
@keyframes fromLeft { from { opacity: 0; transform: translateX(-40px); } }
@keyframes ripple { to { transform: scale(1); opacity: 0; } }
@keyframes load { 0% { width: 0; } 30% { width: 45%; } 100% { width: 90%; } }
@keyframes bump { 0% { transform: scale(1); } 35% { transform: scale(1.18); color: var(--primary); } 100% { transform: scale(1); } }
@keyframes flash { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 45%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }
@keyframes savedGlow { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 50%, transparent); } 100% { box-shadow: 0 0 0 16px transparent; } }
@keyframes sheen { 0%, 70% { left: -60%; } 100% { left: 130%; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes dropIn { from { opacity: 0; transform: translateY(-10px) scale(.95); } }
@keyframes drift { 50% { transform: translate(8vmax, 6vmax) scale(1.15); } }

/* --- Animations coupées --- */
.no-motion *, .no-motion *::before, .no-motion *::after {
  animation: none !important; transition: none !important; scroll-behavior: auto !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
