/* 취향리그+ 연결 중계 화면 — 스타일 v2 "경기장 잡지" (2026-10-21, 사용자 지시로 전면 교체).
   모든 값은 tokens.css 토큰. 마크업·id·클래스는 v1 과 같다 (app/view/field/league.mjs 가 그대로 동작).
   구성: 1 글꼴 → 2 바탕·공통 → 3 사이트바·제목 → 4 무대(방송 프레임) → 5 무대 위 지문창·말풍선 보조 → 6 이야기 로그
         → 7 판정(MATCH)·결과·시작·알림 → 8 조작부·판정석·전술·광고 → 9 우측 레일 → 10 다이얼로그 → 11 모드·반응형 */

/* 1. 글꼴 — 파일은 fonts/ (라이선스: fonts/*LICENSE*.txt) */
@font-face{font-family:"IBM Plex Sans KR";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/IBMPlexSansKR-Regular.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans KR";font-style:normal;font-weight:500;font-display:swap;src:url(fonts/IBMPlexSansKR-Medium.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans KR";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/IBMPlexSansKR-SemiBold.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans KR";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/IBMPlexSansKR-Bold.woff2) format("woff2")}
@font-face{font-family:"KblJumpExtended";src:url(fonts/KBLJump-EB-Extended.woff2) format("woff2");font-style:normal;font-weight:400;font-display:swap}
@font-face{font-family:"NexonLv1Gothic";src:url(fonts/NEXONLv1Gothic-Bold.woff) format("woff");font-style:normal;font-weight:700;font-display:swap}

/* 2. 바탕·공통 */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* 스크롤바 — 얇은 알약 손잡이, 트랙은 비운다. 밝은 셸은 회청, 무대·로그 같은 어두운 면은 반투명 흰색.
   손잡이에 올리면 울트라마린(어두운 면은 밝은 울트라마린). Chromium·Safari 는 ::-webkit-scrollbar,
   그 밖은 scrollbar-color 로 같은 색을 쓴다. */
.video,.storycast{--scroll-thumb:#ffffff33;--scroll-thumb-hover:var(--color-accent-dark)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track,::-webkit-scrollbar-corner{background:transparent}
::-webkit-scrollbar-thumb{background:var(--scroll-thumb);background-clip:padding-box;border:3px solid transparent;border-radius:999px;min-height:36px}
::-webkit-scrollbar-thumb:hover{background-color:var(--scroll-thumb-hover);border-width:2px}
@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent}}
body{margin:0;background:var(--texture-bg) repeat,var(--color-bg);color:var(--color-ink);font:400 var(--fs-14)/var(--lh-ui) var(--font-ui);-webkit-font-smoothing:antialiased;word-break:keep-all}
button,select,textarea,input{font:inherit;color:inherit}
button,select{cursor:pointer;touch-action:manipulation}
button{min-height:40px;background:var(--color-surface);border:1px solid var(--color-line-strong);border-radius:var(--r-2);padding:8px 14px;transition:background var(--dur-1) var(--ease-out),border-color var(--dur-1) var(--ease-out),color var(--dur-1) var(--ease-out)}
button:hover:not(:disabled){border-color:var(--color-ink);background:var(--color-surface-2)}
button:disabled{opacity:.4;cursor:not-allowed}
:focus-visible{outline:2px solid var(--color-accent);outline-offset:3px}
[hidden]{display:none!important}
select{background:var(--color-surface);border:1px solid var(--color-line-strong);border-radius:var(--r-2);padding:6px 8px;min-height:36px;font-size:var(--fs-13)}
.empty{font-size:var(--fs-12);color:var(--color-muted);padding:var(--sp-3) 0}
.shell{max-width:1536px;margin:auto;padding:var(--sp-5) var(--sp-7) var(--sp-6)}
.breadcrumb{display:flex;align-items:center;gap:var(--sp-2);color:var(--color-muted);font-size:var(--fs-12);margin-bottom:var(--sp-4)}
.breadcrumb b{font-weight:600;color:var(--color-ink)}
.breadcrumb .sep{color:var(--color-line-strong)}
/* 경기 제목 옆에 보기 설정, 경기 무대 옆에 레일 — 레일 카드는 무대 프레임과 위아래 끝을 맞춘다. */
.watch-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;grid-template-areas:"title title" "video rail" "main foot";column-gap:var(--sp-6);row-gap:0;align-items:start}
.watch-layout>.match-title{grid-area:title}
.watch-layout>.video{grid-area:video}
.main-column{grid-area:main;min-width:0}
.rail-foot{grid-area:foot;display:flex;flex-direction:column;gap:var(--sp-3);padding-top:var(--sp-4)}
.footer{display:flex;justify-content:space-between;gap:var(--sp-3);color:var(--color-muted);font-size:var(--fs-11);border-top:1px solid var(--color-line);padding-top:var(--sp-4);margin-top:var(--sp-7);letter-spacing:.02em}
/* 라벨·태그 공통 */
.label{font:600 var(--fs-10)/1 var(--font-ui);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--color-muted)}
.story-air,.prime-tag,.match-kicker,.gen-badge,.profile-live,.job-status{font-family:var(--font-display);font-weight:400;letter-spacing:.06em;text-transform:uppercase;font-synthesis:none}

