/* =========================================================================
   Transitions de page (effet « stinger ») + micro-animations de contenu.

   L'application reste multi-pages : chaque navigation recharge le document.
   Le stinger masque ce rechargement derriere un balayage, ce qui donne la
   continuite visuelle d'une application monopage sans en avoir la mecanique.

   Tout est desactive si le systeme demande moins d'animations
   (prefers-reduced-motion) ou si .reduce-motion est pose sur <html>.
   ========================================================================= */

/* --- Le rideau ------------------------------------------------------------ */

.pt-stinger {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  overflow: hidden;
}

.pt-stinger.is-active {
  pointer-events: all;
}

.pt-band {
  position: relative;
  /* Repli explicite : la vitrine ne charge pas design-system.css, donc
     --primary n'y existe pas. Sans valeur de secours les bandes seraient
     transparentes et le rideau ne masquerait rien. */
  background: var(--primary, hsl(199, 89%, 45%));
  /* Bord biseaute : c'est lui qui donne le caractere « stinger » plutot
     qu'un simple fondu. */
  transform: translateX(-101%) skewX(-12deg);
  transform-origin: left center;
  will-change: transform;
  margin-left: -6%;
  width: 112%;
}

.pt-band:nth-child(2) {
  background: color-mix(in srgb, var(--primary, hsl(199, 89%, 45%)) 82%, var(--foreground, #0f172a));
}

.pt-band:nth-child(3) {
  background: color-mix(in srgb, var(--primary, hsl(199, 89%, 45%)) 64%, var(--foreground, #0f172a));
}

/* Le logo et l'indicateur d'attente apparaissent au centre pendant que
   l'ecran est couvert. */
.pt-mark {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.6rem;
  opacity: 0;
  transition: opacity 0.14s ease;
}

.pt-mark img {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 0.9rem;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
}

/* --- Indicateur d'attente -------------------------------------------------
   Carre qui pivote d'un quart de tour a chaque temps, pendant qu'un remplissage
   monte puis redescend. Le cycle dure 2 s et se repete tant que la page
   suivante n'a pas fini de charger.
   ------------------------------------------------------------------------- */

.pt-loader {
  display: inline-block;
  width: 30px;
  height: 30px;
  border: 4px solid #fff;
  animation: ptLoader 2s infinite ease;
}

.pt-loader-inner {
  display: inline-block;
  /* Le remplissage monte depuis le BAS : sans cet alignement il grandirait
     vers le bas et l'effet serait inverse. */
  vertical-align: bottom;
  width: 100%;
  height: 0;
  background: #fff;
  animation: ptLoaderInner 2s infinite ease-in;
}

@keyframes ptLoader {
  0%   { transform: rotate(0deg); }
  25%  { transform: rotate(180deg); }
  50%  { transform: rotate(180deg); }
  75%  { transform: rotate(360deg); }
  100% { transform: rotate(360deg); }
}

@keyframes ptLoaderInner {
  0%   { height: 0%; }
  25%  { height: 0%; }
  50%  { height: 100%; }
  75%  { height: 100%; }
  100% { height: 0%; }
}

/* L'indicateur ne tourne que tant que le rideau est baisse : une animation
   qui continue derriere un ecran devoile consomme sans rien montrer. */
.pt-stinger:not(.is-covered):not(.is-covering) .pt-loader,
.pt-stinger:not(.is-covered):not(.is-covering) .pt-loader-inner {
  animation: none;
}

/* Etat « deja couvert », pose des l'execution du script sur la page qui
   arrive : l'ecran est masque avant le premier rendu, donc on ne voit jamais
   la page apparaitre puis se faire recouvrir. */
.pt-stinger.is-covered .pt-band {
  transform: translateX(0) skewX(-12deg);
}

.pt-stinger.is-covered .pt-mark {
  opacity: 1;
}

/* Couverture : les bandes entrent en decalage, de haut en bas. */
.pt-stinger.is-covering .pt-band {
  animation: ptCover 0.34s cubic-bezier(0.7, 0, 0.3, 1) forwards;
}

.pt-stinger.is-covering .pt-band:nth-child(2) { animation-delay: 0.05s; }
.pt-stinger.is-covering .pt-band:nth-child(3) { animation-delay: 0.1s; }
.pt-stinger.is-covering .pt-mark { opacity: 1; transition-delay: 0.2s; }

/* Reveler : les bandes sortent par la droite. */
.pt-stinger.is-revealing .pt-band {
  transform: translateX(0) skewX(-12deg);
  animation: ptReveal 0.42s cubic-bezier(0.7, 0, 0.3, 1) forwards;
}

.pt-stinger.is-revealing .pt-band:nth-child(2) { animation-delay: 0.06s; }
.pt-stinger.is-revealing .pt-band:nth-child(3) { animation-delay: 0.12s; }

@keyframes ptCover {
  from { transform: translateX(-101%) skewX(-12deg); }
  to   { transform: translateX(0) skewX(-12deg); }
}

@keyframes ptReveal {
  from { transform: translateX(0) skewX(-12deg); }
  to   { transform: translateX(101%) skewX(-12deg); }
}

/* --- Entree du contenu ---------------------------------------------------- */

/* La zone principale monte legerement au chargement, juste apres le rideau. */
.pt-enter .dash-main > *,
.pt-enter main > * {
  animation: ptRise 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Cascade sur les blocs de tete : chiffres cles, cartes, lignes de tableau. */
.pt-enter .stat-grid > *,
.pt-enter .fed-kpis > *,
.pt-enter .card,
.pt-enter .shad-card,
.pt-enter .cashier-card {
  animation: ptRise 0.44s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.pt-enter .stat-grid > *:nth-child(1),
.pt-enter .fed-kpis > *:nth-child(1) { animation-delay: 0.02s; }
.pt-enter .stat-grid > *:nth-child(2),
.pt-enter .fed-kpis > *:nth-child(2) { animation-delay: 0.07s; }
.pt-enter .stat-grid > *:nth-child(3) { animation-delay: 0.12s; }
.pt-enter .stat-grid > *:nth-child(4) { animation-delay: 0.17s; }

@keyframes ptRise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* --- Changements a l'interieur d'une page --------------------------------- */

/* Pose par transitions.js sur les elements qui viennent d'apparaitre
   (lignes de tableau rechargees, resultats de recherche, listes...). */
.pt-in {
  animation: ptIn 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes ptIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Valeur chiffree qui change : un battement discret, sans deplacement. */
.pt-bump {
  animation: ptBump 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes ptBump {
  0%   { transform: none; }
  35%  { transform: scale(1.06); }
  100% { transform: none; }
}

/* --- Respect du reglage systeme ------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .pt-stinger { display: none; }

  .pt-enter .dash-main > *,
  .pt-enter main > *,
  .pt-enter .stat-grid > *,
  .pt-enter .fed-kpis > *,
  .pt-enter .card,
  .pt-enter .shad-card,
  .pt-enter .cashier-card,
  .pt-in,
  .pt-bump {
    animation: none !important;
  }
}

.reduce-motion .pt-stinger { display: none; }

.reduce-motion .pt-enter .dash-main > *,
.reduce-motion .pt-enter main > *,
.reduce-motion .pt-enter .stat-grid > *,
.reduce-motion .pt-enter .fed-kpis > *,
.reduce-motion .pt-enter .card,
.reduce-motion .pt-enter .shad-card,
.reduce-motion .pt-enter .cashier-card,
.reduce-motion .pt-in,
.reduce-motion .pt-bump {
  animation: none !important;
}
