/* ==========================================================================
   Perfils · motion.css (15/10/2026)
   --------------------------------------------------------------------------
   1. Motion tokens: the only place with durations and curves (--ease-*, --dur-*). Every transition and animation of the
      game reads them; motion.js reads the same tokens for the movements it drives.
   2. "Animações" off / prefers-reduced-motion: tokens collapse to 1 ms and the decorative loops stop, so every state
      still changes, instantly.
   3. The motion of the pieces: dialogs in and out, the clue flip, flying numbers, the turn marker, the list of clues at
      the end of a round.
   4. The menu controls for volume and animations.
   Loads right after theme.css. Only transform and opacity animate (the text of a counter changes, nothing else).
   ========================================================================== */

/* ============================ 1. tokens ================================== */
:root {
  /* exponential ease-out for things arriving; the spring overshoots by a hair and is only for things landing */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.5, 0, 0.75, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.28, 0.64, 1);

  --dur-1: 120ms;                       /* press, colour */
  --dur-2: 220ms;                       /* hover, state */
  --dur-3: 380ms;                       /* entrances */
  --dur-4: 640ms;                       /* clue reveal, glow */
  --dur-5: 800ms;                       /* a bar or a counter that follows a score */
  --dur-out: calc(var(--dur-3) * 0.6);  /* every exit is 40 % shorter than its entrance */
  --dur-flip: 360ms;                    /* a clue turning over: 300 to 420 ms */
  --dur-hop: 190ms;                     /* one hop of a pawn (the board sets the real value per walk) */
  --dur-flash: 1200ms;                  /* a clue recalled from the list */
  --dur-float: 1600ms;                  /* the "+N" that rises in place */
  --dur-glow: 1600ms;                   /* the halo of the newest clue */
  --dur-loop: 1900ms;                   /* idle breathing: the active pawn, the podium */
  --dur-loop-slow: 2600ms;              /* the nudge of a fresh board */
  --stagger: 18ms;                      /* step between the lines of a list that enters one by one */
}

/* ============================ 2. no motion =============================== */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-1: 1ms; --dur-2: 1ms; --dur-3: 1ms; --dur-4: 1ms; --dur-5: 1ms; --dur-flip: 1ms; --dur-hop: 1ms; --dur-flash: 1ms;
    --dur-float: 1ms; --dur-glow: 1ms; --dur-loop: 1ms; --dur-loop-slow: 1ms; --stagger: 0ms;
  }
}
:root[data-motion='off'] {
  --dur-1: 1ms; --dur-2: 1ms; --dur-3: 1ms; --dur-4: 1ms; --dur-5: 1ms; --dur-flip: 1ms; --dur-hop: 1ms; --dur-flash: 1ms;
  --dur-float: 1ms; --dur-glow: 1ms; --dur-loop: 1ms; --dur-loop-slow: 1ms; --stagger: 0ms;
}

/* The switch in the menu does what prefers-reduced-motion does (style.css and the blocks at the end of the other sheets). */
:root[data-motion='off'] *,
:root[data-motion='off'] *::before,
:root[data-motion='off'] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  animation-delay: 0ms !important;
  transition-duration: 0.01ms !important;
  transition-delay: 0ms !important;
  scroll-behavior: auto !important;
}
/* resting looks that differ from "the loop has ended" (same as the media blocks of board.css, theme.css and modes.css) */
:root[data-motion='off'] .pf-pawn { transition-duration: 0ms !important; }
:root[data-motion='off'] .pf-hop,
:root[data-motion='off'] .pf-shadow,
:root[data-motion='off'] .pf-land,
:root[data-motion='off'] .pf-clue.is-new .pf-tri-glow { animation: none !important; }
:root[data-motion='off'] .pf-clue.is-new .pf-tri-glow { opacity: 1; }
:root[data-motion='off'] .pf-board.is-fresh .pf-clue:not(.is-open) .pf-tri-glow { animation: none !important; opacity: 0.4; }
:root[data-motion='off'] .pf-pawn.is-active .pf-shadow::after { animation: none !important; opacity: 0.8; transform: scale(1.1); }
:root[data-motion='off'] .p-tri-num.is-new,
:root[data-motion='off'] .p-tri-num[data-state='new'] {
  filter: drop-shadow(0 0 0 var(--p-cream)) drop-shadow(0 0 5px rgb(244 235 173 / 0.95)) drop-shadow(0 2px 0 rgb(15 15 18 / 0.5));
}
:root[data-motion='off'] .p-btn:hover:not(:disabled),
:root[data-motion='off'] .p-btn.is-hover,
:root[data-motion='off'] .p-chip:hover,
:root[data-motion='off'] .p-tri-num:hover { transform: none; }
:root[data-motion='off'] .score-row.is-turn { transform: none; }
:root[data-motion='off'] .aw-opt,
:root[data-motion='off'] .aw-opt:hover,
:root[data-motion='off'] .aw-opt:active { transform: none; }

/* ============================ 3. dialogs ================================= */
/* In: theme.css (spring, --dur-3). Out: the dialog is already closed for the page (focus, inert and `open` are back at once);
   it only finishes fading on screen. A browser without discrete transitions simply closes it at once. */
dialog.p-modal:not([open]) {
  display: none;                          /* where the discrete transition ends */
  position: fixed;
  inset: 0;
  z-index: 1000;
  height: fit-content;
  margin: auto;
  opacity: 0;
  transform: translateY(0.5rem) scale(0.985);
  pointer-events: none;
  transition: opacity var(--dur-out) var(--ease-in-out), transform var(--dur-out) var(--ease-in-out), display var(--dur-out) allow-discrete;
}

/* ============================ 3. a clue opens: the flip ================== */
.pf-clue.is-flipping .pf-tri-n { transform-box: fill-box; transform-origin: 50% 50%; }
.pf-tri-face--old { pointer-events: none; }