/* 3. 사이트바·경기 제목 */
.sitebar{height:68px;display:flex;align-items:center;gap:var(--sp-7);padding:0 var(--sp-7);background:var(--color-surface);border-bottom:1px solid var(--color-line);position:relative}
.brand{display:flex;align-items:center;gap:var(--sp-2);font:700 var(--fs-23)/1 var(--font-emphasis);letter-spacing:var(--ls-tight);white-space:nowrap}
.brand-symbol{width:28px;height:28px;display:grid;place-items:center;background:var(--color-ink);color:#fff;border-radius:var(--r-1);font:400 var(--fs-19)/1 var(--font-display)}
.brand em{color:var(--color-accent);font-style:normal;font-weight:700;font-size:var(--fs-28);line-height:.8;margin-left:1px;align-self:center}
.site-nav{height:100%;display:flex;gap:var(--sp-5);align-items:center}
.site-nav :is(button,a){border:0;border-radius:0;background:none;height:100%;color:var(--color-muted);padding:0 2px;font-size:var(--fs-13);font-weight:600}
.site-nav a{display:inline-flex;align-items:center;text-decoration:none;white-space:nowrap}
.site-nav :is(button,a):hover:not(:disabled){background:none;color:var(--color-ink)}
.site-nav .active{color:var(--color-ink);box-shadow:inset 0 -2px var(--color-accent)}
.site-nav .active:before{content:'';display:inline-block;width:7px;height:7px;background:var(--color-signal);border-radius:50%;margin-right:7px;vertical-align:1px}
.site-right{margin-left:auto;display:flex;align-items:center;gap:var(--sp-3)}
.demo-pill{font-size:var(--fs-11);letter-spacing:.04em;color:var(--color-muted);border:1px solid var(--color-line-strong);border-radius:var(--r-pill);padding:4px 10px}
.avatar{display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--color-surface-3);font:700 var(--fs-12) var(--font-ui);color:var(--color-ink-2)}
.match-title{display:flex;justify-content:space-between;align-items:end;gap:var(--sp-4);padding:var(--sp-2) 0 var(--sp-4)}
.category{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-11);letter-spacing:.08em;text-transform:uppercase;color:var(--color-muted);margin-bottom:var(--sp-2)}
.prime-tag{display:inline-block;color:#fff;background:var(--color-signal);padding:3px 8px 2px;border-radius:var(--r-1);font-size:var(--fs-11)}
.match-title h1{font:700 var(--fs-34)/1.2 var(--font-emphasis);letter-spacing:var(--ls-tight);margin:0}
.match-title h1 span{font:400 var(--fs-16)/1 var(--font-display);color:var(--color-muted);margin:0 var(--sp-2);letter-spacing:.06em}
.match-title h1 .team-name{font:inherit;color:inherit;margin:0;letter-spacing:inherit}
/* 밝은 셸의 팀명은 진한 잉크 글자 + 팀 색 하이라이트 줄 (팀 색을 글자색으로 쓰면 종이 위 대비 2:1 — Hermes P2). */
.match-title h1 .team-name{color:var(--color-ink);padding:0 2px;background:linear-gradient(transparent 68%,var(--team-name-accent,var(--color-line-strong)) 68%)}
#titleA{--team-name-accent:var(--color-home)}#titleB{--team-name-accent:var(--color-away)}
.match-meta{display:flex;align-items:center;gap:var(--sp-2);color:var(--color-muted);font-size:var(--fs-12);margin-top:var(--sp-2)}
.match-meta img{width:20px;height:22px;object-fit:contain;background:var(--color-surface-2);border-radius:var(--r-1)}
.match-meta .dot{color:var(--color-line-strong)}
.attempt-summary{display:flex;flex-direction:column;gap:6px;align-items:flex-end;font-size:var(--fs-11);color:var(--color-muted);white-space:nowrap}
.attempt-line{display:flex;align-items:center;gap:var(--sp-2)}
.attempt-line span{font-weight:700;color:var(--color-ink-2);min-width:2ch;text-align:right}
.attempts{display:flex;gap:4px}
.attempts i{display:inline-block;width:16px;height:5px;border-radius:3px;background:var(--color-line-strong)}
.attempts i.now{background:var(--color-ink)}
.attempts i.goal{background:var(--color-good)}
.attempts i.miss{background:var(--color-line)}

/* 4. 무대 — 어두운 방송 프레임 안의 잔디 경기장 */
.video{position:relative;overflow:hidden;background:var(--color-stage);color:var(--color-stage-ink);border-radius:var(--r-frame);box-shadow:var(--shadow-frame)}
.canvas-stage{position:relative;height:650px;overflow:hidden;isolation:isolate}
.canvas-stage>canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.broadcast-top{position:absolute;inset:18px 20px auto;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:var(--sp-3);pointer-events:none;z-index:var(--z-overlay)}
.score-bug{grid-column:2;position:relative;display:grid;justify-items:center;filter:drop-shadow(0 8px 18px #0008)}
/* 전광판 장식: 판 아래 두 팀 색이 가운데서 만나는 빛 띠, 몇 초마다 판 위를 훑는 빛, 점수 칸의 LED 점 무늬. */
.score-bug:after{content:'';width:calc(100% - 40px);height:3px;margin-top:3px;border-radius:2px;background:linear-gradient(90deg,transparent,var(--color-home) 18%,var(--color-home) 46%,#fff 50%,var(--color-away) 54%,var(--color-away) 82%,transparent);box-shadow:0 0 10px color-mix(in srgb,#fff 30%,transparent);opacity:.85}
/* 스코어버그: 무대 상단 중앙. 홈 팀 색 판(엠블럼+영문 약자) · 남색 점수판 · 원정 팀 색 판, 양 끝은 비스듬히 잘린다.
   공격 중인 팀 판에 흰 공 점이 켜진다(data-attack). 팀 색 판 위 글자는 --team-ink. */
.bug-main{position:relative;display:flex;align-items:stretch;height:48px;clip-path:polygon(14px 0,calc(100% - 14px) 0,100% 100%,0 100%);box-shadow:inset 0 0 0 1px #ffffff1f}
.bug-main:after{content:'';position:absolute;inset:0 auto 0 -40%;width:24%;background:linear-gradient(90deg,transparent,#ffffff55,transparent);transform:skewX(-20deg);animation:bug-sweep 7s ease-in-out 2s infinite;pointer-events:none}
@keyframes bug-sweep{0%,82%{left:-40%}100%{left:130%}}
.bug-team{--plate:var(--color-home);position:relative;display:flex;align-items:center;gap:8px;padding:0 14px 0 28px;min-width:118px;color:var(--color-stage,#0b1326);background:linear-gradient(180deg,#ffffff,#e4e9f1);box-shadow:inset 0 -3px 0 color-mix(in srgb,var(--plate) 85%,transparent)}
.bug-team.away{--plate:var(--color-away);justify-content:flex-end;padding:0 28px 0 14px}
.bug-team:before{content:'';position:absolute;top:0;bottom:0;left:6px;width:7px;background:var(--plate);transform:skewX(-16deg);box-shadow:0 0 10px color-mix(in srgb,var(--plate) 60%,transparent)}
.bug-team.away:before{left:auto;right:6px;transform:skewX(16deg)}
.bug-crest{width:26px;height:26px;object-fit:contain;flex:none;filter:drop-shadow(0 1px 1px #0b132655)}
.bug-code{font:400 22px/1 var(--font-display);letter-spacing:.06em}
.bug-ball{width:8px;height:8px;border-radius:50%;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--plate),0 0 8px var(--plate);background:var(--plate);opacity:0;transition:opacity .25s}
.score-bug[data-attack="0"] .home .bug-ball,.score-bug[data-attack="1"] .away .bug-ball{opacity:1}
.bug-scores{display:flex;align-items:stretch;gap:2px;padding:0 10px;background:radial-gradient(circle,#ffffff12 1px,transparent 1.5px) 0 0/4px 4px,linear-gradient(180deg,#1b2747,#0b1326);color:#fff;box-shadow:inset 0 0 0 1px #ffffff14,inset 0 0 14px #000a}
.bug-score{position:relative;display:grid;place-items:center;min-width:30px;overflow:hidden;font:400 30px/1 var(--font-display);font-variant-numeric:tabular-nums;color:#fff;text-shadow:0 0 12px #ffffff40}
.bug-sep{align-self:center}
/* 득점: 판정 결과의 골 순간(1.5초 중 52%)에 옛 숫자가 위로 빠지고 새 숫자가 아래에서 튀어 오르며 금빛으로 번쩍. 득점 팀 판도 함께 번쩍인다. */
.bug-score:before,.bug-score:after{position:absolute;inset:0;display:grid;place-items:center;opacity:0;color:#fff;text-shadow:0 0 12px #ffffff40}
.bug-score:before{content:attr(data-prev)}
.bug-score:after{content:attr(data-value)}
.bug-score.is-bump{animation:score-hold 1.5s linear both}
.bug-score.is-bump:before{animation:score-out 1.5s linear both}
.bug-score.is-bump:after{animation:score-roll 1.5s linear both}
@keyframes score-hold{0%,99%{color:transparent;text-shadow:none}}
@keyframes score-out{0%,52%{opacity:1;transform:none}62%,100%{opacity:0;transform:translateY(-110%)}}
@keyframes score-roll{0%,52%{opacity:1;transform:translateY(110%)}62%{transform:translateY(-14%);color:var(--color-cast,#f5c33b);text-shadow:0 0 18px var(--color-cast,#f5c33b)}70%{transform:translateY(4%)}76%,90%{opacity:1;transform:none;color:var(--color-cast,#f5c33b);text-shadow:0 0 16px var(--color-cast,#f5c33b)}99%{opacity:1;transform:none;color:#fff}100%{opacity:0}}
.bug-team.is-goal{animation:plate-flash 1.5s linear both}
@keyframes plate-flash{0%,52%,100%{box-shadow:inset 0 -3px 0 color-mix(in srgb,var(--plate) 85%,transparent)}56%{box-shadow:inset 0 0 0 80px color-mix(in srgb,var(--plate) 75%,#fff)}74%{box-shadow:inset 0 -48px 0 color-mix(in srgb,var(--plate) 30%,#fff)}}
@media (prefers-reduced-motion: reduce){.bug-main:after,.bug-score.is-bump,.bug-score.is-bump:before,.bug-score.is-bump:after,.bug-team.is-goal{animation:none}}
.bug-sep{font:400 20px/1 var(--font-display);color:#ffffff70;transform:translateY(-2px)}
/* 점수판 아래 LIVE·차례 띠, 경기장 위 차례 칩·국면 칩은 숨긴다(제리: 무대 위 메시지창 정리). DOM은 화면 읽기·상태용으로 남긴다. */
.bug-meta{display:none}
/* 채널 표시는 왼쪽 위 작은 방송사 로고처럼: TASTE+ 와 SSUL LEAGUE 를 세로 실선으로 나눈 한 줄, 반투명. */
.channel{grid-column:1;justify-self:start;display:flex;align-items:center;gap:8px;opacity:.78}
.channel strong{font:400 var(--fs-16)/1 var(--font-display);letter-spacing:.04em;color:var(--color-stage-ink)}
.channel strong em{color:var(--color-accent);font-style:normal}
.channel small{padding-left:8px;border-left:1px solid #ffffff4d;color:var(--color-stage-muted);font:700 9px/1.25 var(--font-ui);letter-spacing:.24em;width:7.5em}
.focus-player[hidden]{display:none}
/* The phase name and its explainer stay in the DOM for state and assistive tech but are not shown:
   the board, the stack and the score bug already say where the attack is. */
.phase-strap{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.phase-strap span{display:block;font:400 var(--fs-19)/1 var(--font-display);letter-spacing:.01em;color:var(--color-stage-ink)}
.phase-strap small{display:block;margin-top:3px;font-size:var(--fs-11);color:var(--color-stage-muted)}
.field-overlay{position:absolute;top:102px;left:22px;right:22px;display:none;justify-content:space-between;align-items:center;gap:var(--sp-3);pointer-events:none;z-index:var(--z-overlay)}
.lower-third{display:flex;align-items:center;gap:8px;background:var(--color-surface);color:var(--color-ink);border-radius:var(--r-1);padding:0 10px 0 0;overflow:hidden;box-shadow:var(--shadow-soft)}
.lower-third small{display:none}
.lower-third strong{display:block;padding:4px 10px;font:700 var(--fs-12)/1.4 var(--font-emphasis);letter-spacing:var(--ls-tight);border-left:4px solid var(--team-accent,var(--color-accent))}
.tactical-chip{font-size:var(--fs-11);color:var(--color-stage-ink);background:#ffffff1a;padding:5px 10px;border-radius:var(--r-pill);backdrop-filter:blur(6px)}
.story-store,.broadcast-story:before{display:none}

/* 5. 무대 위 지문창 — 공격 팀 쪽 상단 귀퉁이. 반투명 네이비, 왼쪽 팀 색 선, 소설체 본문. */
.script-lane{position:absolute;left:var(--sp-6);right:auto;top:var(--narration-top);width:min(var(--narration-width),var(--narration-max-width));max-height:var(--narration-max-height);z-index:var(--z-lane);pointer-events:none;transition:opacity var(--dur-2) var(--ease-out);display:flex;flex-direction:column;justify-content:flex-end;gap:var(--stack-gap);overflow:clip;overflow-clip-margin:48px;padding-bottom:8px}
.script-lane.side-right{left:auto;right:var(--sp-6)}
.script-lane.is-empty{visibility:hidden}
.script-lane.is-dim{opacity:.55}
.script-item{display:grid;gap:4px;padding:10px 14px 11px;background:color-mix(in srgb,var(--team-accent,var(--color-accent)) 16%,var(--color-caption));border-left:3px solid var(--team-accent,var(--color-accent));border-radius:0 var(--r-2) var(--r-2) 0;box-shadow:var(--shadow-tile);backdrop-filter:blur(2px)}
.script-lane.side-right .script-item{border-left:0;border-right:3px solid var(--team-accent,var(--color-accent));border-radius:var(--r-2) 0 0 var(--r-2);text-align:right}
.script-item p{margin:0;font:400 15px/1.6 var(--font-story);color:var(--color-stage-ink);white-space:pre-line;overflow-wrap:anywhere}
.script-kicker,.script-tag{display:inline-flex;align-items:center;gap:6px;justify-self:start;font:700 var(--fs-10)/1 var(--font-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--team-accent,var(--color-accent))}
.script-lane.side-right .script-kicker,.script-lane.side-right .script-tag{justify-self:end}
.script-kicker:before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor}
.script-lane .script-item.is-cast{--team-accent:var(--color-accent-dark)}
.script-item.is-latest{animation:script-in var(--dur-3) var(--ease-out) both,tile-breathe 2.6s ease-in-out var(--dur-3) infinite}
/* Stage stack: older cards step back; a card pushed out fades upward, then collapses. The lane clips
   48px outside its box so a leaving card pushed above the top edge still shows its exit. */
.script-item{flex:none;transition:opacity var(--dur-2) var(--ease-out)}
.script-item:not(.is-latest){opacity:.72}
.script-item.is-leaving{overflow:hidden;transform-origin:top left;animation:stack-out var(--dur-stack-out) var(--ease-out) forwards}
.script-lane.side-right .script-item.is-leaving{transform-origin:top right}
.script-item.is-floating{position:absolute;top:0;left:0;z-index:1;width:100%}
.script-lane.side-right .script-item.is-floating{left:auto;right:0}
/* 이번 썰 (로그라인): 공격의 첫 메시지는 관객용 소개라 다른 카드와 달리 밝은 종이 카드 — 팀 색 윗띠·딱지, 큰 굵은 글. */
.script-item.logline{position:relative;width:min(100%,620px);gap:0;padding:0;overflow:hidden;background:linear-gradient(160deg,var(--color-surface) 55%,var(--color-surface-3));border:0;border-top:4px solid var(--team-accent,var(--color-accent));border-radius:var(--r-1) var(--r-1) var(--r-2) var(--r-2);box-shadow:0 0 0 1px #0006,0 14px 34px #000a;backdrop-filter:none;text-align:left}
.script-lane.side-right .script-item.logline{align-self:flex-end;border:0;border-top:4px solid var(--team-accent,var(--color-accent));border-radius:var(--r-1) var(--r-1) var(--r-2) var(--r-2);text-align:left}
.logline-tag{display:flex;align-items:center;gap:10px;padding:8px 18px;background:var(--color-stage)}
.logline-tag b{color:#fff;font:400 var(--fs-14)/1 var(--font-display);letter-spacing:.06em}
.logline-tag i{padding:3px 9px;border-radius:var(--r-pill);background:var(--team-accent,var(--color-accent));color:var(--color-stage);font:700 var(--fs-11)/1.3 var(--font-ui);font-style:normal}
.script-item.logline p{padding:12px 18px 14px;font:600 16px/1.55 var(--font-story);color:var(--color-ink);word-break:keep-all}
.script-item.logline .next-cue{background:var(--color-ink)}
.script-item.logline:not(.is-latest){opacity:.85}
/* In: the card lifts in as just its dark tag, the tag wipes across from the team's side, then the
   paper unfolds down out of it and the line settles in. Out (pushed off the stack): the reverse — the paper folds back up into the
   tag, the tag wipes away toward its side, and the stack closes the gap. */
.script-item.logline{--logline-head:38px}
.script-item.logline.is-latest{animation:logline-in .8s var(--ease-out) both}
.script-item.logline.is-latest .logline-tag b{animation:logline-word-in .5s var(--ease-out) .12s both}
.script-item.logline.is-latest p{animation:logline-text-in .4s var(--ease-out) .4s both}
/* The dark head band wipes in from the team's side first, then the paper unfolds below it. */
@keyframes logline-in{0%{opacity:0;clip-path:inset(0 100% calc(100% - var(--logline-head)) 0)}8%{opacity:1}38%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 0)}100%{opacity:1;clip-path:inset(0 0 0 0)}}
@keyframes logline-in-right{0%{opacity:0;clip-path:inset(0 0 calc(100% - var(--logline-head)) 100%)}8%{opacity:1}38%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 0)}100%{opacity:1;clip-path:inset(0 0 0 0)}}
.script-lane.side-right .script-item.logline.is-latest{animation-name:logline-in-right}
@keyframes logline-word-in{from{letter-spacing:.3em;opacity:0}to{letter-spacing:.06em;opacity:1}}
@keyframes logline-text-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.script-item.logline.is-leaving{opacity:1;animation:logline-out .72s var(--ease-out) forwards}
.script-lane.side-right .script-item.logline.is-leaving{animation-name:logline-out-right}
@keyframes logline-out{0%{clip-path:inset(0 0 0 0);height:var(--leave-h)}40%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 0);height:var(--leave-h)}72%{clip-path:inset(0 100% calc(100% - var(--logline-head)) 0);height:var(--leave-h);margin-top:0}100%{clip-path:inset(0 100% calc(100% - var(--logline-head)) 0);height:0;margin-top:calc(var(--stack-gap) * -1);opacity:0}}
@keyframes logline-out-right{0%{clip-path:inset(0 0 0 0);height:var(--leave-h)}40%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 0);height:var(--leave-h)}72%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 100%);height:var(--leave-h);margin-top:0}100%{clip-path:inset(0 0 calc(100% - var(--logline-head)) 100%);height:0;margin-top:calc(var(--stack-gap) * -1);opacity:0}}
/* A card pushed out drifts up, shrinks a touch and blurs away first, then its room closes. */
@keyframes stack-out{0%{height:var(--leave-h)}50%{opacity:0;transform:translateY(-14px) scale(.96);filter:blur(3px);height:var(--leave-h)}100%{opacity:0;transform:translateY(-14px) scale(.96);filter:blur(3px);height:0;padding-top:0;padding-bottom:0;margin-top:calc(var(--stack-gap) * -1)}}
/* Official panel (top centre): the league's own notices, apart from the reading: the coaches'
   tactic allocation and each attack's kick-off. Paper header with the league
   seal, navy body, the side's colour as the base rule; the reading stack steps back while it is up. */
.official-panel{--official-accent:var(--color-accent);position:absolute;z-index:var(--z-notice);top:92px;left:0;right:0;margin:0 auto;width:min(420px,calc(100% - 380px));pointer-events:none;text-align:center;color:var(--color-stage-ink);background:linear-gradient(180deg,var(--color-stage-2),var(--color-stage) 80%);border:1px solid #ffffff38;border-radius:var(--r-2);box-shadow:0 0 0 3px var(--color-stage),var(--shadow-tile);animation:official-in .42s var(--ease-out) both}
.official-panel:after{content:'';position:absolute;left:12px;right:12px;bottom:-1px;height:3px;border-radius:3px 3px 0 0;background:var(--official-accent)}
.official-panel:not([hidden])~.script-lane{opacity:.3}
.official-head{display:flex;align-items:center;justify-content:center;gap:8px;padding:6px 12px 5px;background:var(--color-stage-ink);color:var(--color-stage);border-radius:7px 7px 0 0;font:700 var(--fs-11)/1 var(--font-ui);letter-spacing:.06em}
.official-seal{padding:3px 7px 2px;border-radius:var(--r-1);background:var(--color-stage);color:#fff;font:400 var(--fs-10)/1 var(--font-display);letter-spacing:.04em}
.official-body{display:grid;justify-items:center;gap:7px;padding:12px 18px 14px}
.official-line{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
.official-team{padding:4px 11px 3px;border-radius:var(--r-pill);background:var(--team);color:var(--team-ink);font:700 var(--fs-13)/1.2 var(--font-ui)}
.official-word{font:400 22px/1 var(--font-display);letter-spacing:.02em;color:#fff}
.official-line i{font:600 var(--fs-11)/1 var(--font-ui);font-style:normal;color:var(--color-stage-muted)}
.official-body p{margin:0;font:400 var(--fs-13)/1.55 var(--font-ui);color:var(--color-stage-ink)}
.official-body small{font-size:var(--fs-11);color:var(--color-stage-muted)}
.official-body .prep-line{font-size:var(--fs-12);color:var(--color-stage-ink);opacity:.82}
.official-body .prep-line.is-new{animation:prep-in .45s ease-out}
@keyframes prep-in{from{opacity:0;transform:translateY(5px)}to{opacity:.82;transform:none}}
.official-panel.is-rules{width:min(560px,calc(100% - 40px))}
.official-first{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;font:600 var(--fs-13)/1.2 var(--font-ui);color:var(--color-stage-ink)}
.official-first em{font:400 var(--fs-13)/1 var(--font-display);font-style:normal;padding:4px 8px 3px;border-radius:var(--r-1);background:#fff;color:var(--color-stage)}
.official-rules{counter-reset:rule;margin:2px 0 0;padding:0;list-style:none;display:grid;gap:0;width:100%;text-align:left}
.official-rules li{counter-increment:rule;display:grid;grid-template-columns:26px minmax(0,1fr);column-gap:10px;padding:8px 2px;border-top:1px solid #ffffff1c}
.official-rules li:before{content:counter(rule);grid-row:span 2;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:var(--official-accent);color:var(--team-ink);font:400 var(--fs-13)/1 var(--font-display)}
.official-rules b{font:700 var(--fs-14)/1.35 var(--font-ui);color:#fff}
.official-rules span{font:400 var(--fs-12)/1.45 var(--font-ui);color:var(--color-stage-muted)}
/* The rules wait for their own GO! (the rules gate), smaller than the kick-off one. */
.official-go{display:none;padding-top:4px}
.official-panel.is-go{pointer-events:auto}
.official-panel.is-go .official-go{display:flex;justify-content:center;animation:rules-go-in .4s var(--ease-out) both}
.official-panel.is-go .rules-go{animation:go-ready 1.6s ease-in-out infinite}
.rules-go{min-width:112px;padding:7px 24px 5px;font-size:24px;scroll-margin:24px}
@keyframes rules-go-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes official-in{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:none}}
/* After a missed shot: the regroup panel waits .6s before it shows, so a passage that is already
   written flows on without a flash of it. */
.official-panel.is-regroup{animation:official-in .42s var(--ease-out) .6s both}
@keyframes official-late{from{opacity:0}to{opacity:1}}
/* A spoken line reads as speech, not a caption: a light rounded balloon with a tail toward the board,
   the speaker's 직업·지위 chip riding its top edge in their team color, the name opening the line
   inside it, the line typed in as it is said. 지문 cards stay dark flat tiles beside it. */
.script-item.speech{--speaker:var(--color-accent);position:relative;align-self:flex-start;width:fit-content;max-width:calc(100% - 10px);margin-top:11px;padding:12px 16px 6px;gap:0;background:color-mix(in srgb,var(--speaker) 28%,var(--color-speech));border:1.5px solid color-mix(in srgb,var(--speaker) 70%,transparent);border-radius:var(--r-speech);box-shadow:var(--shadow-tile)}
.script-item.speech.team-0{--speaker:var(--color-home)}
.script-item.speech.team-1{--speaker:var(--color-away)}
.script-lane.side-right .script-item.speech{align-self:flex-end;border:1.5px solid color-mix(in srgb,var(--speaker) 70%,transparent);border-radius:var(--r-speech);text-align:right}
.script-speaker{position:absolute;left:12px;top:-10px;display:inline-flex;white-space:nowrap;align-items:center;height:20px;padding:0 9px;border-radius:var(--r-pill);background:var(--speaker);font:700 var(--fs-11)/1 var(--font-ui);color:var(--team-ink);box-shadow:0 0 0 2px var(--color-stage)}
.speech-name{margin-right:.5em;font:400 .875em/1 var(--font-ui);letter-spacing:.02em;color:color-mix(in srgb,var(--speaker) 40%,#fff)}
.script-lane.side-right .script-speaker{left:auto;right:12px}
.script-item.speech p{font:500 16px/1.5 var(--font-story);color:var(--color-speech-ink);min-height:1.5em}
.type-rest{visibility:hidden}
.script-item.speech:not(.is-latest){opacity:.6}
.script-item.speech.is-latest{transform-origin:left bottom;animation:speech-in var(--dur-speech-in) cubic-bezier(.2,1.5,.4,1) both;--team-accent:var(--speaker)}
.script-lane.side-right .script-item.speech.is-latest{transform-origin:right bottom}
@keyframes speech-in{0%{opacity:0;transform:translateY(14px) scale(.86)}60%{opacity:1}100%{opacity:1;transform:none}}
@keyframes script-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
/* 지문창 강조 (제리 지시): 뜰 때 테두리 근처가 숨쉬듯 빛난다 — 공보다 약하게, 지금 상황임을 알리는 신호. */
@keyframes tile-breathe{0%,100%{box-shadow:var(--shadow-tile),0 0 0 0 transparent}50%{box-shadow:var(--shadow-tile),0 0 16px 2px color-mix(in srgb,var(--team-accent,var(--color-accent)) 55%,transparent)}}
/* Next mark on the newest reading card, as in a visual novel: once its line is fully out a small
   triangle blinks right after the last character. A click on the card (or →, Enter) moves the reading
   on; a line still typing shows in full first. With 자동 넘김 off the reading waits for it. */
.script-lane.can-advance .script-item.is-latest{pointer-events:auto;cursor:pointer}
.canvas-stage.can-advance{cursor:pointer}
.canvas-stage.can-advance .storycast{cursor:auto}
.next-cue{display:none;width:.62em;height:.5em;margin-left:.35em;vertical-align:-.02em;background:var(--team-accent,var(--color-accent));clip-path:polygon(0 0,100% 0,50% 100%);animation:cue-blink 1s steps(1,end) infinite}
.script-item.speech .next-cue{background:var(--speaker)}
.script-lane.can-advance .script-item.is-latest:not(.is-typing) .next-cue{display:inline-block}
.script-lane.is-waiting .script-item.is-latest .next-cue{animation:cue-blink 1s steps(1,end) infinite,cue-bob 1s ease-in-out infinite}
.script-lane.is-loading .script-item.is-latest:not(.is-typing) .next-cue{display:inline-block;width:.78em;height:.78em;margin-left:.42em;vertical-align:-.1em;background:transparent;clip-path:none;border:2px solid color-mix(in srgb,var(--team-accent,var(--color-accent)) 35%,transparent);border-top-color:var(--team-accent,var(--color-accent));border-radius:50%;animation:cue-spin .75s linear infinite}
.script-lane.is-loading .script-item.speech.is-latest:not(.is-typing) .next-cue{border-color:color-mix(in srgb,var(--speaker,var(--color-accent)) 35%,transparent);border-top-color:var(--speaker,var(--color-accent))}
@keyframes cue-blink{0%{opacity:1}55%{opacity:.25}}
@keyframes cue-bob{0%,100%{translate:0 -1px}50%{translate:0 2px}}
@keyframes cue-spin{to{transform:rotate(360deg)}}

/* 6. 이야기 로그 — 무대 바닥의 어두운 캡션 패널(무대보다 한 단계 밝은 네이비). 높이 고정. 팀 색 윗선, 소설체 본문. */
.storycast{position:absolute;inset:auto 20px 16px;z-index:var(--z-log);height:var(--story-frame-height);min-height:var(--story-frame-height);max-height:var(--story-frame-height);display:grid;grid-template-rows:minmax(0,1fr);pointer-events:none}
.storycast button,.storycast .caption-copy{pointer-events:auto}
/* 해설 크롤 — 로그 바로 위, 무대 폭 한 줄. 새 해설이 들어올 때마다 띠가 번쩍이며 흔들리고, 기운 노란 '해설'
   딱지 옆 소리 막대가 뛰고, 외친 말(!)은 노랗게 빛나며 오른쪽에서 한 번 지나간다. */
.cast-crawl{position:absolute;left:20px;right:20px;bottom:calc(16px + var(--story-frame-height) + 8px);z-index:var(--z-log);display:flex;align-items:center;gap:10px;height:30px;padding:0;background:linear-gradient(90deg,color-mix(in srgb,var(--color-accent) 30%,var(--color-stage-2)),var(--color-stage-2) 30%);border:1px solid color-mix(in srgb,var(--color-accent) 70%,transparent);border-radius:var(--r-1);box-shadow:0 0 0 2px var(--color-stage),0 6px 18px #0008;pointer-events:none;overflow:hidden;transition:opacity var(--dur-3) var(--ease-out)}
.cast-crawl b{flex:none;align-self:stretch;display:inline-flex;align-items:center;gap:3px;margin-left:-8px;padding:0 11px 0 18px;background:var(--color-accent);color:var(--color-accent-ink);font:400 var(--fs-13)/1 var(--font-display);letter-spacing:.04em;transform:skewX(-14deg);box-shadow:4px 0 0 var(--color-signal)}
.cast-crawl b i{display:block;width:2px;height:9px;margin-left:2px;border-radius:2px;background:var(--color-accent-ink);transform-origin:50% 100%;animation:cast-bar .5s ease-in-out infinite alternate}
.cast-crawl b i:first-of-type{margin-left:6px}
.cast-crawl b i:nth-of-type(2){animation-delay:-.2s;height:12px}
.cast-crawl b i:nth-of-type(3){animation-delay:-.35s;height:7px}
@keyframes cast-bar{from{transform:scaleY(.35)}to{transform:scaleY(1)}}
.cast-window{flex:1;min-width:0;overflow:hidden;white-space:nowrap;mask-image:linear-gradient(90deg,transparent,#000 3%,#000 96%,transparent)}
.cast-window span{display:inline-block;padding-left:100%;font:600 italic var(--fs-14)/30px var(--font-story);color:var(--color-stage-ink);animation:cast-crawl var(--crawl-time,10s) linear 1 forwards}
.cast-window em{font-style:inherit;color:var(--color-accent-dark);text-shadow:0 0 10px color-mix(in srgb,var(--color-accent) 80%,transparent)}
@keyframes cast-crawl{to{transform:translateX(-100%)}}
.cast-crawl.is-shout{animation:cast-shout .6s var(--ease-out) both}
.cast-crawl.is-shout b{animation:cast-tag .45s cubic-bezier(.2,1.6,.4,1) both}
@keyframes cast-shout{0%{background-color:color-mix(in srgb,var(--color-accent) 60%,var(--color-stage-2));transform:translateX(-3px)}20%{transform:translateX(3px)}40%{transform:translateX(-2px)}60%{transform:translateX(1px)}100%{transform:none}}
@keyframes cast-tag{from{transform:skewX(-14deg) scale(1.25)}to{transform:skewX(-14deg)}}
.cast-crawl.is-idle b i{animation:none;transform:scaleY(.35)}
.canvas-stage.log-expanded .cast-crawl{display:none}
/* 접힌 로그는 무대 아래 깔리는 보조 기록: 반투명 바탕·얇은 팀 색 윗줄·작은 글자로 눈에 덜 띄게(제리 2026-10-23). */
.caption-copy{min-width:0;display:grid;grid-template-rows:auto minmax(0,1fr) auto;row-gap:2px;padding:6px 12px 6px 14px;background:color-mix(in srgb,var(--color-log) 74%,transparent);backdrop-filter:blur(3px);color:var(--color-log-ink);border:1px solid #ffffff12;border-top:2px solid color-mix(in srgb,var(--team-accent,var(--color-accent-dark)) 70%,transparent);border-radius:var(--r-2)}
.caption-heading{display:flex;align-items:center;gap:8px;min-width:0;min-height:20px;flex-shrink:0}
.story-air{flex:none;font-size:var(--fs-10);padding:2px 6px 1px;background:none;color:var(--color-log-muted);border:1px solid var(--color-log-line-strong);border-radius:var(--r-1);letter-spacing:.08em}
.caption-heading h2{margin:0;font:700 var(--fs-12)/1.3 var(--font-emphasis);color:var(--color-log-ink-2);letter-spacing:var(--ls-tight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.source-tag{font-size:var(--fs-10);letter-spacing:.06em;padding:2px 7px;border:1px solid var(--color-log-line-strong);border-radius:var(--r-pill);color:var(--color-log-muted);white-space:nowrap}
.source-tag.live{border-color:var(--color-signal);color:var(--color-signal)}
.focus-player{flex:none;display:inline-flex;align-items:center;gap:8px;min-height:0;height:30px;padding:0 10px 0 0;border:1px solid var(--color-log-line);border-radius:var(--r-pill);background:var(--color-log-2);overflow:hidden;margin-left:auto;text-align:left}
.focus-player:hover:not(:disabled){border-color:var(--color-accent-dark);background:#7b93ff26}
.focus-player .portrait{flex:none;width:30px;height:30px;object-fit:cover;object-position:center 25%;background:var(--color-portrait)}
.focus-player .profile-num{display:none}
.focus-player .identity{display:inline-flex;align-items:baseline;gap:6px}
.identity strong{font:700 var(--fs-12)/1 var(--font-emphasis)}
.identity small{font-size:var(--fs-10);color:var(--color-log-muted)}
.identity .profile-hint{display:none}
.focus-player .profile-live{font-size:9px;padding:2px 6px;background:var(--color-accent);color:#fff;border-radius:var(--r-pill)}
.caption-text{min-height:0;overflow:auto}
/* 스토리 로그 — 방송 대본 형식: [장면] 머리, 지문 줄, 이름: “대사”, 해설: “…”. 썰(회상) 장면은 살구색 옆줄. */
/* Log rows read like a script: a scene head is a small label with a rule after it, prose is the
   plain body, a spoken line hangs its name in the speaker's team colour, 해설 carries a small accent
   tag, and the verdict closes the attack in the cast gold. */
.story-log{display:flex;flex-direction:column;gap:10px;margin:0;padding-right:4px;font:400 var(--fs-12)/1.5 var(--font-story);color:var(--color-log-ink-2)}
.story-log{-webkit-mask-image:linear-gradient(transparent,#000 12px);mask-image:linear-gradient(transparent,#000 12px)}
.story-log>*{opacity:.78}
.story-log>.is-latest{opacity:1}
.log-line{margin:0;overflow-wrap:anywhere;word-break:keep-all}
.log-line b{font:700 var(--fs-12)/1 var(--font-ui);margin-right:4px}
.log-scene{display:flex;align-items:center;gap:8px;margin-top:8px;font:700 var(--fs-10)/1.4 var(--font-ui);letter-spacing:.06em;color:var(--color-log-muted)}
.log-scene:after{content:'';flex:1;height:1px;background:var(--color-log-line)}
.log-scene:first-child{margin-top:0}
.log-scene.is-story{color:var(--team-accent,var(--color-accent-dark))}
.log-scene.is-story:after{background:color-mix(in srgb,var(--team-accent,var(--color-accent-dark)) 35%,transparent)}
.log-line.prose{color:var(--color-log-ink-2)}
.log-line.is-story{padding-left:10px;border-left:2px solid color-mix(in srgb,var(--team-accent,var(--color-accent-dark)) 55%,transparent)}
.log-line.speech{padding-left:1.1em;text-indent:-1.1em;color:var(--color-log-ink);font-weight:500}
.log-line.speech.is-story{padding-left:calc(10px + 1.1em)}
.log-line.speech b{color:var(--color-home)}
.log-line.speech.team-1 b{color:var(--color-away)}
.log-line.logline{padding:8px 12px 9px;border-left:3px solid var(--team-accent,var(--color-accent));border-radius:0 var(--r-1) var(--r-1) 0;background:color-mix(in srgb,var(--team-accent,var(--color-accent)) 12%,transparent);font-weight:600;color:var(--color-log-ink)}
.log-line.logline b{display:inline-block;margin-right:8px;padding:2px 6px 1px;background:var(--color-log-ink);color:var(--color-stage);font:400 var(--fs-10)/1.3 var(--font-display);letter-spacing:.04em;vertical-align:1px}
.log-line.cast{color:var(--color-log-ink-2);font-style:italic}
.log-line.cast b{display:inline-block;padding:2px 6px 1px;border-radius:var(--r-1);background:color-mix(in srgb,var(--color-accent) 22%,transparent);color:var(--color-accent-dark);font-size:var(--fs-10);font-style:normal;letter-spacing:.04em;text-indent:0;vertical-align:1px}
.log-line.system{padding-top:6px;border-top:1px dashed var(--color-log-line);font:400 var(--fs-11)/1.6 var(--font-ui);color:var(--color-log-muted)}
.log-line.verdict{font:400 var(--fs-16)/1.3 var(--font-display);letter-spacing:.04em;color:var(--color-cast)}
.caption-heading .log-expand{margin-left:auto;flex:none;font-size:var(--fs-11);color:var(--color-log-muted);background:none;border:0;padding:0;min-height:0;border-radius:0;text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--color-log-line-strong);white-space:nowrap}
.caption-heading .log-expand:hover:not(:disabled){color:var(--color-accent-dark);background:none;text-decoration-color:currentColor}
.log-expand[aria-pressed="true"]{color:var(--color-accent-dark);text-decoration-color:currentColor}
/* 로그 전체보기 (DESIGN 09): 위로 펼침, 뒤의 경기장은 흐린 배경, 지문창·말풍선 숨김 */
.canvas-stage.log-expanded .storycast{inset:var(--log-expanded-top) 20px 16px;height:auto;min-height:0;max-height:none;transition:inset var(--dur-3) var(--ease-out)}
.canvas-stage.log-expanded .caption-copy{background:var(--color-log-expanded);backdrop-filter:blur(4px) saturate(.9)}
.canvas-stage.log-expanded .script-lane{display:none}
.canvas-stage.log-expanded .story-log{font-size:var(--fs-16);line-height:1.5;gap:17px;padding:6px 8px 6px 0;max-width:760px}
.canvas-stage.log-expanded .story-log>*{opacity:.92}
.canvas-stage.log-expanded .story-log>.is-latest{opacity:1}
.canvas-stage.log-expanded .log-scene{margin-top:18px;font-size:var(--fs-12)}
.canvas-stage.log-expanded .log-line b{font-size:var(--fs-14)}
.canvas-stage.log-expanded .log-line.cast b{font-size:var(--fs-12)}
.canvas-stage.log-expanded .match-call{top:auto;bottom:16px!important;left:20px;right:20px;height:auto;background:none;backdrop-filter:none}
.canvas-stage.log-expanded .match-panel{width:100%}
.canvas-stage.log-expanded.judgment-waiting .storycast{bottom:calc(var(--expanded-call-height,0px) + 28px);transition:none}
.canvas-stage.log-expanded .result-overlay.is-result{animation:none;top:var(--stinger-band-top-expanded);height:var(--stinger-band-height-expanded);background:linear-gradient(115deg,var(--color-band),var(--color-band-2));backdrop-filter:blur(2px)}
.canvas-stage.log-expanded .result-overlay.is-result b{animation:none;font-size:var(--fs-stinger-band)}
.canvas-stage.log-expanded .result-overlay.is-result:after{display:none}
.canvas-stage.log-expanded .result-overlay.is-result span{animation:none;margin-top:6px;gap:7px;padding:3px 4px 3px 3px;font-size:var(--fs-13)}
.canvas-stage.log-expanded .result-overlay.is-result span:after{display:none}

/* 7. 판정(MATCH)·결과 스팅어·시작·알림 */
/* The call: once the shot is charged, a bar rises above the log and the viewer judges with the
   board in view (the charged ball and the last word stay on the stage above it). */
.match-call{position:absolute;z-index:var(--z-match);left:0;right:0;display:grid;justify-items:center;pointer-events:none}
.match-panel{display:grid;grid-template-columns:auto minmax(0,1fr) minmax(240px,300px);align-items:center;gap:2px 18px;width:min(820px,calc(100% - 40px));padding:10px 14px 8px 18px;background:color-mix(in srgb,var(--color-surface) 94%,transparent);backdrop-filter:blur(6px);color:var(--color-ink);border-radius:var(--r-3);border-left:5px solid var(--color-accent);box-shadow:var(--shadow-pop);pointer-events:auto;animation:match-rise .42s cubic-bezier(.2,1.3,.4,1)}
@keyframes match-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes match-rise{0%{opacity:0;transform:translateY(24px) scale(.96)}100%{opacity:1;transform:none}}
.match-call-top{display:contents}
.match-kicker{font-size:var(--fs-10);color:var(--color-muted)}
.match-call h2{font:400 40px/1 var(--font-display);letter-spacing:.02em;color:var(--color-ink);margin:2px 0 0}
.match-call-top p{font-size:var(--fs-13);line-height:1.5;margin:0;color:var(--color-ink-2)}
.match-call-top p span{font-size:var(--fs-11);color:var(--color-muted)}
.judge-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px;width:100%}
.judge-actions button{min-height:46px;padding:9px 14px;font:700 var(--fs-16)/1 var(--font-emphasis);letter-spacing:var(--ls-tight);border-radius:var(--r-2)}
.canvas-stage.judgment-waiting:not(.log-expanded) .cast-crawl{opacity:0}
@media(max-width:1180px){.match-panel{grid-template-columns:auto minmax(0,1fr);gap:0 14px}.match-kicker,.match-call-top p{display:none}}
/* Shot charge (start of the judgment beat): the reading steps aside while the board rushes onto the
   ball, and the line the shot is taken on slams onto the stage in the speaker's team colour — held
   back from the reading until now — then stays up, breathing, while the viewer judges. */
.canvas-stage.is-charging .script-lane,.canvas-stage.is-charging .official-panel,.canvas-stage.judgment-waiting:not(.log-expanded) .script-lane{opacity:0}
.shot-cue{--team:var(--color-accent);position:absolute;z-index:var(--z-notice);left:0;right:0;top:92px;margin:0;padding:0 40px;display:grid;justify-items:center;gap:8px;pointer-events:none;animation:line-slam .55s cubic-bezier(.2,1.5,.4,1) .55s both}
.canvas-stage.log-expanded .shot-cue{display:none}
/* GO!: a match the viewer has not started waits behind a kick-off card on the stage. The button
   wakes once the first beat is ready; pressing it starts the playback. */
.kickoff-gate{position:absolute;inset:0;z-index:var(--z-match);display:grid;place-items:center;padding:16px;background:radial-gradient(ellipse at 50% 46%,#0a122dcc 0,#0a122d99 45%,#0a122d55 100%);backdrop-filter:blur(1.5px)}
.kickoff-gate[hidden]{display:none}
.canvas-stage.is-gated .script-lane,.canvas-stage.is-gated .official-panel{visibility:hidden}
.gate-card{display:flex;flex-direction:column;align-items:center;gap:16px;width:min(760px,100%);max-height:100%;padding:0 0 20px;text-align:center;background:linear-gradient(180deg,var(--color-stage-2),var(--color-stage) 75%);border:1px solid #ffffff38;border-radius:var(--r-2);box-shadow:0 0 0 3px var(--color-stage),0 24px 60px #000a;animation:official-in .42s var(--ease-out) both;overflow:hidden}
.gate-card>*{flex:none}
.kickoff-gate[data-kind=resume] .gate-card{width:min(620px,100%)}
.gate-head{align-self:stretch;display:flex;align-items:center;justify-content:center;gap:8px;padding:7px 12px 6px;background:var(--color-stage-ink);color:var(--color-stage);font:700 var(--fs-12)/1 var(--font-ui);letter-spacing:.04em}
.gate-seal{padding:3px 7px 2px;border-radius:var(--r-1);background:var(--color-stage);color:#fff;font:400 var(--fs-10)/1 var(--font-display);letter-spacing:.04em}
.gate-card>.gate-match{flex:0 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain;align-self:stretch}
.gate-match{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:start;gap:14px;padding:0 22px}
.gate-vs{align-self:center;font:400 var(--fs-23)/1 var(--font-display);font-style:normal;color:var(--color-stage-muted);letter-spacing:.06em}
.gate-side{display:grid;justify-items:start;align-content:start;gap:12px;min-width:0;padding:16px 18px 14px;text-align:left;border-radius:var(--r-2);background:linear-gradient(180deg,color-mix(in srgb,var(--team) 20%,transparent),color-mix(in srgb,var(--team) 6%,transparent) 70%);border-top:4px solid var(--team)}
.gate-id{display:flex;align-items:center;gap:14px;min-width:0;justify-self:stretch}
.gate-side.side-1 .gate-id{flex-direction:row-reverse}
.gate-id>div{display:grid;gap:4px;min-width:0}
.gate-crest{width:52px;height:52px}
span.gate-crest{font-size:24px;border-radius:24%;box-shadow:0 0 0 2px #ffffff26,0 8px 18px #0008}
img.gate-crest{filter:drop-shadow(0 8px 14px #0009)}
.gate-name{font:400 19px/1.2 var(--font-display);color:#fff;letter-spacing:.01em;overflow-wrap:anywhere}
.gate-side.side-1{justify-items:end;text-align:right}
.gate-team{display:inline-flex;align-items:center;gap:7px;max-width:100%;padding:4px 13px 4px 5px;border-radius:var(--r-pill);background:var(--team,var(--color-home));color:var(--team-ink);font:700 var(--fs-16)/1.2 var(--font-emphasis)}
.gate-team img{width:22px;height:22px;flex:none}
.gate-team span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gate-world{margin:0;font:600 var(--fs-13)/1.45 var(--font-ui);color:color-mix(in srgb,var(--team) 45%,#fff);overflow-wrap:anywhere}
.gate-roster{margin:0;padding:0;list-style:none;display:grid;gap:0;justify-self:stretch}
.gate-roster li{display:grid;gap:4px;padding:10px 0;border-top:1px solid #ffffff1c;font-size:var(--fs-14)}
.gate-who{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px}
.gate-side.side-1 .gate-who{justify-content:flex-end}
.gate-bio{margin:0;font:400 var(--fs-13)/1.55 var(--font-story);color:var(--color-stage-ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
.gate-roster b{color:#fff;font:700 var(--fs-16)/1.3 var(--font-ui)}
.gate-roster i{font-style:normal;padding:3px 9px 2px;border-radius:var(--r-pill);background:color-mix(in srgb,var(--team) 22%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--team) 55%,transparent);font:600 var(--fs-12)/1.3 var(--font-ui);color:color-mix(in srgb,var(--team) 35%,#fff)}
.gate-score{grid-column:1/-1;padding:16px 4px 4px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:16px}
.gate-score .gate-team:first-child{justify-self:end}
.gate-score .gate-team:last-child{justify-self:start}
.gate-score .gate-team{position:relative;transition:opacity var(--dur-2) var(--ease-out)}
.gate-team.is-waiting{opacity:.4}
.gate-team.is-next{box-shadow:0 0 0 3px var(--color-stage),0 0 0 5px var(--team),0 0 22px color-mix(in srgb,var(--team) 70%,transparent)}
.gate-next{position:absolute;left:50%;top:-13px;translate:-50% 0;padding:3px 9px 2px;border-radius:var(--r-pill);background:#fff;color:var(--color-stage);font:700 var(--fs-11)/1 var(--font-ui);font-style:normal;white-space:nowrap;box-shadow:0 0 0 2px var(--color-stage)}
.gate-note:empty{display:none}
.gate-score strong{font:400 40px/1 var(--font-display);color:#fff;letter-spacing:.04em}
.go-btn{position:relative;min-width:136px;padding:8px 30px 6px;border:0;border-radius:var(--r-1);transform:skewX(-10deg);background:var(--color-accent);color:var(--color-accent-ink);font:400 30px/1 var(--font-display);letter-spacing:.04em;cursor:pointer;overflow:hidden;box-shadow:0 0 0 3px var(--color-stage),0 0 0 5px color-mix(in srgb,var(--color-accent) 60%,transparent),0 10px 30px color-mix(in srgb,var(--color-accent) 50%,transparent);transition:transform var(--dur-1) var(--ease-out),background var(--dur-1) var(--ease-out)}
.go-btn span{display:block;transform:skewX(10deg);text-shadow:0 2px 0 #0003}
.go-btn:after{content:'';position:absolute;inset:0 auto 0 -60%;width:40%;background:linear-gradient(90deg,transparent,#ffffff70,transparent);animation:go-sweep 2.4s ease-in-out .6s infinite}
.kickoff-gate.is-ready .go-btn{animation:go-ready 1.6s ease-in-out infinite}
.go-btn:hover:not(:disabled){transform:skewX(-10deg) scale(1.04);background:var(--color-accent);filter:brightness(1.1)}
.go-btn:active:not(:disabled){transform:skewX(-10deg) scale(.97)}
.go-btn:focus-visible{outline:3px solid #fff;outline-offset:4px}
.go-btn:disabled{opacity:1;background:var(--color-stage-2);color:var(--color-stage-muted);box-shadow:0 0 0 3px var(--color-stage),0 0 0 5px #ffffff22;cursor:wait}
.go-btn:disabled:after{animation-duration:1.2s}
.gate-note{font:600 var(--fs-12)/1.4 var(--font-ui);color:var(--color-stage-muted)}
.kickoff-gate.is-ready .gate-note{color:var(--color-stage-ink)}
@keyframes go-sweep{0%{left:-60%}55%,100%{left:130%}}
@keyframes go-ready{0%,100%{box-shadow:0 0 0 3px var(--color-stage),0 0 0 5px color-mix(in srgb,var(--color-accent) 60%,transparent),0 10px 30px color-mix(in srgb,var(--color-accent) 50%,transparent)}50%{box-shadow:0 0 0 3px var(--color-stage),0 0 0 11px color-mix(in srgb,var(--color-accent) 25%,transparent),0 10px 40px color-mix(in srgb,var(--color-accent) 75%,transparent)}}
.shot-speaker{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 12px 0 4px;border-radius:var(--r-pill);background:var(--team);color:var(--team-ink);font:700 var(--fs-13)/1 var(--font-ui);white-space:nowrap;box-shadow:0 0 0 2px var(--color-stage)}
.shot-speaker i{padding:3px 8px;border-radius:var(--r-pill);background:var(--color-stage);color:#fff;font:700 var(--fs-11)/1 var(--font-ui);font-style:normal}
.shot-cue blockquote{max-width:min(780px,100%);margin:0;padding:8px 30px 9px;text-align:center;font:700 30px/1.35 var(--font-story);color:#fff;overflow-wrap:anywhere;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--team) 45%,var(--color-stage)) 12%,color-mix(in srgb,var(--team) 45%,var(--color-stage)) 88%,transparent);text-shadow:0 0 18px color-mix(in srgb,var(--team) 85%,transparent),0 2px 0 var(--color-stage);animation:line-glow 1.1s ease-in-out 1.1s infinite alternate}
.shot-cue.is-long blockquote{font-size:23px}
.shot-cue.is-longer blockquote{font-size:18px;line-height:1.45}
@keyframes line-slam{0%{opacity:0;transform:scale(2.1);filter:blur(6px) brightness(2)}45%{opacity:1;transform:scale(.94);filter:none}60%{transform:scale(1.02) translateX(-4px)}75%{transform:translateX(3px)}100%{opacity:1;transform:none}}
@keyframes line-glow{to{text-shadow:0 0 30px var(--team),0 2px 0 var(--color-stage)}}
.judge-actions .no{background:var(--color-surface);border:1px solid var(--color-line-strong);color:var(--color-ink)}
.judge-actions .yes{background:var(--color-accent);border:1px solid var(--color-accent);color:#fff}
.judge-actions .yes:hover:not(:disabled){background:#1733d6;border-color:#1733d6}
.judge-actions .no:hover:not(:disabled){border-color:var(--color-ink)}
.judge-actions button:focus-visible{outline:3px solid var(--color-ink);outline-offset:2px}
.match-call-note{grid-column:1/-1;text-align:center;font-size:var(--fs-10);line-height:1.5;color:var(--color-muted);margin-top:4px}
.result-overlay{position:absolute;inset:0;z-index:var(--z-result);display:grid;place-content:center;text-align:center;pointer-events:none;background:#0b1326a6;backdrop-filter:blur(4px);color:var(--color-stage-ink)}
.result-overlay .decision-kicker{font:400 var(--fs-11)/1 var(--font-display);letter-spacing:.2em;color:var(--color-stage-muted);margin-bottom:10px}
.result-overlay b{font:400 clamp(44px,7vw,88px)/1 var(--font-display);letter-spacing:.02em;color:#fff}
.result-overlay span{display:inline-block;margin-top:12px;padding:5px 14px;background:var(--color-accent);color:#fff;border-radius:var(--r-pill);font-size:var(--fs-12);font-weight:600}
/* 결과 스팅어 — 판정 직후 0.8초는 슛을 보여 주고, 닿는 순간(--result-impact) 글자가 꽂힌다.
   골: 득점 팀 색 띠가 왼쪽에서 쓸고 GOAL! 이 크게 박힌다. 무득점: 반대 방향으로 띠가 흐르고
   NO GOAL! 가 도장처럼 떨어진다. 2.6초에 로그 위 띠로 내려앉는다. */
.result-overlay.is-result{top:118px;bottom:auto;height:150px;background:transparent;backdrop-filter:none;isolation:isolate;animation:result-show 1ms linear var(--result-impact) both,result-settle var(--dur-stinger) var(--ease-snap) var(--delay-stinger) both}
@keyframes result-show{from{opacity:0}to{opacity:1}}
.result-overlay.is-result:after{content:'';position:absolute;left:-3%;right:-3%;top:50%;height:104px;margin-top:-52px;z-index:-1;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--result-color,var(--color-accent)) 90%,transparent) 12%,color-mix(in srgb,var(--result-color,var(--color-accent)) 90%,transparent) 88%,transparent);transform:skewY(-4deg);animation:stripe-wipe .28s var(--ease-out) var(--result-impact) both,stripe-out .3s ease var(--delay-stinger) both}
.result-overlay.is-miss:after{transform:skewY(4deg);animation-name:stripe-wipe-miss,stripe-out}
@keyframes stripe-wipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}
@keyframes stripe-wipe-miss{from{clip-path:inset(0 0 0 100%)}to{clip-path:inset(0)}}
@keyframes stripe-out{to{opacity:0}}
.result-overlay.is-result .decision-kicker{display:none}
@keyframes result-settle{to{top:calc(100% - var(--story-frame-height) - 156px);height:92px;background:linear-gradient(115deg,var(--color-band),var(--color-band-2));backdrop-filter:blur(2px)}}
.result-overlay.is-result b{font-size:64px;color:#fff;-webkit-text-stroke:3px var(--color-stage);paint-order:stroke fill;text-shadow:5px 5px 0 var(--color-stage);animation:goal-slam .55s cubic-bezier(.2,.9,.3,1.3) var(--result-impact) both,result-word var(--dur-stinger) var(--ease-snap) var(--delay-stinger) both}
.result-overlay.is-miss b{animation-name:miss-stamp,result-word;animation-duration:.5s,var(--dur-stinger);animation-timing-function:var(--ease-out),var(--ease-snap)}
@keyframes goal-slam{0%{transform:scale(2.8);opacity:0;filter:blur(6px)}45%{transform:scale(.92);opacity:1;filter:none}70%{transform:scale(1.06)}100%{transform:scale(1)}}
@keyframes miss-stamp{0%{transform:translateY(-70px) rotate(-12deg) scale(1.5);opacity:0}55%{transform:translateY(4px) rotate(-3deg) scale(.95);opacity:1}75%{transform:translateY(-2px) rotate(-3deg) scale(1.02)}100%{transform:rotate(-3deg)}}
@keyframes result-word{to{font-size:var(--fs-stinger-band)}}
.result-overlay.is-result span{position:relative;display:inline-flex;align-items:center;gap:10px;margin-top:14px;padding:5px 6px 5px 5px;overflow:hidden;background:var(--color-stage);color:#fff;font:700 18px/1 var(--font-ui);border:2px solid var(--result-color,var(--color-accent));box-shadow:0 0 0 3px var(--color-stage),0 0 22px color-mix(in srgb,var(--result-color,var(--color-accent)) 70%,transparent),4px 5px 0 3px var(--color-stage);animation:caption-pop .35s cubic-bezier(.2,.9,.3,1.4) calc(var(--result-impact) + .22s) both,caption-glow 1.4s ease-in-out calc(var(--result-impact) + .6s) infinite alternate,result-caption var(--dur-stinger) var(--ease-snap) var(--delay-stinger) both}
/* Score capsule: the side's name on its own colour, the call in white, the new score on a paper chip;
   a light sweep crosses it once as it lands. */
.result-overlay.is-result span em{font-style:normal;padding:.34em .66em;border-radius:var(--r-pill);background:var(--result-color,var(--color-accent));color:var(--team-ink)}
.result-overlay.is-result span i{font-style:normal;letter-spacing:.01em}
.result-overlay.is-result span strong{padding:.22em .5em .16em;border-radius:var(--r-pill);background:#fff;color:var(--color-stage);font:400 1.34em/1 var(--font-display);letter-spacing:.06em}
.result-overlay.is-result span:after{content:'';position:absolute;inset:0;background:linear-gradient(105deg,transparent 35%,#ffffff8c 50%,transparent 65%);transform:translateX(-120%);animation:caption-sweep .9s var(--ease-out) calc(var(--result-impact) + .5s) both}
@keyframes caption-sweep{to{transform:translateX(120%)}}
@keyframes caption-glow{to{box-shadow:0 0 0 3px var(--color-stage),0 0 34px color-mix(in srgb,var(--result-color,var(--color-accent)) 95%,transparent),4px 5px 0 3px var(--color-stage)}}
@keyframes caption-pop{from{transform:scale(0) rotate(-6deg);opacity:0}to{transform:none;opacity:1}}
/* 경기장 임팩트 — 골은 크게 흔들리며 번쩍, 무득점은 짧게 '쿵'. 점수는 닿는 순간 새 숫자가 튄다. */
.canvas-stage.impact-goal>canvas{animation:impact-flash .45s ease-out var(--result-impact),shake-goal .5s linear var(--result-impact)}
.canvas-stage.impact-miss>canvas{animation:impact-flash-miss .3s ease-out var(--result-impact),shake-miss .32s linear var(--result-impact)}
@keyframes impact-flash{0%{filter:brightness(2.3) saturate(1.3)}100%{filter:none}}
@keyframes impact-flash-miss{0%{filter:brightness(1.5) contrast(1.2)}100%{filter:none}}
@keyframes shake-goal{0%,100%{transform:none}10%{transform:translate(-8px,5px)}25%{transform:translate(7px,-5px)}40%{transform:translate(-5px,3px)}60%{transform:translate(3px,-2px)}80%{transform:translate(-1px,1px)}}
@keyframes shake-miss{0%,100%{transform:none}20%{transform:translateX(10px)}45%{transform:translateX(-5px)}70%{transform:translateX(2px)}}
/* 판정 버튼 — 누르면 꾹 눌리고, 먹혔다는 앞으로 튀어 나가며 날아가고 안 먹혔다는 잠시 흔들리다 떨어진다. */
.judge-actions button{transition:transform 90ms var(--ease-out)}
.judge-actions button:active:not(:disabled){transform:scale(.95)}
.match-call.is-leaving{visibility:hidden}
.call-ghost{pointer-events:none;animation:ghost-veil .6s ease both}
@keyframes ghost-veil{to{background:transparent;backdrop-filter:none}}
.call-ghost .match-panel{animation:.62s both}
.call-ghost.is-hit .match-panel{animation-name:panel-shoot;animation-timing-function:cubic-bezier(.5,0,.75,0)}
.call-ghost.is-miss .match-panel{animation-name:panel-block;animation-timing-function:ease-in}
@keyframes panel-shoot{0%{transform:none}22%{transform:scale(.95)}100%{transform:translate(42%,-10%) scale(.35) rotate(8deg);opacity:0}}
@keyframes panel-block{0%{transform:none}12%{transform:translateX(-14px)}24%{transform:translateX(11px)}36%{transform:translateX(-6px)}50%{transform:none;opacity:1}100%{transform:translateY(70px) scale(.9);opacity:0}}
.call-ghost .is-chosen{animation:chosen-punch .28s cubic-bezier(.2,.9,.3,1.4) both}
@keyframes chosen-punch{0%{transform:scale(1)}40%{transform:scale(.9)}100%{transform:scale(1.07);box-shadow:0 0 0 6px color-mix(in srgb,var(--color-accent) 35%,transparent)}}
.call-ghost.is-miss .is-chosen{animation-name:chosen-punch-miss}
@keyframes chosen-punch-miss{0%{transform:scale(1)}40%{transform:scale(.9)}100%{transform:scale(1.04);box-shadow:0 0 0 6px color-mix(in srgb,var(--color-ink) 25%,transparent)}}
@keyframes result-caption{to{margin-top:6px;gap:7px;padding:3px 4px 3px 3px;font-size:var(--fs-13)}}
.stage-notice{--notice:var(--color-signal);position:absolute;z-index:var(--z-notice);left:50%;transform:translateX(-50%);top:auto;bottom:calc(16px + var(--story-frame-height) + 48px);display:flex;align-items:center;gap:8px;background:color-mix(in srgb,var(--notice) 7%,var(--color-surface));color:var(--color-ink);border:1px solid color-mix(in srgb,var(--notice) 45%,transparent);border-radius:var(--r-pill);padding:5px 14px 5px 5px;font-size:var(--fs-11);line-height:1.5;max-width:min(460px,42%);pointer-events:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--notice) 16%,transparent),0 10px 24px #0007;animation:notice-in .34s cubic-bezier(.2,.9,.3,1.3) both}
.stage-notice.error{--notice:var(--color-bad)}
/* Alarm badge: a filled circle with a glyph, ringing (bell) while waiting, a steady "!" on errors. */
.stage-notice .notice-dot{flex:none;position:relative;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--notice);color:#fff}
.stage-notice .notice-dot:before{content:'';width:9px;height:9px;background:currentColor;-webkit-mask:var(--notice-bell) center/contain no-repeat;mask:var(--notice-bell) center/contain no-repeat;animation:notice-ring 1.4s ease-in-out infinite}
.stage-notice .notice-dot:after{content:'';position:absolute;inset:-3px;border-radius:50%;border:2px solid var(--notice);opacity:0;animation:notice-pulse 1.4s ease-out infinite}
.stage-notice.error .notice-dot:before{content:'!';width:auto;height:auto;background:none;-webkit-mask:none;mask:none;font:800 12px/1 var(--font-ui);animation:none}
.stage-notice.error .notice-dot:after{animation:none}
.stage-notice{--notice-bell:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5a4.5 4.5 0 0 0-4.5 4.5v3L2 11.5h12L12.5 9V6A4.5 4.5 0 0 0 8 1.5zM6 13a2 2 0 0 0 4 0z'/%3E%3C/svg%3E")}
@keyframes notice-in{from{opacity:0;transform:translateX(-50%) translateY(10px) scale(.94)}to{opacity:1;transform:translateX(-50%)}}
@keyframes notice-ring{0%,55%,100%{transform:rotate(0)}10%,30%{transform:rotate(16deg)}20%,40%{transform:rotate(-16deg)}}
@keyframes notice-pulse{0%{opacity:.7;transform:scale(.85)}100%{opacity:0;transform:scale(1.5)}}
/* Live generation progress lives inside the AI 모델 panel so it never covers the board. */
.gen-live{display:flex;align-items:center;gap:8px;background:var(--color-surface);color:var(--color-ink);border-left:3px solid var(--color-signal);border-radius:0 var(--r-1) var(--r-1) 0;padding:6px 10px;font-size:var(--fs-11);line-height:1.5}
.gen-live .notice-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--color-signal);animation:blink 1.1s infinite}
@keyframes blink{50%{opacity:.25}}
.stage-overlay{position:absolute;inset:0;z-index:var(--z-start);display:grid;place-items:center;background:#0b1326e6;backdrop-filter:blur(6px);padding:18px;overflow:auto}
.start-panel{width:min(560px,100%);background:var(--color-surface);color:var(--color-ink);border-radius:var(--r-3);box-shadow:var(--shadow-pop);padding:20px 24px 18px}
.start-panel h2{font:400 var(--fs-40)/1 var(--font-display);letter-spacing:.02em;color:var(--color-ink);margin:4px 0 14px}
.start-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.start-grid label{display:flex;flex-direction:column;gap:5px;font-size:var(--fs-11);color:var(--color-muted)}
.start-grid select{width:100%;font-size:var(--fs-12)}
.start-hint{font-size:var(--fs-11);color:var(--color-muted);line-height:1.6;margin:12px 0}
.start-notice{font-size:var(--fs-12);color:var(--color-ink);border-left:3px solid var(--color-signal);padding:6px 10px;background:var(--color-surface-2);margin:0 0 12px;line-height:1.6}
.start-actions{display:flex;justify-content:flex-end;gap:8px;flex-wrap:wrap}
.start-actions .yes{background:var(--color-accent);color:#fff;border-color:var(--color-accent);font-weight:700;min-width:140px}
.start-actions .yes:hover:not(:disabled){background:#1733d6}

/* 8. 조작부·판정석·공격 횟수·광고 */
.transport{background:var(--color-stage-2);border-top:1px solid var(--color-stage-line);padding:0 16px 10px}
.progress-row{display:flex;align-items:center;gap:12px;margin-bottom:6px}
.progress{display:flex;flex:1;gap:4px;height:12px;padding:5px 0 3px}
.turn-count{flex:none;font:700 var(--fs-11)/1 var(--font-ui);font-variant-numeric:tabular-nums;letter-spacing:.02em;color:var(--color-stage-muted);white-space:nowrap}
.progress i{position:relative;overflow:hidden;height:4px;flex:1;border-radius:2px;background:#ffffff26}
/* Each attack's cell fills in real time as it is played; the fill shimmers while it runs and holds
   still from MATCH! (the judgment) on. */
.progress i b{position:absolute;inset:0 auto 0 0;width:0;border-radius:inherit;background:linear-gradient(90deg,var(--color-accent),#8fb0ff,var(--team-accent,var(--color-accent)),var(--color-accent)) 0 0/300% 100%;animation:progress-wave 2.4s linear infinite;transition:width .12s linear}
.progress i.past b{width:100%;background:#ffffff80;animation:none}
.progress.is-held i b{animation-play-state:paused}
@keyframes progress-wave{to{background-position:-300% 0}}
.controls{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.controls button{min-height:34px;font-size:var(--fs-12);padding:6px 10px;border:1px solid transparent;background:transparent;color:var(--color-stage-ink);border-radius:var(--r-2)}
.controls button:hover:not(:disabled){background:#ffffff14;border-color:transparent}
.controls #playBtn{background:#ffffff1a;font-weight:700}
.controls .live-state{display:flex;align-items:center;gap:6px;margin-left:4px;font-size:var(--fs-10);letter-spacing:.08em;color:var(--color-stage-muted)}
/* 중계 중 표시: 빨간 불만 숨쉬듯 깜빡인다. */
.live-state:before{content:'';width:7px;height:7px;background:var(--color-signal);border-radius:50%;box-shadow:0 0 8px var(--color-signal);animation:onair-blink 1.4s ease-in-out infinite}
@keyframes onair-blink{0%,100%{opacity:1}50%{opacity:.3}}
@media (prefers-reduced-motion: reduce){.live-state:before{animation:none}}
.status-strip{display:flex;align-items:center;gap:10px;border-top:1px solid var(--color-stage-line);padding:8px 2px 2px;font-size:var(--fs-11);color:#ffd7cc;line-height:1.5}
.status-strip span{flex:1;min-width:0}
.status-strip button{min-height:30px;font-size:var(--fs-11);padding:3px 8px;white-space:nowrap}
/* 판정석 묶음(이야기가 전개되고 있어요 · 감상 남기기)은 쓰이지 않아 숨긴다(제리). 판정은 로그 위 MATCH! 바, #feedback 은 빈 값으로 남는다. */
.broadcast-story{display:none}
.read-card{background:var(--color-surface);color:var(--color-ink);border-top:1px solid var(--color-line);border-radius:0 0 var(--r-frame) var(--r-frame)}
.judge{padding:14px 20px 12px}
.judge-line{display:flex;justify-content:space-between;align-items:center;gap:15px}
.judge h3{font:700 var(--fs-14)/1.4 var(--font-emphasis);margin:0}
.judge small{display:block;font-size:var(--fs-12);color:var(--color-muted)}
.judge details{margin-top:6px;color:var(--color-muted);font-size:var(--fs-12)}
.judge summary{cursor:pointer;min-height:24px;width:max-content}
.judge label{display:block;margin-top:8px;color:var(--color-ink-2)}
.judge textarea{width:100%;background:var(--color-surface-2);border:1px solid var(--color-line-strong);color:var(--color-ink);padding:10px;border-radius:var(--r-2);resize:vertical;margin:6px 0}
.tactics-board{margin-top:var(--sp-4);background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--r-3);padding:14px 18px 16px}
.tactics-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.tactics-head strong{font:700 var(--fs-14)/1.3 var(--font-emphasis);letter-spacing:var(--ls-tight)}
.tactics-head small{color:var(--color-muted);font-size:var(--fs-11);margin-left:auto}
.tactics-teams{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.tactic-team{border-left:3px solid var(--color-home);padding:8px 12px;background:var(--color-surface-2);border-radius:0 var(--r-2) var(--r-2) 0}
.tactic-team.away{border-color:var(--color-away)}
.tactic-team b{display:block;font:700 var(--fs-13)/1.4 var(--font-emphasis);margin-bottom:6px}
.tactic-row{display:flex;justify-content:space-between;gap:8px;font-size:var(--fs-12);color:var(--color-muted);padding:2px 0}
.tactic-row em{font-style:normal;color:var(--color-ink);white-space:nowrap}
.tactics-pending{font-size:var(--fs-12);color:var(--color-muted);grid-column:1/-1}
.sponsor{display:flex;align-items:center;overflow:hidden;margin-top:var(--sp-3);background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--r-2);height:36px;position:relative}
.sponsor-label{flex:none;padding:0 12px;border-right:1px solid var(--color-line);color:var(--color-muted);font-size:var(--fs-10);line-height:1.3;z-index:1;background:var(--color-surface)}
.sponsor-label b{display:block;font:400 var(--fs-12)/1 var(--font-display);letter-spacing:.08em;color:var(--color-ink)}
.ticker-window{overflow:hidden;min-width:0;flex:1;mask-image:linear-gradient(90deg,transparent,#000 2%,#000 98%,transparent)}
.ticker-track{display:flex;width:max-content;animation:marquee 42s linear infinite}
.ticker-group{display:flex;align-items:center;flex:none;gap:40px;padding-right:40px;white-space:nowrap;font-size:var(--fs-12);color:var(--color-ink-2)}
.ticker-group b{font:400 var(--fs-13)/1 var(--font-display);letter-spacing:.08em;color:var(--color-ink)}
.ticker-group .divider{color:var(--color-line-strong)}
.sponsor:hover .ticker-track,.motion-paused .ticker-track{animation-play-state:paused}
@keyframes marquee{to{transform:translateX(-50%)}}

/* 9. 우측 레일 — 흰 카드. 탭 선택은 울트라마린 밑줄, 팀 색은 팀 표시에만. */
.rail{grid-area:rail;align-self:stretch;position:relative;min-width:0}
.rail-box{position:absolute;inset:0;display:flex;flex-direction:column;background:var(--color-surface);border:1px solid var(--color-line);border-top:3px solid var(--team-accent,var(--color-line-strong));border-radius:var(--r-3);overflow:hidden;transition:border-color var(--dur-2) var(--ease-out)}
.rail-box>[role=tabpanel]:not([hidden]){flex:1;min-height:0;overflow:auto}
.rail-box>#crowdPanel:not([hidden]){display:flex;flex-direction:column;overflow:hidden}
.rail-box>#crowdPanel .crowd-feed{flex:1;height:auto;min-height:160px}
.rail-tabs{flex:none;display:flex;border-bottom:1px solid var(--color-line);padding:0 var(--sp-3);gap:var(--sp-4)}
.rail-tabs button{flex:none;border:0;border-radius:0;background:none;padding:12px 2px;min-height:46px;font-size:var(--fs-13);font-weight:600;color:var(--color-muted)}
.rail-tabs button:hover:not(:disabled){background:none;color:var(--color-ink)}
.rail-tabs button[aria-selected=true]{color:var(--color-ink);font-weight:700;box-shadow:inset 0 -2px var(--color-accent)}
.rail-panel{padding:var(--sp-4) var(--sp-4) var(--sp-5);min-width:0;overflow-wrap:anywhere}
.rail-panel input,.rail-panel select,.rail-panel button,.rail-panel label{max-width:100%;min-width:0;box-sizing:border-box}
.crowd-header{display:flex;justify-content:space-between;align-items:center;padding:var(--sp-3) var(--sp-4) var(--sp-2)}
.crowd-header strong{display:flex;align-items:center;gap:8px;font:400 var(--fs-16)/1 var(--font-display);letter-spacing:.06em;color:var(--color-ink)}
.crowd-header strong i{width:7px;height:7px;border-radius:50%;background:var(--color-signal);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-signal) 25%,transparent);animation:blink 1.4s infinite}
.example-tag{font-size:var(--fs-10);padding:2px 8px;border:1px solid var(--color-line-strong);color:var(--color-muted);border-radius:var(--r-pill)}
.crowd-header .example-tag{min-height:0;padding:4px 10px;font-size:var(--fs-11);font-weight:700}
.crowd-header .example-tag[aria-pressed=true]{border-color:var(--color-ink);background:var(--color-ink);color:#fff}
/* Fan zone feed: nicknames with a colored avatar, loud short shouts, quoted replies, my reaction on the right. */
.crowd-feed{height:332px;overflow:auto;padding:var(--sp-2) var(--sp-4) var(--sp-3);display:flex;flex-direction:column;gap:9px;mask-image:linear-gradient(180deg,transparent,#000 4%,#000 96%,transparent)}
.chat-item{display:grid;grid-template-columns:28px minmax(0,1fr);gap:9px;align-items:start;animation:chat-in .32s cubic-bezier(.2,1.2,.4,1) both}
@keyframes chat-in{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}
.chat-avatar{height:28px;width:28px;display:grid;place-items:center;border-radius:50%;background:var(--fan,var(--color-surface-3));color:var(--color-stage);font:700 var(--fs-12)/1 var(--font-ui);box-shadow:inset 0 0 0 2px #ffffff80}
.chat-body{min-width:0}
.chat-name{display:block;font:700 var(--fs-11)/1.3 var(--font-ui);color:var(--color-muted)}
.chat-reply{margin-top:3px;padding:2px 8px;border-left:2px solid var(--color-line-strong);border-radius:0 6px 6px 0;background:var(--color-surface-2);color:var(--color-muted);font-size:var(--fs-11);line-height:1.4;overflow-wrap:anywhere}
.chat-item.mine .chat-reply{display:none}
.chat-text{margin-top:2px;font-size:var(--fs-13);line-height:1.5;color:var(--color-ink);overflow-wrap:anywhere}
.chat-item.is-hype .chat-text{display:inline-block;margin-top:3px;padding:3px 10px 4px;border-radius:4px 12px 12px 12px;background:color-mix(in srgb,var(--fan,var(--color-cast)) 34%,var(--color-surface));font-size:var(--fs-16);font-weight:800;letter-spacing:-.01em}
.chat-item.is-hype{animation:chat-in .32s cubic-bezier(.2,1.2,.4,1) both,chat-pop .5s cubic-bezier(.2,1.8,.4,1) .1s both}
@keyframes chat-pop{0%{transform:scale(.9)}60%{transform:scale(1.04)}100%{transform:none}}
.chat-item.mine{grid-template-columns:minmax(0,1fr);justify-items:end}
.chat-item.mine .chat-avatar,.chat-item.mine .chat-name{display:none}
.chat-item.mine .chat-text{padding:6px 12px 7px;border-radius:12px 4px 12px 12px;background:var(--color-accent);color:#fff;font-weight:600}
.crowd-status{display:flex;align-items:center;gap:7px;margin:0 var(--sp-4) var(--sp-2);padding:5px 10px;border-radius:var(--r-pill);background:var(--color-surface-2);color:var(--color-muted);font-size:var(--fs-11);line-height:1.3}
.crowd-status:before{content:'';flex:none;width:6px;height:6px;border-radius:50%;background:var(--color-line-strong)}
.crowd-status.is-live:before{background:var(--color-signal);animation:blink 1.1s infinite}
.crowd-status.is-typing:after{content:'···';margin-left:-3px;letter-spacing:1px;animation:blink .9s infinite}
.reactions{border-top:1px solid var(--color-line);padding:var(--sp-3) var(--sp-4) var(--sp-3);display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-2)}
.reaction-label{display:flex;justify-content:space-between;gap:8px;color:var(--color-muted);font-size:var(--fs-11);font-weight:600}
.reaction-label span:last-child{font-weight:400;font-size:var(--fs-10)}
/* The scene's three reaction choices: speech-bubble chips that wrap; the picked one turns blue. */
.reaction-buttons{display:flex;flex-wrap:wrap;gap:6px}
.reaction-buttons button{flex:0 1 auto;max-width:100%;min-height:30px;padding:4px 11px;text-align:left;white-space:normal;overflow-wrap:anywhere;font-size:var(--fs-12);font-weight:600;line-height:1.35;border-radius:4px 14px 14px 14px}
.reaction-buttons button.is-picked,.reaction-buttons button.is-picked:disabled{border-color:var(--color-accent);background:var(--color-accent);color:#fff;opacity:1}
.reaction-buttons:empty{display:none}
.reaction-buttons button:hover:not(:disabled){border-color:var(--color-accent);color:var(--color-accent);background:var(--color-accent-soft)}
.reaction-buttons button:active:not(:disabled){transform:scale(.94)}
.reaction-note{color:var(--color-muted);font-size:var(--fs-10);line-height:1.5}
.lineup{display:grid;gap:var(--sp-4)}
.lineup-team{display:grid;gap:0}
.lineup-head{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:2px 8px;padding:8px 10px;border-left:4px solid var(--team);border-radius:0 var(--r-1) var(--r-1) 0;background:color-mix(in srgb,var(--team) 14%,var(--color-surface))}
.lineup-head img{grid-row:span 2;width:26px;height:26px}
.lineup-head b{font:700 var(--fs-13)/1.25 var(--font-emphasis);color:var(--color-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lineup-head small{font-size:var(--fs-11);line-height:1.4;color:var(--color-ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lineup-team .profile-row{min-height:54px}
.lineup-team .profile-row.on{--team-accent:var(--team)}
.profile-row{display:flex;align-items:center;width:100%;text-align:left;gap:var(--sp-3);padding:var(--sp-2);min-height:62px;border:0;border-bottom:1px solid var(--color-line);border-left:2px solid transparent;border-radius:0;background:none;color:var(--color-ink-2)}
.profile-row:hover:not(:disabled){background:var(--color-surface-2);border-color:var(--color-line);border-left-color:transparent}
.profile-row.on{background:var(--color-surface-2);color:var(--color-ink);border-left-color:var(--team-accent,var(--color-accent))}
.profile-row .mini-portrait{width:40px;height:46px;flex:none;object-fit:cover;object-position:center 25%;border-radius:var(--r-1);background:var(--color-portrait);image-rendering:pixelated}
.profile-row .mini-sprite{background:linear-gradient(180deg,var(--color-surface-3),#cfd6e0)}
.profile-row .jersey{display:none}
.player-id{display:grid;gap:2px;min-width:0}
.player-id b{font:700 var(--fs-13)/1.2 var(--font-emphasis);letter-spacing:var(--ls-tight);color:var(--color-ink)}
.player-title{font:600 var(--fs-10)/1.2 var(--font-ui);color:var(--color-muted)}
.profile-row .tag{margin-left:auto;font:400 9px/1 var(--font-display);letter-spacing:.1em;padding:4px 7px;background:var(--color-ink);color:#fff;border-radius:var(--r-pill);flex:none;white-space:nowrap}
.history-label{font-size:var(--fs-11);color:var(--color-muted);margin-bottom:var(--sp-3)}
.history{display:grid;gap:4px;min-height:120px;max-height:440px;overflow:auto}
.history button{display:flex;justify-content:space-between;gap:10px;align-items:center;text-align:left;font-size:var(--fs-12);border:0;border-bottom:1px solid var(--color-line);border-radius:0;padding:10px 4px;background:none;color:var(--color-ink-2)}
.history button:hover:not(:disabled){background:var(--color-surface-2)}
.history small{color:var(--color-muted);font-size:var(--fs-10)}
.history .goal{color:var(--color-good-ink);font-weight:700}
/* 보기 설정 — 무대 아래 진행 줄 오른쪽에 붙는 어두운 작은 칩들: 배속 · 자동 넘김 · 자막화면 · 집중 모드. */
.view-settings{margin-left:auto;display:flex;align-items:center;gap:6px;min-width:0}
.setting-row{display:flex;align-items:center;gap:6px}
.setting-row:first-child{display:contents}
.setting-row label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.view-settings select{height:28px;min-height:0;padding:0 4px 0 8px;font:700 var(--fs-11) var(--font-ui);color:var(--color-stage-ink);background:#ffffff14;border:1px solid #ffffff24;border-radius:var(--r-pill)}
.view-settings select option{color:var(--color-ink);background:var(--color-surface)}
.controls .view-settings button{display:inline-flex;align-items:center;gap:5px;height:28px;min-height:0;padding:0 10px;font-size:var(--fs-11);font-weight:600;white-space:nowrap;border:1px solid #ffffff24;border-radius:var(--r-pill);color:var(--color-stage-muted);background:transparent}
.controls .view-settings .focus-btn{order:3}
.setting-row.toggles button:before{content:'';width:6px;height:6px;border-radius:50%;background:#ffffff40}
.controls .setting-row.toggles button[aria-pressed=true]{color:var(--color-stage-ink);background:#ffffff14;border-color:transparent}
.setting-row.toggles button[aria-pressed=true]:before{background:var(--color-accent);box-shadow:0 0 6px var(--color-accent)}
.controls .view-settings button:hover:not(:disabled){background:#ffffff1f}
.match-info{display:flex;align-items:center;gap:10px;padding:var(--sp-2) var(--sp-1)}
.match-info .info-icon{height:32px;width:32px;display:grid;place-items:center;border:1px solid var(--color-line-strong);border-radius:var(--r-2);color:var(--color-accent);font-size:var(--fs-16)}
.match-info strong{display:block;font:700 var(--fs-12)/1.4 var(--font-emphasis);color:var(--color-ink)}
.match-info small{font-size:var(--fs-10);color:var(--color-muted)}
.rail-note{color:var(--color-muted);font-size:var(--fs-10);line-height:1.8;padding:0 var(--sp-1)}
/* AI 모델 패널 */
.gen-panel{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}
.gen-mode .gen-state{margin-left:auto}
.gen-current{display:grid;gap:4px;overflow-wrap:anywhere;font-size:var(--fs-12)}
.gen-current span{font-size:var(--fs-11);color:var(--color-muted)}
.gen-metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
.gen-metric{display:grid;gap:4px;padding:10px;border:1px solid var(--color-line);border-radius:var(--r-2);background:var(--color-surface-2);min-width:0}
.gen-metric span{font-size:var(--fs-11);color:var(--color-muted)}
.gen-metric strong{font-size:var(--fs-14);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.gen-panel summary{cursor:pointer;min-height:32px;padding:6px 0;font-size:var(--fs-11);font-weight:600;color:var(--color-ink-2)}
.gen-panel details[open]>summary{margin-bottom:4px}
.gen-panel>.gen-section{border-top:1px solid var(--color-line);padding-top:8px}
.gen-ready:has(ul:empty),.job-actions:empty{display:none}
.gen-row{display:flex;align-items:center;gap:8px;font-size:var(--fs-11);color:var(--color-ink-2);line-height:1.5}
.gen-badge{flex:none;font-size:var(--fs-10);padding:3px 8px 2px;background:var(--color-ink);color:#fff;border-radius:var(--r-1)}
.gen-badge.live{background:var(--color-signal)}
.gen-section h3{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font:700 var(--fs-12)/1.4 var(--font-emphasis);margin:0 0 8px;color:var(--color-ink)}
.gen-section h3 small{font:400 var(--fs-10) var(--font-ui);color:var(--color-muted)}
.gen-state{display:inline-block;font-size:var(--fs-11);font-weight:600;padding:3px 9px;border-radius:var(--r-pill);background:var(--color-signal);color:#fff}
.gen-state.ok{background:var(--color-good);color:#fff}
.gen-ready ul{margin:6px 0 0;padding-left:16px;font-size:var(--fs-11);color:var(--color-ink-2);line-height:1.7}
.gen-ready ul:empty{display:none}
.gen-kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:3px 10px;font-size:var(--fs-11);color:var(--color-muted);margin-top:6px}
.gen-kv b{font-weight:600;color:var(--color-ink);overflow-wrap:anywhere}
.gen-search{display:flex;gap:6px;margin:6px 0}
.gen-search input{flex:1;min-width:0;background:var(--color-surface-2);border:1px solid var(--color-line-strong);border-radius:var(--r-2);padding:6px 10px;font-size:var(--fs-12)}
.gen-search button{min-height:34px;font-size:var(--fs-11);padding:4px 10px;white-space:nowrap}
.gen-meta{font-size:var(--fs-11);color:var(--color-muted);line-height:1.6;margin:0;overflow-wrap:anywhere}
.gen-recent{display:flex;flex-wrap:wrap;gap:4px;margin:4px 0}
.gen-recent button{min-height:26px;font-size:var(--fs-10);padding:2px 8px;border-radius:var(--r-pill)}
.model-list{display:grid;gap:4px;max-height:240px;overflow:auto}
.model-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 8px;text-align:left;padding:7px 10px;border:1px solid var(--color-line);border-radius:var(--r-2);min-height:0;font-size:var(--fs-11);color:var(--color-ink-2);background:var(--color-surface)}
.model-item b{font-weight:600;color:var(--color-ink);overflow-wrap:anywhere;grid-column:1}
.model-item small{color:var(--color-muted);font-size:var(--fs-10);grid-column:1;overflow-wrap:anywhere}
.model-item .price{grid-column:2;grid-row:1/3;align-self:center;font-size:var(--fs-10);color:var(--color-ink-2);text-align:right;white-space:nowrap}
.model-item[aria-selected=true]{border-color:var(--color-accent);background:var(--color-accent-soft)}
.model-item.unsupported{opacity:.5}
.gen-params{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:8px 0;align-items:end}
.gen-params label{display:grid;gap:4px;font-size:var(--fs-10);color:var(--color-muted)}
.gen-params input,.gen-params select{width:100%;min-width:0;background:var(--color-surface-2);color:var(--color-ink);border:1px solid var(--color-line-strong);border-radius:var(--r-2);padding:6px 8px;font-size:var(--fs-12);min-height:34px}
.gen-params button{grid-column:1/-1;min-height:36px;font-size:var(--fs-12)}
.gen-params .gen-search-toggle{grid-column:1/-1;display:flex;align-items:center;gap:var(--sp-2);min-height:44px;font-size:var(--fs-12);color:var(--color-ink);cursor:pointer}
.gen-params .gen-search-toggle input{width:18px;height:18px;min-height:0;padding:0;flex:none;accent-color:var(--color-accent)}
.job-list{display:grid;gap:6px;max-height:320px;overflow:auto}
.job{display:grid;gap:3px;border:1px solid var(--color-line);border-left:3px solid var(--color-line-strong);border-radius:0 var(--r-2) var(--r-2) 0;padding:8px 10px;font-size:var(--fs-11);color:var(--color-ink-2)}
.job.running,.job.queued{border-left-color:var(--color-signal)}
.job.succeeded{border-left-color:var(--color-good)}
.job.failed,.job.outcome_unknown{border-left-color:var(--color-bad)}
.job.cancelled{border-left-color:var(--color-muted)}
.job-head{display:flex;justify-content:space-between;gap:8px;align-items:center}
.job-head b{font-weight:600;color:var(--color-ink)}
.job-status{font-size:var(--fs-10);padding:3px 6px 2px;border:1px solid var(--color-line-strong);border-radius:var(--r-1);white-space:nowrap;color:var(--color-muted)}
.job-metrics{font-size:var(--fs-12);font-variant-numeric:tabular-nums;color:var(--color-ink)}
.job details small{display:block;line-height:1.6}
.job small.job-error{color:var(--color-bad)}
.job-actions{display:flex;gap:6px;margin-top:4px;flex-wrap:wrap}
.job-actions button{min-height:28px;font-size:var(--fs-10);padding:3px 8px}
.job small{color:var(--color-muted);overflow-wrap:anywhere}
.floating-reaction{position:absolute;right:22px;bottom:84px;z-index:var(--z-notice);background:var(--color-surface);color:var(--color-ink);border-radius:var(--r-pill);box-shadow:var(--shadow-soft);padding:7px 14px;font-size:var(--fs-11);max-width:250px;animation:appear .3s ease;pointer-events:none}
.floating-reaction span{color:var(--color-accent);margin-right:8px;font-size:var(--fs-10);font-weight:700}
@keyframes appear{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

/* 10. 다이얼로그 */
dialog{background:var(--color-surface);color:var(--color-ink);border:0;border-radius:var(--r-3);padding:24px;width:min(640px,calc(100% - 30px));max-height:85vh;box-shadow:var(--shadow-pop)}
dialog::backdrop{background:#0b1326b3;backdrop-filter:blur(6px)}
.dialoghead{display:flex;justify-content:space-between;align-items:center;gap:15px;margin-bottom:18px}
dialog h2{font:700 var(--fs-19)/1.3 var(--font-emphasis);letter-spacing:var(--ls-tight);margin:0}
dialog p{white-space:pre-line;line-height:1.8}
dialog small{color:var(--color-muted)}
.clubs{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.clubs img{width:80px;height:90px;background:var(--color-surface-2);object-fit:contain;border-radius:var(--r-2)}
.clubs h3{font:700 var(--fs-16)/1.3 var(--font-emphasis);margin:8px 0 2px}
.clubs p{font-size:var(--fs-13);color:var(--color-ink-2)}
.log-reading p{white-space:pre-line;font:400 var(--fs-14)/1.85 var(--font-story);margin:10px 0}
.dialogue-record{padding-left:24px;margin-top:12px}
.dialogue-record li{padding:8px 4px;border-bottom:1px solid var(--color-line)}
.dialogue-record li::marker{color:var(--color-accent);font-weight:700}
.dialogue-record strong{font:700 var(--fs-12)/1.4 var(--font-emphasis);color:var(--color-home)}
.dialogue-record p{font:400 var(--fs-14)/1.8 var(--font-story);margin:4px 0}
.profile-detail{display:grid;grid-template-columns:150px 1fr;gap:22px;align-items:start}
.profile-detail img{width:150px;height:190px;object-fit:cover;object-position:center 25%;background:var(--color-portrait);border-radius:var(--r-2)}
.profile-detail h3{font:700 var(--fs-23)/1.2 var(--font-emphasis);margin:4px 0 6px}
.profile-detail p{font-size:var(--fs-13);margin:12px 0;color:var(--color-ink-2)}
.profile-detail .profile-upload{display:inline-flex;align-items:center;min-height:40px;background:var(--color-accent);color:#fff;padding:7px 14px;border-radius:var(--r-2);font-weight:700;font-size:var(--fs-12);cursor:pointer}
.profile-detail input{display:block;max-width:100%;font-size:var(--fs-12);margin:12px 0}
.profile-help{color:var(--color-muted);font-size:var(--fs-12);line-height:1.7}
.profile-error{color:var(--color-bad);font-size:var(--fs-12)}

/* 11. 모드·반응형 */
body.booting .video,body.booting .tactics-board{opacity:.75}
.focus-mode .watch-layout{grid-template-areas:"title title" "video video" "main main"}
.focus-mode :is(.rail,.rail-foot){display:none}
.focus-mode .shell{max-width:1300px}
.focus-mode .canvas-stage{max-height:none}
@media(min-width:1400px){.canvas-stage{height:670px}}
@media(min-width:1600px){.shell{padding-top:var(--sp-7)}.watch-layout{gap:var(--sp-7);grid-template-columns:minmax(0,1fr) 336px}}
@media(max-width:1180px){
  .sitebar{padding:0 var(--sp-6);gap:var(--sp-6)}.shell{padding:var(--sp-5) var(--sp-6)}
  .watch-layout{grid-template-columns:minmax(0,1fr) 260px;gap:var(--sp-4)}
  .phase-strap{right:130px}.phase-strap span{font-size:var(--fs-16)}
  .match-title h1{font-size:var(--fs-28)}
}
@media(max-width:900px){
  .watch-layout,.focus-mode .watch-layout{grid-template-columns:minmax(0,1fr);grid-template-areas:"title" "video" "rail" "main" "foot";row-gap:0}
  .rail{margin-top:var(--sp-4)}
  .rail-box{position:static}
  .rail-box>#crowdPanel .crowd-feed{flex:none;height:260px}
  .phase-strap{right:150px}
  .controls{flex-wrap:nowrap;overflow:auto;scrollbar-width:none}
  .controls button{white-space:nowrap}
}
@media(max-width:600px){
  .official-panel{top:88px;width:calc(100% - 20px)}
  .official-word{font-size:18px}
  .rules-go{min-width:100px;font-size:22px;padding:6px 20px 4px}
  .sitebar{height:60px;padding:0 var(--sp-4);gap:var(--sp-4)}.brand{font-size:var(--fs-19)}.brand em{font-size:var(--fs-23)}
  .site-nav{gap:var(--sp-3)}.site-nav :is(button,a){font-size:var(--fs-12)}.demo-pill,.site-right .avatar{display:none}
  .shell{padding:var(--sp-4) var(--sp-3) var(--sp-5)}
  .match-title{flex-direction:column;align-items:stretch;gap:var(--sp-2)}.match-title h1{font-size:var(--fs-28)}
  .attempt-summary{align-items:flex-start}
  .video{border-radius:var(--r-3)}
  .canvas-stage{height:var(--stage-frame-height);min-height:var(--stage-frame-height);max-height:var(--stage-frame-height);padding-top:320px;background:var(--color-stage)}
  .canvas-stage>canvas{height:320px;bottom:auto}
  .broadcast-top{inset:10px 10px auto}
  .bug-main{height:36px;clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 100%,0 100%)}.bug-team{min-width:0;gap:5px;padding:0 7px 0 18px}.bug-team.away{padding:0 18px 0 7px}.bug-team:before{left:4px;width:5px}.bug-team.away:before{right:4px}.bug-crest{width:18px;height:18px}.bug-code{font-size:15px}.bug-ball{width:6px;height:6px}.bug-scores{padding:0 6px}.bug-score{min-width:18px;font-size:21px}.bug-sep{font-size:14px}
  .channel{display:none}
  .phase-strap{top:92px;right:12px}.phase-strap span{font-size:var(--fs-13)}.phase-strap small{display:none}
  .field-overlay{top:92px;left:10px;right:auto}.lower-third strong{font-size:var(--fs-10);padding:3px 8px}.tactical-chip{display:none}
  .script-lane{left:10px;margin:0}.script-lane.side-right{left:auto;right:10px}
  .script-item{padding:7px 10px 8px}.script-item p{font-size:13px;line-height:1.5}
  /* The phone lane is 150px: a card's text is capped so the card (name plate included) always fits;
     longer text scrolls inside it and fades at the bottom. */
  .script-item.logline{--logline-head:34px}.logline-tag{padding:6px 12px}.script-item.logline p{padding:9px 12px 10px;font-size:13px;line-height:1.5}
  .script-item p,.script-item.speech p{max-height:100px;overflow:hidden}
  .script-item p.is-clipped{overflow-y:auto;pointer-events:auto;overscroll-behavior:contain;mask-image:linear-gradient(180deg,#000 80%,transparent)}
  .storycast{inset:auto;margin:0 10px 12px;position:relative}
  .caption-copy{padding:6px 10px 6px 12px}.caption-heading{flex-wrap:wrap;min-height:0}.caption-heading h2{font-size:var(--fs-12)}
  .focus-player{margin-left:auto;height:26px}.focus-player .portrait{width:26px;height:26px}
  .story-log{font-size:var(--fs-12)}
  .canvas-stage.log-expanded .storycast{position:absolute;inset:var(--log-expanded-top) 10px 12px;margin:0;height:auto;min-height:0;max-height:none;z-index:var(--z-log)}
  .canvas-stage.log-expanded .story-log{font-size:var(--fs-14)}
  .canvas-stage.log-expanded .match-call{left:10px;right:10px;bottom:12px!important}
  .canvas-stage.log-expanded.judgment-waiting .storycast{bottom:calc(var(--expanded-call-height,0px) + 24px)}
  .match-call{top:246px;bottom:auto!important}.match-panel{width:calc(100% - 20px);padding:7px 8px 7px 10px;gap:0 10px}.match-call-note{display:none}.judge-actions{gap:6px}
  .kickoff-gate{padding:8px}.gate-card{gap:12px;padding-bottom:14px}.gate-match{grid-template-columns:1fr;gap:8px;padding:0 12px}.gate-side,.gate-side.side-1{justify-items:start;text-align:left;padding:10px 12px}.gate-side.side-1 .gate-who{justify-content:flex-start}.gate-roster li{padding:6px 0;gap:2px}.gate-bio{-webkit-line-clamp:1}.gate-side{gap:8px}.gate-world{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.go-btn{font-size:26px;padding:7px 24px 5px;min-width:116px}.gate-side.side-1 .gate-id{flex-direction:row}.gate-crest{width:40px;height:40px}span.gate-crest{font-size:20px}.gate-name{font-size:17px}.gate-world{font-size:var(--fs-13)}.gate-roster b{font-size:var(--fs-14)}.gate-roster i{font-size:var(--fs-11)}
  .shot-cue{top:84px;padding:0 12px}.shot-cue blockquote{font-size:19px;padding:6px 16px 7px}.shot-cue.is-long blockquote{font-size:16px}.shot-cue.is-longer blockquote{font-size:14px}
  .match-call h2{font-size:24px}.judge-actions button{font-size:var(--fs-14);min-height:44px;padding:8px 6px}
  .stage-notice{font-size:var(--fs-10);max-width:calc(100% - 20px);width:max-content;border-radius:14px}
  .result-overlay b{font-size:var(--fs-40)}
  .start-grid{grid-template-columns:1fr}.start-panel{padding:16px}.start-panel h2{font-size:var(--fs-34)}
  .transport{padding:0 10px 8px}.controls button{font-size:var(--fs-11);padding:5px 7px}
  .tactics-teams{grid-template-columns:1fr}
  .profile-detail{grid-template-columns:1fr}.profile-detail img{width:120px;height:150px}
  dialog{padding:16px}
}
@media(prefers-reduced-motion:reduce){
  .cast-window span{animation:none;padding-left:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:top}
  .progress i b,.script-item.is-latest,.script-item.logline.is-latest,.script-item.logline.is-latest .logline-tag b,.script-item.logline.is-latest p,.script-item.speech.is-latest,.official-panel,.match-panel,.shot-cue,.shot-cue blockquote,.chat-item,.chat-item.is-hype,.cast-crawl.is-shout,.cast-crawl.is-shout b,.cast-crawl b i,.floating-reaction,.stage-notice,.stage-notice .notice-dot:before,.stage-notice .notice-dot:after,.next-cue,.script-lane.is-waiting .script-item.is-latest .next-cue,.gate-card,.go-btn:after,.kickoff-gate.is-ready .go-btn,.official-panel.is-go .official-go,.official-panel.is-go .rules-go{animation:none}
  .official-panel.is-regroup{animation:official-late 0s .6s both}
  .result-overlay.is-result,.result-overlay.is-result b,.result-overlay.is-result span,.result-overlay.is-result span:after,.result-overlay.is-result:after,.canvas-stage>canvas,.bug-score.is-bump{animation:none}
  .canvas-stage.log-expanded .storycast,.rail-box,button{transition:none}
  .ticker-track{animation:none}
}

/* 모바일 중계 정리(제리): 머리 경로·경기 설명 줄을 접고, 시즌 띠·보기 설정은 한 줄로, 로그 머리와 아래 링크는
   글자가 안 꺾이게 줄인다. 무대 높이를 경기와 로그에 더 쓴다. */
@media(max-width:600px){
  .breadcrumb{display:none}
  .shell .season-strip{flex-direction:row;align-items:center;gap:var(--sp-2);padding:8px 10px;margin-bottom:var(--sp-3)}
  .shell .season-strip div{display:flex;align-items:baseline;gap:6px;min-width:0;white-space:nowrap;overflow:hidden}
  .shell .season-strip b{font-size:var(--fs-13);overflow:hidden;text-overflow:ellipsis}.shell .season-strip span{font-size:var(--fs-11);overflow:hidden;text-overflow:ellipsis}
  .shell .season-strip button{min-height:32px;padding:0 10px;font-size:var(--fs-12)}
  .match-title{padding:0 0 var(--sp-2)}.category{margin-bottom:4px}.match-title h1{font-size:var(--fs-23)}.match-title h1 span{font-size:var(--fs-13);margin:0 4px}
  .match-meta{display:none}
  .caption-heading{flex-wrap:nowrap;gap:6px}.caption-heading h2{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
  .story-air{flex:none;font-size:var(--fs-10);padding:2px 5px 1px}
  .controls{flex-wrap:wrap;overflow:visible;row-gap:8px}
  .view-settings{margin-left:0;width:100%;padding-top:8px;border-top:1px solid #ffffff14}
  .view-settings .setting-row.toggles{flex:1}.controls .setting-row.toggles button{flex:1;justify-content:center}
}
