/* 탁구 앱의 함께 보는 화면 — 라이브 관람(tw), 홈 피드(th), 경기 공유(ts), 순위 필터·급상승(ttr…).
 *
 * 색·글꼴·간격은 사이트 토큰(var(--…))과 놀이터 키트(kit.css 의 --tp-*)만 쓴다 — 다크 모드가 한 곳에서 바뀌게.
 * 움직임은 transform·opacity 만(저사양 폰에서 끊기지 않게), 움직임 줄이기면 맨 아래에서 모두 멈춘다.
 */

/* ── 공용: LIVE 배지 ── 빨간 점이 숨 쉬듯 깜빡인다 */
.twBadge{display:inline-flex;align-items:center;gap:6px;font-weight:900;font-size:var(--fs-sm);letter-spacing:.08em;
  color:#fff;background:var(--accent);border-radius:999px;padding:3px 12px 3px 10px;line-height:1.4}
.twBadge[data-live]::before{content:"";width:9px;height:9px;border-radius:50%;background:#fff;animation:twPulse 1.4s ease-in-out infinite}
.twBadge.off{background:var(--surface-2);color:var(--dim);border:1px solid var(--border)}
@keyframes twPulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.55);opacity:.45}}

/* ── 라이브 관람 ── */
.twHead{display:flex;align-items:center;gap:var(--sp-4);margin:0 0 var(--sp-5)}
.twHead .tpPongi{width:72px}
.twHead h1{font-size:var(--fs-2xl);line-height:1.25;margin:6px 0 4px;overflow-wrap:anywhere}
.twHead .lead{margin:0;color:var(--dim)}
.twApp{position:relative;display:grid;gap:var(--sp-3);margin:0 0 var(--sp-6)}
.twBoard{display:grid;grid-template-columns:1fr 1fr;gap:10px;position:relative}
.twHalf{position:relative;overflow:hidden;display:grid;justify-items:center;align-content:center;gap:4px;min-width:0;
  min-height:min(46vh,340px);border-radius:22px;padding:var(--sp-5) var(--sp-2);border:3px solid var(--tp-line);color:#fffaf2;
  background:linear-gradient(180deg,var(--tp-table-2),var(--tp-table));box-shadow:0 6px 0 color-mix(in srgb,var(--tp-table) 60%,#000);
  transition:box-shadow .3s var(--tp-spring)}
.twHalf:first-child{border-right-width:6px}.twHalf:last-child{border-left-width:6px}
.twHalf.serving{box-shadow:0 6px 0 var(--accent-hover),0 0 0 4px var(--accent)}
.twHalf.won{box-shadow:0 6px 0 var(--accent-hover),0 0 0 5px var(--tp-sun)}
.twGames{position:absolute;top:10px;left:12px;font-size:var(--fs-sm);font-weight:800;opacity:.85}
.twName{font-size:var(--fs-lg);font-weight:800;max-width:100%;overflow-wrap:anywhere;text-align:center;padding:0 6px}
.twPts{font-size:clamp(64px,22vw,190px);font-weight:900;line-height:1;font-variant-numeric:tabular-nums;color:#fffaf2;display:inline-block}
.twServe{display:flex;align-items:center;gap:6px;min-height:40px;font-weight:800}
.twServe .tpPongi{width:34px}
.twCall{text-align:center;font-weight:900;font-size:var(--fs-xl);color:var(--accent-text);min-height:1.5em;margin:0}
.twCall.big{animation:twShout .6s var(--tp-spring)}
@keyframes twShout{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.15);opacity:1}100%{transform:scale(1)}}
.twSets{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:6px;padding:0;margin:0}
.twSets li{border:2px solid var(--border-2);border-radius:999px;padding:2px 12px;font-weight:800;font-variant-numeric:tabular-nums;background:var(--surface);animation:tpIn .4s var(--tp-spring) both}
.twSets li.now{border-color:var(--accent);color:var(--accent-text)}
/* 랠리 타임라인 — 이번 게임의 득점이 작은 공으로 줄을 선다. 왼쪽 선수 공은 흰 공, 오른쪽은 주황 공 */
.twTimeline{display:flex;flex-wrap:wrap;justify-content:center;gap:5px;min-height:22px;padding:0;margin:0;list-style:none}
.twTimeline li{width:16px;height:16px;border-radius:50%;border:2px solid var(--tp-ink);background:var(--tp-ball);animation:twDrop .45s var(--tp-spring) both}
.twTimeline li.B{background:var(--tp-orange)}
[data-theme="dark"] .twTimeline li{border-color:#fffaf2}
@keyframes twDrop{0%{transform:translateY(-14px) scale(.4);opacity:0}100%{transform:none;opacity:1}}
.twLegend{display:flex;justify-content:center;gap:var(--sp-4);font-size:var(--fs-sm);color:var(--dim);margin:0}
.twLegend i{display:inline-block;width:11px;height:11px;border-radius:50%;border:2px solid var(--tp-ink);background:var(--tp-ball);vertical-align:-1px;margin-right:4px}
.twLegend i.B{background:var(--tp-orange)}
/* 득점하면 공 하나가 그 선수 칸으로 날아가 톡 */
.twFly{position:absolute;top:30%;left:50%;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;background:var(--tp-ball);border:3px solid var(--tp-ink);
  pointer-events:none;z-index:4;animation:twFly .55s cubic-bezier(.3,.7,.4,1) forwards}
@keyframes twFly{0%{transform:translate(0,0) scale(.6)}45%{transform:translate(calc(var(--dx)*.55),-70px) scale(1.1)}100%{transform:translate(var(--dx),40px) scale(.8);opacity:0}}
.twToast{position:absolute;left:50%;top:40%;z-index:6;display:flex;align-items:center;gap:10px;max-width:90%;transform:translate(-50%,-50%);
  background:var(--surface);color:var(--text);border:3px solid var(--accent);border-radius:20px;padding:12px 18px;box-shadow:var(--shadow-lg);
  font-size:var(--fs-lg);font-weight:800;animation:twToast 2.6s var(--tp-spring) both}
.twToast .tpPongi{width:44px}
@keyframes twToast{0%{opacity:0;transform:translate(-50%,-30%) scale(.8)}12%{opacity:1;transform:translate(-50%,-50%) scale(1)}85%{opacity:1}100%{opacity:0}}
/* 응원 */
.twCheers{display:flex;justify-content:center;gap:var(--sp-3);flex-wrap:wrap}
.twCheer{appearance:none;font:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:8px;min-height:48px;padding:8px 18px;border-radius:999px;
  border:2px solid var(--border-2);background:var(--surface);color:var(--text);font-weight:800;box-shadow:0 4px 0 var(--border-2);transition:transform .2s var(--tp-spring)}
.twCheer .e{font-size:24px;line-height:1}
.twCheer:active{transform:translateY(3px) scale(.95);box-shadow:0 1px 0 var(--border-2)}
.twCheer:focus-visible{outline:3px solid var(--text);outline-offset:2px}
.twCheer[disabled]{opacity:.5;cursor:not-allowed}
.twFloats{position:fixed;inset:0;pointer-events:none;z-index:60;overflow:hidden}
.twFloat{position:absolute;bottom:-40px;font-size:30px;animation:twFloat 2.2s ease-out forwards}
@keyframes twFloat{0%{transform:translate(0,0) scale(.6);opacity:0}15%{opacity:1}100%{transform:translate(var(--sx,0),-70vh) scale(1.2) rotate(var(--rot,0deg));opacity:0}}
.twConn{display:flex;align-items:center;justify-content:center;gap:6px;font-size:var(--fs-sm);color:var(--dim);margin:0}
.twConn::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--ok)}
.twConn.wait::before{background:var(--warn-fill);animation:twPulse 1s infinite}
.twConn.off::before{background:var(--border-2)}
.twTools{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-2)}
.twOwner[hidden]{display:none}
.twOwner{border:2px dashed var(--accent);border-radius:var(--r-lg);padding:var(--sp-4);display:grid;gap:var(--sp-2);justify-items:center;text-align:center;background:var(--accent-bg)}
.twFoot{font-size:var(--fs-sm);margin:var(--sp-5) 0 0}