/* ============================ 3. things that fly ========================= */
.fx-fly {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 10000;
  display: block;
  padding: 0.1rem 0.55rem;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.2;
  color: var(--p-black);
  background: linear-gradient(180deg, var(--p-gold-hi), var(--p-orange));
  border: 2px solid var(--p-black);
  border-radius: var(--r-2);
  box-shadow: 0 2px 0 var(--p-black);
  font-variant-numeric: lining-nums tabular-nums;
  pointer-events: none;
  will-change: transform, opacity;
}
/* the number of a clue travelling from its triangle to the clue card */
.fx-fly--clue { min-width: 2rem; text-align: center; font-size: 1.15rem; }
/* the number of the clue that was on the card, travelling into the list of the revealed ones */
.fx-fly--line { min-width: 1.8rem; text-align: center; font-size: 1rem; color: var(--p-teal-ink); background: var(--p-paper); box-shadow: 0 2px 0 var(--p-teal-deep); border-color: var(--p-teal-deep); }
/* the destination shows only when the number lands */
.clue-live.is-landing .p-card__no { opacity: 0; }
.clue-item.is-landing .clue-item-n { opacity: 0; }
.clue-item.is-entering { animation: mo-line-in var(--dur-3) var(--ease-out) backwards; }
@keyframes mo-line-in {
  from { opacity: 0; transform: translateY(0.45rem); }
  to { opacity: 1; transform: none; }
}

/* ============================ 3. the turn marker slides ================== */
/* The frame around the player in turn is one element that travels between the cards (motion.js moves it with transform). */
.turn-glide {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
  border-radius: var(--r-3);
  box-shadow: 0 0 0 3px var(--p-cream), 0 0 0 5px var(--p-black), 0 8px 14px -4px rgb(232 163 58 / 0.55);
  pointer-events: none;
}
.turn-glide[hidden] { display: none; }
.turn-glide.is-gliding { will-change: transform; }
/* with the glide the cards keep their gold fill, the frame comes from the glide */
.score-wrap.has-glide .score-row.is-turn { box-shadow: 0 3px 0 var(--p-black); }

/* ============================ 3. end of round: the clues come in one by one */
.dlg-round[open] .rd-lines li {
  animation: mo-line-in var(--dur-3) var(--ease-out) backwards; /* backwards: the line waits invisible for its turn, then rests in its normal style */
  animation-delay: calc(var(--dur-2) + var(--i, 0) * var(--stagger));
}

/* ============================ 4. menu: volume and animations ============= */
.menu-volume { cursor: default; flex-wrap: wrap; row-gap: 0.4rem; }
.menu-volume:hover, .menu-volume:active { transform: none; box-shadow: inset 0 0 0 2px var(--p-paper), inset 0 0 0 3px var(--p-teal-deep), 0 3px 0 var(--p-black); }
.menu-volume .menu-item__text b { display: block; font-family: var(--font-label); font-weight: 600; font-size: var(--fs-sm); letter-spacing: var(--track-label); text-transform: uppercase; line-height: 1.2; }
.menu-volume__text { font-weight: 700; color: var(--p-teal-ink); font-variant-numeric: lining-nums tabular-nums; }
.menu-range {
  --fill: 90%;
  flex: 1 1 11rem;
  min-width: 0;
  height: 2.75rem;                        /* a 44 px target */
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.menu-range:disabled { cursor: not-allowed; opacity: 0.5; }
.menu-range:focus-visible { outline: 3px solid var(--p-focus); outline-offset: 2px; }
.menu-range::-webkit-slider-runnable-track {
  height: 0.7rem;
  background: linear-gradient(to right, var(--p-teal) var(--fill), var(--p-disabled-face) var(--fill));
  border: 2px solid var(--p-black);
  border-radius: var(--r-1);
  box-shadow: inset 0 2px 0 rgb(15 15 18 / 0.2);
}
.menu-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: calc((0.7rem - 4px - 1.5rem) / 2);
  background: linear-gradient(180deg, var(--p-gold-glow), var(--p-orange));
  border: 2px solid var(--p-black);
  border-radius: var(--r-1);
  box-shadow: 0 2px 0 var(--p-black);
}
.menu-range::-moz-range-track {
  height: 0.7rem;
  background: linear-gradient(to right, var(--p-teal) var(--fill), var(--p-disabled-face) var(--fill));
  border: 2px solid var(--p-black);
  border-radius: var(--r-1);
}
.menu-range::-moz-range-thumb {
  width: 1.5rem;
  height: 1.5rem;
  background: linear-gradient(180deg, var(--p-gold-glow), var(--p-orange));
  border: 2px solid var(--p-black);
  border-radius: var(--r-1);
  box-shadow: 0 2px 0 var(--p-black);
}
/* the menu now has two more rows: on a wide window it takes two columns, so it still fits a laptop screen without scrolling */
@media (min-width: 760px) {
  dialog.dlg-menu { width: min(44rem, calc(100vw - 2rem)); }
  dialog.dlg-menu .menu-list { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
  dialog.dlg-menu .menu-list > li { display: flex; }
  dialog.dlg-menu .menu-list > li > .menu-item { height: 100%; }
}
.menu-lab { margin: 0 0 var(--sp-3); font-size: var(--fs-xs); text-align: center; }
.menu-lab a { color: var(--p-teal-ink); text-underline-offset: 0.2em; }
.menu-lab[hidden] { display: none; }

@media (forced-colors: active) {
  .fx-fly, .turn-glide { border: 2px solid ButtonText; }
  .menu-range::-webkit-slider-runnable-track, .menu-range::-webkit-slider-thumb { border-color: ButtonText; }
}
