/* ==========================================================================
   motion.css — the results layout (score card + crew cards) and the app's
   micro-motion. Loaded after the main <style> in public/index.html, so it
   refines rather than restates. Colours come from the page tokens only, so
   dark and light both work with no extra rules.

   Timing: snappy. Everything a player waits on is under 400ms; the only long
   things are the score count (scaled to the number) and the confetti fall.
   ========================================================================== */

/* ------------------------------------------------------------ score card */
.res { padding-bottom:4px; }
.res-chips { margin-top:2px; }

.res .verdictcard { margin:10px 0 0; padding:14px 16px 18px; border-radius:20px;
                    overflow:hidden; isolation:isolate; }
.vc-top { display:flex; align-items:center; gap:8px; text-align:left; min-height:34px; }
.vc-top .vc-label { flex:0 0 auto; }
.res .vc-date { flex:1 1 auto; margin:0; padding:0; background:none; justify-content:flex-end;
                font:500 10.5px/1.2 var(--mono); letter-spacing:.04em; color:var(--dim);
                white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.res .vc-date.old { background:var(--gold-soft); color:var(--gold); padding:5px 9px;
                    border-radius:99px; flex:0 1 auto; margin-left:auto; }
.res .vc-score { font-size:100px; margin:4px 0 2px; font-variant-numeric:tabular-nums; }
.res .vc-band { font:750 15px/1 var(--mono); letter-spacing:.2em; margin-top:6px;
                display:inline-block; transform-origin:50% 50%; }
.res .vc-meter { height:12px; max-width:340px; margin-top:14px; background:var(--sunk);
                 border:1px solid var(--line); }
.res .vc-meter i { transition:none; background:linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 70%, var(--gold))); }
.vc-head { margin:13px auto 0; max-width:30em; font-size:15.5px; line-height:1.35;
           letter-spacing:-.01em; font-weight:560; }
.res .vc-sub { margin-top:8px; font-size:13px; }

/* The speaker toggle. Sits in the card's top row; motion.js wires it. */
.m-spk { flex:0 0 auto; width:34px; height:34px; display:grid; place-items:center;
         border:1px solid var(--line); border-radius:99px; background:var(--sunk);
         color:var(--fg); cursor:pointer; padding:0; transition:transform .12s, color .15s; }
.m-spk[aria-pressed="false"] { color:var(--dim); }
.m-spk:active { transform:scale(.9); }
.m-spk:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

/* The reveal lane's slot: a compact row of chips. Empty until it has data. */
.vc-reveal { display:flex; flex-wrap:wrap; justify-content:center; gap:6px; margin-top:12px; }
.vc-reveal .rv { font:600 11px/1 var(--mono); letter-spacing:.04em; padding:6px 9px;
                 border-radius:99px; background:var(--sunk); color:var(--dim);
                 border:1px solid var(--line); }
.vc-reveal .rv b { color:var(--fg); }
.vc-reveal .rv.gold { background:var(--gold-soft); color:var(--gold); border-color:transparent; }
.vc-reveal .rv.good { color:var(--good); }

/* While the number counts, the verdict and the lines under it wait. They are
   hidden only while motion.js says it is counting, so a failed load of the
   script can never leave them invisible. */
.m-counting .vc-band, .m-counting .vc-head, .m-counting .vc-sub, .m-counting .vc-reveal { opacity:0; }

/* Verdict moods, set by motion.js when the count lands. */
.m-great .vc-band { color:var(--gold); }
.m-great .vc-meter i { background:linear-gradient(90deg, var(--good), var(--gold)); }
.m-great { border-color:color-mix(in srgb, var(--gold) 60%, var(--line)); }
.m-bad .vc-band { color:var(--bad); }
.m-bad .vc-meter i { background:var(--bad); }
.m-bad { border-color:color-mix(in srgb, var(--bad) 55%, var(--line)); }

/* ------------------------------------------------------------ crew cards */
.crew { display:grid; gap:10px; margin:14px 0 8px; }
.cc { position:relative; border:1px solid var(--line); border-radius:16px; background:var(--card);
      box-shadow:var(--shadow); overflow:hidden; isolation:isolate; }