/* ── 홈 피드 ── */
.thHero{display:flex;align-items:center;gap:var(--sp-5);margin:0 0 var(--sp-6);padding:var(--sp-5);border-radius:24px;
  background:radial-gradient(circle at 12px 12px,var(--tp-dot) 3px,transparent 3.5px) 0 0/28px 28px,var(--surface);border:2px solid var(--border-2)}
.thHero h1{font-size:var(--fs-3xl);margin:0 0 var(--sp-2);line-height:1.2}
.thHero .lead{color:var(--dim);margin:0 0 var(--sp-3)}
.thBtns{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0}
.thSec{margin:0 0 var(--sp-7)}
.thSec h2{font-size:var(--fs-xl);margin:0 0 var(--sp-3);display:flex;align-items:center;gap:8px}
.thDot{width:12px;height:12px;border-radius:50%;background:var(--accent);animation:twPulse 1.4s ease-in-out infinite}
.thEmpty{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;border:2px dashed var(--border-2);border-radius:var(--r-lg);padding:var(--sp-4)}
.thEmpty p{margin:0}
.thEmpty .tpPongi{width:64px}
.thLives,.thRecent,.thTasks{list-style:none;padding:0;margin:0;display:grid;gap:var(--sp-2)}
.thLives li,.thRecent li,.thTasks li,.thNews li{animation:tpIn .45s var(--tp-spring) both;animation-delay:calc(var(--i,0) * 60ms)}
.thLiveCard{display:grid;gap:4px;justify-items:start;padding:var(--sp-3) var(--sp-4);border-radius:var(--r-lg);text-decoration:none;color:inherit;
  border:2px solid var(--border-2);background:var(--surface);transition:transform .2s var(--tp-spring)}
.thLiveCard:hover{border-color:var(--accent);transform:translateY(-2px)}
.thVs{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;font-size:var(--fs-lg)}
.thScore{font-weight:900;font-variant-numeric:tabular-nums;color:var(--accent-text);padding:0 4px}
.thRecent li{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;border-bottom:1px solid var(--border);padding:var(--sp-2) 0}
.thRecent a{display:flex;align-items:center;gap:var(--sp-2);text-decoration:none;color:inherit;flex-wrap:wrap}
.thRecent b.win::after{content:" 🏆";font-size:.85em}
.thTasks a,.thTasks .task{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-radius:var(--r-lg);border:2px solid var(--border-2);
  background:var(--surface);text-decoration:none;color:inherit;font-weight:700}
.thTasks a:hover{border-color:var(--accent)}
.thTasks .ic{font-size:22px;line-height:1}
.thTasks .done{border-style:dashed;color:var(--dim)}
.thTasks .count{margin-left:auto;min-width:28px;height:28px;border-radius:999px;background:var(--accent);color:#fff;display:grid;place-items:center;font-size:var(--fs-sm);font-weight:900;animation:tpPop .6s var(--tp-spring)}
.thDots{display:inline-flex;gap:5px;vertical-align:middle}
.thDots i,.ttrDots i{width:9px;height:9px;border-radius:50%;background:var(--tp-orange);animation:twDot 1s var(--tp-spring) infinite}
.thDots i:nth-child(2),.ttrDots i:nth-child(2){animation-delay:.15s;background:var(--accent)}
.thDots i:nth-child(3),.ttrDots i:nth-child(3){animation-delay:.3s;background:var(--tp-ink)}
.ttrDots{display:inline-flex;gap:5px;vertical-align:middle}
@keyframes twDot{0%,100%{transform:translateY(0)}40%{transform:translateY(-7px)}}

/* ── 경기 공유 ── 작은 점수판 카드. 이긴 쪽에 왕관이 통통 */
.tsCard{position:relative;max-width:560px;margin:0 auto var(--sp-5);padding:var(--sp-5) var(--sp-4) var(--sp-4);border-radius:26px;color:#fffaf2;
  background:linear-gradient(180deg,var(--tp-table-2),var(--tp-table));border:3px solid var(--tp-line);box-shadow:0 8px 0 color-mix(in srgb,var(--tp-table) 60%,#000);
  animation:tpIn .5s var(--tp-spring) both}
.tsTop{display:flex;align-items:center;gap:var(--sp-2);justify-content:center}
.tsTop .pongi{width:54px;height:auto}
.tsKicker{margin:0;font-weight:800;letter-spacing:.06em;opacity:.85}
.tsBoard{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:var(--sp-2);margin:var(--sp-4) 0}
.tsSide{display:grid;justify-items:center;gap:4px;min-width:0;text-align:center}
.tsSide a{color:#fffaf2}
.tsName{font-size:var(--fs-lg);overflow-wrap:anywhere}
.tsSets{font-size:clamp(56px,16vw,96px);font-weight:900;line-height:1;font-variant-numeric:tabular-nums}
.tsSide:not(.win) .tsSets{opacity:.6}
.tsVs{font-size:44px;font-weight:900;color:#ff8fa8}
.tsCrown{font-size:28px;display:inline-block;animation:tsCrown 1.6s var(--tp-spring) infinite}
@keyframes tsCrown{0%,100%{transform:translateY(0) rotate(-6deg)}50%{transform:translateY(-8px) rotate(6deg)}}
.tsSide .ttrDelta{font-weight:800;font-size:var(--fs-sm)}
.tsSide .ttrDelta.up{color:#8ef0b0}.tsSide .ttrDelta.down{color:#ffb3c1}
.tsGames{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:6px;padding:0;margin:0 0 var(--sp-3)}
.tsGames li{display:grid;justify-items:center;border:2px solid rgba(255,250,242,.5);border-radius:14px;padding:4px 12px;animation:twDrop .45s var(--tp-spring) both;animation-delay:calc(var(--i,0) * 90ms)}
.tsGames span{font-size:var(--fs-xs);opacity:.8}
.tsGames b{font-variant-numeric:tabular-nums}
.tsFacts{text-align:center;margin:0;color:rgba(255,250,242,.8)!important}
.tsCta{display:flex;flex-wrap:wrap;gap:var(--sp-2);justify-content:center}

/* ── 순위: 필터·급상승 ── */
.ttrRankFilters{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);margin:0 0 var(--sp-4)}
.ttrChips{display:flex;gap:6px;flex-wrap:wrap}
.ttrChipLink{display:inline-flex;align-items:center;min-height:40px;padding:6px 16px;border-radius:999px;border:2px solid var(--border-2);
  background:var(--surface);color:var(--text);text-decoration:none;font-weight:700;transition:transform .2s var(--tp-spring)}
.ttrChipLink[aria-current="page"]{background:var(--accent);border-color:var(--accent);color:#fff}
.ttrChipLink:active{transform:scale(.95)}
.ttrRankClub{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.ttrRankClub select{font:inherit;padding:8px 10px;border-radius:12px;border:2px solid var(--border-2);background:var(--surface);color:var(--text);max-width:12em}
.ttrRankWhere{font-weight:800;color:var(--accent-text);margin:0 0 var(--sp-3)}
.ttrRisers{border:2px solid var(--border-2);border-radius:var(--r-lg);padding:var(--sp-4);margin:0 0 var(--sp-5);background:var(--surface)}
.ttrRisers h2{margin:0 0 var(--sp-2);font-size:var(--fs-lg)}
.ttrRiseList{list-style:none;padding:0;margin:0 0 var(--sp-2);display:grid;gap:6px}
.ttrRiseList li{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;animation:tpIn .45s var(--tp-spring) both;animation-delay:calc(var(--i,0) * 70ms)}
.ttrRise{display:inline-block;animation:ttrRocket 1.8s ease-in-out infinite}
@keyframes ttrRocket{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-4px) rotate(-8deg)}}

@media (max-width:520px){
  .twHead{gap:var(--sp-3)}.twHead .tpPongi{width:56px}
  .twHalf{min-height:min(40vh,280px)}
  .thHero{flex-direction:column;text-align:center}
  .thBtns{justify-content:center}
}

@media (prefers-reduced-motion:reduce){
  .twBadge[data-live]::before,.thDot,.twConn.wait::before,.tsCrown,.ttrRise,.thDots i,.ttrDots i{animation:none}
  .twFly,.twFloat,.twFloats{display:none}
  .twToast,.twCall.big,.twSets li,.twTimeline li,.thLives li,.thRecent li,.thTasks li,.thNews li,.tsCard,.tsGames li,.ttrRiseList li,.thTasks .count{animation:tpFade .2s both}
  .twHalf,.thLiveCard,.twCheer,.ttrChipLink{transition:none}
}