.cc::before { content:""; position:absolute; left:0; top:0; bottom:0; width:4px; z-index:2;
              background:var(--line-2); }
.cc.g--good::before { background:var(--good); }
.cc.g--mid::before  { background:var(--gold); }
.cc.g--bad::before  { background:var(--bad); }
.cc.g--void { border-style:dashed; box-shadow:none; background:transparent; }
.cc.g--void::before { background:transparent; }
.cc.is-first { border-color:var(--gold); }

.cc-face { list-style:none; display:block; position:relative; cursor:pointer;
           min-height:112px; padding:14px 38% 14px 18px; }
.cc-face::-webkit-details-marker { display:none; }
.cc-face:focus-visible { outline:2px solid var(--accent); outline-offset:-3px; border-radius:16px; }
/* The open/close hint: a small round chip in the corner, over the portrait. */
.cc-face::after { content:"+"; position:absolute; right:9px; bottom:9px; z-index:3;
                  width:22px; height:22px; border-radius:99px; display:grid; place-items:center;
                  font:600 14px/1 var(--mono); color:var(--fg);
                  background:color-mix(in srgb, var(--bg) 70%, transparent);
                  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); }
.cc[open] > .cc-face::after { content:"\2212"; color:var(--accent); }

.cc-txt { position:relative; z-index:2; }
.cc-top { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
.cc-role { font:650 10px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase;
           color:var(--dim); padding:4px 6px; border-radius:5px; background:var(--sunk);
           border:1px solid var(--line); }
.cc-verdict { font:700 10px/1 var(--mono); letter-spacing:.12em; text-transform:uppercase;
              color:var(--dim); }
.cc.g--good .cc-verdict { color:var(--good); }
.cc.g--mid  .cc-verdict { color:var(--gold); }
.cc.g--bad  .cc-verdict, .cc.is-void .cc-verdict { color:var(--bad); }
.cc-tags { position:absolute; top:10px; right:10px; z-index:3; display:flex; flex-direction:column;
           align-items:flex-end; gap:4px; pointer-events:none; }
.cc-tags .cc-tag { box-shadow:0 2px 8px rgba(0,0,0,.35); }
.cc-tag { font:750 9.5px/1 var(--mono); letter-spacing:.1em; text-transform:uppercase;
          padding:4px 6px; border-radius:5px; }
.cc-tag.mvp { background:var(--good); color:var(--bg); }
.cc-tag.bust { background:var(--bad); color:var(--bg); }
.cc-tag.gold { background:var(--gold); color:var(--bg); }
.cc-name { font-weight:720; font-size:23px; line-height:1.08; letter-spacing:-.022em;
           margin:8px 0 5px; display:-webkit-box; -webkit-box-orient:vertical;
           -webkit-line-clamp:2; overflow:hidden; text-shadow:0 1px 12px var(--card); }
.cc.is-void .cc-name { color:var(--dim); text-decoration:line-through;
                       text-decoration-thickness:1.5px; text-decoration-color:var(--bad); }
.cc-why { font-size:13.5px; line-height:1.4; color:var(--dim); display:-webkit-box;
          -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden; }
/* Open, the full reasoning is right below; the face keeps only the name. */
.cc[open] .cc-why { display:none; }

/* The face, bleeding in from the right. The mask fades it into the card so the
   name can run over its left edge and still read. */
.cc-pic { position:absolute; top:0; right:0; bottom:0; width:46%; z-index:1; overflow:hidden;
          pointer-events:none; }
.cc-pic img { display:block; width:100%; height:100%; object-fit:cover; object-position:50% 22%;
              -webkit-mask-image:linear-gradient(to right, transparent 0, rgba(0,0,0,.55) 32%, #000 70%);
              mask-image:linear-gradient(to right, transparent 0, rgba(0,0,0,.55) 32%, #000 70%);
              filter:saturate(.92); }
.cc.is-void .cc-pic img { filter:grayscale(1); opacity:.45; }
.cc-cap { position:absolute; right:38px; bottom:11px; max-width:70%; text-align:right;
          font:600 8.5px/1.25 var(--mono); letter-spacing:.06em; text-transform:uppercase;
          color:#fff; text-shadow:0 1px 3px rgba(0,0,0,.8); }
/* The monogram is a designed state: a wash of the record's hue and the initials. */
.cc-mono { position:absolute; inset:0; display:flex; align-items:center; justify-content:flex-end;
           padding-right:18px;
           background:linear-gradient(to right, transparent 0,
             hsl(var(--h, 0) 42% 38% / .35) 40%, hsl(var(--h, 0) 42% 38% / .75) 100%); }
.cc-mono span { font:800 58px/1 var(--mono); letter-spacing:-.04em; color:#fff; opacity:.8; }

.cc-more { padding:0 18px 16px; position:relative; z-index:2; border-top:1px solid var(--line); }
.cc-more > :first-child { margin-top:12px; }
.cc-more .fit { font-size:14.5px; }
.cc-more .rp-desc { margin:0 0 8px; }
.cc-better { margin-top:10px; font-size:13.5px; color:var(--fg); font-weight:560; }
.cc-rare { margin-top:4px; font-size:13px; color:var(--dim); }
.cc-key:empty { display:none; }
/* The argue anchor (public/argue.js looks for .rp[data-seat]). It is a bare row
   here, so the old result-row box styles are switched off. */
.cc-more .rp.cc-argue { border:0; border-radius:0; background:none; box-shadow:none;
                        padding:0; margin:0; }
.cc-more .rp.cc-argue:empty { display:none; }
.cc-alts { margin-top:8px; display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.cc-alts .k { width:100%; font:600 9.5px/1 var(--mono); letter-spacing:.14em;
              text-transform:uppercase; color:var(--dim); margin-bottom:2px; }
.cc-alt { font-size:13px; padding:5px 9px; border-radius:99px; background:var(--sunk);
          border:1px solid var(--line); }

.res .credits { margin:4px 2px 14px; padding-top:0; border-top:0; }
.res .discovery { margin:4px 0 14px; }
.res-go { display:grid; grid-template-columns:1fr 1fr; gap:9px; margin:6px 0 18px; }
.res-go .big { padding:15px 10px; }
.res-more { margin-top:4px; }

@media (max-width:374px) {
  .res .vc-score { font-size:88px; }
  .cc-name { font-size:20px; }
  .cc-face { padding-right:34%; }
}
@media (min-width:700px) {
  /* A wide card would crop a face to a letterbox, so the portrait keeps a
     portrait-ish width and the text takes the rest. */
  .cc-face { min-height:140px; padding-right:220px; }
  .cc-pic { width:210px; }
  .cc-name { font-size:26px; }
}

/* ------------------------------------------------------------ confetti */
#m-confetti { position:fixed; inset:0; pointer-events:none; z-index:60; overflow:hidden; }
#m-confetti i { position:absolute; width:8px; height:12px; border-radius:1.5px; opacity:0;
                will-change:transform, opacity;
                animation:m-burst 1.9s cubic-bezier(.2,.6,.4,1) forwards; }
#m-confetti i.m-round { width:8px; height:8px; border-radius:99px; }
@keyframes m-burst {
  0%   { opacity:1; transform:translate3d(0,0,0) rotate(0); }
  22%  { opacity:1; transform:translate3d(calc(var(--dx) * .5), var(--dy), 0) rotate(calc(var(--dr) * .3)); }
  100% { opacity:0; transform:translate3d(var(--dx), 62vh, 0) rotate(var(--dr)); }
}

/* ------------------------------------------------------------ motion
   Everything below moves, so all of it is behind no-preference. Under reduced
   motion the page simply renders in its end state. */
@media (prefers-reduced-motion: no-preference) {
  /* The score card arrives, the number counts (motion.js), then it lands. */
  .res .verdictcard { animation:m-rise 320ms cubic-bezier(.2,.9,.3,1) both; }
  .m-landed .vc-score { animation:m-pop 300ms cubic-bezier(.2,1.4,.4,1) both; }
  .m-landed .vc-band { animation:m-stamp 240ms cubic-bezier(.2,1.3,.4,1) both; }
  .m-landed .vc-head { animation:m-rise 300ms ease-out 80ms both; }
  .m-landed .vc-sub, .m-landed .vc-reveal { animation:m-rise 300ms ease-out 150ms both; }
  .res .verdictcard.m-great { animation:m-glow-gold 1.3s ease-out both; }
  .res .verdictcard.m-bad { animation:m-shake 420ms cubic-bezier(.36,.07,.19,.97) both, m-glow-red 1.3s ease-out both; }

  /* Crew cards deal in, one after another, while the number counts. */
  .res .cc { animation:m-deal 340ms cubic-bezier(.2,.9,.3,1.05) both;
             animation-delay:calc(180ms + var(--i, 0) * 75ms); }
  .res .cc-tags .cc-tag { animation:m-stamp 260ms cubic-bezier(.2,1.3,.4,1) both;
                          animation-delay:calc(480ms + var(--i, 0) * 75ms); }
  .cc-pic img { opacity:0; transform:translateX(18px); transition:opacity .35s ease-out, transform .38s cubic-bezier(.2,.9,.3,1); }
  .cc-pic.is-in img { opacity:1; transform:none; }
  .cc[open] > .cc-more { animation:m-drop 220ms ease-out both; }
  .cc-face:active { transform:scale(.992); }
  .cc-face { transition:transform .1s; }

  /* Sections open with a short drop rather than a jump. */
  details.sect[open] > .sect-b { animation:m-drop 220ms ease-out both; }

  /* Seats: a pop when one gets a name, a stagger when a board arrives. */
  .slot.m-fill { animation:m-fill 360ms cubic-bezier(.2,1.3,.4,1); }
  .slot.m-enter { animation:m-rise 320ms cubic-bezier(.2,.9,.3,1) both;
                  animation-delay:calc(var(--m-i, 0) * 55ms); }

  /* Sheets slide and drag in shell.css + sheet.js; the shell lane owns them. */

  button.big { transition:transform .08s ease-out; }
  button.big:active:not(:disabled) { transform:scale(.975); }
}

@keyframes m-rise { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:none; } }
@keyframes m-deal { from { opacity:0; transform:translateY(16px) scale(.985); } to { opacity:1; transform:none; } }
@keyframes m-drop { from { opacity:0; transform:translateY(-4px); } to { opacity:1; transform:none; } }
@keyframes m-pop { 0% { transform:scale(1); } 45% { transform:scale(1.07); } 100% { transform:scale(1); } }
@keyframes m-stamp { from { transform:scale(1.5) rotate(-4deg); opacity:0; } to { transform:none; opacity:1; } }
@keyframes m-fill { 0% { transform:scale(1); } 40% { transform:scale(1.012); border-color:var(--accent); } 100% { transform:scale(1); } }
@keyframes m-shake {
  0%, 100% { transform:translateX(0); }
  15% { transform:translateX(-7px) rotate(-.4deg); }
  30% { transform:translateX(6px) rotate(.3deg); }
  45% { transform:translateX(-5px); }
  60% { transform:translateX(4px); }
  75% { transform:translateX(-2px); }
}
@keyframes m-glow-red {
  0%   { box-shadow:0 0 0 0 color-mix(in srgb, var(--bad) 0%, transparent), var(--shadow); }
  25%  { box-shadow:0 0 0 3px color-mix(in srgb, var(--bad) 55%, transparent), 0 0 42px 4px color-mix(in srgb, var(--bad) 45%, transparent); }
  100% { box-shadow:0 0 0 1px color-mix(in srgb, var(--bad) 25%, transparent), 0 0 26px -6px color-mix(in srgb, var(--bad) 35%, transparent); }
}
@keyframes m-glow-gold {
  0%   { box-shadow:0 0 0 0 transparent, var(--shadow); }
  30%  { box-shadow:0 0 0 3px color-mix(in srgb, var(--gold) 55%, transparent), 0 0 48px 6px color-mix(in srgb, var(--gold) 40%, transparent); }
  100% { box-shadow:0 0 0 1px color-mix(in srgb, var(--gold) 30%, transparent), 0 0 30px -6px color-mix(in srgb, var(--gold) 35%, transparent); }
}
