/* JYB web runtime layer. Loaded after the shared design files and owns the live
   site's composition: one shell, two content widths, one head pattern per page.
   Colours are App tokens from brand.css; the few extra values name their App
   token. Every surface wears the colour the App gives the same element, the App's
   two blues included (vizAway, clubNavy): App parity, R19-F (owner 2026-10-03). */
:root{
 --live:#a6433d;--live-soft:#a6433d14;                      /* JybTokens.live */
 --surface-2:#eaf0f7;                                        /* JybTokens.surface2 · table heads */
 --black-card:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='15.9%25' y1='13.45%25' x2='84.1%25' y2='86.55%25'%3E%3Cstop offset='0' stop-color='%23082040'/%3E%3Cstop offset='0.68' stop-color='%230a2b57'/%3E%3Cstop offset='1' stop-color='%23093671'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* JybTokens.ppHeroGradient, drawn with Flutter's Alignment geometry (see --pill-face) */
 --black-button:var(--btn-face);                            /* JybTokens.btnGradient */
 --on-dark:#ffffff;--on-dark-muted:#cfc8b8;--on-dark-line:#d8c18c33; /* on-dark = JybTokens.accentInk (titles on dark heroes) */
 --wide:1096px;--narrow:880px;--page-gutter:24px;
}

/* 0 · Base */
/* Shell and scores tokens. Each value is the App token it names. */
:root{
 --hair:#16171a21;                 /* JybTokens.hair rgba(22,23,26,.13) · header bands */
 --row-line:#d9e2ef;               /* JybTokens.border · MatchRow.divider, rails */
 --act-line:#0a2b5794;             /* JybTokens.actLine rgba(182,149,85,.58) */
 --state-ring:#0a2b5773;           /* JybTokens.actLine.withValues(alpha:.45) · JybStateView disc (withValues sets the alpha, it does not multiply) */
 --btn-line:#82858a;               /* JybTokens.btnLine · idle chip frame */
 --faint:#656666;                  /* JybTokens.faint (iconFaint) */
 --ink-soft:#3e3e3e;               /* JybTokens.inkSoft */
 --light-gold:#e8d7ac;             /* JybTokens.lightGold (pillFg, btnFg) */
 --soft-clear:#e4ecf600;           /* JybTokens.actSoft @ 0 · gradient end */
 /* JybTokens.pillGradient (= btnGradient). Every App gradient token is an SVG userSpaceOnUse background:
    Flutter places begin / end at Alignment points of the box in pixels, so the gradient follows the
    box's shape (corner to corner on a wide pill); a CSS angle cannot (R19-F tools/gradcheck.mjs). */
 --pill-face:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='39.6%25' y1='1.1%25' x2='60.4%25' y2='98.9%25'%3E%3Cstop offset='0' stop-color='%23123e70'/%3E%3Cstop offset='0.62' stop-color='%230a2b57'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat;
 --sh-1:0px 1px 2px #0000000a;       /* JybTokens.sh1 (pillShadow) */
 --press:#e4ecf673;                /* JybTokens.pressHighlight (actSoft @ .45) */
 --live-text:#8e342f;              /* JybTokens.liveText */
 --live-pill:#a6433d17;            /* JybTokens.live @ MatchRow.livePillFillAlpha .09 */
 --abnormal-pill:#a6433d1a;        /* JybTokens.live @ .10 · MatchRow abnormal pill */
 --lg-t1:#6d5524;                  /* JybTokens.lgT1 · top-flight league name */
 --lg-t2:#205e56;                  /* JybTokens.lgT2 (upText) · second-tier league name */
 --lg-t9:#6f6455;                  /* JybTokens.lgT9 · unlisted league name */
 --tabbar-fill:#ffffffd1;          /* JybTokens.surface @ JybTabBar.fillAlpha .82 */
 --tabbar-line:#d9e2ef9e;          /* JybTokens.border @ JybTabBar.borderAlpha .62 */
 --tabbar-shadow:0px 6px 16px -8px #00000033; /* JybTokens.tabBarShadow */
 --band-top:48px;                  /* where the sticky scores tabs start (under the tool row) */
}
[hidden]{display:none!important}
:focus-visible{outline:3px solid var(--gold-ink);outline-offset:3px}
[data-route-focus]:focus{outline:none}
body{font-family:"PingFang SC","Microsoft YaHei UI","Microsoft YaHei","Noto Sans CJK SC",Arial,sans-serif}
input[type=checkbox]{accent-color:var(--gold-ink)}
.match,.news-row,.schedule-versus{text-decoration:none;color:inherit}
.error{color:var(--live)}
#freshness{margin:0;padding:8px 16px;font-size:12px;color:var(--muted)}
/* JybStateView: 15/600 title, 12 faint message, the ① compact primary pill as its action */
.blank{padding:40px 32px;text-align:center;color:var(--faint);font-size:12px;line-height:17px}
.blank strong{display:block;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
.blank p{margin:8px 0 0;font-size:12px;line-height:17px;color:var(--faint)}
.blank button,.page-error button{display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;margin-top:16px;padding:0 16px;border:0;border-radius:999px;background:var(--pill-face);color:var(--pill-fg);font-size:13px;font-weight:600;letter-spacing:.04em;box-shadow:none}
.blank button:hover,.page-error button:hover{color:var(--card)}
/* 页面不存在 (render.mjs notFoundPage): JybStateView.empty inside the site shell — the 74 disc and its glyph, 15/600 title,
   12 faint line, then the ① compact primary pill (回到数据) and the ③ neutral one (下载 App). App tokens only. */
.nf-state{display:flex;flex-direction:column;align-items:center;padding:48px 32px 56px;text-align:center}
.nf-disc{display:grid;place-items:center;width:74px;height:74px;border:1px solid var(--state-ring);border-radius:50%;background:radial-gradient(circle 50px at 50% 42%,var(--soft),var(--soft-clear));color:var(--gold-ink)}
.nf-disc svg{display:block;width:32px;height:32px}
.nf-state h1{margin:12px 0 0;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
.nf-state p{max-width:280px;margin:8px 0 0;color:var(--faint);font-size:12px;line-height:17px}
.nf-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin-top:16px}
.nf-actions a{display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;padding:0 20px;border-radius:999px;font-size:13px;font-weight:600;letter-spacing:.04em;text-decoration:none}
.nf-home{background:var(--pill-face);box-shadow:var(--btn-glow);color:var(--pill-fg)}
.nf-download{border:1px solid var(--row-line);background:var(--card);color:var(--ink)}
.gold{background:var(--black-button);color:var(--gold);border:0;border-radius:var(--radius-card);font-weight:700}

/* 1 · Shell: the App header skeleton, the App tab item, PC header and page widths */
/* JybHeaderSkeleton: 48 high, 6 side inset, 48 tool slots, the 15/800 title centred on the bar. */
.app-header{grid-template-columns:48px 48px minmax(0,1fr) 48px 48px;align-items:center;height:48px;padding:0 6px;background:var(--card);border-bottom:1px solid var(--hair);color:var(--ink)}
.app-header strong{grid-column:3;grid-row:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;font-size:15px;font-weight:800;line-height:1.2;color:var(--ink)}
.app-header button,.app-header a{display:grid;place-items:center;width:48px;height:48px;min-height:48px;padding:0;border:0;border-radius:50%;background:none;color:var(--muted);box-shadow:none}
.app-header svg{width:24px;height:24px}
.app-header .app-back{grid-column:1;grid-row:1;color:var(--ink)}
.app-header .app-filter{grid-column:1;grid-row:1}
.app-header .app-search{grid-column:2;grid-row:1}
.app-header button:last-child{grid-column:5;grid-row:1}
.app-header button[aria-expanded=true],.app-header button[aria-pressed=true]{color:var(--gold-ink);background:none}
.app-header :is(a,button):active{background:var(--press)}
/* An active league filter: brand-gold funnel plus the App's count badge (pillBg ink, pillFg, 11/600) */
.app-header .app-filter{position:relative}
.app-header .app-filter.filtered{color:var(--gold-ink)}
.app-header .app-filter.filtered:after{content:"1";position:absolute;top:4px;right:4px;box-sizing:border-box;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:var(--ink);color:var(--pill-fg);font-size:11px;font-weight:600;line-height:16px;text-align:center;font-variant-numeric:tabular-nums}
@media(hover:hover){.app-header :is(a,button):hover{background:var(--press)}}
body[data-page=scores] .app-header .app-back{display:none}
/* JybTabBar cell: a ticket-shaped actSoft indicator behind the 24 icon, an 11/600 label under it. */
.nav-icon{position:relative;display:grid;place-items:center;flex:none;width:46px;height:30px;border-radius:0;background:none}
.nav-icon:before{content:"";position:absolute;inset:0;border-radius:9px;background:var(--soft);-webkit-mask:radial-gradient(circle 4px at 0 50%,#0000 98%,#000) left/51% 100% no-repeat,radial-gradient(circle 4px at 100% 50%,#0000 98%,#000) right/51% 100% no-repeat;mask:radial-gradient(circle 4px at 0 50%,#0000 98%,#000) left/51% 100% no-repeat,radial-gradient(circle 4px at 100% 50%,#0000 98%,#000) right/51% 100% no-repeat;opacity:0;transform:scale(.6);transition:opacity .15s,transform .15s}
.nav-icon svg{position:relative;display:block;width:24px;height:24px;transition:transform .15s}
.nav-label{display:block;width:auto;height:12px;font-size:11px;font-weight:600;line-height:12px;white-space:nowrap}
[data-nav].active .nav-icon:before{opacity:1;transform:none}
[data-nav].active .nav-icon svg{transform:scale(1.081)}
@media(prefers-reduced-motion:reduce){.nav-icon:before,.nav-icon svg{transition:none}}
@media(min-width:651px){
 :root{--shell-pad:32px;--head-h:64px}
 .shell{max-width:calc(var(--wide) + 2*var(--shell-pad));padding-inline:var(--shell-pad)}
 /* PC header: the App's surface bar with a hairline; brand left, App tab items right. */
 body>header{position:sticky;top:0;z-index:30;background:var(--card);border-bottom:1px solid var(--hair);color:var(--ink)}
 .head{min-height:var(--head-h);gap:24px}
 .brand{gap:10px;color:var(--ink)}
 .brand .monogram{width:32px;height:32px;border-radius:9px;background:none}
 .brand-name{font-size:17px;font-weight:800;line-height:24px;letter-spacing:0;color:var(--ink)}
 .head nav{gap:4px}
 .head nav a,.head nav a:hover,.head nav a.active,.head nav a.active:hover{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;width:72px;min-width:0;height:50px;padding:0;border-radius:12px;background:none;color:var(--muted);font-size:11px;font-weight:600;line-height:1}
 .head nav a.active,.head nav a.active:hover{color:var(--gold-ink)}
 .head nav a:hover:not(.active){color:var(--ink)}
 .head nav a:hover:not(.active) .nav-icon:before{opacity:1;transform:none;background:var(--press)}
 #news,#match,#team,#schedule,#lottery,#support{max-width:var(--narrow);margin-inline:auto}
 #article{max-width:760px;margin-inline:auto}
 #login{max-width:960px;margin-inline:auto}
 .intro,.data-heading,.section-title,.club-heading{display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0;padding:28px 0 20px;border:0;max-width:none}
 .intro h1,.data-heading h1,.section-title h1,.club-heading h1{margin:0;font-size:22px;font-weight:800;line-height:1.35;letter-spacing:-.02em}
 .intro>a,.section-title>a,.data-heading>span{display:inline-flex;align-items:center;min-height:36px;font-size:13px;font-weight:600;color:var(--gold-ink)}
 .intro>div{display:flex;flex-direction:column;align-items:flex-start;gap:4px}
 .back{display:inline-flex;align-items:center;min-height:32px;margin:0;font-size:13px;color:var(--muted)}
 .back:hover{color:var(--gold-ink)}
 footer{max-width:calc(var(--wide) + 2*var(--shell-pad));padding:24px var(--shell-pad) 32px;border-top:1px solid var(--hair);color:var(--muted)}
}
@media(min-width:651px) and (max-width:1100px){:root{--shell-pad:24px}}

/* 2 · App download edge tab (web only): one piece, handle on top, always flush right */
.app-float.float-c{position:fixed;right:0;top:58%;bottom:auto;transform:translateY(-50%);z-index:35;display:flex;flex-direction:column;align-items:stretch;gap:0;width:46px;margin:0;border:1px solid var(--act-line);border-right:0;border-radius:14px 0 0 14px;background:linear-gradient(155deg,var(--card) 0%,var(--soft) 100%);box-shadow:var(--tabbar-shadow);filter:none;overflow:hidden}
.app-float.float-c>button{display:grid;place-items:center;width:100%;height:44px;min-height:44px;margin:0;padding:0;border:0;border-bottom:1px solid var(--act-line);border-radius:0;background:transparent;color:var(--gold-ink);font-size:17px;line-height:1;box-shadow:none}
.app-float.float-c>button:hover{background:var(--press)}
.app-float.float-c .float-mini{display:none;width:20px;height:20px;border-radius:6px;box-shadow:var(--sh-1)}
.app-float.float-c>a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;width:100%;min-height:90px;padding:10px 4px 12px;border:0;border-radius:0;background:none;color:var(--gold-ink);animation:none;box-shadow:none}
/* member-surfaces.css still gives this tab the pre-10-07 ivory candidate's warm inset rule and a 7 s sheen sweep; neither
   belongs to the App palette (Owner 2026-10-14 brand consistency), so the navy tab draws neither. */
.app-float.float-c>a:after{content:none;animation:none}
.app-float.float-c>a:hover{background:var(--press)}
.app-float.float-c>a .monogram{width:26px;height:26px;margin-bottom:3px;border-radius:8px;border:1px solid var(--act-line);box-shadow:var(--sh-1)}
.app-float.float-c>a strong{font-size:11px;font-weight:600;letter-spacing:.04em;line-height:1.25}
.app-float.float-c>a small{font-size:11px;line-height:1.25;color:var(--gold-ink)}
.app-float.float-c.collapsed{width:45px}
.app-float.float-c.collapsed>button{height:56px;min-height:56px;border:0}
.app-float.float-c.collapsed .float-chevron{display:none}
.app-float.float-c.collapsed .float-mini{display:block}
/* It starts open at every width, also before the script runs; see R19-A at the end. */

/* 3 · Scores: the App's 足球 screen (matches_screen.dart) at every width.
   Band = tool row (the shell .app-header) + underline tabs + date strip (赛程 only)
   + search row, one hairline under the band; flat rows on paper; the 一级/全部 pill. */
/* The App screen has no page heading; the h1 stays for screen readers, the schedule link
   only shows with the league chips. */
#scores>.intro{display:block;margin:0;padding:0;border:0}
#scores>.intro{position:relative}
/* The visually hidden page title stays at the column start (R19: every tab title starts where the brand starts),
   even when the desktop sport switch pushes the intro row to the end. */
#scores>.intro h1{position:absolute;inset-inline-start:0;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
#scores>.intro>a{display:none}
/* Shared football/basketball shell: 44 px hit targets with a compact blue face. */
.score-sport-switch{display:inline-flex;align-items:center;gap:2px;height:44px;padding:0 4px;border-radius:14px;background:var(--surface-2);font-size:13px;line-height:19px}
body[data-page=scores] .app-header strong{grid-column:2/5}
.score-sport-switch a{position:relative;isolation:isolate;display:inline-flex;align-items:center;justify-content:center;width:auto;height:44px;min-width:68px;min-height:44px;padding:0 12px;border:0;border-radius:12px;color:var(--muted);font-weight:600;white-space:nowrap;text-decoration:none;pointer-events:auto}
.score-sport-switch a:before{content:"";position:absolute;inset:5px 0;z-index:-1;border-radius:10px}
.score-sport-switch a[aria-current=page]{color:var(--pill-fg);font-weight:800}
.score-sport-switch a[aria-current=page]:before{background:var(--pill-face);box-shadow:var(--sh-1)}
.score-sport-switch a:focus-visible{outline:2px solid var(--gold-ink);outline-offset:-2px}
.desktop-sport-switch{display:none}
@media(min-width:651px){
 .desktop-sport-switch{display:inline-flex;flex:none}
 /* The old club heading's direct span is a 40px icon slot, not a sport control. */
 .club-heading>.desktop-sport-switch{width:auto;height:auto;border-radius:0;background:none}
 #scores>.intro{display:flex;justify-content:flex-end;padding:12px 0}
}
#scores .layout{display:block}
#scores .scores-panel{min-width:0;margin:0;overflow:visible;border:0;border-radius:0;background:none}
/* JybUnderlineTabs: 48 cells, 15/400 muted → 15/800 ink, an 18×3 act indicator 6 above the edge */
#scores .toolbar{position:sticky;top:var(--band-top);z-index:29;display:flex;gap:0;height:48px;padding:0;border:0;border-bottom:1px solid var(--hair);background:var(--card)}
#scores .toolbar button{position:relative;display:block;flex:1 1 auto;min-width:48px;height:48px;min-height:48px;padding:0 16px;border:0;border-radius:0;background:none;color:var(--muted);font-size:15px;font-weight:400;line-height:22px;box-shadow:none}
#scores .toolbar button.active{color:var(--ink);font-weight:800}
#scores .toolbar button.active:after{content:"";position:absolute;left:calc(50% - 9px);bottom:6px;width:18px;height:3px;border-radius:999px;background:var(--gold-ink)}
@media(hover:hover){#scores .toolbar button:not(.active):hover{color:var(--ink)}}
#scores .scores-panel:has(#fixture-dates:not([hidden])) .toolbar{border-bottom-color:transparent}
/* The date strip: 48 band, 8 inset, 4 gap; the selected day is the black selection face */
#scores .fixture-dates{position:sticky;top:calc(var(--band-top) + 48px);z-index:28;display:flex;gap:4px;height:48px;padding:0 8px;overflow-x:auto;scrollbar-width:none;border:0;border-bottom:1px solid var(--hair);background:var(--card)}
#scores .fixture-dates::-webkit-scrollbar{display:none}
.fixture-day{position:relative;isolation:isolate;display:flex;flex:none;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-width:48px;height:48px;min-height:48px;padding:0 8px;border:0;border-radius:12px;background:none;box-shadow:none}
.fixture-day:before{content:"";position:absolute;inset:6px 0;z-index:-1;border-radius:12px}
.fixture-day>span{font-size:11px;font-weight:600;line-height:11px;color:var(--muted)}
.fixture-day b{font-size:15px;font-weight:800;line-height:15px;color:var(--ink);font-variant-numeric:tabular-nums}
.fixture-day.active:before{background:var(--pill-face);box-shadow:var(--sh-1)}
.fixture-day.active>span,.fixture-day.active b{color:var(--pill-fg)}
@media(hover:hover){.fixture-day:not(.active):hover:before{background:var(--press)}}
/* Search row (JybTextField.search): a surface2 pill, 40 face in a 48 row, glyph at the left.
   Pinned under the band like the App's (owner 2026-10-04 「點放大鏡 畫面會被放大 搜索窗口異常抖動卡住」): its wrapper has
   no box, so the row sticks within the whole panel. R66 restores this after 9f148e8d9 had moved the tier rail into a
   shared band under the tabs (Owner 2026-10-11: 一级／全部 belongs to the App's bottom tools). */
#scores .score-controls{display:contents}
#scores .search-wrap{position:sticky;top:calc(var(--band-top) + 48px);z-index:27;display:none;max-width:none;padding:8px 16px;border-bottom:1px solid var(--hair);background:var(--card)}
#scores .scores-panel:has(#fixture-dates:not([hidden])) .search-wrap{top:calc(var(--band-top) + 96px)}
.mobile-search-open #scores .search-wrap{display:block}
.mobile-search-open #scores .toolbar,.mobile-search-open #scores .fixture-dates{border-bottom-color:transparent}
#scores .search-wrap:before{content:"";position:absolute;left:30px;top:calc(50% - 10px);width:20px;height:20px;background:var(--muted);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M16 16l4.5 4.5'/%3E%3C/svg%3E") center/20px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='M16 16l4.5 4.5'/%3E%3C/svg%3E") center/20px no-repeat;pointer-events:none}
/* 16 px, not the App's 15: iOS Safari zooms the whole page into a field under 16 px as it takes focus (2026-10-04). */
#scores .search{display:block;width:100%;max-width:none;height:40px;min-height:40px;margin:4px 0;padding:0 16px 0 42px;border:1px solid transparent;border-radius:999px;background:var(--surface-2);color:var(--ink);font-size:16px;line-height:22px;-webkit-appearance:none;appearance:none}
#scores .search::placeholder{color:var(--faint)}
#scores .search::-webkit-search-decoration{-webkit-appearance:none;appearance:none}
/* the clear key is the App's close glyph (JybIcons.close) in iconMuted, never the browser's blue */
#scores .search::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;width:20px;height:20px;margin:0 -4px 0 8px;background:var(--muted);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center/20px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center/20px no-repeat;cursor:pointer}
#scores .search:focus{border-color:var(--gold-ink);outline:none;background:var(--surface-2)}
#scores .search:focus-visible{outline:none}
/* League chips under the funnel (JybChip: 32 face in a 48 hit, white + btnLine, selected black) */
#scores .layout>.side{display:none}
.mobile-filter-open #scores .layout>.side{display:flex;flex-wrap:wrap;gap:0 8px;margin:0;padding:4px 16px;border:0;border-bottom:1px solid var(--hair);border-radius:0;background:var(--card)}
#scores .side button{position:relative;isolation:isolate;display:grid;place-items:center;flex:none;width:auto;min-width:48px;height:48px;min-height:48px;margin:0;padding:0 12px;border:0;border-radius:999px;background:none;box-shadow:none;color:var(--ink);font-size:13px;font-weight:600;line-height:19px;text-align:center;white-space:nowrap}
#scores .side button:before{content:"";position:absolute;inset:8px 0;z-index:-1;border:1px solid var(--btn-line);border-radius:999px;background:var(--card)}
#scores .side button.active{color:var(--pill-fg);font-weight:600;box-shadow:none}
#scores .side button.active:before{border-color:transparent;background:var(--pill-face);box-shadow:var(--sh-1)}
@media(hover:hover){#scores .side button:not(.active):hover:before{background:var(--press)}}
.mobile-filter-open #scores>.intro{display:flex;justify-content:flex-end;align-items:center;margin:0;padding:0 16px;border:0;background:var(--card)}
.mobile-filter-open #scores>.intro>a{display:inline-flex;align-items:center;min-height:44px;font-size:13px;font-weight:600;color:var(--gold-ink)}
:root{
 --skel-shine:#fafcff;             /* JybTokens.skelShine (skelBase = surface2) */
 --warn-soft:#efe8da;              /* JybTokens.warnSoft · JybFallbackBanner stale face */
 --warn-text:#7f5514;              /* JybTokens.warnText */
}
/* Stale data: the App's JybFallbackBanner (warnSoft face, hair frame, radius 14, ⚠️, warnText) */
#scores #freshness:not(.sr){display:flex;align-items:flex-start;gap:8px;margin:8px 12px;padding:10px 12px;border:1px solid var(--hair);border-radius:14px;background:var(--warn-soft);color:var(--warn-text);font-size:12.5px;font-weight:400;line-height:1.55}
#scores #freshness:not(.sr):before{content:"⚠️";flex:none;font-size:14px;line-height:19px}
/* Search scope: the App's ScoresSearchNote (actSoft band, actLine frame, radius 12, actDeep 12/600) */
#scores .scores-note{margin:8px 16px;padding:8px 12px;border:1px solid var(--act-line);border-radius:12px;background:var(--soft);color:var(--gold-ink);font-size:12px;font-weight:600;line-height:17px}
/* Loading: five JybSkeletonRow (44 disc, 160/96 lines) on skelBase with the 1.2s skelShine sweep */
#scores .scores-skeleton{display:block;padding:4px 0}
#scores .skel-row{display:flex;align-items:center;gap:12px;padding:12px 15px}
#scores .skel-row>span{display:grid;flex:1;gap:8px;min-width:0}
#scores .skel-dot,#scores .skel-line{display:block;background:linear-gradient(105deg,var(--surface-2) 30%,var(--skel-shine) 50%,var(--surface-2) 70%) 0 0/300% 100%;animation:skel-sweep 1.2s linear infinite}
#scores .skel-dot{flex:none;width:44px;height:44px;border-radius:50%}
#scores .skel-line{width:160px;max-width:100%;height:12px;border-radius:6px}
#scores .skel-line.short{width:96px}
@keyframes skel-sweep{from{background-position:100% 0}to{background-position:0 0}}
@media(prefers-reduced-motion:reduce){#scores .skel-dot,#scores .skel-line{animation:none}}
/* Status band (ScoresSectionHeader): surface2, 8/16/4, 12/600 muted. League bands match it. */
#scores .score-section,#scores .league{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0;padding:8px 16px 4px;border:0;background:var(--surface-2);color:var(--muted);font-size:12px;font-weight:600;line-height:17px;letter-spacing:0}
#scores .league strong{font-weight:600}
#scores .league small{font-size:11px;font-weight:400;color:var(--muted)}
/* MatchRow: 24 league/clock/status band, 44 team band, 15 sub line; one border hairline */
/* R74: the same rules draw the basketball history rows (BasketballMatchRow in 分析); :is() keeps the #scores weight */
:is(#scores,.basket-history-rows) .match{position:relative;display:block;width:100%;min-height:0;margin:0;padding:0;border:0;border-bottom:1px solid var(--row-line);border-radius:0;background:none;color:var(--ink);text-align:left}
:is(#scores,.basket-history-rows) .row-top{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;column-gap:8px;min-height:24px;padding:4px 16px 0}
:is(#scores,.basket-history-rows) .row-league{grid-column:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:600;line-height:16px;color:var(--lg-t9)}
:is(#scores,.basket-history-rows) .row-league.lt0{font-weight:700;color:var(--live)}
:is(#scores,.basket-history-rows) .row-league.lt1{font-weight:700;color:var(--lg-t1)}
:is(#scores,.basket-history-rows) .row-league.lt2{font-weight:700;color:var(--lg-t2)}
:is(#scores,.basket-history-rows) .match .time{grid-column:2;position:static;max-width:none;margin:0;padding:0;background:none;transform:none;font-size:11px;font-weight:600;line-height:16px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:center}
:is(#scores,.basket-history-rows) .match .time.live{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;background:var(--live-pill);color:var(--live-text);font-weight:800}
:is(#scores,.basket-history-rows) .match .time.live:before{content:none;display:none}
:is(#scores,.basket-history-rows) .match .time.live i{flex:none;width:6px;height:6px;border-radius:50%;background:var(--live);animation:row-live 1.2s ease-in-out infinite alternate}
@keyframes row-live{to{opacity:.25}}
@media(prefers-reduced-motion:reduce){:is(#scores,.basket-history-rows) .match .time.live i{animation:none}}
:is(#scores,.basket-history-rows) .row-state,:is(#scores,.basket-history-rows) .row-pill{grid-column:3;justify-self:start;font-size:11px;font-weight:600;line-height:16px;white-space:nowrap}
:is(#scores,.basket-history-rows) .row-state{color:var(--muted)}
:is(#scores,.basket-history-rows) .row-pill{display:inline-flex;align-items:center;min-height:18px;padding:0 8px;border-radius:4px;background:var(--abnormal-pill);color:var(--live-text)}
:is(#scores,.basket-history-rows) .row-main{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 16px}
:is(#scores,.basket-history-rows) .match .teams{display:flex;flex:1;flex-direction:column;justify-content:center;gap:0;min-width:0;padding:0;font-size:13px}
:is(#scores,.basket-history-rows) .team{display:flex;align-items:center;justify-content:flex-start;gap:4px;min-width:0;min-height:22px;text-align:left}
:is(#scores,.basket-history-rows) .team-mark{display:grid;place-items:center;flex:none;width:24px;height:22px}
:is(#scores,.basket-history-rows) .team-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:19px;color:var(--ink)}
.score-team-crest{display:grid;place-items:center;flex:none;width:20px;height:20px}
.score-team-crest img{display:block;width:20px;height:20px;border-radius:50%;object-fit:contain;background:var(--card);box-shadow:0 0 0 1px var(--hair)}
.side-badge{display:inline-grid;place-items:center;flex:none;min-width:18px;height:18px;padding:0 1px;border:1px solid var(--row-line);border-radius:4px;background:var(--surface-2);color:var(--muted);font-size:11px;font-style:normal;font-weight:600;line-height:1}
.side-badge.home{border-color:var(--act-line);background:var(--soft);color:var(--gold-ink)}
:is(#scores,.basket-history-rows) .match .score{display:flex;flex:none;flex-direction:column;align-items:center;justify-content:center;gap:0;min-width:34px;margin:0;font-size:17px;font-weight:800;line-height:1;color:var(--ink);font-variant-numeric:tabular-nums;text-align:center}
:is(#scores,.basket-history-rows) .match .score>span{display:grid;place-items:center;min-height:22px}
:is(#scores,.basket-history-rows) .match .score:before,:is(#scores,.basket-history-rows) .match .score>span:after{content:none;display:none}
:is(#scores,.basket-history-rows) .match .score.live-score{color:var(--live)}
:is(#scores,.basket-history-rows) .match .score.unplayed{font-size:13px;font-weight:600;line-height:19px;color:var(--muted)}
:is(#scores,.basket-history-rows) .row-chevron{display:block;flex:none;width:16px;height:16px;color:var(--faint)}
:is(#scores,.basket-history-rows) .row-sub{display:block;min-height:15px;padding:0 16px 4px;font-size:11px;line-height:11px;color:var(--muted);text-align:center}
:is(#scores,.basket-history-rows) a.match:active{background:var(--press)}
@media(hover:hover){:is(#scores,.basket-history-rows) a.match:hover{background:var(--press)}}
/* Empty state (JybStateView.empty): the 74 disc with the tray glyph, title, note, one action */
#scores .scores-empty{position:relative;padding:32px 32px 40px}
#scores .scores-empty:before{content:"";display:block;width:74px;height:74px;margin:0 auto 12px;border:1px solid var(--state-ring);border-radius:50%;background:radial-gradient(circle at 50% 42%,var(--soft) 0,var(--soft-clear) 68%)}
#scores .scores-empty:after{content:"";position:absolute;top:53px;left:calc(50% - 16px);width:32px;height:32px;background:var(--gold-ink);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13.5l2.4-6.6a1.6 1.6 0 0 1 1.5-1h8.2a1.6 1.6 0 0 1 1.5 1l2.4 6.6'/%3E%3Cpath d='M4 13.5v4.2a1.8 1.8 0 0 0 1.8 1.8h12.4a1.8 1.8 0 0 0 1.8-1.8v-4.2h-4.6l-1.2 2h-3.4l-1.2-2z'/%3E%3C/svg%3E") center/32px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13.5l2.4-6.6a1.6 1.6 0 0 1 1.5-1h8.2a1.6 1.6 0 0 1 1.5 1l2.4 6.6'/%3E%3Cpath d='M4 13.5v4.2a1.8 1.8 0 0 0 1.8 1.8h12.4a1.8 1.8 0 0 0 1.8-1.8v-4.2h-4.6l-1.2 2h-3.4l-1.2-2z'/%3E%3C/svg%3E") center/32px no-repeat;pointer-events:none}
/* ScoresBottomTools (scores_quick_pill.dart). The ScoresQuickPill rail: surface, clubNavyLine edge, 36 high, inset 4;
   28 faces hugging their label (inset 4, the 1px edge inside it) in 48 hits; the selected face solid clubNavy with clubNavyLine, its label
   accentInk, the other inkSoft (chipLabel 13/19/600). PC: the rail keeps the list's foot (sticky; beside the status tabs
   from 901) and the two round tools stay hidden; phones float the whole group over the rows, no band (Owner 2026-10-14; see
   the R66 block at the end). */
#scores .score-dock{display:contents}
#scores .dock-tool{display:none}
#scores .score-tier{position:sticky;bottom:24px;z-index:6;display:flex;align-items:center;width:max-content;height:36px;margin:16px auto 0;padding:0 4px;border:1px solid var(--club-navy-line);border-radius:999px;background:var(--card);box-shadow:none;transform:none}
#scores .score-tier button{display:grid;place-items:center;flex:none;min-width:48px;height:48px;min-height:48px;margin:-6px 0;padding:0;border:0;border-radius:999px;background:none;color:var(--ink-soft);font-size:13px;font-weight:600;line-height:19px;box-shadow:none}
#scores .score-tier button>span{display:grid;place-items:center;box-sizing:border-box;height:28px;padding:0 3px;border:1px solid transparent;border-radius:999px}
#scores .score-tier button.active{color:var(--pill-fg)}
#scores .score-tier button.active>span{background:var(--club-navy);border-color:var(--club-navy-line)}
@media(hover:hover){#scores .score-tier button:not(.active):hover>span{background:var(--press)}}
.mobile-search-open #scores .score-tier,#scores .scores-panel[data-status=favourite] .score-tier{display:none}
#scores .scores-empty .scores-empty-action{display:inline-grid;place-items:center;min-width:96px;min-height:44px;margin-top:16px;padding:0 20px;border-radius:999px;background:var(--club-navy);color:var(--pill-fg);font-size:15px;font-weight:600;text-decoration:none}
@media(min-width:651px){
 /* PC: the same screen in the centred narrow column, its tool row sticky under the site header */
 :root{--band-top:calc(var(--head-h) + 48px)}
 #scores{max-width:var(--narrow);margin-inline:auto}
 body[data-page=scores] .app-header{position:sticky;top:var(--head-h);z-index:29;display:grid;width:min(var(--narrow),calc(100% - 2*var(--shell-pad)));margin:0 auto;border-bottom:0}
 /* The App's header band spans the screen. A border-image outset paints it edge to edge
    (ink overflow only, so no horizontal scroll); its last pixel row is the band hairline. */
 body[data-page=scores] .app-header,#scores .toolbar,#scores .fixture-dates,#scores .search-wrap,.mobile-filter-open #scores .layout>.side,.mobile-filter-open #scores>.intro{background:none;border-image:linear-gradient(var(--card) 0 0) fill 0/0/0 100vmax}
 #scores .toolbar,#scores .fixture-dates,#scores .search-wrap,.mobile-filter-open #scores .layout>.side{border-image-source:linear-gradient(var(--card) calc(100% - 1px),var(--hair) 0)}
 #scores .scores-panel:has(#fixture-dates:not([hidden])) .toolbar,.mobile-search-open #scores .toolbar,.mobile-search-open #scores .fixture-dates{border-image-source:linear-gradient(var(--card) 0 0)}
}


/* 4 · Data: standings, scorers and the team board (App StandingsScreen, StandingsTable, TeamScreen) */
:root{
 --ink-soft:#3e3e3e;                         /* JybTokens.inkSoft · table figures */
 --faint:#656666;                            /* JybTokens.faint · dimmed rows, chevrons */
 --hair:#16171a21;                           /* JybTokens.hair · hero and schedule separators */
 --border-2:#b7c5d8;                         /* JybTokens.border2 · neutral status tag frame */
 --link:#0a2b57;                             /* JybTokens.link · podium digits, text actions */
 --act-line:#0a2b5794;                       /* JybTokens.actLine · podium ring */
 --rail:#e4ecf68c;                           /* JybTokens.rail (act at 55%) · own-team rail */
 --press:#e4ecf673;                          /* JybTokens.pressHighlight (actSoft at 45%) */
 --btn-line:#82858a;                         /* JybTokens.btnLine · idle chip frame */
 --pill-fg:#ffffff;                          /* JybTokens.pillFg · selected chip label */
 --pill-face:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='39.6%25' y1='1.1%25' x2='60.4%25' y2='98.9%25'%3E%3Cstop offset='0' stop-color='%23123e70'/%3E%3Cstop offset='0.62' stop-color='%230a2b57'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* JybTokens.pillGradient */
 --sh-1:0px 1px 2px #0000000a;                 /* JybTokens.sh1 · selected chip lift */
 --up:#2e7468;--up-text:#205e56;             /* JybTokens.up / upText · form W */
 --live-text:#8e342f;                        /* JybTokens.liveText · form L */
 --up-tint:#2e746824;--muted-tint:#53535424;--live-tint:#a6433d24; /* up / muted / live at 14% · form beads */
}
/* Board tabs (JybUnderlineTabs: 48 strip, 15/400 → 15/800, 18×3 indicator 6 above the edge) */
#data .data-modes{display:flex;gap:0;margin:0;padding:0;border-bottom:1px solid var(--line);background:var(--card)}
#data .data-modes button{position:relative;flex:1 1 0;min-width:0;min-height:48px;margin:0;padding:0 8px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400}
#data .data-modes button.active{color:var(--ink);font-weight:800}
#data .data-modes button.active:after{content:"";position:absolute;left:calc(50% - 9px);bottom:6px;width:18px;height:3px;border-radius:3px;background:var(--gold-ink)}
/* League chips (JybChip: face 32, hit 48, 13/600; idle surface + btnLine, selected black face + pillFg) */
#data .data-leagues{display:flex;gap:8px;margin:0;padding:8px 16px;overflow-x:auto;scrollbar-width:none;background:none}
#data .data-leagues::-webkit-scrollbar{display:none}
#data .data-leagues a{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:none;min-height:32px;padding:0 12px;border:1px solid var(--btn-line);border-radius:999px;background:var(--card);box-shadow:none;color:var(--ink);font-size:13px;line-height:19px;font-weight:600;white-space:nowrap;text-decoration:none}
#data .data-leagues a:after{content:"";position:absolute;inset:-8px -4px}
#data .data-leagues a.active{border-color:transparent;background:var(--pill-face);box-shadow:var(--sh-1);color:var(--pill-fg)}
@media(hover:hover){#data .data-leagues a:not(.active):hover{border-color:var(--gold-ink);color:var(--gold-ink)}}
/* Table (StandingsHeadRow / StandingsRow): head 11/600 on surface2, rows ≥48 on surface,
   cells 8/4, row inset 12 plus a 3px rail; figures size to content, the name takes the rest */
.board-panel{min-width:0}
.board-panel .blank p{margin:8px 0 0}
:is(#data,#team) .data-table-wrap{container-type:inline-size;margin:0;padding:0;overflow:visible;border:0;border-radius:0;background:none}
:is(#data,#team) .standings-table{width:100%;min-width:0;margin:0;border-collapse:separate;border-spacing:0;table-layout:auto;color:var(--ink-soft);font-size:13px;line-height:19px;white-space:normal;font-variant-numeric:tabular-nums}
:is(#data,#team) .standings-table :is(th,td){position:static;z-index:auto;width:1%;min-width:0;padding:8px 4px;border:0;border-bottom:1px solid var(--line);background:var(--card);font-weight:400;text-align:center;vertical-align:middle;white-space:nowrap}
:is(#data,#team) .standings-table thead th{background:var(--surface-2);color:var(--muted);font-size:11px;line-height:16px;font-weight:600}
:is(#data,#team) .standings-table tr>:first-child{padding-left:16px;border-left:3px solid transparent}
:is(#data,#team) .standings-table tr>:last-child{padding-right:16px}
:is(#data,#team) .standings-table tbody tr{height:48px;background:none}
:is(#data,#team) .standings-table :is(.col-team,.col-player,.col-club){width:auto;text-align:left;white-space:normal}
:is(#data,#team) .standings-table tbody :is(.col-points,.col-goals){color:var(--ink);font-weight:600}
:is(#data,#team) .standings-table .standing-current>:first-child{border-left-color:var(--rail)}
:is(#data,#team) .standing-current .standing-name{font-weight:600}
:is(#data,#team) .native-standings tbody tr:has(.standing-name a){cursor:pointer}
@media(hover:hover){:is(#data,#team) .native-standings tbody tr:has(.standing-name a):hover>*{background:linear-gradient(var(--press),var(--press)),var(--card)}}
/* Rank (StandingsRankCell): 13/600 accentDeep; the top three sit in a 20 actSoft ring, 11/800 link */
.rank-mark{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;color:var(--green);font-size:13px;line-height:19px;font-weight:600;font-variant-numeric:tabular-nums}
.rank-mark.podium{width:20px;border:1px solid var(--act-line);border-radius:50%;background:var(--soft);color:var(--link);font-size:11px;line-height:1;font-weight:800;box-sizing:border-box}
/* Name (StandingsNameCell): 20 crest on a surface disc, gap 8, 13/400 ink, two lines then ellipsis */
.standing-team{display:flex;align-items:center;gap:8px;min-width:0}
.standing-team>img{flex:none;width:20px;height:20px;border-radius:50%;background:var(--card);object-fit:contain}
.standing-label{display:flex;flex-wrap:wrap;align-items:center;gap:2px 6px;min-width:0}
.standing-name{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-width:0;color:var(--ink);overflow-wrap:anywhere}
.standing-name a{display:inline;min-height:0;color:inherit;font-weight:inherit;text-decoration:none}
@media(hover:hover){.standing-name a:hover{color:var(--gold-ink)}}
.standing-deduct{flex:none;padding:0 6px;border-radius:4px;background:var(--soft);color:var(--gold-ink);font-size:11px;line-height:16px;font-weight:600;white-space:nowrap}
/* Form (StandingsFormCell): five 14 beads, gap 2; frame = tone, fill = tone at 14%, letter = text tone */
.form-beads{display:inline-flex;align-items:center;gap:2px;vertical-align:middle}
.form-beads i{display:grid;place-items:center;flex:none;width:14px;height:14px;border:1px solid;border-radius:50%;font-size:8px;line-height:1;font-style:normal;font-weight:800;box-sizing:border-box}
.form-beads .form-w{border-color:var(--up);background:var(--up-tint);color:var(--up-text)}
.form-beads .form-d{border-color:var(--muted);background:var(--muted-tint);color:var(--muted)}
.form-beads .form-l{border-color:var(--live);background:var(--live-tint);color:var(--live-text)}
/* Notes (StandingsFootnotes): the server's note per team, 12/400 muted on paper */
.standings-notes{margin:0;padding:12px 16px;color:var(--muted);font-size:12px;line-height:17px}
.standings-notes p{margin:0}.standings-notes p+p{margin-top:4px}
/* Scorers: the same table language (former App _ScorersList); club 16 crest, 11/400 muted */
:is(#data,#team) .scorers-table caption{caption-side:top;padding:4px 16px 12px;background:none;color:var(--muted);font-size:12px;line-height:17px;font-weight:600;text-align:left}
.scorer-club{display:flex;align-items:center;gap:8px;min-width:0;color:var(--muted);font-size:11px;line-height:16px}
.scorer-club>img{flex:none;width:16px;height:16px;border-radius:50%;background:var(--card);object-fit:contain}
.scorer-club>span{min-width:0;overflow-wrap:anywhere}
/* The App's yield ladder (StandingsColumnLayout): form first, then the crest, then 平 负 胜 净 赛; 分 stays */
@container(min-width:347px) and (max-width:370px){.native-standings.has-form .standing-team>img{display:none}}
@container(max-width:346px){.native-standings .col-form{display:none}}
@container(max-width:284px){.native-standings .standing-team>img{display:none}}
@container(max-width:261px){.native-standings .col-draw{display:none}}
@container(max-width:238px){.native-standings .col-lose{display:none}}
@container(max-width:215px){.native-standings .col-win{display:none}}
@container(max-width:184px){.native-standings .col-gd{display:none}}
@container(max-width:161px){.native-standings .col-played{display:none}}
/* Team (TeamScreen): surface hero band, 48 crest on a paper disc, 17/600 name; compact section head */
#team .team-summary{max-width:none;margin:0;padding:0}
#team .team-identity{display:flex;align-items:center;gap:12px;margin:0;padding:12px 16px;border-bottom:1px solid var(--hair);background:var(--card)}
.team-hero-crest{display:block;flex:none;width:48px;height:48px;overflow:hidden;border-radius:50%;background:var(--paper)}
.team-hero-crest>img{display:block;width:100%;height:100%;object-fit:contain}
#team .team-identity h1{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;min-width:0;margin:0;color:var(--ink);font-size:17px;line-height:24px;font-weight:600;letter-spacing:0;overflow-wrap:anywhere}
#team .team-league-board h2{margin:0;padding:16px 16px 12px;color:var(--muted);font-size:12px;line-height:17px;font-weight:600}
@media(max-width:650px){
 #data,#team{padding:0}
 #data .data-heading{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
 #team .team-summary>.back{display:none}
 :is(#data,#team) .standings-table thead th{position:sticky;top:48px;z-index:2}
}
@media(min-width:651px){
 #data{max-width:var(--narrow);margin-inline:auto}
 #data .data-modes{justify-content:flex-start;gap:8px;background:none}
 #data .data-modes button{flex:0 0 auto;min-width:88px;padding:0 16px}
 #data .data-leagues{padding:16px 0 20px}
 :is(#data,#team) .data-table-wrap{overflow:hidden;border:1px solid var(--line);border-radius:14px;background:var(--card)}
 :is(#data,#team) .standings-table tbody tr:last-child>*{border-bottom:0}
 :is(#data,#team) .scorers-table caption{padding:12px 16px;border-bottom:1px solid var(--line);background:var(--card)}
 :is(#data,#team) .native-standings :is(.col-played,.col-win,.col-draw,.col-lose,.col-gd,.col-points){width:52px}
 :is(#data,#team) .scorers-table :is(.col-goals,.col-assists){width:64px}
 :is(#data,#team) .standings-notes{padding:12px 0}
 #team .team-summary{padding-top:20px}
 #team .team-summary>.back{margin:0 0 12px}
 #team .team-identity{padding:16px 20px;border:1px solid var(--line);border-radius:14px}
 #team .team-league-board h2{padding:24px 0 12px}
}

/* 5 · News and article — App TeamNewsSection and NewsArticleScreen (tokens in §8) */
#news .news-tabs{display:flex;gap:24px;margin:0;padding:0;overflow-x:auto;scrollbar-width:none;white-space:nowrap;border-bottom:1px solid var(--hair)}
#news .news-tabs::-webkit-scrollbar{display:none}
#news .news-tabs button{position:relative;flex:none;min-width:0;min-height:48px;margin:0;padding:0 2px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400}
#news .news-tabs button.active{color:var(--ink);font-weight:800}
#news .news-tabs button.active:after{content:"";position:absolute;left:calc(50% - 10px);bottom:0;width:20px;height:3px;border-radius:3px;background:var(--gold-ink)}
#news .news-card{margin:16px 0 0;padding:5px 16px;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#news .news-feed{max-width:none;margin:0}
#news .news-row{display:grid;grid-template-columns:minmax(0,1fr) 92px;grid-template-areas:"text pic";column-gap:12px;row-gap:12px;align-items:start;width:100%;padding:8px 0;border:0;border-radius:0;background:none;color:inherit;text-align:left;text-decoration:none}
#news .news-row:not([hidden])~.news-row:not([hidden]){border-top:1px solid var(--hair)}
#news .news-row.is-text{grid-template-columns:minmax(0,1fr);grid-template-areas:"text"}
#news .news-row.is-lead{grid-template-columns:minmax(0,1fr);grid-template-areas:"pic" "text"}
#news .news-thumb{grid-area:pic;position:relative;display:block;width:100%;min-width:0;min-height:0;aspect-ratio:4/3;margin:0;padding:0;overflow:hidden;border-radius:12px;background:var(--paper);color:var(--muted)}
#news .news-thumb img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:contain}
#news .news-thumb i{position:absolute;inset:0;display:none;place-items:center;font-style:normal}
#news .news-thumb.img-failed i{display:grid}
#news .news-thumb svg{width:24px;height:24px}
#news .news-text{grid-area:text;display:flex;flex-direction:column;gap:8px;min-width:0}
#news .news-text strong{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:15px;line-height:22px;font-weight:600;color:var(--ink)}
#news .news-row.is-lead .news-text strong{font-size:17px;line-height:24px}
#news .news-text small{font-size:12px;line-height:17px;color:var(--muted);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
@media(hover:hover){#news .news-row:hover .news-text strong{color:var(--gold-ink)}}
#news .news-status{margin:0;padding:12px 0;font-size:12px;line-height:17px;color:var(--muted)}
#news .news-feed>.blank{padding:32px 8px}
#article .news-article{max-width:none;margin:0;padding:0}
#article .news-article h1{margin:0;font-size:23px;line-height:1.5;font-weight:800;letter-spacing:0;color:var(--ink);overflow-wrap:anywhere}
#article .art-meta{display:flex;flex-wrap:wrap;gap:4px 16px;margin:12px 0 22px;font-size:12px;line-height:17px;color:var(--muted)}
#article .art-meta>span{min-width:0;overflow-wrap:anywhere}
#article .art-cover,#article #article-body img{display:block;width:100%;max-width:100%;height:auto;margin:0 0 18px;border-radius:10px;background:var(--paper)}
#article #article-body p{max-width:none;margin:0 0 18px;font-size:16px;line-height:1.85;color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere}
@media(min-width:651px){
 #news .news-card{margin-top:20px;padding:5px 20px}
 #news .news-row{grid-template-columns:minmax(0,1fr) 128px;column-gap:20px;padding:14px 0}
 #news .news-row.is-lead{grid-template-columns:minmax(0,5fr) minmax(0,6fr);grid-template-areas:"pic text";column-gap:24px;align-items:center;padding:16px 0}
 #news .news-row.is-lead .news-text strong{font-size:20px;line-height:27px;font-weight:800;-webkit-line-clamp:3}
 #article .news-article{padding-top:20px}
 #article .news-article>.back{margin:0 0 12px}
}
@media(max-width:650px){
 #news{padding:0 0 24px}
 #news .news-tabs{padding:0 var(--page-gutter);background:var(--card)}
 #news .news-card{margin:12px var(--page-gutter) 0}
 #article .news-article{padding:20px 20px 40px}
 #article .news-article>.back{display:none}
}

/* 6 · Match detail: the App MatchDetailScreen (apps/mobile/lib/features/matches).
   One dark theatre header for every match state (owner 2026-09-22), the App's
   underline tabs, then 赛况 / 阵容 in the DetailStyle language: numbered section
   heads, rings and tug rows, a hairline timeline, flat team cards. Each value
   names its App token. Both sports retain the App semantic home bronze / away
   blue axes; brand chrome remains separate. Team names and values identify sides. */
:root{
 --md-theatre-0:#082040;--md-theatre-1:#0a2b57;--md-theatre-2:#093671; /* JybTokens.matchTheatreGradient stops 0 / .62 / 1 */
 --md-theatre-ink:#ffffff;            /* JybTokens.matchTheatreInk (= accentInk) */
 --md-theatre-muted:#c3ccd3;       /* JybTokens.matchTheatreMuted (= silver) */
 --md-theatre-accent:#ffffff;      /* JybTokens.matchTheatreAccent (= jybGoldSoft) */
 --md-theatre-rule:#ffffff38;      /* JybTokens.matchTheatreRule (= matchAnimGlassLine) */
 --md-crest-face:#ffffffd9;        /* JybTokens.crestFace */
 --md-crest-ring:#ffffff40;        /* JybTokens.crestInnerRing */
 --md-hair:#16171a21;              /* JybTokens.hair */
 --md-border:#d9e2ef;              /* JybTokens.border */
 --md-border-2:#b7c5d8;            /* JybTokens.border2 */
 --md-ink-soft:#3e3e3e;            /* JybTokens.inkSoft */
 --md-faint:#656666;               /* JybTokens.faint */
 --md-link:#0a2b57;                /* JybTokens.link (text actions) */
 --md-act-line:#0a2b5794;          /* JybTokens.actLine */
 --md-act-line-soft:#0a2b5773;     /* JybTokens.actLine.withValues(alpha:.45) (empty-state ring) */
 --md-act-soft-0:#e4ecf600;        /* JybTokens.actSoft at zero alpha (halo fade) */
 --viz-home:#9e7a3c;              /* JybTokens.vizHome: semantic team axis, not brand chrome */
 --viz-away:#4a87a5;              /* JybTokens.vizAway: paired and tested in the App */
 --md-viz-home:var(--viz-home);
 --md-viz-away:var(--viz-away);
 --sharks-orange:#f47b35;          /* JybTokens.sharksOrange: the basketball home (上海久事大鲨鱼) style */
 --sharks-orange-ink:#8b390c;      /* JybTokens.sharksOrangeInk */
 --sharks-orange-soft:#fff0e6;     /* JybTokens.sharksOrangeSoft */
 --md-warn:#c9922f;                /* JybTokens.warn (yellow card) */
 --md-warn-text:#7f5514;           /* JybTokens.warnText */
 --md-danger:#b84f50;              /* JybTokens.danger (iconDanger) */
 --md-up:#2e7468;                  /* JybTokens.up (substitution) */
 --md-skel-shine:#fafcff;          /* JybTokens.skelShine */
 --md-btn-0:#123e70;--md-btn-1:#0a2b57; /* JybTokens.btnGradient */
 --md-btn-ink:#ffffff;             /* JybTokens.btnFg (= lightGold) */
 --md-btn-shadow:#0a2b5724;        /* JybTokens.btnShadow (archiveGold 14%) */
 --md-pitch-grass:#2c6339;         /* JybTokens.pitchGrass */
 --md-pitch-stripe:#336c40;        /* JybTokens.pitchGrassStripe */
 --md-pitch-line:#ffffff4d;        /* JybTokens.pitchLine */
 --md-pitch-home-ink:#e8d8b0;      /* JybTokens.pitchHomeInk */
 --md-pitch-away-ink:#d6dce1;      /* JybTokens.pitchAwayInk */
}
.md-page{--md-gutter:var(--page-gutter,16px);position:relative}
.md-basket-periods{padding:20px var(--md-gutter)}
.basket-insight{padding:16px;margin:12px 0;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card);min-width:0}
.basket-insight :is(h3,h4){color:var(--ink);font-size:13px;line-height:19px;font-weight:600;margin:12px 0}
.basket-trend{display:block;width:100%;height:auto;max-height:180px}
.basket-chart-grid{fill:none;stroke:var(--hair);stroke-width:1}
.basket-trend-line{fill:none;stroke:var(--club-navy);stroke-width:2}
.basket-trend-labels{display:flex;font-size:11px;color:var(--muted)}
.basket-trend-labels span{flex:1;text-align:center;min-width:0}
/* A1 (Owner 2026-10-13 「分析TAB…一目了然」, the App's BasketballInsightTiles / ZoneBars / FormSummary): three tiles on top, the biggest
   lead marked on the trend, paint / mid-range / three bars for both teams, W/L beads (the standings .form-beads) and the next games. */
.basket-tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}
.basket-tile{display:grid;justify-items:center;gap:4px;padding:12px 4px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card);min-width:0;text-align:center}
.basket-tile small{max-width:100%;overflow:hidden;color:var(--muted);font-size:11px;line-height:16px;text-overflow:ellipsis;white-space:nowrap}
.basket-tile b{font-size:20px;line-height:27px;font-weight:700;font-variant-numeric:tabular-nums}
.basket-tile b.is-home,.basket-zone-n b.is-home{color:var(--md-viz-home)}
.basket-tile b.is-away,.basket-zone-n b.is-away{color:var(--md-viz-away)}
.basket-trend-max{fill:var(--md-viz-home)}
.basket-trend-maxnote{margin:0 0 8px;color:var(--md-viz-home);font-size:13px;line-height:19px;font-weight:600;text-align:center}
.basket-zone{display:grid;grid-template-columns:56px minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 0;font-size:13px;line-height:19px}
.basket-zone-bars{display:grid;gap:4px}
.basket-zone-bar{display:block;height:8px;border-radius:999px;background:var(--surface-2);overflow:hidden}
.basket-zone-bar>i{display:block;height:100%;border-radius:inherit}
.basket-zone-bar.is-home>i{background:var(--md-viz-home)}
.basket-zone-bar.is-away>i{background:var(--md-viz-away)}
.basket-zone-n{display:grid;justify-items:end;font-size:11px;line-height:16px;font-variant-numeric:tabular-nums}
.basket-form-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:4px 0;font-size:13px;line-height:19px}
.basket-form-row small{color:var(--muted)}
/* D2 打磨版 (the App's _verdict / DetailRatePair / DetailButterflyRow / _topThree): the verdict card, ring-pair cards in a 2 × 2 grid,
   butterfly rows (numbers by the centre label, bars outward, the trailing side at 35%), the top three per side and the folded table. */
.md-basket-verdict{margin:12px var(--md-gutter) 0;padding:12px;border-radius:var(--radius-card);background:var(--card);border-left:4px solid var(--md-viz-home)}
.md-basket-verdict.is-away{border-left-color:var(--md-viz-away)}
.md-basket-verdict p{margin:0;font-size:13px;line-height:19px}
.md-basket-verdict p.is-lead{color:var(--ink);font-weight:600}
.md-basket-verdict p.is-home{color:var(--md-viz-home)}
.md-basket-verdict p.is-away{color:var(--md-viz-away)}
.md-rate-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0 var(--md-gutter)}
.md-rate-card{padding:12px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card);min-width:0}
.md-rate-card header{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;line-height:19px}
.md-rate-card header small{font-size:11px;line-height:16px;font-weight:800}
.md-rate-card header small.is-home,.md-rate-side.is-home.is-lead b{color:var(--md-viz-home)}
.md-rate-card header small.is-away,.md-rate-side.is-away.is-lead b{color:var(--md-viz-away)}
.md-rate-card>div{display:grid;grid-template-columns:1fr 1fr;margin-top:8px}
.md-rate-side{position:relative;display:grid;justify-items:center;gap:4px;min-width:0}
.md-rate-side svg{width:56px;height:56px}
.md-rate-side b{position:absolute;top:18px;font-size:13px;line-height:19px;font-weight:500;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.md-rate-side.is-lead b{font-weight:700}
.md-rate-side small{color:var(--muted);font-size:11px;line-height:16px;font-variant-numeric:tabular-nums}
.md-rate-track,.md-rate-arc{fill:none;stroke-width:6}
.md-rate-track{stroke:var(--surface-2)}
.md-rate-arc{stroke-linecap:round}
.md-rate-side.is-home .md-rate-arc{stroke:var(--md-viz-home)}
.md-rate-side.is-away .md-rate-arc{stroke:var(--md-viz-away)}
.md-rate-side:not(.is-lead) .md-rate-arc{opacity:.35}
.md-fly-list{margin:0 var(--md-gutter)}
.md-fly-group{margin:8px 0 2px;color:var(--club-navy);font-size:11px;line-height:16px;font-weight:800}
.md-fly{display:grid;grid-template-columns:minmax(0,1fr) 132px minmax(0,1fr);align-items:center;padding:4px 0}
.md-fly-bar{display:flex;height:12px;border-radius:999px;background:var(--surface-2);overflow:hidden}
.md-fly-bar.is-home{justify-content:flex-end}
.md-fly-bar>i{display:block;height:100%;border-radius:inherit;opacity:.35}
.md-fly-bar.is-lead>i{opacity:1}
.md-fly-bar.is-home>i{background:var(--md-viz-home)}
.md-fly-bar.is-away>i{background:var(--md-viz-away)}
.md-fly-mid{display:grid;grid-template-columns:34px minmax(0,1fr) 34px;align-items:center;font-variant-numeric:tabular-nums}
.md-fly-mid>span{overflow:hidden;color:var(--muted);font-size:11px;line-height:16px;text-align:center;text-overflow:ellipsis;white-space:nowrap}
.md-fly-mid>b{font-size:13px;line-height:19px;font-weight:400;color:var(--ink-soft)}
.md-fly-mid>b.is-home{text-align:end}
.md-fly-mid>b.is-lead{font-weight:700}
.md-fly-mid>b.is-home.is-lead{color:var(--md-viz-home)}
.md-fly-mid>b.is-away.is-lead{color:var(--md-viz-away)}
.md-fly-note{margin:8px 0 0;color:var(--muted);font-size:11px;line-height:16px;text-align:center}
.md-top-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:8px var(--md-gutter) 0}
.md-top{display:flex;align-items:center;gap:8px;margin-bottom:8px;padding:8px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card)}
.md-top>span{display:grid;flex:1;min-width:0}
.md-top strong{overflow:hidden;font-size:13px;line-height:19px;text-overflow:ellipsis;white-space:nowrap}
/* #10: the face takes about 40 px of the name's room, so a long name wraps to a second line instead of being cut (App maxLines 2) */
.md-top:has(>.player-face) strong{white-space:normal;overflow-wrap:anywhere}
.md-top em{font-style:normal;font-size:11px;line-height:16px;font-weight:800}
.md-top small{color:var(--muted);font-size:11px;line-height:16px}
.md-top>b{font-size:20px;line-height:27px;font-weight:700;font-variant-numeric:tabular-nums}
.md-top.is-home>b,.md-top.is-home em{color:var(--md-viz-home)}
.md-top.is-away>b,.md-top.is-away em{color:var(--md-viz-away)}
.md-top.is-mvp.is-home{border-color:var(--md-viz-home)}
.md-top.is-mvp.is-away{border-color:var(--md-viz-away)}
.md-basket-full{margin:0 var(--md-gutter)}
.md-basket-full>summary{display:grid;place-items:center;min-height:48px;border:1px solid var(--line);border-radius:999px;color:var(--club-navy);font-size:13px;line-height:19px;font-weight:600;list-style:none;cursor:pointer}
.md-basket-full>summary::-webkit-details-marker{display:none}
.md-basket-full>.md-basket-table-wrap{margin-inline:0}
/* P3-15 · the App's R75 (Owner 10-12 「球员表右側欄被切、沒有能滑的提示」, jyb_pinned_table.dart:197-222): a 24 fade of the
   table's own surface over its right edge, only while columns wait to the right (client.mjs syncBasketFades sets data-more
   from the scroll position); scrolled to the end it is gone. Inside the box's 1 px rule and its 12 corner. */
.md-basket-scroll{position:relative;margin-top:12px;margin-inline:0}
.md-basket-scroll>.md-basket-table-wrap{margin-top:0}
/* (同色淡出: the head row fades into its own surface-2, the rows into the card; --md-head-h is the head row's height) */
.md-basket-scroll::after{content:"";position:absolute;top:1px;right:1px;bottom:1px;width:24px;border-radius:0 11px 11px 0;background:linear-gradient(90deg,transparent,var(--surface-2)) 0 0/100% var(--md-head-h,0px) no-repeat,linear-gradient(90deg,transparent,var(--card)) 0 var(--md-head-h,0px)/100% calc(100% - var(--md-head-h,0px)) no-repeat;pointer-events:none;opacity:0;transition:opacity .14s}
.md-basket-scroll[data-more]::after{opacity:1}
@media(prefers-reduced-motion:reduce){.md-basket-scroll::after{transition:none}}
.md-basket-full:not([open]) .basket-more-close,.md-basket-full[open] .basket-more-open{display:none}
.basket-chart-note{text-align:center;font-size:12px;color:var(--muted);line-height:1.6}
.basket-court{display:block;width:200px;max-width:100%;height:auto;margin:12px auto}
.basket-court .basket-chart-grid{stroke-width:.25}
.basket-shot-points{fill:var(--club-navy)}
.basket-shot-miss{fill:none;stroke:var(--muted);stroke-width:.4}
.basket-history td{white-space:normal;overflow-wrap:anywhere;min-width:64px}
.md-basket-table-wrap{overflow-x:auto;margin-top:12px;border:1px solid var(--md-hair);border-radius:12px;background:var(--card)}
.basket-list-wrap{padding:0 16px;overflow-x:auto}
.basket-list-grid{width:100%;border-collapse:collapse;table-layout:fixed;font-size:12px;font-variant-numeric:tabular-nums}
.basket-list-grid :is(th,td){width:30px;padding:3px 0;text-align:center;vertical-align:middle}
.basket-list-grid thead{font-size:10px;color:var(--muted);font-weight:400}
.basket-list-grid th:first-child{width:auto;text-align:left;overflow-wrap:anywhere}
.basket-list-grid tbody th{font-size:13px;font-weight:600}
#scores .basket-list-grid th:first-child .team-mark{display:inline-block;vertical-align:middle;width:20px;margin-right:4px}
.basket-list-grid :is(th,td):last-child{width:40px}
.basket-list-grid .basket-list-total{font-size:16px;font-weight:800;color:var(--ink)}
.basket-list-grid .basket-list-total.live-score{color:var(--live)}
.basket-list-grid .team-name{vertical-align:middle}
/* R20261014 · BasketballMatchRow (basketball_match_row.dart) on 比分: the top line is the competition muted (never a
   football tier colour), the tip-off in ink — kept while the game is live — and the status with its clock at the end,
   muted, or live while live; the period grid takes the row's width beside the App's chevron. */
#scores .bb-top .row-league{color:var(--muted)}
#scores .match .bb-top .time{color:var(--ink)}
#scores .bb-top .row-state{justify-self:end;white-space:normal;text-align:end}
#scores .bb-top .row-state.live{color:var(--live)}
#scores .match>div.row-main>.basket-list-wrap{flex:1;min-width:0;padding:0}
#scores .match>div.row-main>.row-chevron{margin-left:auto}
#schedule .schedule-kickoff{display:block;font-variant-numeric:tabular-nums;color:var(--muted);margin-top:4px}
#schedule .schedule-date{display:flex;flex-direction:column;align-items:flex-start;gap:2px;font-size:11px;line-height:16px;color:var(--muted)}
#schedule .schedule-date strong{font-size:12px;line-height:17px;font-weight:600;color:var(--club-navy);font-variant-numeric:tabular-nums}
#schedule .schedule-body .schedule-teams{margin:0 0 8px}
#schedule .schedule-body .schedule-teams img{width:24px;height:24px}
#schedule .schedule-body .schedule-teams b{height:24px;font-size:13px;line-height:19px;font-weight:600;padding-inline:8px}
#schedule .schedule-body .schedule-teams>span{gap:4px}
#schedule .schedule-body .schedule-foot{margin-top:4px;flex-wrap:wrap}
.md-basket-table{width:100%;border-collapse:collapse;font-size:13px;font-variant-numeric:tabular-nums}
.md-basket-table :is(th,td){padding:12px 8px;text-align:center;white-space:nowrap}
.md-basket-table thead{background:var(--surface-2);color:var(--muted);font-size:11px}
.md-basket-table tbody tr+tr{border-top:1px solid var(--md-hair)}
.md-basket-table th:first-child{width:36%;min-width:110px;max-width:180px;padding-left:12px;text-align:left;white-space:normal;overflow-wrap:anywhere}
.md-basket-table th small{display:block;margin-top:4px;color:var(--muted);font-size:10px;font-weight:400}
.md-basket-table th:first-child{position:sticky;left:0;z-index:1;background:var(--card)}
.md-basket-table thead th:first-child{background:var(--surface-2)}
.md-basket-who{display:flex;align-items:center;gap:8px}
.md-basket-who>span{flex:1;min-width:0}
.md-basket-total{color:var(--ink);font-weight:800;background:var(--surface-2)}
.md-basket-sides{display:flex;gap:16px;padding:12px 0;color:var(--ink);font-size:13px}
.md-basket-sides strong{flex:1;min-width:0;overflow-wrap:anywhere}
.md-basket-sides strong:last-child{text-align:right}
.md-basket-events{padding:0;list-style:none}
.md-basket-events li{padding:12px 0;border-bottom:1px solid var(--md-hair)}
.md-basket-events li>div{display:flex;justify-content:space-between;gap:12px;font-variant-numeric:tabular-nums}
.md-basket-events small{color:var(--muted)}
.md-basket-events p{padding-top:8px;overflow-wrap:anywhere}
/* zero-specificity reset of the global heading/paragraph rules; every component below sets its own spacing */
:where(#match .md-page) :is(h2,h3,p){margin:0;letter-spacing:0}
.md-icon{display:block;flex:none}
/* Header: MatchDetailHeader, chrome row, meta strip, lockup, status strip */
.md-hero{position:relative;z-index:0;isolation:isolate;overflow:hidden;padding:16px var(--md-gutter) 6px;border-bottom:1px solid var(--md-theatre-rule);background:var(--md-theatre-1);color:var(--md-theatre-ink)}
.md-hero-bg,.md-hero-art{position:absolute;z-index:-1;inset:0;width:100%;height:100%;pointer-events:none}
.md-hero-bg stop:nth-child(1){stop-color:var(--md-theatre-0)}.md-hero-bg stop:nth-child(2){stop-color:var(--md-theatre-1)}.md-hero-bg stop:nth-child(3){stop-color:var(--md-theatre-2)}
.md-hero-art{color:var(--md-theatre-accent)}
.md-hero-bar{display:none;align-items:center;justify-content:space-between;height:48px}
.md-back{display:inline-flex;align-items:center;width:48px;height:48px;color:var(--md-theatre-ink);text-decoration:none}
.md-back>span,.md-share>span{display:grid;place-items:center;width:36px;height:36px;border:1px solid var(--md-theatre-rule);border-radius:50%;transition:background-color .14s}
.md-back .md-icon{width:20px;height:20px}
/* P3-5 · 分享赛事, the bar's right-hand chip (MatchDetailBar): the 返回 chip's hair circle, flush with the right gutter */
#match .md-share{display:inline-flex;align-items:center;justify-content:flex-end;width:48px;height:48px;min-height:48px;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--md-theatre-ink);cursor:pointer}
.md-share svg{display:block;width:18px;height:18px}
#match .md-share:focus-visible{outline:3px solid var(--md-theatre-accent);outline-offset:-2px}
@media(hover:hover){.md-back:hover>span,.md-share:hover>span{background:var(--md-theatre-rule)}}
.md-hero a:focus-visible{outline-color:var(--md-theatre-accent);outline-offset:-2px}
.md-meta{display:flex;flex-wrap:wrap;justify-content:center;gap:2px 4px;padding:8px 0 12px;color:var(--md-theatre-muted);font-size:11px;line-height:16px;font-weight:600;letter-spacing:.08em;font-variant-numeric:tabular-nums;text-align:center}
#match .md-hero .md-meta{margin:0}
.md-meta>*{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.md-meta strong{font-weight:800;color:var(--md-theatre-accent)}
.md-meta i{font-style:normal;font-weight:400;color:var(--md-theatre-rule)}
.md-lockup{display:grid;grid-template-columns:minmax(0,1fr) minmax(118px,auto) minmax(0,1fr)}
.md-side{display:flex;flex-direction:column;align-items:flex-start;min-width:0;padding-right:12px;container-type:inline-size}
.md-side-away{align-items:flex-end;padding:0 0 0 12px}
.md-hero .md-crest{position:relative;display:block;flex:none;width:34px;height:34px;overflow:hidden;border-radius:50%;background:var(--md-crest-face)}
.md-hero .md-crest:after{content:"";position:absolute;inset:0;border-radius:50%;box-shadow:inset 0 0 0 1px var(--md-crest-ring)}
.md-hero .md-crest img{display:block;width:100%;height:100%;object-fit:contain}
.md-team-name{display:block;max-width:100%;height:19px;margin:8px 0;overflow:hidden;color:var(--md-theatre-ink);font-size:15px;font-size:min(15px,100cqi / var(--md-name-em,1));line-height:19px;font-weight:800;white-space:nowrap}
.md-side-away .md-team-name{text-align:right}
.md-team-rule{display:block;flex:none;width:22px;height:2px;margin-top:auto;background:var(--md-theatre-accent)}
.md-side-away .md-team-rule{background:var(--md-theatre-muted)}
.md-centre{display:flex;flex-direction:column;align-items:center;min-width:118px;text-align:center}
.md-score,.md-countdown b{display:block;font-size:28px;line-height:34px;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
.md-score-sub{display:block;max-width:100%;color:var(--md-theatre-muted);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.md-countdown small{color:var(--md-theatre-muted);font-size:11px;line-height:16px;font-weight:600;letter-spacing:.08em}
.md-status{display:flex;align-items:center;min-height:16px;margin-top:8px;color:var(--md-theatre-muted);font-size:11px;line-height:16px;font-weight:800;font-variant-numeric:tabular-nums}
.md-status.is-active{color:var(--md-theatre-accent)}
.md-status-dot{flex:none;width:6px;height:6px;margin-right:4px;border-radius:50%;background:var(--live)}
.md-status-parts{display:flex;flex-wrap:wrap;align-items:center;min-width:0;margin-right:8px}
.md-status-sep{padding:0 4px;color:var(--md-theatre-muted);font-style:normal;font-weight:400}
.md-status-rule{flex:1 1 0;min-width:0;height:1px;background:var(--md-theatre-rule)}
/* Tabs: JybUnderlineTabs, 48 high, 18×3 act indicator 6 above the bottom */
.md-tabs{display:flex;border-bottom:1px solid var(--md-hair);background:var(--paper)}
#match .md-tabs button{position:relative;flex:1 1 0;min-width:48px;min-height:48px;margin:0;padding:12px 16px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400;white-space:nowrap}
#match .md-tabs button.active{color:var(--ink);font-weight:800}
#match .md-tabs button:after{content:"";position:absolute;left:50%;bottom:6px;width:0;height:3px;border-radius:999px;background:var(--gold-ink);transform:translateX(-50%);transition:width .14s ease-out}
#match .md-tabs button.active:after{width:18px}
.md-pane{min-height:280px;padding:16px 0 24px}
/* Section head: DetailSectionHeader */
.md-section{display:flex;align-items:center;margin:0;padding:12px var(--md-gutter) 8px;color:var(--ink);font-size:15px;line-height:22px;font-weight:800;letter-spacing:0}
#match .md-section{margin:0}
.md-section-no{flex:none;margin-right:8px;color:var(--gold-ink);font-size:11px;line-height:16px;font-weight:800;font-variant-numeric:tabular-nums}
.md-section>.md-icon{width:20px;height:20px;margin-right:6px;color:var(--gold-ink)}
.md-section-title{flex:0 1 auto;min-width:0;overflow-wrap:anywhere}
.md-section-rule{flex:1 1 24px;min-width:24px;height:1px;margin-left:8px;background:var(--md-border)}
.md-section>small{flex:none;margin-left:8px;color:var(--muted);font-size:12px;line-height:17px;font-weight:400}
/* Notice (DetailSectionNotice), state view (JybStateView) and the compact primary button */
.md-notice{display:flex;align-items:center;gap:12px;padding:4px var(--md-gutter) 16px}
#match .md-notice p{flex:1;min-width:0;margin:0;color:var(--muted);font-size:12px;line-height:17px}
#match .md-retry,#data .bb-sheet .md-retry{display:inline-flex;align-items:center;justify-content:center;flex:none;min-width:48px;min-height:48px;margin:6px 0;padding:0 16px;border:0;border-radius:999px;background:linear-gradient(168deg,var(--md-btn-0),var(--md-btn-1) 62%);box-shadow:0 5px 14px var(--md-btn-shadow);color:var(--md-btn-ink);font-size:13px;line-height:19px;font-weight:600;letter-spacing:.04em}
.md-state{display:flex;flex-direction:column;align-items:center;padding:24px 32px;text-align:center}
.md-state-icon{display:grid;place-items:center;width:74px;height:74px;border:1px solid var(--md-act-line-soft);border-radius:50%;background:radial-gradient(circle 50px at 50% 42%,var(--soft),var(--md-act-soft-0));color:var(--gold-ink)}
.md-state-icon .md-icon{width:32px;height:32px}
.md-state.is-error .md-state-icon{border-color:var(--md-border);background:var(--surface-2);color:var(--md-danger)}
.md-state strong{margin-top:12px;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
#match .md-state p{max-width:280px;margin:8px 0 0;color:var(--md-faint);font-size:12px;line-height:17px}
#match .md-state .md-retry{margin-top:16px}
/* Skeletons: JybSkeleton, surface2 with the lighter skelShine sweep */
.md-skel{display:block;flex:none;height:12px;border-radius:6px;background:linear-gradient(105deg,var(--surface-2) 30%,var(--md-skel-shine) 50%,var(--surface-2) 70%) 0 0/400% 100%;animation:md-shimmer 1.2s ease-in-out infinite}
@keyframes md-shimmer{from{background-position:100% 0}to{background-position:0 0}}
.md-skel-head{gap:0}.md-skel-head>.md-skel:first-child{margin-right:8px}.md-skel-head .md-skel-icon{width:20px;height:20px;margin-right:6px;border-radius:4px}
.md-skel-head.has-accessory{min-height:56px;padding-top:8px;padding-bottom:0}
.md-skel-sides{display:flex;justify-content:space-between;padding-bottom:8px}
.md-skel-tug{padding-bottom:8px}.md-skel-tug>span{display:flex;justify-content:space-between}.md-skel-tug .md-skel-bar{width:100%;height:5px;margin-top:4px;border-radius:999px}
.md-skel-event{display:flex;align-items:flex-start;gap:8px;padding:8px var(--md-gutter)}.md-skel-event>.md-skel:first-child{margin-left:14px}.md-skel-event .md-skel-glyph{width:16px;height:16px;border-radius:4px}
.md-skel-row{display:flex;align-items:center;gap:12px;padding:12px 15px}.md-skel-row .md-skel-circle{width:44px;height:44px;border-radius:50%}.md-skel-row>span{display:grid;gap:8px}
/* 赛况: news strip (MatchNewsStrip) */
.md-news{margin-bottom:4px}
.md-news-scroller{display:flex;gap:8px;overflow-x:auto;padding:4px var(--md-gutter);scrollbar-width:none;overscroll-behavior-x:contain}
.md-news-scroller::-webkit-scrollbar{display:none}
.md-news-card{display:flex;flex:none;flex-direction:column;width:168px;min-height:176px;overflow:hidden;border:1px solid var(--md-hair);border-radius:14px;background:var(--card);color:var(--ink);text-decoration:none}
.md-news-cover{position:relative;display:grid;place-items:center;flex:none;height:96px;overflow:hidden;background:var(--soft);color:var(--gold-ink)}
.md-news-cover .md-icon{width:24px;height:24px}
.md-news-cover img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
.md-news-copy{display:flex;flex:1;flex-direction:column;padding:8px 12px 12px}
.md-news-copy strong{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:13px;line-height:19px;font-weight:600}
.md-news-copy small{margin-top:auto;padding-top:6px;overflow:hidden;color:var(--muted);font-size:11px;line-height:16px;font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap}
@media(hover:hover){.md-news-card:hover strong{color:var(--gold-ink)}}
/* 赛况: 01 统计 (DetailSides, DetailStatRing, DetailTugRow, DetailStatGlyph) */
.md-stats{padding:0 var(--md-gutter) 4px}
.md-sides{display:flex;gap:12px;padding-bottom:8px;color:var(--muted);font-size:11px;line-height:16px}
.md-sides>span{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md-sides>span+span{text-align:right}
.md-rings{display:flex;align-items:flex-start;padding-bottom:12px}
.md-ring{display:flex;flex:1 1 0;flex-direction:column;align-items:center;min-width:0;text-align:center}
.md-ring svg{display:block;width:64px;height:64px}
.md-ring-track{stroke:var(--surface-2)}.md-ring-home{stroke:var(--md-viz-home)}.md-ring-away{stroke:var(--md-viz-away)}
#match .md-ring-values{display:flex;flex-wrap:wrap;justify-content:center;gap:0 8px;margin:8px 0 0;font-size:11px;line-height:16px;font-weight:800;font-variant-numeric:tabular-nums}
.md-ring-values b:first-child,.md-tug-values>b:first-child{color:var(--green)}
.md-ring-values b:last-child,.md-tug-values>b:last-child{color:var(--md-ink-soft)}
.md-stat-label{display:flex;align-items:center;justify-content:center;gap:4px;min-width:0;color:var(--muted);font-size:11px;line-height:16px;font-weight:400}
.md-stat-label .md-icon{width:16px;height:16px;color:var(--gold-ink)}
.md-ring .md-stat-label{margin-top:4px}.md-ring .md-stat-label>span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.md-stat-card{display:block;flex:none;width:9.6px;height:13.1px;margin:1.45px 3.2px;border-radius:2px;background:var(--md-warn)}.md-stat-card.is-red{background:var(--live)}
.md-tug{padding-bottom:8px}
.md-tug-values{display:flex;align-items:center;gap:8px;font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.md-tug-values>b{flex:none;font-weight:inherit}
.md-tug-values .md-stat-label{flex:1 1 auto}.md-tug-values .md-stat-label>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#match .md-tug .bar,.md-tug-track{display:block;height:5px;margin:4px 0 0;overflow:hidden;border-radius:999px;background:var(--md-viz-away)}
#match .md-tug .bar i{display:block;height:100%;background:var(--md-viz-home)}
.md-tug .md-tug-track{background:var(--surface-2)}
/* 赛况: 02 事件直播 (FeedTimelineRow, FeedDividerRow), newest first */
.md-event{position:relative;display:flex;align-items:flex-start;gap:8px;padding:8px var(--md-gutter);border-bottom:1px solid var(--md-hair)}
.md-event.is-goal{background:var(--soft)}
.md-event.is-note{opacity:.9}
.md-event[data-side]:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--md-viz-home)}
.md-event[data-side=away]:before{background:var(--md-viz-away)}
.md-event-min{flex:none;width:40px;color:var(--md-ink-soft);font-size:11px;line-height:16px;font-weight:800;font-variant-numeric:tabular-nums;text-align:right}
.md-event.is-goal .md-event-min{color:var(--gold-ink)}
.md-glyph{display:grid;place-items:center;flex:none;width:16px;height:16px;color:var(--ink)}.md-glyph .md-icon{width:16px;height:16px}
.md-tone-brand{color:var(--gold-ink)}.md-tone-live{color:var(--live)}.md-tone-warn{color:var(--md-warn)}.md-tone-up{color:var(--md-up)}.md-tone-muted{color:var(--muted)}
.md-event-body{flex:1;min-width:0}
#match .md-event-body p{display:flex;align-items:center;gap:8px;min-width:0;margin:0;color:var(--ink);font-size:11px;line-height:16px;font-weight:600}
.md-event.is-strong .md-event-body p{font-weight:800}
.md-event-body strong{min-width:0;overflow:hidden;font-weight:inherit;text-overflow:ellipsis;white-space:nowrap}
.md-event-score{flex:none;color:var(--green);font-weight:800;font-variant-numeric:tabular-nums}
.md-event-body>span{display:block;color:var(--ink);font-size:12px;line-height:17px;overflow-wrap:anywhere}
.md-event.is-goal .md-event-body>span{font-weight:600}.md-event.is-note .md-event-body>span{color:var(--muted)}
.md-event-who{display:flex;align-items:center;gap:8px;margin-top:4px}
.md-event-who>span{flex:1;min-width:0;color:var(--ink);font-size:12px;line-height:17px;overflow-wrap:anywhere}
.md-event.is-goal .md-event-who>span{font-weight:600}
.md-divider{display:flex;align-items:center;gap:8px;padding:12px var(--md-gutter)}
.md-divider b{flex:none;width:40px;color:var(--muted);font-size:11px;line-height:16px;font-weight:800;font-variant-numeric:tabular-nums;text-align:right}
.md-divider span{flex:0 1 auto;min-width:0;color:var(--md-ink-soft);font-size:11px;line-height:16px;font-weight:800}
.md-divider.is-accent b,.md-divider.is-accent span{color:var(--green)}
.md-divider i{flex:1 1 24px;height:1px;background:var(--md-border)}
/* 阵容: LineupOverview status block, captions, team cards and rows */
.md-lineup-status{padding:4px var(--md-gutter) 0}
#match .md-lineup-state{margin:0;color:var(--ink);font-size:13px;line-height:19px;font-weight:600}
#match .md-lineup-state.is-tentative{color:var(--md-warn-text)}#match .md-lineup-state.is-unknown{color:var(--muted)}
#match .md-lineup-note{margin:0;color:var(--muted);font-size:12px;line-height:17px}
.md-progress{position:relative;height:2px;margin:8px 0 0;overflow:hidden;background:var(--soft)}
.md-progress:after{content:"";position:absolute;inset:0 auto 0 0;width:40%;background:var(--gold);animation:md-progress 1.2s ease-in-out infinite}
@keyframes md-progress{from{transform:translateX(-100%)}to{transform:translateX(250%)}}
.md-lineup-error{display:flex;align-items:center;gap:8px}
#match .md-lineup-error p{flex:1;margin:0;color:var(--muted);font-size:12px;line-height:17px}
#match .md-text-action{min-height:48px;margin:0;padding:0 8px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--md-link);font-size:13px;line-height:19px;font-weight:600}
#match .md-caption{margin:0;padding:8px var(--md-gutter) 0;color:var(--muted);font-size:11px;line-height:16px}
#match .md-caption-tight{padding-top:0}
.md-cards{display:grid;gap:12px;padding:8px var(--md-gutter) 0}
.md-team-card{min-width:0;padding:12px 12px 4px;border:1px solid var(--md-hair);border-radius:14px;background:var(--card)}
.md-team-head{display:flex;align-items:flex-start;gap:8px;margin:0;font-size:15px;line-height:22px;font-weight:600;letter-spacing:0}
.md-team-head:before{content:"";flex:none;width:3px;height:22px;background:var(--md-viz-home)}
.md-team-away:before{background:var(--md-viz-away)}
.md-team-head strong{flex:1;min-width:0;color:var(--ink);font-weight:600;overflow-wrap:anywhere}
.md-team-head small{flex:none;color:var(--muted);font-size:11px;line-height:22px;font-weight:400}
#match .md-formation{display:flex;align-items:baseline;gap:8px;margin:8px 0 4px;color:var(--muted);font-size:12px;line-height:17px}
.md-formation b{color:var(--ink);font-size:15px;line-height:22px;font-weight:800;font-variant-numeric:tabular-nums}
#match .md-team-empty{margin:0;padding:12px 0;color:var(--muted);font-size:13px;line-height:19px}
.md-players{margin:0;padding:0;list-style:none}
.md-player{display:flex;align-items:center;gap:8px;min-height:56px;padding:8px 0;border-top:1px solid var(--md-hair)}
.md-player:first-child{border-top:0}
.md-avatar{position:relative;display:grid;place-items:center;flex:none;width:24px;height:24px;overflow:hidden;border-radius:50%;background:var(--surface-2);color:var(--muted)}
.md-avatar .md-icon{width:16px;height:16px}
.md-avatar img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
/* #10 球員頭像 (Owner 2026-10-14「足球籃球的數據有提到球員的地方都給我補上球員頭像…」): the one player face (product.mjs
   playerFace = the App's JybPlayerAvatar): the person glyph on the surface-2 disc, the photo over it (a failed photo is
   hidden by client.mjs and the glyph stays). 24 in rows, tables and the timeline; 32 where the face leads a card. */
.player-face{position:relative;display:inline-grid;flex:none;place-items:center;width:24px;height:24px;overflow:hidden;border-radius:50%;background:var(--surface-2);color:var(--icon-muted);font-style:normal;vertical-align:middle}
.player-face>svg{width:16px;height:16px}
.player-face.is-32{width:32px;height:32px}
.player-face.is-32>svg{width:20px;height:20px}
.player-face>img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
.md-player-no{flex:none;min-width:22px;color:var(--ink);font-size:15px;line-height:22px;font-weight:600;font-variant-numeric:tabular-nums}
.md-player-copy{flex:1;min-width:0}
.md-player-copy strong{display:block;color:var(--ink);font-size:15px;line-height:22px;font-weight:600;overflow-wrap:anywhere}
.md-player-copy small{display:block;color:var(--muted);font-size:12px;line-height:17px}
.md-rating{flex:none;min-width:36px;padding:2px 4px;border:1px solid var(--md-hair);border-radius:4px;background:var(--surface-2);color:var(--muted);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums;text-align:center}
.md-rating.is-mid{color:var(--md-ink-soft)}
.md-rating.is-high{border-color:var(--md-act-line);background:var(--soft);color:var(--gold-ink);font-weight:800}
.md-group{padding:12px var(--md-gutter) 0}
.md-group .md-players{margin-top:4px}
.md-bench{margin-top:8px}
.md-bench>summary{min-height:48px;cursor:pointer;list-style:none}
.md-bench>summary::-webkit-details-marker{display:none}
.md-section-action{flex:none;margin-left:8px;color:var(--gold-ink);font-size:13px;line-height:19px;font-weight:600}
.md-bench .md-open,.md-bench[open] .md-closed{display:none}.md-bench[open] .md-open{display:inline}
.md-bench>summary:focus-visible{outline:3px solid var(--gold-ink);outline-offset:-3px}
/* 阵容: the pitch (LineupPitch), away above and home below */
.md-pitch-wrap{display:flex;justify-content:center;padding:12px 8px 0}
.lineup-pitch{position:relative;max-width:100%;aspect-ratio:.64;overflow:hidden;border-radius:12px;background:var(--md-pitch-grass);color:var(--md-pitch-line)}
.md-pitch-lines{position:absolute;inset:0;width:100%;height:100%}
.md-pitch-mown{fill:var(--md-pitch-stripe)}
.md-pitch-label{position:absolute;z-index:1;left:12px;max-width:calc(50% - 43px);padding:0 2px;border-radius:4px;background:var(--md-pitch-grass);line-height:1.3}
.md-pitch-label-away{top:10px}.md-pitch-label-home{bottom:10px}
.md-pitch-label b{display:flex;gap:8px;color:var(--md-pitch-away-ink);font-size:12px;font-weight:800;white-space:nowrap}
.md-pitch-label-home b{color:var(--md-pitch-home-ink)}
.md-pitch-label b span{font-variant-numeric:tabular-nums}
.md-pitch-label small{display:block;overflow:hidden;color:var(--md-theatre-ink);font-size:11px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
.pitch-player{position:absolute;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;width:50px;height:46px;transform:translate(-50%,-50%);text-align:center}
.md-portrait{position:relative;display:grid;place-items:center;width:32px;height:32px;padding:2px;border:2px solid var(--md-theatre-muted);border-radius:50%;background:var(--surface-2);background-clip:content-box;color:var(--muted)}
.pitch-home .md-portrait{border-color:var(--md-theatre-accent)}
.md-portrait .md-icon{width:20px;height:20px}
.md-portrait img{position:absolute;inset:2px;display:block;width:24px;height:24px;border-radius:50%;object-fit:cover}
.md-portrait b{position:absolute;right:-6px;bottom:-2px;min-width:16px;height:16px;padding:0 2px;border:1px solid var(--md-pitch-grass);border-radius:999px;background:var(--ink);color:var(--md-pitch-away-ink);font-size:11px;line-height:14px;font-weight:800;font-variant-numeric:tabular-nums;text-align:center}
.pitch-home .md-portrait b{color:var(--md-pitch-home-ink)}
.pitch-player>strong{max-width:100%;margin-top:2px;padding:0 2px;overflow:hidden;color:var(--md-theatre-ink);font-size:11px;line-height:1.2;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
/* 阵容: DetailEmptyState with the line pitch */
.md-empty{display:flex;flex-direction:column;align-items:center;padding:32px 24px;text-align:center}
.md-pitch-figure{width:118px;height:76px;color:var(--md-border-2)}
.md-empty strong{margin-top:16px;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
#match .md-empty p{margin:4px 0 0;color:var(--muted);font-size:12px;line-height:17px}
@media(prefers-reduced-motion:reduce){.md-skel,.md-progress:after{animation:none}.md-skel{background:var(--surface-2)}#match .md-tabs button:after,.md-back>span{transition:none}}
/* Phone: the shell header owns the back control; the tab strip stays under it. */
@media(max-width:650px){
 .md-tabs{position:sticky;top:48px;z-index:20}
}
/* Tablet and PC: the same components in the centred column, the hero as a card. */
@media(min-width:651px){
 #match .md-page{--md-gutter:24px;padding-top:24px}
 .md-hero{padding:4px var(--md-gutter) 16px;border:0;border-radius:20px}
 .md-hero-bar{display:flex}
 .md-hero .md-crest{width:44px;height:44px}
 .md-team-name{height:22px;font-size:17px;font-size:min(17px,100cqi / var(--md-name-em,1));line-height:22px}
 .md-score,.md-countdown b{font-size:34px;line-height:40px}
 /* the kicker and status lines step up one App level (micro 11 -> caption 12) on the wider card */
 .md-meta,.md-status,.md-score-sub,.md-countdown small{font-size:12px;line-height:17px}
 .md-status{margin-top:12px}
 .md-pane{padding-top:20px}
}
@media(min-width:901px){
 .md-live-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:24px;align-items:start}
 .md-live-cols>.md-block:only-child{grid-column:1/-1}
 /* the statistics stay in view beside a long timeline (below the sticky site header) */
 .md-live-cols>.md-block:first-child:not(:only-child){position:sticky;top:96px}
 .md-cards{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:start}
 .md-cards>.lineup-home{order:-1}
}

/* 7 · Shenhua schedule (App PassportSchedulePage, ScheduleVersusCard; secondary path from scores) */
#schedule .club-schedule{max-width:none;margin:0;padding:0}
#schedule .schedule-source{margin:0 0 8px;color:var(--muted);font-size:12px;line-height:17px}
#schedule .schedule-status{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:0 4px 0 12px;border:1px solid var(--hair);border-radius:14px;background:var(--card);color:var(--muted);font-size:12px;line-height:17px}
#schedule .schedule-status>span{flex:1;min-width:0;padding:10px 0}
#schedule .schedule-status button{flex:none;min-height:48px;margin:0;padding:0 8px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--link);font-size:13px;font-weight:600}
/* Month head (JybSectionHead.compact + JybSectionMeta): 12/600 and 12/400 muted; 24 between months, 12 below */
#schedule .month-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:24px 0 12px;padding:0;border:0;color:var(--muted);font-size:12px;line-height:17px}
#schedule :is(.club-heading,.schedule-source,.schedule-status,summary)+.month-heading,#schedule .month-heading:first-child{margin-top:0}
#schedule .month-heading strong{min-width:0;font-weight:600}
#schedule .month-heading span{flex:none;font-weight:400}
/* Matchup row: eyebrow 12/600 date + 12/400 meta; band 13/600 names around a 20/800 VS; foot 12/400 + tag */
#schedule .schedule-versus{display:block;width:100%;min-height:48px;margin:0;padding:12px 0;border:0;border-bottom:1px solid var(--hair);border-radius:0;background:none;color:inherit;text-align:left;text-decoration:none}
#schedule .schedule-meta{margin:0;color:var(--muted);font-size:12px;line-height:17px}
#schedule .schedule-meta strong{color:var(--gold-ink);font-weight:600;font-variant-numeric:tabular-nums}
#schedule .schedule-teams{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:0;margin:8px 0 12px;text-align:center}
#schedule .schedule-teams span{min-width:0;color:var(--ink);font-size:13px;line-height:19px;font-weight:600;overflow-wrap:anywhere}
#schedule .schedule-teams b{padding:0 12px;color:var(--gold-ink);font-size:20px;line-height:27px;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
/* Crests (44) sit above the names and the VS centres on the crest band; a failed crest keeps its box */
#schedule .schedule-teams>span{display:flex;flex-direction:column;align-items:center;gap:8px}
#schedule .schedule-teams img{display:block;flex:none;width:44px;height:44px;object-fit:contain}
#schedule .schedule-teams .img-failed:before{content:"";display:block;width:44px;height:44px}
#schedule .has-crests .schedule-teams{align-items:start}
#schedule .has-crests .schedule-teams b{display:flex;align-items:center;height:44px}
#schedule .schedule-shootout{margin:-8px 0 12px;color:var(--muted);font-size:12px;line-height:17px;text-align:center}
#schedule .schedule-foot{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:12px;line-height:17px}
#schedule .schedule-foot>span{flex:1;min-width:0;overflow-wrap:anywhere}
/* Status tag (PassportTag, line tone): face 32, surface, border2 frame, 13/600 muted */
#schedule .schedule-state{display:inline-flex;align-items:center;flex:none;min-height:32px;margin:0;padding:0 12px;border:1px solid var(--border-2);border-radius:999px;background:var(--card);color:var(--muted);font-size:13px;line-height:19px;font-style:normal;font-weight:600;white-space:nowrap}
#schedule .schedule-state.live{border-color:var(--live);color:var(--live)}
#schedule .schedule-go{display:grid;place-items:center;flex:none;width:16px;height:16px;color:var(--faint)}
#schedule .schedule-go svg,#schedule .past-icon svg,#schedule .past-toggle svg{display:block;width:100%;height:100%}
/* Played rows dim as one (App `dim`): faint eyebrow and foot, muted band */
#schedule .schedule-versus.is-past :is(.schedule-meta,.schedule-meta strong,.schedule-foot){color:var(--faint)}
#schedule .schedule-versus.is-past .schedule-teams :is(span,b){color:var(--muted)}
@media(hover:hover){#schedule a.schedule-versus:hover{background:var(--press)}}
/* 已赛 head (JybSectionHead: 20 brand icon, 15/800, trailing meta); the web keeps it folded */
#schedule .past-schedule{margin:24px 0 0}
#schedule .past-schedule summary{display:flex;align-items:center;gap:6px;min-height:48px;margin:0;padding:0;cursor:pointer;list-style:none;color:var(--ink);font-size:15px;line-height:22px;font-weight:800}
#schedule .past-schedule summary::-webkit-details-marker{display:none}
#schedule .past-schedule summary:before{content:none;display:none}
#schedule .past-icon{order:-1;flex:none;width:20px;height:20px;color:var(--gold-ink)}
#schedule .past-schedule summary small{margin-left:auto;color:var(--muted);font-size:12px;line-height:17px;font-weight:400}
#schedule .past-toggle{flex:none;width:16px;height:16px;color:var(--faint);transition:transform .16s}
#schedule .past-schedule[open] .past-toggle{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){#schedule .past-toggle{transition:none}}
@media(max-width:650px){
 #schedule{padding:0}
 #schedule .club-schedule{padding:16px 16px 24px}
 #schedule .club-heading{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
}
@media(min-width:651px) and (max-width:900px){#schedule .club-schedule{max-width:720px;margin-inline:auto}}
/* PC: the same matchup rows at App width, two per line, each on a JybCard face */
@media(min-width:901px){
 #schedule .schedule-rows{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
 #schedule .schedule-versus{padding:12px 16px;border:1px solid var(--line);border-radius:14px;background:var(--card)}
}
@media(min-width:901px) and (hover:hover){#schedule a.schedule-versus:hover{border-color:var(--gold);background:linear-gradient(var(--press),var(--press)),var(--card)}}

/* 8 · Member surfaces: 我的, 登录, 抽奖与序号, 设置与支持 — the App's account, auth and lottery
   screens built from the App's components. Each page owns its phone rules here, not in §10. */
:root{
 /* Shared by every member and news surface (§5, §8, §9); each names its JybTokens source
    (apps/mobile/lib/design/jyb_tokens.dart). */
 --hair:#16171a21;              /* hair · card outline on paper */
 --faint:#656666;               /* faint */
 --ink-soft:#3e3e3e;            /* inkSoft */
 --border-2:#b7c5d8;            /* border2 · perforation and dashed rules */
 --surface-3:#d9e2ef;           /* surface3 · JybDisabledButton.primaryFill */
 --btn-line:#82858a;            /* btnLine · neutral control outline */
 --act-line:#0a2b5794;          /* actLine · avatar ring */
 --act-track:#0a2b57;           /* actTrack · empty avatar dash */
 --light-gold:#e8d7ac;          /* lightGold · type on black faces */
 --gold-on-dark:#d7be81;        /* jybGoldSoft · kicker, stamp and artwork on dark */
 --hero-sub:#d6dcd8;            /* ppHeroSub */
 --hero-name:#f1e9d4;           /* ppTabCount · member name on the pass */
 --coin:#82662b;                /* coin */
 --danger-text:#8c2f30;         /* dangerText */
 --press:#e4ecf673;             /* pressHighlight · actSoft .45 */
 --btn-face:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='39.6%25' y1='1.1%25' x2='60.4%25' y2='98.9%25'%3E%3Cstop offset='0' stop-color='%23123e70'/%3E%3Cstop offset='0.62' stop-color='%230a2b57'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* btnGradient */
 --btn-glow:0px 5px 14px #0a2b5724; /* btnShadow · archiveGold .14 */
 --auth-lift:0px 18px 42px #04132c33; /* authCardShadow rgba(4,19,44,.2) */
 /* The draw centre keeps the App's own dc palette (lottery_screen.dart, lottery_cards.dart). */
 --dc-hero:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='15.9%25' y1='13.45%25' x2='84.1%25' y2='86.55%25'%3E%3Cstop offset='0' stop-color='%23082040'/%3E%3Cstop offset='0.68' stop-color='%230a2b57'/%3E%3Cstop offset='1' stop-color='%23093671'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* dcHeroGradient */
 --dc-hero-error:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='14%25' y1='0%25' x2='86%25' y2='100%25'%3E%3Cstop offset='0' stop-color='%23442722'/%3E%3Cstop offset='1' stop-color='%236b362d'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* dcErrHeroGradient */
 --dc-line:#ded7c8;             /* dcLine */
 --dc-shadow:0px 12px 34px -28px #1c211f94; /* dcShadow */
 --dc-ink:#ffffff;                 /* dcHeroInk */
 --dc-body:#d7ddd9;             /* dcHeroBody */
 --dc-label:#b8c1bc;            /* dcMetaLabel */
 --dc-cell:#ffffff12;           /* dcMetaFill */
 --dc-cell-line:#ffffff1f;      /* dcMetaLine */
 --dc-pill:#ffffff14;           /* dcStatusFill */
 --dc-pill-line:#ffffff2e;      /* dcStatusLine */
 --dc-dot-open:#69bd88;         /* dcDotOpen */
 --dc-dot-wait:#d3b466;         /* dcDotWaiting */
 --dc-primary:#d7be8133;        /* dcPrimaryTint · jybGoldSoft .20 */
 --dc-primary-line:#e6c977;     /* dcPrimaryLine */
 --dc-primary-ink:#efe5cd;      /* ppTabLabelOn */
 --dc-off:#ffffff1a;            /* dcDisabledFill */
 --dc-off-line:#ffffff2e;       /* dcDisabledLine */
 --dc-off-ink:#b8c0bc;          /* dcDisabledInk */
 --dc-face:#ffffff;                /* dcCardFace · dcSerialFace */
 --dc-title:#222b29;            /* dcCardTitle */
 --dc-note:#827865;             /* dcCardNote */
 --dc-prize:#6b5019;            /* dcPrizeName */
 --dc-serial:#6d5117;           /* dcSerialInk */
 --dc-serial-label:#746c5d;     /* dcSerialLabel */
 --dc-result:#fffdf7;           /* dcResultFace */
 --dc-result-line:#cdb36d;      /* dcResultLine */
 --dc-win:#eaf5ed;              /* dcWinFace */
 --dc-win-ink:#245f39;          /* dcWinInk · dcSupportInk */
 --dc-winner-line:#e6dfd1;      /* dcWinnerLine */
 --dc-winner-mine:#f9f2df;      /* dcWinnerMineFace */
 --dc-winner-mine-line:#b18a33; /* dcWinnerMineLine */
 --dc-winner-serial:#5e491b;    /* dcWinnerSerial */
 --dc-winner-nick:#807765;      /* dcWinnerNick */
 --dc-support-line:#2d7246;     /* dcSupportLine */
 --dc-rules-ink:#6b511c;        /* dcRulesInk */
 --dc-rules-line:#d9d0be;       /* dcRulesLine */
}
/* App components: JybCard, JybCard.list, JybListRow, JybSectionHead.compact, JybPrimaryButton */
:is(#me,#login,#lottery,#support,#download) .jcard{margin:0;padding:16px;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
:is(#me,#support) .jlist{margin:0;overflow:hidden;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
:is(#me,#support) .jrow{display:flex;align-items:center;gap:12px;width:100%;min-height:56px;margin:0;padding:0 16px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--ink);font:inherit;text-align:left;text-decoration:none;cursor:pointer}
:is(#me,#support) .jrow+.jrow{border-top:1px solid var(--hair)}
:is(#me,#support) .jrow-tile{display:grid;place-items:center;flex:none;width:32px;height:32px;margin:12px 0;border-radius:8px;background:var(--soft);color:var(--gold-ink)}
:is(#me,#support) .jrow-tile svg{width:20px;height:20px}
:is(#me,#support) .jrow-main{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;flex:1;min-width:0;padding:12px 0}
:is(#me,#support) .jrow-title{min-width:0;font-size:15px;line-height:22px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
:is(#me,#support) .jrow-value{flex:1 0 auto;max-width:100%;margin-left:auto;font-size:13px;line-height:19px;color:var(--muted);text-align:right;overflow-wrap:anywhere}
:is(#me,#support) .jrow-end{display:grid;place-items:center;flex:none;color:var(--faint)}
:is(#me,#support) .jrow-end svg{width:16px;height:16px}
:is(#me,#support) .jrow:focus-visible{outline-offset:-3px}
:is(#me,#support) .jrow:active{background:var(--press)}
@media(hover:hover){:is(#me,#support) .jrow:hover{background:var(--press)}}
:is(#me,#login,#lottery,#download) .jbtn{display:flex;align-items:center;justify-content:center;width:100%;min-height:48px;margin:0;padding:12px 16px;border:0;border-radius:14px;background:var(--btn-face);box-shadow:var(--btn-glow);color:var(--pill-fg);font:inherit;font-size:15px;line-height:22px;font-weight:600;letter-spacing:.6px;text-align:center;text-decoration:none;cursor:pointer}
:is(#me,#login,#lottery,#download) .jbtn:disabled{border:1px solid var(--border-2);background:var(--surface-3);box-shadow:none;color:var(--muted);cursor:default}
/* 我的 · the 球迷通行证 ticket (MeGuestHero / MeIdentityCard), its perforation and MeAssetCells */
#me .me-page{max-width:var(--narrow);margin-inline:auto}
#me .me-grid{display:grid;gap:12px;align-items:start}
#me .me-side{display:grid;gap:12px;min-width:0}
#me .pass-card{position:relative;margin:0;overflow:hidden;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#me .pass-top{position:relative;padding:16px 16px 12px;background:var(--black-card);color:var(--on-dark)}
#me .pass-art{position:absolute;inset:0;width:100%;height:100%;color:var(--gold-on-dark);opacity:.12;pointer-events:none}
#me .pass-meta,#me .pass-person{position:relative}
#me .pass-meta{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:24px}
#me .pass-kicker{flex:none;font-size:11px;line-height:16px;font-weight:600;letter-spacing:.88px;color:var(--gold-on-dark)}
#me .pass-stamp{min-width:0;max-width:60%;overflow:hidden;padding:2px 8px;border:1.5px solid var(--gold-on-dark);border-radius:4px;font-size:11px;line-height:16px;font-weight:600;color:var(--gold-on-dark);text-overflow:ellipsis;white-space:nowrap;transform:rotate(-1.5deg)}
#me .pass-person{display:flex;align-items:center;gap:12px;margin-top:12px}
#me .pass-avatar{display:grid;place-items:center;flex:none;width:56px;height:56px;border:1.5px dashed var(--act-track);border-radius:50%;background:var(--soft);color:var(--gold-ink)}
#me .pass-avatar svg{width:24px;height:24px}
#me .pass-card[data-state=member] .pass-avatar{border:0;background:var(--surface-2);box-shadow:0 0 0 1px var(--act-line)}
#me .pass-id{min-width:0}
#me .pass-id h2{margin:0;font-size:20px;line-height:27px;font-weight:800;letter-spacing:0;color:var(--paper);overflow-wrap:anywhere}
#me .pass-id p{margin:4px 0 0;font-size:12px;line-height:17px;color:var(--hero-sub)}
#me .pass-id p:empty{display:none}
#me .pass-card[data-state=member] .pass-id h2{color:var(--hero-name)}
#me .pass-card[data-state=member] .pass-id p{color:var(--gold-on-dark);font-variant-numeric:tabular-nums}
#me .pass-perf{position:relative;height:14px;background:radial-gradient(circle at 0 50%,var(--paper) 7px,transparent 7.5px),radial-gradient(circle at 100% 50%,var(--paper) 7px,transparent 7.5px)}
#me .pass-perf:before{content:"";position:absolute;left:7px;right:7px;top:6px;height:1px;background:repeating-linear-gradient(90deg,var(--border-2) 0 4px,transparent 4px 7px)}
#me .pass-bottom{padding:8px 16px 16px}
#me .pass-card[data-state=member] .pass-bottom{padding:8px}
#me .pass-perks{margin:0 0 8px;padding:0;list-style:none}
#me .pass-perks li{display:flex;align-items:center;gap:12px;min-height:36px;font-size:13px;line-height:19px;font-weight:600;color:var(--ink)}
#me .pass-perks svg{flex:none;width:20px;height:20px;color:var(--gold-ink)}
#me .pass-note,#me .pass-status{margin:12px 0 0;font-size:12px;line-height:17px;color:var(--muted);text-align:center}
#me .pass-assets{display:flex}
#me .pass-asset{display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-width:0;min-height:56px;text-align:center}
#me .pass-asset+.pass-asset{background:repeating-linear-gradient(180deg,var(--border-2) 0 3px,transparent 3px 5px) left center/1px calc(100% - 24px) no-repeat}
#me .pass-asset-value{font-size:20px;line-height:27px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#me .pass-asset-value.is-coin{color:var(--coin)}
#me .pass-asset span{font-size:12px;line-height:17px;color:var(--muted)}
#me #signout{border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#me #account-message{margin:0;font-size:12px;line-height:17px;color:var(--danger-text)}
#me #account-message:empty{display:none}
/* 登录 · AuthIdentityHero, then the form card: AuthFieldCard, AuthAgreementRow, layer ① */
#login .login-page{max-width:440px;margin-inline:auto;padding:0}
#login .login-col{display:grid;gap:12px}
#login .auth-hero{position:relative;overflow:hidden;padding:16px;border-radius:20px;background:var(--black-card);color:var(--on-dark)}
#login .auth-art{position:absolute;inset:0;width:100%;height:100%;color:var(--gold-on-dark);opacity:.12;pointer-events:none}
#login .auth-hero p{position:relative;margin:0;max-width:none}
#login .auth-kicker{font-size:11px;line-height:16px;font-weight:600;letter-spacing:.88px;color:var(--pill-fg)}
#login .auth-hero .auth-title{margin-top:8px;font-size:20px;line-height:27px;font-weight:800;color:var(--on-dark)}
#login .auth-hero .auth-sub{margin-top:4px;font-size:12px;line-height:17px;color:var(--hero-sub)}
#login .auth-form-panel{padding:16px;border:1px solid var(--line);border-radius:20px;background:var(--card);box-shadow:var(--auth-lift)}
#login .auth-form-panel h1{margin:0;font-size:17px;line-height:24px;font-weight:800;letter-spacing:0;color:var(--ink)}
#login .auth-lead{margin:4px 0 16px;font-size:12px;line-height:17px;color:var(--muted)}
#login :is(#login-form,#register-form){display:grid;margin:0}
#login .auth-fields{overflow:hidden;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#login .auth-field{display:flex;flex-direction:column;gap:4px;margin:0;padding:12px 16px;cursor:text}
#login .auth-field+.auth-field{border-top:1px solid var(--hair)}
#login .auth-field:focus-within{background:var(--soft)}
#login .auth-field>span,#login .auth-field>label{margin:0;font-size:12px;line-height:17px;font-weight:600;color:var(--muted)}
#login .auth-field input{display:block;width:100%;min-width:0;min-height:24px;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;font-size:17px;line-height:24px;color:var(--ink);outline:0}
#login .captcha-line{display:flex;align-items:center;gap:8px}
#login .captcha-box{display:grid;place-items:center;flex:none;min-width:96px;height:40px;padding:0 8px;overflow:hidden;border:1px solid var(--line);border-radius:12px;background:var(--surface-2);color:var(--muted);font-size:11px;line-height:16px}
#login .captcha-box img{display:block;width:auto;height:26px;max-width:112px}
#login .captcha-box[data-state=loading]:after{content:"读取中…"}
#login .captcha-box[data-state=error]:after{content:"点 ↻ 重试"}
#login .captcha-line input{flex:1}
#login .captcha-refresh{position:relative;display:grid;place-items:center;flex:none;width:44px;height:40px;min-height:0;margin:0;padding:0;border:1px solid var(--border-2);border-radius:12px;background:var(--card);box-shadow:none;color:var(--muted);font-size:17px;line-height:24px}
#login .captcha-refresh:before{content:"";position:absolute;inset:-4px -2px}
#login .captcha-refresh:disabled{border-color:var(--hair);background:var(--surface-2)}
#login #auth-message{margin:12px 0 0;font-size:13px;line-height:19px;color:var(--danger-text)}
#login #auth-message:empty{display:none}
#login .auth-forgot,#login .auth-switch{display:inline-flex;align-items:center;min-height:48px;padding:0 8px;font-size:13px;line-height:19px;font-weight:600;color:var(--gold-ink)}
#login .auth-forgot{justify-self:end;margin-right:-8px}
#login .auth-switch{justify-self:center;margin-top:16px}
#login .auth-agree{display:flex;align-items:flex-start}
#login .auth-check{display:grid;place-items:center;flex:none;width:48px;height:48px;margin:0;cursor:pointer}
#login .auth-check input{width:18px;height:18px;margin:0}
#login .auth-agree>:is(span,label[for]){padding-top:14px;font-size:13px;line-height:19px;color:var(--ink-soft)}
#login .auth-agree a{font-weight:600;color:var(--gold-ink);text-decoration:underline;text-underline-offset:3px}
#login :is(#login-form,#register-form) .jbtn{margin-top:16px}
#login .auth-send-code{flex:none;min-height:44px;margin:0;padding:0 10px;border:0;border-radius:10px;background:var(--soft);box-shadow:none;color:var(--gold-ink);font-size:13px;line-height:19px;white-space:nowrap}
#login .auth-send-code:disabled{color:var(--muted)}
#login .auth-legal{margin:12px 0 0;font-size:12px;line-height:17px;color:var(--muted);text-align:center}
/* 抽奖与序号 · the draw centre (_DcHero, _DcCard and friends, lottery_cards.dart) */
#lottery .lot-page{max-width:640px;margin-inline:auto}
#lottery .lot-content{display:grid;gap:12px}
#lottery .dc-form{display:grid;gap:12px;margin:0}
#lottery .dc-hero{position:relative;overflow:hidden;padding:24px;border:1px solid var(--dc-line);border-radius:20px;background:var(--dc-hero);box-shadow:var(--dc-shadow);color:var(--dc-ink)}
#lottery .dc-hero.is-error{background:var(--dc-hero-error)}
#lottery .dc-hero>:not(.dc-art){position:relative}
#lottery .dc-art{position:absolute;inset:0;width:100%;height:100%;color:var(--gold-on-dark);opacity:.12;pointer-events:none}
#lottery .dc-kicker{margin:0;font-size:11px;line-height:16px;font-weight:600;letter-spacing:.88px;color:var(--gold-on-dark)}
#lottery .dc-status{display:inline-flex;align-items:center;gap:8px;margin:16px 0 0;padding:4px 8px;border:1px solid var(--dc-pill-line);border-radius:999px;background:var(--dc-pill);font-size:11px;line-height:16px;font-weight:600;color:var(--dc-ink)}
#lottery .dc-status i{width:8px;height:8px;border-radius:50%;background:var(--dc-dot-wait)}
#lottery .dc-hero[data-state=open] .dc-status i{background:var(--dc-dot-open)}
#lottery .dc-hero[data-state=done] .dc-status i{background:var(--dc-ink)}
#lottery .dc-title{margin:12px 0 0;font-size:20px;line-height:27px;font-weight:800;letter-spacing:0;color:var(--dc-ink);overflow-wrap:anywhere}
#lottery .dc-hero.is-error .dc-title{margin-top:12px}
#lottery .dc-body{margin:8px 0 0;font-size:12px;line-height:17px;color:var(--dc-body)}
#lottery .dc-meta{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:16px}
#lottery .dc-meta-cell{display:flex;flex-direction:column;gap:4px;min-width:0;padding:12px;border:1px solid var(--dc-cell-line);border-radius:10px;background:var(--dc-cell)}
#lottery .dc-meta-cell.is-wide{grid-column:1/-1}
#lottery .dc-meta-cell small{font-size:11px;line-height:16px;color:var(--dc-label)}
#lottery .dc-meta-cell b{font-size:12px;line-height:17px;font-weight:600;color:var(--dc-ink);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#lottery .dc-serial{display:flex;flex-direction:column;gap:4px;margin-top:12px;padding:12px;border-radius:12px;background:var(--dc-face)}
#lottery .dc-serial small{font-size:11px;line-height:16px;color:var(--dc-serial-label)}
#lottery .dc-serial b{font-size:28px;line-height:34px;font-weight:800;color:var(--dc-serial);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#lottery .dc-serial-more{display:flex;flex-wrap:wrap;gap:4px 8px;margin:0;font-size:13px;line-height:19px;font-weight:600;color:var(--dc-serial);font-variant-numeric:tabular-nums}
#lottery .dc-primary{display:inline-flex;align-items:center;justify-content:center;min-height:48px;margin:12px 0 0;padding:0 16px;border:1px solid var(--dc-primary-line);border-radius:10px;background:var(--dc-primary);box-shadow:none;color:var(--dc-primary-ink);font:inherit;font-size:13px;line-height:19px;font-weight:600;letter-spacing:.52px;text-decoration:none;cursor:pointer}
#lottery .dc-primary:disabled{border-color:var(--dc-off-line);background:var(--dc-off);color:var(--dc-off-ink);cursor:default}
#lottery .dc-note{margin:8px 0 0;font-size:11px;line-height:16px;color:var(--dc-body)}
#lottery #lottery-message{margin:0;font-size:13px;line-height:19px;color:var(--danger-text)}
#lottery #lottery-message:empty{display:none}
#lottery .dc-card{padding:16px;border:1px solid var(--dc-line);border-radius:20px;background:var(--dc-face);box-shadow:var(--dc-shadow)}
#lottery .dc-card.is-result{border-color:var(--dc-result-line);background:var(--dc-result)}
#lottery .dc-card-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:4px 12px}
#lottery .dc-card-head h3{margin:0;font-size:17px;line-height:24px;font-weight:600;letter-spacing:0;color:var(--dc-title)}
#lottery .dc-card-head small{font-size:12px;line-height:17px;color:var(--dc-note)}
#lottery .dc-card p{margin:8px 0 0;font-size:13px;line-height:19px;color:var(--ink-soft);overflow-wrap:anywhere}
#lottery .dc-card .dc-prize{margin-top:12px;font-size:20px;line-height:27px;font-weight:800;color:var(--dc-prize)}
#lottery .dc-card .dc-fine{font-size:12px;line-height:17px;color:var(--dc-note)}
#lottery .dc-card .dc-roster{font-size:12px;line-height:17px;font-weight:600;color:var(--dc-title);font-variant-numeric:tabular-nums}
#lottery .dc-card .dc-tickets{margin-top:12px;font-weight:600;color:var(--dc-serial);font-variant-numeric:tabular-nums}
#lottery .dc-card code{display:block;margin-top:4px;font-size:11px;line-height:16px;color:var(--dc-serial);overflow-wrap:anywhere;word-break:break-all}
#lottery .dc-link{display:inline-flex;align-items:center;min-height:48px;font-size:13px;line-height:19px;font-weight:600;color:var(--gold-ink)}
#lottery .dc-prizes{display:grid;margin:8px 0 0;padding:0;list-style:none}
#lottery .dc-prizes li{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px 12px;padding:4px 0;font-size:15px;line-height:22px;color:var(--ink)}
#lottery .dc-prizes small{font-size:13px;line-height:19px;color:var(--muted);font-variant-numeric:tabular-nums}
#lottery .dc-card .dc-mine{padding:12px;border-radius:10px;background:var(--dc-win);color:var(--dc-win-ink)}
#lottery .dc-mine b{display:block;font-size:15px;line-height:22px}
#lottery .dc-mine p{margin:4px 0 0;font-size:12px;line-height:17px;color:var(--dc-win-ink)}
#lottery .dc-support{display:inline-flex;align-items:center;min-height:48px;margin-top:8px;padding:0 12px;border:1px solid var(--dc-support-line);border-radius:14px;background:var(--dc-face);color:var(--dc-win-ink);font-size:13px;line-height:19px;font-weight:600}
#lottery .dc-winners{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:12px 0 0;padding:0;list-style:none}
#lottery .dc-winners li{display:flex;flex-wrap:wrap;align-items:center;gap:0 8px;min-width:0;padding:8px;border:1px solid var(--dc-winner-line);border-radius:8px;background:var(--dc-face)}
#lottery .dc-winners li.is-mine{border-color:var(--dc-winner-mine-line);background:var(--dc-winner-mine)}
#lottery .dc-winners b{font-size:12px;line-height:17px;font-weight:600;color:var(--dc-winner-serial);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#lottery .dc-winners span{min-width:0;font-size:11px;line-height:16px;color:var(--dc-winner-nick);overflow-wrap:anywhere}
#lottery .dc-steps{display:grid;gap:8px;margin:12px 0 0;padding:0;list-style:none}
#lottery .dc-steps li{display:flex;align-items:flex-start;gap:12px;padding:12px;border:1px solid var(--line);border-radius:12px;background:var(--card)}
#lottery .dc-steps i{display:grid;place-items:center;flex:none;width:24px;height:24px;border-radius:50%;background:var(--gold);font-size:12px;line-height:17px;font-style:normal;font-weight:800;color:var(--ink)}
#lottery .dc-steps span{display:flex;flex-direction:column;gap:4px;min-width:0}
#lottery .dc-steps b{font-size:13px;line-height:19px;font-weight:600;color:var(--ink)}
#lottery .dc-steps small{font-size:12px;line-height:17px;color:var(--muted)}
#lottery .dc-rules{display:flex;align-items:center;justify-content:center;min-height:48px;margin-top:12px;padding:0 12px;border:1px solid var(--dc-rules-line);border-radius:14px;background:var(--dc-face);color:var(--dc-rules-ink);font-size:13px;line-height:19px;font-weight:600;letter-spacing:.52px}
#lottery .dc-compliance{margin:0;font-size:12px;line-height:17px;color:var(--muted)}
#lottery .dc-refresh{display:flex;align-items:center;justify-content:center;width:100%;min-height:48px;margin:0;padding:0 16px;border:1px solid var(--btn-line);border-radius:14px;background:var(--card);box-shadow:none;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
#lottery .dc-question{min-width:0;margin:0;padding:16px;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#lottery .dc-question legend{float:left;width:100%;margin:0 0 8px;padding:0;font-size:13px;line-height:19px;font-weight:600;color:var(--ink)}
#lottery .dc-options{display:flex;flex-wrap:wrap;gap:0 8px;clear:both}
#lottery .dc-option{position:relative;display:inline-flex;align-items:center;min-height:48px;margin:0;cursor:pointer}
#lottery .dc-option input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
#lottery .dc-option span{display:inline-flex;align-items:center;min-height:32px;padding:0 16px;border:1px solid var(--btn-line);border-radius:999px;background:var(--card);font-size:13px;line-height:19px;font-weight:600;color:var(--ink)}
#lottery .dc-option input:checked+span{border-color:transparent;background:var(--btn-face);color:var(--pill-fg)}
#lottery .dc-option input:focus-visible+span{outline:3px solid var(--gold-ink);outline-offset:3px}
#lottery .lot-notice{display:grid;gap:8px;padding:16px;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
#lottery .lot-notice>b,#lottery .lot-notice>h2{margin:0;font-size:15px;line-height:22px;font-weight:600;letter-spacing:0;color:var(--ink)}
#lottery .lot-notice>p{margin:0;font-size:12px;line-height:17px;color:var(--faint)}
#lottery .lot-notice form{display:grid;gap:8px;margin:0}
#lottery .lot-check{display:flex;align-items:center;gap:8px;min-height:48px;font-size:13px;line-height:19px;color:var(--ink-soft)}
#lottery .lot-check input{width:18px;height:18px;margin:0}
#lottery .lot-notice .jbtn{margin-top:4px}
/* 设置与支持 · titled JybListRow groups and the credential note */
#support .sup-page{max-width:640px;margin-inline:auto}
#support .jgroup{margin:0}
#support .jgroup+.jgroup{margin-top:24px}
#support .jgroup-label{margin:0 0 12px;font-size:12px;line-height:17px;font-weight:600;letter-spacing:0;color:var(--muted)}
#support .sup-note{margin:24px 0 0;font-size:12px;line-height:17px;color:var(--faint);text-align:center}
@media(min-width:901px){#me .me-grid{grid-template-columns:minmax(0,360px) minmax(0,1fr);gap:24px}}
@media(min-width:651px) and (max-width:900px){#me .me-page{max-width:560px}}
@media(min-width:651px){
 #login .login-page{padding:24px 0 8px}
 #login .login-back{margin:0 0 12px}
 /* The phone hero's artwork scale (≈ the card width), kept at the bottom right on a wide card */
 #lottery .dc-art{inset:auto 0 0 auto;width:min(100%,400px);height:min(100%,200px)}
}
@media(max-width:650px){
 :is(#me,#lottery,#support) :is(.me-page,.lot-page,.sup-page){padding:16px var(--page-gutter) 24px}
 #login .login-page{max-width:none;padding:16px var(--page-gutter) 24px}
 #login .login-back{display:none}
}

/* 9 · Download — the App's brand card, one card per platform, the App's own screenshots */
#download .dl-page{max-width:720px;margin-inline:auto}
#download .dl-brand{display:flex;align-items:center;gap:16px}
#download .dl-icon{flex:none;width:56px;height:56px;border-radius:14px}
#download .dl-brand h2{margin:0;font-size:20px;line-height:27px;font-weight:800;letter-spacing:0;color:var(--ink)}
#download .dl-brand p{margin:4px 0 0;font-size:12px;line-height:17px;color:var(--muted)}
#download .download-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:12px 0 0}
#download .dl-platform{display:flex;flex-direction:column}
#download :is(.dl-platform,.dl-shots) h3{margin:0;font-size:17px;line-height:24px;font-weight:600;letter-spacing:0;color:var(--ink)}
#download .dl-platform p{margin:4px 0 16px;font-size:12px;line-height:17px;color:var(--muted)}
#download .dl-platform .jbtn{min-width:0;margin-top:auto}
#download .dl-shots{margin-top:12px}
#download .dl-phones{display:flex;justify-content:center;gap:16px;margin-top:12px}
#download .dl-phones img{display:block;width:calc(50% - 8px);max-width:200px;height:auto;border:1px solid var(--hair);border-radius:16px;background:var(--paper)}
#download .dl-note{margin:24px 0 0;font-size:12px;line-height:17px;color:var(--faint)}
@media(max-width:650px){
 #download{padding:0}
 #download .dl-page{padding:16px var(--page-gutter) 24px}
 #download .download-options{grid-template-columns:minmax(0,1fr)}
}

/* 10 · Phones: App header, centred floating navigation, shared gutters */
@media(max-width:650px){
 :root{--page-gutter:16px}                                   /* JybSpace.gutter */
 body{padding-bottom:calc(96px + env(safe-area-inset-bottom))}
 body[data-page=scores]{padding-bottom:calc(132px + env(safe-area-inset-bottom))}
 #main-content.shell{width:100%;margin:0;padding:0}
 .app-header{position:sticky;top:0;z-index:30;display:grid}
 body[data-page=scores] .app-header{border-bottom:0}
 body[data-page=data] .app-back,body[data-page=news] .app-back,body[data-page=me] .app-back{visibility:hidden}
 /* JybTabBar: a glass pill 12 from the sides and 8 above the safe area, 60 + border high */
 .mobile-nav{left:50%;right:auto;bottom:calc(8px + env(safe-area-inset-bottom));transform:translateX(-50%);width:calc(100% - 24px);max-width:420px;height:62px;min-height:0;gap:2px;padding:5px 6px;border:1px solid var(--tabbar-line);border-radius:18px;background:var(--tabbar-fill);box-shadow:var(--tabbar-shadow);-webkit-backdrop-filter:blur(22px) saturate(1.9);backdrop-filter:blur(22px) saturate(1.9)}
 .mobile-nav a{height:50px;min-height:0;gap:2px;line-height:1}
 .mobile-nav a>span,.mobile-nav a.active>span{border-radius:0;background:none}
 .mobile-nav a>.nav-label{width:auto;height:12px}
 /* the App reserves the bar's space: content fades out above it and never shows below it */
 body:after{content:"";position:fixed;z-index:19;left:0;right:0;bottom:0;height:calc(92px + env(safe-area-inset-bottom));background:linear-gradient(transparent,var(--paper) 16px);pointer-events:none}
 footer{padding:20px var(--page-gutter) 8px;margin-top:20px}
 /* scores: the phone rules live in §3 */
 /* data and team */
 /* (data and team phone rules live in §4) */
 /* news and article */
 #article-body p{font-size:16px;line-height:1.85}
 /* match detail */
 #match>.intro{display:none}
 #match .detail-grid>.stack>*+*{margin-top:0}
 #match .scoreboard{padding:22px var(--page-gutter) 18px;border-radius:0;border-width:0 0 1px}
 #match .versus{grid-template-columns:minmax(0,1fr) 104px minmax(0,1fr);gap:10px;margin:20px 0 16px;min-height:88px}
 #match .big-score{font-size:32px}
 .hero-team strong{font-size:15px}.hero-team{gap:10px}
 .team-crest{width:44px;height:44px}
 #match .detail-grid>.stack>.panel{overflow:visible;border:0;border-radius:0}
 #match .tabs{position:sticky;top:48px;z-index:20}
 #match .tabcontent{padding:22px var(--page-gutter)}
 .detail-section-title{font-size:17px}
 .match-news-cards>a{width:180px}.match-news-image{height:96px}
 .lineup-columns{grid-template-columns:minmax(0,1fr)}
 .lineup-columns section{padding:14px}
 /* schedule */
 /* (schedule phone rules live in §7) */
 /* member surfaces */
 /* download */
 .download-options a,.download-options button{width:100%;min-width:0}
}
@media(max-width:360px){
 #scores .match .teams>span{font-size:14px}
 .news-row{grid-template-columns:96px minmax(0,1fr);gap:12px}
}
@media(prefers-reduced-motion:reduce){.app-float.float-c>a{animation:none}}

/* R18-B news */
/* 资讯 is news only, 资讯详情 is one reading column, GIF clips live in their match as
   比赛动图 (owner 2026-10-02 「導航的資訊只放新聞 那GIF只放在對應的比賽內」).
   Every colour is an existing token; this block only adds the pieces R18 introduced. */
/* 资讯 · 更多资讯 is the App PassportMoreLink: the whole bottom row is the hit box, the
   13/600 text action and a 16 chevron sit right, in the App's club navy (R19-F). */
#news .news-more{display:flex;align-items:center;justify-content:flex-end;gap:4px;width:100%;min-height:48px;margin:0;padding:8px 0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--gold-ink);font-size:13px;line-height:19px;font-weight:600;letter-spacing:0;text-align:right;cursor:pointer}
#news .news-more svg{flex:none;width:16px;height:16px}
#news .news-more:active{background:var(--press)}
@media(hover:hover){#news .news-more:hover{background:var(--press)}}
/* 资讯详情 · NewsArticleScreen at every width; on a wide screen the same column, centred,
   at a reading measure (about 42 characters a line). */
@media(min-width:651px){
 #article{max-width:720px}
 #article .news-article{padding:20px 20px 48px}
}
/* 比赛动图 · App MatchClipCard (JybCard.dense): 12 inset, 14 radius, hair outline and no
   shadow; a 108×61 cover (8 radius, surface2 until it loads), a 13/19 two-line title, the
   12/17 time and a 16 chevron. One column on a phone, two in the wider column. */
.md-gifs{margin-top:16px}
.md-gif-list{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;padding:4px var(--md-gutter) 8px}
.md-gif{display:grid;grid-template-columns:108px minmax(0,1fr) 16px;column-gap:12px;align-items:start;min-width:0;padding:12px;border:1px solid var(--md-hair);border-radius:14px;background:var(--card);color:var(--ink);text-decoration:none}
.md-gif:active{background:linear-gradient(var(--press),var(--press)),var(--card)}
.md-gif-cover{position:relative;display:block;width:108px;height:61px;overflow:hidden;border-radius:8px;background:var(--surface-2)}
.md-gif-cover img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
.md-gif-copy{display:flex;flex-direction:column;gap:4px;min-width:0}
.md-gif-copy strong{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--ink);font-size:13px;line-height:19px;font-weight:400;overflow-wrap:anywhere}
.md-gif-copy small{color:var(--muted);font-size:12px;line-height:17px;font-variant-numeric:tabular-nums}
.md-gif>svg{display:block;width:16px;height:16px;margin-top:2px;color:var(--muted)}
@media(hover:hover){.md-gif:hover strong{color:var(--gold-ink)}}
@media(min-width:651px){.md-gif-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* R18-B news end */
/* R18-D data+member — 数据, 球队资料, 赛程 and the member surfaces (我的, 登录, 抽奖与序号,
   设置与支持, 下载) taken the rest of the way to the App: standings_screen.dart,
   standings_table.dart, team_screen.dart, schedule_versus_card.dart, auth_shell.dart,
   auth_agreement_row.dart, jyb_list_row.dart, jyb_page_header.dart. Overrides only; every
   colour is an existing token. */
/* Standings (StandingsHeadRow / StandingsRow): cell rules are JybTokens.border; the board tabs
   divide on hair (JybUnderlineTabs); on PC the board, the team band and the schedule cards are
   JybCard faces (1px hair). */
:is(#data,#team) .standings-table :is(th,td){border-bottom-color:var(--row-line)}
#data .data-modes{border-bottom-color:var(--hair)}
@media(min-width:651px){
 :is(#data,#team) .data-table-wrap,#team .team-identity{border-color:var(--hair)}
}
@media(min-width:901px){#schedule .schedule-versus{border-color:var(--hair)}}
/* Phones: StandingsScreen keeps the league chips and the head row fixed under the page header
   while the rows scroll (the web-only 积分榜/射手榜 tabs scroll away above them). */
@media(max-width:650px){
 #data .data-leagues{position:sticky;top:48px;z-index:3;background:var(--paper)}
 #data .standings-table thead th{top:96px}
}
/* ScheduleVersusCard: a row that does not open keeps the chevron's width (8 + 16), so every
   status tag lines up on the right. */
#schedule div.schedule-versus .schedule-foot:after{content:"";flex:none;width:16px}
/* 登录: AuthPageHeader is the plain JybPageHeader (page ground, not the pearl surface); 忘记密码
   and the two agreement links are the App's text-action role (link 13/600, links underlined). */
@media(max-width:650px){body[data-page=login] .app-header{background:var(--paper)}}
#login .auth-forgot,#login .auth-agree a{color:var(--link)}
/* JybListRow: 8 between the texts and the chevron (12 stays between the tile and the texts). */
:is(#me,#support) .jrow-end{margin-left:-4px}
/* 抽奖 and 设置与支持 on PC: the back link above the title, as on the team and login pages. */
@media(min-width:651px){
 :is(#lottery,#support) :is(.lot-page,.sup-page){padding-top:20px}
 :is(#lottery,#support) :is(.lot-page,.sup-page)>.back{margin:0 0 12px}
 :is(#lottery,#support) .back+.intro{padding-top:0}
}
@media(max-width:650px){:is(#lottery,#support) :is(.lot-page,.sup-page)>.back{display:none}}
/* R18-A performance */
/* Long lists skip layout and paint while far off screen. Each row keeps its last measured
   height (auto) and starts from the measured content height (padding and hairline come on
   top): score rows 83+1 at every width, news rows 69+8+8+1 on phones and 96+14+14+1 from
   651px. A row on screen renders exactly as before. */
#match-list>.match{content-visibility:auto;contain-intrinsic-block-size:auto 83px}
#news .news-row{content-visibility:auto;contain-intrinsic-block-size:auto 69px}
@media(min-width:651px){#news .news-row{contain-intrinsic-block-size:auto 96px}}
/* R18-C scores+match ──────────────────────────────────────────────────────────────
   Round 18, part C: the 比分 list and 比赛详情 matched to the App's own widgets
   (match_row.dart, matches_screen.dart, match_detail_header.dart, live_pane.dart,
   jyb_tabs.dart JybSegmented, jyb_state_view.dart). Overrides only, appended last so
   the shared sections above stay as they are; every colour is an existing token. */

/* Scores · crest (MatchRow _Crest): the 20 disc is surface with an outside hair ring and
   belongs to the slot, so a crest that never draws leaves the App's empty circle. */
.score-team-crest{overflow:hidden;border-radius:50%;background:var(--card);box-shadow:0 0 0 1px var(--hair)}
.score-team-crest img{background:none;box-shadow:none}
.score-team-crest.crest-failed{overflow:visible;border-radius:0;background:none;box-shadow:none}

/* Scores · live pill (MatchRow _StatusZone): the clock at 800, the phase beside it at 600. */
#scores .match .time.live>b{font-weight:800}
#scores .match .time.live>span{font-weight:600}

/* Scores · PC: the same 足球 screen in one centred column of App width (tool row, tabs,
   rows, the 赛程 band and the 一级/全部 pill keep their App sizes), not rows stretched
   across the shell. The header band itself still spans the screen (§3). */
:root{--scores-col:560px}
@media(min-width:651px){
 #scores{max-width:var(--scores-col)}
 body[data-page=scores] .app-header{width:min(var(--scores-col),calc(100% - 2*var(--shell-pad)))}
}

/* Match · phone header: the App screen has no title bar. The theatre header carries the
   back chip (_Bar: 4 inset, a 48 row, the 36 hair circle on the gutter) and the
   赛况 / 阵容 tabs pin to the top edge. P3-5 (2026-10-14): with the 打开 App notice too (it
   kept a white 「‹ 比赛详情」 bar over the hero on jyb9.com), and only while the hero is drawn:
   a match that could not be read keeps the shell header and its back. */
@media(max-width:650px){
 body[data-page=match]:has(.md-hero) .app-header{display:none}
 .md-hero{padding-top:4px}
 .md-hero-bar{display:flex}
 .md-tabs{top:0}
}
/* P3-7 · a match that does not exist offers 返回 (the App pops back) in the pill every retry wears (.blank button) */
.page-error .blank-back{display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;margin-top:16px;padding:0 16px;border-radius:999px;background:var(--pill-face);box-shadow:var(--btn-glow);color:var(--pill-fg);font-size:13px;font-weight:600;letter-spacing:.04em;text-decoration:none}
.page-error .blank-back:active{background:linear-gradient(var(--press),var(--press)),var(--pill-face)}

/* Match · team names (_Side): one line that only shrinks to fit, then the › of the App's
   team entry where the web has that team's page; the team rule stays at the foot. */
.md-team-line{display:flex;align-items:flex-end;max-width:100%;min-width:0;margin:8px 0}
#match .md-team-line>.md-team-name{flex:0 1 auto;min-width:0;margin:0}
.md-team-chev{flex:none;margin-left:4px;color:var(--md-theatre-accent);font-size:15px;font-style:normal;font-weight:600;line-height:19px}
.md-side.is-link .md-team-name{font-size:min(15px,(100cqi - 13px) / var(--md-name-em,1))}
a.md-side{color:inherit;text-decoration:none}
a.md-side:focus-visible{outline:2px solid var(--md-theatre-accent);outline-offset:2px;border-radius:12px}
@media(hover:hover){a.md-side:hover .md-team-name{color:var(--md-theatre-accent)}}

/* Match · status strip (_StatusStrip): a 48 row 8 under the lockup (the animation entry's
   hit, so the header never jumps when the note arrives): dot · parts · rule, then the
   entry (MatchAnimationInlineEntry 11/800): a reason in theatre muted, 实时动画 › in accent. */
.md-status{min-height:48px}
.md-anim-note{flex:0 1 auto;min-width:0;max-width:40%;margin-left:8px;overflow:hidden;color:var(--md-theatre-muted);font-size:11px;line-height:16px;font-weight:800;text-overflow:ellipsis;white-space:nowrap}
.md-anim-note:empty{display:none}
a.md-anim-note{display:inline-flex;align-items:center;min-height:48px;color:var(--md-theatre-accent);text-decoration:none}
a.md-anim-note i{flex:none;margin-left:4px;font-size:13px;font-style:normal;font-weight:600;line-height:1}

/* Match · 事件直播 heading with its accessory (DetailSectionHeader 8/16/0): the control
   sits beside the title while a 16 rule still fits, else on its own line at the end. */
.md-section-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;column-gap:8px;padding:8px var(--md-gutter) 0}
#match .md-section-row>.md-section{flex:1 1 auto;padding:0}
.md-section-row .md-section-rule{flex-basis:16px;min-width:16px}
/* JybSegmented: a 36 surface2 rail with the border hairline, cells 4 in from its edge and
   equal, 28 faces in 48 hits; selected = the black pill with pillFg, idle ink, 13/600. */
.md-seg{display:inline-grid;flex:none;grid-template-columns:1fr 1fr;align-items:center;height:36px;margin:6px 0;padding:0 3px;border:1px solid var(--row-line);border-radius:999px;background:var(--surface-2)}
.md-seg label{position:relative;display:grid;place-items:center;height:48px;margin:-6px 0;cursor:pointer}
.md-seg input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.md-seg span{display:grid;place-items:center;min-width:48px;height:28px;padding:0 8px;border-radius:999px;color:var(--ink);font-size:13px;font-weight:600;line-height:19px;white-space:nowrap;pointer-events:none}
.md-seg input:checked+span{background:var(--pill-face);box-shadow:var(--sh-1);color:var(--pill-fg)}
.md-seg input:focus-visible+span{outline:3px solid var(--gold-ink);outline-offset:2px}
@media(hover:hover){.md-seg input:not(:checked):hover+span{background:var(--press)}}
.md-key-empty{display:none}
.md-feed:has(#md-evt-key:checked) .md-events>:not(.is-key){display:none}
.md-feed:has(#md-evt-key:checked) .md-key-empty{display:block}

/* Match · error state (JybStateView.error): the 74 disc is a surface2 halo, not a flat fill. */
.md-state.is-error .md-state-icon{background:radial-gradient(circle 50px at 50% 42%,var(--surface-2),transparent)}

@media(min-width:651px){
 .md-side.is-link .md-team-name{font-size:min(17px,(100cqi - 15px) / var(--md-name-em,1))}
 .md-team-chev{font-size:17px;line-height:22px}
 .md-anim-note{font-size:12px;line-height:17px}
}
/* PC two columns: 01 统计 sits on the same title line as 02 事件直播 and its accessory row. */
@media(min-width:901px){
 .md-live-cols>.md-block:first-child:not(:only-child)>.md-section{padding-top:21px}
}

/* R19-A shell+member ───────────────────────────────────────────────────────────────────
   Round 19, part A: the shell (site header, page gutters, phone header, tab bar and the App
   download edge tab) and the member surfaces (我的, 登录, 抽奖与序号, 设置与支持, 下载 App),
   measured against the App at 360 dp (App 254 screenshots and uiautomator bounds) and its
   source: jyb_page_header.dart, jyb_tab_bar.dart, jyb_card.dart, jyb_list_row.dart,
   me_widgets.dart, auth_shell.dart, auth_agreement_row.dart, login_screen.dart,
   about_screen.dart. Overrides only; every colour is an existing token. */

/* Edge tab · open at every width, also before the script runs (owner 2026-10-03
   「網頁版下載app默認展開」); a reader's own collapse is remembered (client.mjs). Wherever it is
   open, the layout keeps its place free, so it never covers anything that can be tapped:
   wide screens keep it in the side margin, the in-between widths widen the page gutters to
   clear it, and phones dock it above the tab bar inside the band the page already reserves.
   It stays clear of a landscape notch. */
.app-float.float-c{right:env(safe-area-inset-right,0px)}
@media(min-width:651px) and (max-width:1199px){
 /* gutter = the open tab (46) + 8, plus the notch side of a phone held sideways */
 :root{--shell-pad:calc(54px + max(env(safe-area-inset-left,0px),env(safe-area-inset-right,0px)))}
}

/* Site header and footer on the page column (880, the width 数据 and 我的 read at; 资讯's 640
   column starts on its left edge, see R19 integration at the end):
   the brand starts on the page title's left edge and the tab items end on the content's
   right edge, instead of 108 px outside it on each side. */
@media(min-width:651px){
 body>header>.head{max-width:calc(var(--narrow) + 2*var(--shell-pad))}
 body>footer{width:calc(100% - 2*var(--shell-pad));max-width:var(--narrow);padding-inline:0}
 /* 我的, 抽奖与序号, 设置与支持 and 下载 App read in that same column (was 560 on tablets for 我的,
    640, 640 and 720), so the page's left edge does not move between tabs; 登录 keeps its
    centred auth card (AuthShell, 440). */
 :is(#me .me-page,#lottery .lot-page,#support .sup-page,#download .dl-page){max-width:var(--narrow)}
}

/* JybPageHeader: the back chevron is an 18 glyph centred in its 48 slot (tool glyphs stay 24). */
.app-header .app-back svg{width:18px;height:18px}

@media(max-width:650px){
 /* JybTabBar: 60 high including its 1px frame, so the cells are 48 (60 - 2 x (5 + 1)). */
 .mobile-nav{height:60px}
 .mobile-nav a{height:48px}
 /* Reserve the bottom navigation band; the later phone shell sets the final spacing. */
 body[data-page]{padding-bottom:calc(136px + env(safe-area-inset-bottom))}
 body:after{height:calc(134px + env(safe-area-inset-bottom))}
}

/* JybCard paints its 1px hair frame over its content (a Material shape border), so the card
   is exactly as high as its content and a dark panel runs to the card's edge: the 我的 ticket
   is 351 high (was 353), a two-row list 113 (was 115), texts sit 16 in, not 17. */
:is(#me .pass-card,:is(#me,#support) .jlist,#me #signout,#download .jcard){position:relative;border:0}
:is(#me .pass-card,:is(#me,#support) .jlist,#me #signout,#download .jcard):after{content:"";position:absolute;inset:0;z-index:1;border:1px solid var(--hair);border-radius:inherit;pointer-events:none}
/* MeIdentityCard: the member head keeps 16 under it (the guest ticket 12); the name is one
   line ending in an ellipsis, and every asset value stays on one line. */
#me .pass-card[data-state=member] .pass-top{padding-bottom:16px}
#me .pass-card[data-state=member] .pass-id h2{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
#me .pass-asset-value{white-space:nowrap}
/* 登录: a TextButton keeps 12 inside its 48 hit (Material 3), so 忘记密码 ends 12 in from the
   card's content edge; the agreement text starts 12 down beside its 48 checkbox. */
#login .auth-forgot,#login .auth-switch{padding:0 12px}
#login .auth-forgot{margin-right:0}
#login .auth-agree>:is(span,label[for]){padding-top:12px}
/* 下载 App: a platform card is title, note, 12, the button (the App's update card). */
#download .dl-platform p{margin-bottom:12px}
/* end R19-A */
/* R19-B scores+match ──────────────────────────────────────────────────────────────
   Round 19, part B: 比分 and 比赛详情 taken the rest of the way to the App
   (match_row.dart, matches_screen.dart, scores_header.dart, match_detail_screen.dart,
   named_team_stats_panel.dart, match_clip_card.dart). Overrides only, appended last;
   every colour is an existing token. */

/* Scores · PC: the 足球 screen sits in the same centred column as 比赛详情, 资讯 and 榜单
   (--narrow, 880), so the pages share one pair of edges. The tool row, tabs, date strip and
   search row span that column. From 768 the App rows are laid two to a line, each at the
   phone width the row was drawn for (about 350–430), in the App's own order read left to
   right; status bands, notes and states span both. */
@media(min-width:651px){:root{--scores-col:var(--narrow)}}
@media(min-width:768px){
 #scores #match-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:24px;align-items:start}
 #scores #match-list>:not(.match){grid-column:1/-1}
}

/* 比赛详情 · 更多球队统计 (NamedTeamStatsPanel, an ExpansionTile under 01 统计): a 56 row with the
   15/600 title 16 in, the 12/400 已保存的比赛统计 subtitle when archived and the 24 expand glyph
   24 from the end (ListTile insets), which turns over when open; inside, the sides line, then
   one row per counter — 13/600 ink
   values at the ends and the 13/400 inkSoft label centred, 8 above and below. Retry is the
   App's text action (link, 13/600, 48 hit). */
.md-more{margin:0}
.md-more[open]{border-block:1px solid var(--md-border)}
.md-more>summary{display:flex;align-items:center;gap:12px;min-height:56px;padding:8px 24px 8px var(--md-gutter);cursor:pointer;list-style:none}
.md-more>summary::-webkit-details-marker{display:none}
.md-more>summary:focus-visible{outline:3px solid var(--gold-ink);outline-offset:-3px}
.md-more-head{display:flex;flex:1;flex-direction:column;min-width:0}
.md-more-head strong{color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
.md-more-head small{color:var(--muted);font-size:12px;line-height:17px;font-weight:400}
.md-more-chev{width:24px;height:24px;color:var(--muted);transition:transform .2s ease-out}
.md-more[open] .md-more-chev{transform:rotate(180deg)}
.md-more-body{padding:0 var(--md-gutter) 8px}
#match .md-more-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr) minmax(0,1fr);align-items:center;margin:0;padding:8px 0;font-size:13px;line-height:19px}
.md-more-row b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.md-more-row b:last-child{text-align:right}
.md-more-row span{min-width:0;color:var(--md-ink-soft);font-weight:400;text-align:center;overflow-wrap:anywhere}
.md-more-retry{padding:0 var(--md-gutter)}
@media(hover:hover){.md-more>summary:hover{background:var(--press)}}
@media(prefers-reduced-motion:reduce){.md-more-chev{transition:none}}

/* 比赛详情 · 前瞻 (PreviewPane, the third tab when /analysis has something to draw): the same
   DetailStyle language — numbered heads, the sides line and tug rows (胜率 at 800). Rank figures
   15/800 (home accentDeep, away inkSoft, none muted) joined by a border rule; W/D/L beads 16
   with an 11/800 letter on the up / muted / live frames and fills; fixture lists of 11 lines on
   hair rules after a tabular date column; the goal-time axis grows the home bar left and the
   away bar right (7 high, pill ends, counts outside, minutes 52 in the middle); 赛制 12/17
   inkSoft as the server wrote it. From 901 the sections flow in two columns. */
.pv-body{padding:0 var(--md-gutter) 8px}
#match .pv-rank{display:flex;align-items:center;gap:8px;margin:0}
.pv-rank b{flex:0 1 auto;max-width:calc(50% - 16px);color:var(--green);font-size:15px;line-height:22px;font-weight:800;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.pv-rank b:last-child{color:var(--md-ink-soft);text-align:right}
.pv-rank b.is-none{color:var(--muted)}
.pv-rank i{flex:1 1 16px;height:1px;background:var(--md-border)}
.pv-neutral{display:block;margin-top:8px;color:var(--muted);font-size:11px;line-height:16px}
.pv-bead-row{display:flex;gap:12px;margin-bottom:8px}
.pv-beads{display:flex;flex:1 1 0;flex-direction:column;align-items:flex-start;gap:4px;min-width:0}
.pv-beads.is-end{align-items:flex-end}
.pv-beads>span{display:flex;flex-wrap:wrap;gap:4px}
.pv-beads.is-end>span{justify-content:flex-end}
.pv-beads small{color:var(--muted);font-size:11px;line-height:16px}
.pv-bead{display:grid;place-items:center;box-sizing:border-box;width:16px;height:16px;border:1px solid;border-radius:50%;font-size:11px;line-height:1;font-style:normal;font-weight:800}
.pv-w{border-color:var(--up);background:var(--up-tint);color:var(--up-text)}
.pv-d{border-color:var(--muted);background:var(--surface-2);color:var(--muted)}
.pv-l{border-color:var(--live);background:var(--live-tint);color:var(--live-text)}
.md-tug.is-strong .md-tug-values>b{font-weight:800}
.pv-fixtures{margin:0 0 8px}
#match .pv-fixture{display:grid;grid-template-columns:68px minmax(0,1fr) auto minmax(0,1fr);align-items:center;margin:0;padding:8px var(--md-gutter);border-bottom:1px solid var(--md-hair);font-size:11px;line-height:16px}
.pv-date{overflow:hidden;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.pv-team{min-width:0;overflow:hidden;color:var(--ink);text-overflow:ellipsis;white-space:nowrap}
.pv-fixture>.pv-team:nth-child(2){text-align:right}
.pv-fixture>b{padding:0 8px;color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.pv-fixture>b.is-score{color:var(--ink);font-weight:800}
.pv-axis{padding:0 var(--md-gutter) 8px}
#match .pv-axis-row{display:flex;align-items:center;margin:0 0 8px;font-size:11px;line-height:16px}
.pv-axis-row>b{flex:none;width:24px;color:var(--md-ink-soft);font-weight:600;font-variant-numeric:tabular-nums;text-align:center}
.pv-axis-bar{display:flex;flex:1 1 0;min-width:0;height:7px;margin-right:4px}
.pv-axis-bar.is-home{justify-content:flex-end;margin:0 0 0 4px}
.pv-axis-bar i{display:block;height:100%;border-radius:0 999px 999px 0;background:var(--md-viz-away)}
.pv-axis-bar.is-home i{border-radius:999px 0 0 999px;background:var(--md-viz-home)}
.pv-axis-label{flex:none;width:52px;color:var(--muted);font-variant-numeric:tabular-nums;text-align:center}
#match .pv-rule{margin:0;padding:0 var(--md-gutter) 8px;color:var(--md-ink-soft);font-size:12px;line-height:17px;white-space:pre-line;overflow-wrap:anywhere}
@media(min-width:901px){
 .pv-pane{column-count:2;column-gap:24px}
 .pv-pane>.md-block{break-inside:avoid}
}
/* end R19-B */
/* R19-C data+team+schedule ────────────────────────────────────────────────────────
   Round 19, part C: 榜单 (积分榜 / 射手榜), 球队资料 and 申花赛程 against the App's own widgets
   (standings_screen.dart, standings_table.dart, team_screen.dart, schedule_versus_card.dart).
   Overrides only, appended last; every colour is an existing token. */
/* PC and tablet board tabs: the first label starts on the page's left edge, in line with the
   heading, the league chips and the table (it sat 22 px in); 24 between the labels, each hit
   at least 48, and the App indicator (18×3, 6 above the edge) stays centred under its label. */
@media(min-width:651px){
 #data .data-modes{gap:24px}
 #data .data-modes button{min-width:48px;padding:0}
}
/* ScheduleVersusCard._side: the own club's name wears the club colour (App clubNavy, set in
   R19-F with the date and VS); a played row dims both names to muted. */
#schedule .schedule-teams .is-own{color:var(--gold-ink)}
/* end R19-C */
/* R19-D news+article ─────────────────────────────────────────────────────────────
   资讯 and 资讯详情 taken the rest of the way to the App (owner 2026-10-02 「給我做到跟APP一膜
   一樣的效果」「排版還是沒對齊」): team_news_section.dart (_NewsTile, _PassportNewsImage),
   passport_controls.dart (PassportSectionCard, PassportStatusLine, PassportMoreLink),
   jyb_tabs.dart (JybUnderlineTabs) and news_article_screen.dart (NewsArticleScreen, NewsImage).
   The App's numbers at every width — a wide screen only gets a wider, centred column — and
   every colour an existing token. Overrides only, appended last. */
/* 资讯 categories · JybUnderlineTabs: 48 cells, 16 inside each side, 15/400 muted → 15/800 ink,
   an 18×3 act indicator 6 above the edge. Natural widths that scroll when they do not fit (a
   phone), cells sharing the strip equally when they do (the App's expand); the first label sits on
   the card's outer edge, as the App's strip does over its 16 gutter. */
#news .news-tabs{display:flex;gap:0;margin:0;padding:0;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;white-space:nowrap;border-bottom:1px solid var(--hair)}
#news .news-tabs button{position:relative;flex:1 0 auto;min-width:48px;min-height:48px;margin:0;padding:12px 16px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400;letter-spacing:0;white-space:nowrap}
#news .news-tabs button.active{color:var(--ink);font-weight:800}
#news .news-tabs button:after,#news .news-tabs button.active:after{content:"";position:absolute;left:50%;bottom:6px;width:0;height:3px;border-radius:999px;background:var(--gold-ink);transform:translateX(-50%);transition:width .14s ease-out}
#news .news-tabs button.active:after{width:18px}
#news .news-tabs button:active{background:var(--press)}
@media(hover:hover){#news .news-tabs button:not(.active):hover{color:var(--ink)}}
@media(prefers-reduced-motion:reduce){#news .news-tabs button:after{transition:none}}
/* The card · PassportSectionCard: JybCard (surface, 1px hair, 14 radius, no shadow) whose content
   sits 16 from the outer edge at the sides and 5 at the top and bottom (the border is part of it). */
#news .news-card{padding:4px 15px;border:1px solid var(--hair);border-radius:14px;background:var(--card);box-shadow:none}
/* Rows · _NewsTile: 8 above and below; the title column, 12, then a 92-wide 4:3 cover (12 radius,
   paper, contained); 15/22 600 ink title in at most two lines, 8, the 12/17 muted time; a 1px hair
   between tiles. The first tile leads: its cover over the full width, 12, a 17/24 600 title. */
#news .news-row{grid-template-columns:minmax(0,1fr) 92px;grid-template-areas:"text pic";column-gap:12px;row-gap:12px;align-items:start;padding:8px 0}
#news .news-row.is-text{grid-template-columns:minmax(0,1fr);grid-template-areas:"text"}
#news .news-row.is-lead{grid-template-columns:minmax(0,1fr);grid-template-areas:"pic" "text";column-gap:0;align-items:start;padding:8px 0}
#news .news-row.is-lead.is-text{grid-template-areas:"text"}
#news .news-text{gap:8px}
#news .news-text strong{-webkit-line-clamp:2;font-size:15px;line-height:22px;font-weight:600;color:var(--ink)}
#news .news-row.is-lead .news-text strong{font-size:17px;line-height:24px;font-weight:600;-webkit-line-clamp:2}
#news .news-thumb{border-radius:12px;background:var(--paper)}
/* A cover that is being asked for a second time keeps its paper box (never a broken glyph). */
#news .news-thumb img[data-wait]{visibility:hidden}
/* Status lines · PassportStatusLine: 12/17 muted with 12 above and below; a failed read carries
   the 重试 text action (13/600, 48 hit) at the right. A list that ends without 更多资讯 keeps 12
   more under its last tile (PassportSectionCard.statusGap). */
#news .news-status{margin:0;padding:12px 0;font-size:12px;line-height:17px;color:var(--muted)}
#news .news-failed{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0}
#news .news-failed>span{padding:12px 0}
#news .news-failed>button{flex:none;min-width:48px;min-height:48px;margin:0;padding:0 8px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--gold-ink);font-size:13px;line-height:19px;font-weight:600;letter-spacing:0}
#news .news-failed>button:active{background:var(--press)}
#news .news-card:has(>#news-more[hidden]):has(>#news-empty[hidden]):not(:has(.news-failed))>.news-feed{padding-bottom:12px}
@media(max-width:650px){
 #news .news-tabs{padding:0;background:var(--card)}
 #news .news-card{margin:12px var(--page-gutter) 0}
}
/* PC: the same tiles in one centred column; nothing grows but the column. */
@media(min-width:651px){
 #news{max-width:640px}
 #news .news-tabs{background:none}
 #news .news-card{margin:16px 0 0;padding:4px 15px}
 #news .news-row{grid-template-columns:minmax(0,1fr) 92px;column-gap:12px;padding:8px 0;contain-intrinsic-block-size:auto 69px}
 #news .news-row.is-text{grid-template-columns:minmax(0,1fr)}
 #news .news-row.is-lead{grid-template-columns:minmax(0,1fr);grid-template-areas:"pic" "text";column-gap:0;align-items:start;padding:8px 0}
 #news .news-row.is-lead.is-text{grid-template-areas:"text"}
 #news .news-row.is-lead .news-text strong{font-size:17px;line-height:24px;font-weight:600;-webkit-line-clamp:2}
}
/* 资讯详情 pictures · NewsImage: full width, its own shape, 10 radius, 18 below. The box is held
   from the provider's size while the picture is on its way (paper shows, nothing jumps); a picture
   that cannot be shown becomes the App's face: 80 high, paper, the 24 image glyph in iconMuted. */
#article .art-img{position:relative;display:block;margin:0 0 18px;overflow:hidden;border-radius:10px;background:var(--paper)}
#article .art-img>img,#article #article-body .art-img>img{display:block;width:100%;max-width:100%;height:auto;margin:0;border-radius:0;background:none}
#article .art-img>img[data-wait]{visibility:hidden}
#article .art-img>i{display:none;font-style:normal;color:var(--muted)}
#article .art-img>i svg{display:block;width:24px;height:24px}
#article .art-img.img-failed{display:grid;place-items:center;height:80px}
#article .art-img.img-failed>i{display:block}
/* A GIF arrives as production's animation, 360 wide (crest-proxy.js animWidth): on a phone it fills
   the column as in the App; a wider column shows it at that width, centred, instead of stretching a
   256-colour animation into blocks. A failed one keeps the full-width face. */
@media(min-width:651px){#article .art-img.art-gif:not(.img-failed){max-width:360px;margin-inline:auto}}
/* PC: 资讯详情 reads in the same centred 640 column as 资讯, its back link, title and text on the
   column's edge where the list has its heading, categories and card — opening a story moves nothing. */
@media(min-width:651px){
 #article{max-width:640px}
 #article .news-article{padding:20px 0 48px}
}
/* A read that failed: NewsArticleScreen's line and its 重新加载 text action (13/600 link, 48 hit). */
#article .art-state{display:flex;flex-direction:column;align-items:center;padding:22px 0 0;text-align:center}
#article .art-state p{margin:0;font-size:15px;line-height:22px;color:var(--ink)}
#article .art-state button{min-width:48px;min-height:48px;margin:0;padding:0 8px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--link);font-size:13px;line-height:19px;font-weight:600;letter-spacing:0}
#article #article-body p{white-space:normal}
/* end R19-D */
/* R19 integration ─────────────────────────────────────────────────────────────────
   Where the four R19 blocks meet. Overrides only, appended last; no new colour.
   PC and tablet: 资讯 and 资讯详情 keep R19-D's 640 reading column, on the left edge every other tab
   shares — R19-A's 880 page column that the brand, the page titles, 我的 and the footer start on, and
   R19-B's 足球 list on that same column — so switching tabs moves no edge (at 1440 the column sat
   120 px right of the brand; at 1024 also 120; at 768, 10) and opening a story still moves nothing. */
@media(min-width:651px){
 :is(#news,#article){margin-left:max(0px,(100% - var(--narrow))/2);margin-right:auto}
}
/* end R19 integration */
/* R19-E lineup+match-news ────────────────────────────────────────────────────────
   Round 19, part E: 比赛详情 · 阵容 and 赛况's 本场快讯 taken the rest of the way to the App (owner
   2026-10-03 「陣容 還有比賽詳情的新聞要橫向排好」「給我做到跟APP一膜一樣的效果」): lineup_overview.dart,
   lineup_pitch.dart, t339_lineup_player_avatar.dart, lineup_player_sheet.dart, detail_style.dart,
   jyb_sheet.dart, jyb_dialog.dart and match_news_strip.dart. Overrides only, appended last; every
   colour is an existing App token (the four names below are App values this page had not named). */
.md-page{
 --md-marker-hover:#ffffff14;      /* JybTokens.accentInk @ .08: a pitch marker's highlight */
 --md-marker-press:#ffffff24;      /* JybTokens.accentInk @ .14: its splash */
 --md-sheet-shadow:0px -8px 30px #0000002e; /* JybTokens.shSheet */
}
/* 阵容 starts right under the tab strip: the App's lineup list has no top inset (赛况 keeps 16). */
#detail-content:has(>.md-lineup){padding-top:0}
/* 01 阵容示意 · DetailSectionHeader with its accessory: 8 above, the ⓘ (20, iconMuted) in a 48 box
   on the title's line, the hairline stopping 8 before it. */
.md-lineup-head{min-height:56px}
#match .md-info{display:grid;place-items:center;flex:none;width:48px;height:48px;min-height:48px;margin:0;padding:0;border:0;border-radius:50%;background:none;color:var(--muted)}
#match .md-info svg{display:block;width:20px;height:20px}
/* The pitch · LineupPitch: the field is the pane less 8 a side, up to 480, at 0.64 (0.62 when the
   markers need it); the corner labels sit in the field's corners, or just off it when a marker
   comes near them. A marker is a 48-high box as wide as the densest line allows: the portrait
   (32, or 28 when the lineup needs room) over the 11/600 short name, 2 between. */
.lineup-pitch{display:flex;flex-direction:column;aspect-ratio:auto}
.md-pitch-field{position:relative;flex:none;width:100%}
.md-pitch-off{display:flex;padding:12px 12px 2px}
.md-pitch-off.is-home{padding:2px 12px 12px}
.md-pitch-label{display:flex;flex-direction:column;align-items:flex-start;min-width:0;max-width:100%;padding:0 2px;border-radius:4px;background:var(--md-pitch-grass)}
.md-pitch-field>.md-pitch-label{position:absolute;z-index:1;left:12px;max-width:var(--md-label-w)}
.md-pitch-field>.md-pitch-label-away{top:10px;bottom:auto}
.md-pitch-field>.md-pitch-label-home{top:auto;bottom:10px}
.md-pitch-off>.md-pitch-label{position:static}
.md-pitch-label b{display:flex;gap:8px;max-width:100%;color:var(--md-pitch-away-ink);font-size:12px;line-height:15.6px;font-weight:800;white-space:nowrap}
.md-pitch-label-home b{color:var(--md-pitch-home-ink)}
.md-pitch-label b>span{flex:none}
.md-pitch-label b>.md-pitch-form{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.md-pitch-label small{display:block;max-width:100%;overflow:hidden;color:var(--md-theatre-ink);font-size:11px;line-height:14.3px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
#match .pitch-player{position:absolute;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;width:var(--md-marker-w);height:48px;min-height:0;margin:0;padding:0;border:0;border-radius:8px;background:none;color:var(--md-theatre-ink);font:inherit;letter-spacing:0;transform:translate(-50%,-50%);text-align:center}
@media(hover:hover){#match .pitch-player:hover{background:var(--md-marker-hover)}}
#match .pitch-player:active{background:var(--md-marker-press)}
#match .pitch-player:focus-visible{outline:2px solid var(--md-theatre-accent);outline-offset:0}
.pitch-player>strong{width:auto;max-width:100%;margin-top:2px;line-height:13.2px}
/* LineupPortrait: the photo fills the 2-wide team ring (gold at home, silver away) over surface2
   with the 20 person glyph; the number badge sits 4 past the right edge on the bottom edge — the
   team's label ink on ink, a 1 hairline of grass inside it, 16 high (14 on the compact one). */
.md-portrait{display:grid;width:32px;height:32px;padding:0;background:var(--surface-2);background-clip:border-box}
.md-portrait.is-compact{width:28px;height:28px}
.md-portrait>.md-icon{width:20px;height:20px}
.md-portrait>img{inset:0;width:100%;height:100%}
.md-portrait>b{z-index:1;box-sizing:border-box;height:16px;padding:0 2px;border:0;box-shadow:inset 0 0 0 1px var(--md-pitch-grass);line-height:16px}
.md-portrait.is-compact>b{width:16px;min-width:0;height:14px;padding:0;overflow:hidden;line-height:14px}
/* Under the pitch: the caption, then each coach (_CoachLine: the 24 portrait, 8, 12/17 inkSoft). */
#match .md-coach{display:flex;align-items:center;gap:8px;margin:0;padding:8px var(--md-gutter) 0;color:var(--md-ink-soft);font-size:12px;line-height:17px}
#match :is(.md-coach,.md-team-coach)>span:last-child{flex:1;min-width:0}
/* The list · _TeamCard: JybCard (surface, its 1 hair painted over the edge, radius 14) with 12 in
   (4 at the foot): the heading, 8, 阵型 and the 15/800 formation on one centred line, the coach,
   a role-conflict note, 4, then the rows. */
.md-team-card{position:relative;border:0}
.md-team-card:after{content:"";position:absolute;inset:0;border:1px solid var(--md-hair);border-radius:inherit;pointer-events:none}
#match .md-formation{align-items:center;margin:8px 0 0}
#match .md-team-coach{display:flex;align-items:center;gap:8px;margin:8px 0 0;color:var(--md-ink-soft);font-size:12px;line-height:17px}
#match .md-team-conflict{margin:8px 0 0;color:var(--md-warn-text);font-size:12px;line-height:17px}
.md-team-card>.md-players{margin-top:4px}
#match .md-team-card>.md-team-empty{margin-top:4px}
.md-group .md-players{margin-top:0}
/* _EntryRow: at least 56 high, 8 above and below — the 24 portrait, 8, the shirt number in a column
   two digits wide plus 4, 8, the 15/600 name over the 12/400 位置, 8, the rating chip, 4, the 16
   chevron in iconFaint. The whole row is the target (it opens the player sheet). */
.md-player{display:block;min-height:0;padding:0}
#match .md-player-row{display:flex;align-items:center;width:100%;min-height:56px;margin:0;padding:8px 0;border:0;border-radius:0;background:none;color:var(--ink);font:inherit;letter-spacing:0;text-align:left}
.md-player-row>.md-avatar{margin-right:8px}
.md-player-row>.md-player-no{min-width:calc(2ch + 4px);margin-right:8px}
.md-player-row>.md-player-copy{flex:1 1 auto}
.md-player-row>.md-rating{margin-left:8px}
.md-player-row>svg{display:block;flex:none;width:16px;height:16px;margin-left:4px;color:var(--faint)}
@media(hover:hover){#match .md-player-row:hover,.md-bench>summary:hover,#match .md-info:hover,#match .md-sheet-close:hover,#match .md-dialog-action:hover{background:var(--press)}}
#match .md-player-row:active,#match .md-info:active,#match .md-sheet-close:active,#match .md-dialog-action:active{background:var(--press)}
#match .md-player-row:focus-visible{outline-offset:-3px}
/* The page's one dialog. The player sheet (showJybSheet): surface, top radius 20, the sheet shadow,
   the 36×4 border2 handle 8 from the top, at most 85% of the screen over the scrim; the header 4
   below it (16 in): the portrait on a 48 grass disc, 12, the 17/800 name over the 12/400 muted
   facts line, the 48 close; then the facts, 16 in, 8 above and 24 below: 15/22 rows 4 apart, the
   12/600 muted group heads 12 above. On a wide screen it stays 640 wide (Material's sheet). */
body:has(.md-sheet[open]){overflow:hidden}
.md-sheet{max-width:none;max-height:none;margin:0;padding:0;border:0;background:var(--card);color:var(--ink);overflow:hidden}
.md-sheet:not([open]){display:none}
.md-sheet::backdrop{background:#1e1e1e80} /* JybTokens.scrim */
.md-sheet.is-player{position:fixed;inset:auto 0 0;width:100%;max-width:640px;max-height:85vh;max-height:85dvh;margin:0 auto;border-radius:20px 20px 0 0;box-shadow:var(--md-sheet-shadow)}
.md-sheet-body{display:flex;flex-direction:column;max-height:inherit;padding-bottom:env(safe-area-inset-bottom)}
.md-sheet-handle{display:block;flex:none;width:36px;height:4px;margin:8px auto 0;border-radius:999px;background:var(--md-border-2)}
.md-sheet-head{display:flex;flex:none;align-items:flex-start;padding:4px 4px 0 16px}
.md-sheet-disc{display:grid;flex:none;place-items:center;width:48px;height:48px;margin-right:12px;border-radius:50%;background:var(--md-pitch-grass)}
.md-sheet-title{flex:1;min-width:0}
#match .md-sheet-title h2{margin:0;color:var(--ink);font-size:17px;line-height:24px;font-weight:800;overflow-wrap:anywhere}
#match .md-sheet-title p{margin:0;color:var(--muted);font-size:12px;line-height:17px}
#match .md-sheet-close{display:grid;place-items:center;flex:none;width:48px;height:48px;min-height:48px;margin:0;padding:0;border:0;border-radius:50%;background:none;color:var(--muted)}
#match .md-sheet-close svg{display:block;width:20px;height:20px}
.md-sheet-facts{flex:1 1 auto;min-height:0;padding:8px 16px 24px;overflow-y:auto;overscroll-behavior:contain}
#match .md-fact{display:flex;align-items:center;gap:12px;margin:0;padding:4px 0;color:var(--ink);font-size:15px;line-height:22px}
.md-fact>span{flex:1;min-width:0}
.md-fact>b{flex:none;font-weight:600;font-variant-numeric:tabular-nums}
#match .md-fact-group{margin:0;padding:12px 0 4px;overflow:hidden;color:var(--muted);font-size:12px;line-height:17px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
#match .md-fact-note{margin:0;padding:8px 0;color:var(--ink);font-size:15px;line-height:22px}
/* The diagram note (showJybDialog): surface, radius 20, 24 from the screen edges, 280–560 wide; the
   17/800 title 24 in, the 15/22 inkSoft text 16 below it and 24 above the actions, which end 16 in:
   知道了 a 13/800 link-colour text action in a 48 pill. */
.md-sheet.is-dialog{position:fixed;inset:0;width:min(560px,calc(100% - 48px));min-width:min(280px,calc(100% - 48px));height:fit-content;max-height:calc(100% - 48px);margin:auto;border-radius:20px;overflow-y:auto}
.md-dialog-body{padding-top:24px}
#match .md-dialog-body h2{margin:0;padding:0 24px;color:var(--ink);font-size:17px;line-height:24px;font-weight:800}
#match .md-dialog-body p{margin:0;padding:16px 24px 24px;color:var(--md-ink-soft);font-size:15px;line-height:22px}
.md-dialog-actions{display:flex;justify-content:flex-end;padding:0 16px 16px}
#match .md-dialog-action{min-width:48px;min-height:48px;margin:0;padding:0 12px;border:0;border-radius:999px;background:none;color:var(--md-link);font-size:13px;line-height:19px;font-weight:800;letter-spacing:0}
/* 赛况 · 本场快讯 (MatchNewsStrip): one row of JybCards — 168 wide, the 96 cover on top (no cover:
   the actSoft face with the news glyph), a two-line 13/600 title and the 11/400 date at the foot,
   176 high at least, the hair painted over the edge — 8 apart from 16 in, the second card cut by
   the screen edge; a swipe coasts freely, as the App's strip does (no snapping). PC and tablet: the same
   cards, as many to the row as fill it edge to edge (three to 900, four from there), the cover
   kept at 7:4; the rest of the row is a swipe, Shift+wheel or the thin scrollbar away. */
.md-news-scroller{scroll-snap-type:none}
.md-news-card{position:relative;min-height:0;border:0}
.md-news-card:after{content:"";position:absolute;inset:0;z-index:1;border:1px solid var(--md-hair);border-radius:inherit;pointer-events:none}
.md-news-cover{height:auto;aspect-ratio:7/4}
.md-news-copy{min-height:80px}
.md-news-copy small{padding-top:0}
@media(min-width:651px){
 #detail-content:has(>.md-lineup){padding-top:4px}
 .md-news-scroller{--md-news-k:3}
 .md-news-card{width:calc((100% - (var(--md-news-k) - 1)*8px)/var(--md-news-k))}
}
@media(min-width:901px){.md-news-scroller{--md-news-k:4}}
@media(min-width:651px) and (hover:hover) and (pointer:fine){
 .md-news-scroller{padding-bottom:12px;scrollbar-width:thin;scrollbar-color:var(--md-border-2) transparent}
}
/* Motion, as the App moves (none under reduce motion, JybMotion.reduced): the sheet rises from
   the bottom edge over Material's 250 ms while the scrim fades in; the dialog fades in over
   150 ms; 替补 opens and closes over JybMotion.standard (220 ms, AnimatedSize from the top). */
@media(prefers-reduced-motion:no-preference){
 .md-sheet.is-player[open]{animation:md-sheet-rise .25s cubic-bezier(.2,.7,.3,1)}
 .md-sheet.is-dialog[open]{animation:md-sheet-fade .15s ease-out}
 .md-sheet[open]::backdrop{animation:md-sheet-fade .25s ease-out}
 .md-bench{interpolate-size:allow-keywords}
 .md-bench::details-content{block-size:0;overflow:clip;transition:block-size .22s linear,content-visibility .22s allow-discrete}
 .md-bench[open]::details-content{block-size:auto}
}
@keyframes md-sheet-rise{from{transform:translateY(100%)}}
@keyframes md-sheet-fade{from{opacity:0}}
/* end R19-E */
/* R19-H data+download+footer+tier ──────────────────────────────────────────────────
   Round 19, part H (owner 2026-10-03): the 榜单 lists against the App's own table
   (standings_screen.dart, standings_table.dart), 下载 App rebuilt as one page in the App's parts
   (about_screen.dart, no screenshots), and the filing line on every page. Overrides only,
   appended last; every colour is an existing token. */
/* StandingsHeadRow: a 32 band with its rule inside (a DecoratedBox paints the border over the band;
   it was 33 here). Rows stay 48 with theirs. */
:is(#data,#team) .standings-table thead th{padding-bottom:7px}
@media(min-width:651px){
 /* StandingsColumnLayout at every width: each figure column is as wide as its own content and the
    name takes the rest (on PC they were fixed 52 / 64 px columns). */
 :is(#data,#team) .native-standings :is(.col-played,.col-win,.col-draw,.col-lose,.col-gd,.col-points){width:1%}
 /* _LeagueChips: 8 above and below the 32 faces (a 48 row), the table straight under it (was 16 / 20). */
 #data .data-leagues{padding:8px 0}
 /* 榜单 is pushed inside the 数据 tab: the PC back link above the title, as on the other pushed pages. */
 #data>.back{margin:20px 0 12px}
 #data>.back+.data-heading{padding-top:0}
}
/* Phones: 榜单 is a pushed page (the App's JybPageHeader with its back arrow), no longer a tab root. */
@media(max-width:650px){
 body[data-page=data] .app-back{visibility:visible}
 #data>.back{display:none}
}
/* 下载 App · one JybCard: the 关于本应用 brand block, the filed one-line introduction, then a part per
   platform on a hair rule (title 17/24 600, note 12/17 muted; the App Store button, or Android's
   status tag — not a button, since nothing can be downloaded), the About rows (label 15/22 600, value
   13/19 muted, 12 / 16 inside, at least 48) and the App's non-affiliation note. */
#download .dl-card{display:block}
#download .dl-lead{margin:12px 0 0;font-size:13px;line-height:19px;color:var(--ink-soft)}
#download .dl-way{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;margin:16px -16px 0;padding:16px 16px 0;border-top:1px solid var(--hair)}
#download .dl-way h3{margin:0;font-size:17px;line-height:24px;font-weight:600;letter-spacing:0;color:var(--ink)}
#download .dl-way p{margin:4px 0 0;font-size:12px;line-height:17px;color:var(--muted)}
#download .dl-store{gap:6px}
#download .dl-store svg{flex:none;width:16px;height:16px}
#download .dl-state{display:inline-flex;align-items:center;justify-self:start;min-height:32px;padding:0 12px;border:1px solid var(--border-2);border-radius:999px;color:var(--muted);font-size:13px;line-height:19px;font-weight:600}
#download .dl-facts{position:relative;margin:12px 0 0;overflow:hidden;border-radius:14px;background:var(--card)}
#download .dl-facts:after{content:"";position:absolute;inset:0;border:1px solid var(--hair);border-radius:inherit;pointer-events:none}
#download .dl-fact{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:4px 12px;min-height:48px;padding:12px 16px}
#download .dl-fact+.dl-fact{border-top:1px solid var(--hair)}
#download .dl-fact-label{font-size:15px;line-height:22px;font-weight:600;color:var(--ink)}
#download .dl-fact-value{min-width:0;font-size:13px;line-height:19px;color:var(--muted);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
#download .dl-fact-value a{color:var(--link);font-weight:600;text-decoration:none}
@media(hover:hover){#download .dl-fact-value a:hover{text-decoration:underline}}
@media(min-width:651px){
 #download .dl-way{grid-template-columns:minmax(0,1fr) auto;align-items:center}
 #download .dl-store{width:auto;min-width:200px}
}
/* Footer · the filing line on every page: the website's ICP number, the App's ICP number under its
   label, and the official public-security badge before the website's public-security number; each
   opens its official query site. 12/17 (the App's caption) — it was 10 px. */
footer .site-filing{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:0 16px;margin-top:4px;font-size:12px;line-height:17px}
footer .site-filing a{gap:4px;min-height:44px;font-size:12px;line-height:17px;color:var(--muted)}
footer .site-filing img{flex:none;width:16px;height:17px}
/* end R19-H */
/* R19-F colour parity ─────────────────────────────────────────────────────────────
   Every page, element by element, in the colour the App paints the same element
   (apps/mobile/lib/design/jyb_tokens.dart and the widget that draws it). Owner 2026-10-03
   「測試站網頁版還是有色調不正確的問題一張一張看」「給我做到跟APP一膜一樣的效果」: App parity wins
   over the earlier warm-white-gold "no blue" web rule (CORE_TASKLIST T239 ②), so the App's own
   blue roles are back — vizAway on the match statistics (token above), clubNavy on the club
   surfaces. Values are pinned to the Dart source by tests/unit/web-r19-f-colour-parity.test.mjs.
   Layout is untouched: this block only names the token an element wears. */
:root{
 --club-navy:#0a2b57;              /* JybTokens.clubNavy (= iconClub) */
 --club-navy-line:#b9cde6;         /* JybTokens.clubNavyLine · ScoresQuickPill rail and the round bottom tools */
 --club-hero:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='15.9%25' y1='13.45%25' x2='84.1%25' y2='86.55%25'%3E%3Cstop offset='0' stop-color='%23082040'/%3E%3Cstop offset='0.68' stop-color='%230a2b57'/%3E%3Cstop offset='1' stop-color='%23093671'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* JybTokens.ppClubHeroGradient */
 --accent-soft:#e4ecf6;            /* JybTokens.accentSoft (= colorScheme.secondaryContainer) */
 --up-soft:#dceae5;                /* JybTokens.upSoft */
 --danger-soft:#f6e6e6;            /* JybTokens.dangerSoft */
 --auth-card-line:#dae1ecf2;       /* JybTokens.authCardLine rgba(218,225,236,.95) */
}
/* 我的 · MeGuestHero paints the ticket's dark half in ppClubHeroGradient; MeIdentityCard (signed
   in) in flat clubNavy, both under the same stadium artwork. */
/* Current Shanghai product: guest, member and auth follow the shared App navy roles. */
:is(#me .pass-top,#login .auth-hero){background:var(--club-hero)}
#me .pass-card[data-state=member] .pass-top{background:var(--club-navy)}
/* Web auth uses the same neutral card and navy actions as the member page. The form's
   structure, caret, captcha frame and checkbox roles remain shared with the App. */
#login .auth-form-panel{border-color:var(--line);box-shadow:var(--sh-3)}
#login .auth-switch{color:var(--gold-ink)}
#login .captcha-box{border-color:var(--row-line)}
/* W4 2026-10-11: the caret is the App's JybTokens.caret (= link). It was --gold (#e4ecf6), the
   same value as the focused row's --soft: 1.00:1, an invisible caret on login and register. */
#login .auth-field input{caret-color:var(--link)}
input[type=checkbox]{accent-color:var(--act-track)}
/* 申花赛程 · ScheduleVersusCard: the VS and the own club's name in clubNavy; the date in clubNavy
   on a home row (the club named first), actDeep away; played rows keep their faint / muted dim.
   The status line's 重试 is passportTextActionStyle (clubNavy). */
#schedule .schedule-teams b,#schedule .schedule-teams .is-own{color:var(--club-navy)}
#schedule .schedule-versus:not(.is-past):has(.schedule-teams>.is-own:first-child) .schedule-meta strong{color:var(--club-navy)}
#schedule .schedule-status button{color:var(--club-navy)}
/* 资讯 · PassportMoreLink (更多…: clubNavy words, iconClub chevron) and the card's text actions
   (重试 / 继续查找: passportTextActionStyle, clubNavy). */
#news .news-more,#news .news-failed>button{color:var(--club-navy)}
/* 比分 · JybTextField.search: the focused frame and the caret in link. */
#scores .search{caret-color:var(--link)}
#scores .search:focus{border-color:var(--link)}
/* 比赛详情 · 阵容 loading is the themed LinearProgressIndicator (bar iconBrand, track accentSoft);
   前瞻 W / L beads sit on upSoft / dangerSoft (PreviewPane._FormBlock); 更多球队统计 open turns its
   ExpansionTile chevron colorScheme.primary (act). */
.md-progress{background:var(--accent-soft)}
.md-progress:after{background:var(--gold-ink)}
.pv-w{background:var(--up-soft)}
.pv-l{background:var(--danger-soft)}
.md-more[open] .md-more-chev{color:var(--gold)}
#match .md-retry,#data .bb-sheet .md-retry{background:var(--btn-face)}
/* 比分 · JybStateView's halo: a RadialGradient of radius .68 of the 74 disc (50px) at 42% height. */
#scores .scores-empty:before{background:radial-gradient(circle 50px at 50% 42%,var(--soft),var(--soft-clear))}
/* 数据 · the PC scorers caption rule and 抽奖's 参加流程 steps are framed in border, not surface3. */
:is(#data,#team) .scorers-table caption{border-bottom-color:var(--row-line)}
#lottery .dc-steps li{border-color:var(--row-line)}
/* end R19-F */
/* R19-G scroll+speed ─────────────────────────────────────────────────────────────
   「全站下滑抖動」and the slow, stuttering first load from Taiwan. Measured in Chrome on every page at 390,
   360 (touch, 3×, 4× CPU), 1440 and 1024: what moved under a scrolling reader, and what each frame cost.
   Overrides only, appended last; no new colour. The script half is client.mjs (keyed refresh, keepPlace,
   the settling footer) and server.mjs (crests, 前瞻 and the page state drawn once, pictures kept). */
/* Phones: the tab bar's 22 px backdrop blur sat on the opaque paper of the fade band below it (body:after,
   solid from 16 px under its top edge), so it blurred one flat colour: no visible effect (the bar's face is
   the same to within one level in one channel), but a full-width blur pass the GPU redid on every scrolled
   frame. The bar keeps its glass face (tabbar-fill over that paper) without it. */
@media(max-width:650px){.mobile-nav{-webkit-backdrop-filter:none;backdrop-filter:none}}
/* 比赛详情, 抽奖 and 我的 fill in after the page is drawn: until then the footer stood in the middle of a short
   page and jumped away under the reader (CLS 0.06–0.15 while scrolling a loading page). It keeps its place
   but stays out of sight until the page has settled (client.mjs enter), and shows after 8 s whatever happens. */
body[data-settling] footer{visibility:hidden;animation:r19g-settled 0s 8s forwards}
@keyframes r19g-settled{to{visibility:visible}}
/* 资讯详情 pictures: the box keeps the provider's shape (product.mjs articleImage) and the picture is fitted
   inside it on the paper face, so a picture of another shape never moves the text under it. */
#article .art-img>img[style*="aspect-ratio"]{object-fit:contain}
/* 比分 from 768 px: one row per line, as on the phone and in the App. Laid two to a line (R19-B), one match
   that kicked off or ended moved every later row to the other column: on the 15 s refresh 23 of the 24 rows
   on a 1440 screen changed place. In one column such a change only moves the rows under it down or up by one
   row, which the browser's scroll anchoring (or keepPlace) cancels for the reader. */
@media(min-width:768px){#scores #match-list{display:block}}
/* A desktop browser with classic scrollbars (Windows: 15 px) moved the whole centred page sideways by half a
   scrollbar whenever the scrollbar came or went: 抽奖 growing past the screen while it filled in, a short page
   (我的, 下载) after a long one, and 阵容's player sheet locking the page's scroll (measured at 1440: 7.5 px each
   time). The gutter is kept whether the page scrolls or not, in the desktop layout (651 px up; overlay scrollbars,
   as on phones and macOS, take no room anyway). */
@media(min-width:651px){html{scrollbar-gutter:stable}}
/* end R19-G */
/* R20-B news full-width + sitewide finish ─────────────────────────────────────────────────
   Owner 2026-10-03 「新闻页面设计满版」「全站优化打磨得更好更有质感一点」. The ruler is the App, in the order
   克制 → 一致 → 材質: no new visual direction, no new colour, only the App's own steps —
   type JybType (sizes 11/12/13/15/17/20/28 at line heights 16/17/19/22/24/27/34, weights 400/600/800),
   space JybSpace (2/4/6/8/12/16/24/32), corners JybRadius (4/8/12/14/20/999) and depth JybElevation
   (cards flat on a hair frame). tests/unit/web-r20-b-news-quality.test.mjs reads those scales from the
   Dart source and holds every rendered page to them. Overrides only, appended last. */

/* A · 资讯 at tablet and PC fills the page column (the 880 that 比分, 榜单 and 我的 read in) with cards made
   of the App's featured news tile (TeamNewsSection _NewsTile featured): a JybCard (surface, hair frame
   painted over, radius 14, no shadow) holding the cover letterboxed on paper in a 12-radius box (never
   cropped), 12, the 15/22 600 two-line title, 8, the 12/17 time at the foot. From 901 three columns, the
   lead story two columns by two rows with its 4:3 cover and a 20/27 headline; the other covers are a
   little wider (16:10), so a lead stands exactly as high as the two cards beside it, and every page of 12
   (and every 更多资讯 step of 12) closes on a full row (4 + 11 cells = 5 rows). 651–900: two columns, every
   card the App's own tile with its 4:3 cover. A story without a cover keeps the cover's face. Phones keep
   the App's list (section 5). */
#news .news-thumb.is-blank{display:none}
@media(min-width:651px){
 :is(#news,#article){max-width:var(--narrow);margin-inline:auto}
 #news .news-card{margin:16px 0 0;padding:0;border:0;border-radius:0;background:none}
 #news .news-feed{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:stretch}
 #news .news-row,#news .news-row.is-text,#news .news-row.is-lead{position:relative;display:flex;flex-direction:column;gap:12px;min-width:0;padding:12px;border:0;border-radius:14px;background:var(--card);contain-intrinsic-block-size:auto 330px}
 #news .news-row:not([hidden])~.news-row:not([hidden]){border-top:0}
 #news .news-row:after{content:"";position:absolute;inset:0;z-index:1;border:1px solid var(--hair);border-radius:inherit;pointer-events:none}
 #news .news-thumb,#news .news-thumb.is-blank{display:block;flex:none;width:100%;aspect-ratio:4/3;border-radius:12px;background:var(--paper)}
 #news .news-thumb.is-blank i{display:grid}
 #news .news-text{flex:1 1 auto;gap:8px;padding:0}
 #news .news-text small{margin-top:auto}
 #news .news-row.is-lead .news-text strong{font-size:15px;line-height:22px}
 /* The status lines (PassportStatusLine) and 更多资讯 (PassportMoreLink), now that each story is a card. */
 #news .news-feed>.news-failed{grid-column:1/-1}
 #news :is(.news-feed>.news-failed,.news-card>#news-empty){padding:0 16px;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
 #news .news-card>#news-empty{padding-block:12px}
 #news .news-more{margin-top:4px;padding:8px 0}
 #news .news-card:has(>#news-more[hidden]):has(>#news-empty[hidden]):not(:has(.news-failed))>.news-feed{padding-bottom:0}
}
@media(min-width:901px){
 #news .news-feed{grid-template-columns:repeat(3,minmax(0,1fr))}
 #news .news-row,#news .news-row.is-text{contain-intrinsic-block-size:auto 268px}
 #news .news-thumb,#news .news-thumb.is-blank{aspect-ratio:16/10}
 #news .news-row.is-lead{grid-column:span 2;grid-row:span 2;padding:16px}
 #news .news-row.is-lead .news-thumb{flex:1 0 auto;aspect-ratio:4/3}
 #news .news-row.is-lead .news-text{flex:none}
 #news .news-row.is-lead .news-text strong{font-size:20px;line-height:27px;font-weight:600}
}
/* B · 资讯详情 at tablet and PC: the page column is the full one, the story reads in a centred column of
   the App's article measure (720, about 45 characters); its pictures stay inside that column, since the
   image path serves them at most 480 wide (a wider box would only blow them up). */
@media(min-width:651px){
 #article .news-article{max-width:720px;margin-inline:auto;padding:16px 0 48px}
}

/* C · One type scale (JybType). Measured on every page at 1440/1024/768/390/360 (MEASUREMENTS.md): the
   values below were the ones off the App's seven levels and three weights. */
:root{
 --press-splash:#e4ecf61a;         /* JybTokens.pressSplash (act @ .10) · the splash of a press, on a dark face */
}
@media(min-width:651px){
 /* the PC page title is the App's in-page headline 20/27/800, tracked 0 like every App title (was 22/29.7, -.02em) */
 :is(.intro,.data-heading,.section-title,.club-heading) h1{font-size:20px;line-height:27px;font-weight:800;letter-spacing:0}
 /* the pushed pages' back link is a 13/19 text action (was 13 on the body's 1.6) */
 .back{font-size:13px;line-height:19px}
}
/* the footer is the App's caption, 12/17, on every line (the company line was 11/22 on PC and 10/20 on phones,
   under the App's smallest size) */
body>footer,body>footer a,body>footer>div{font-size:12px;line-height:17px}
/* 01 统计: the ring figures are 11/800 (a bare <b> made them 900) */
#match .md-ring-values b{font-weight:inherit}
/* _TeamHeading: 主队 / 客队 is 11/16, centred on the 15/22 name (was set on the name's 22 line) */
.md-team-head small{align-self:center;line-height:16px}
/* the skip link reads as the App's text action (it inherited the body's 15/24) */
.skip{font-size:13px;line-height:19px;font-weight:600}
@media(min-width:651px){
 /* MatchDetailHeader on the PC card: the score is the App's 28/34 numeral (JybType.display), the largest step
    the App has (was 34/40) */
 .md-score,.md-countdown b{font-size:28px;line-height:34px}
}

/* D · One spacing scale (JybSpace 4/8/12/16/24/32). */
@media(min-width:651px){
 /* a page head: 24 above the title, 16 to the content (was 28 / 20) */
 :is(.intro,.data-heading,.section-title,.club-heading){padding:24px 0 16px}
 /* a pushed page: 16 above its back link, 16 under it, then the title (was 20 / 12; the title stays where it was) */
 :is(#lottery,#support) :is(.lot-page,.sup-page){padding-top:16px}
 :is(#lottery,#support) :is(.lot-page,.sup-page)>.back,#team .team-summary>.back,#article .news-article>.back,#login .login-back{margin:0 0 16px}
 #team .team-summary{padding-top:16px}
 #data>.back{margin:16px 0}
 #login .login-page{padding-top:16px}
 /* _TeamHero on the PC card: 16 in from the frame on every side (was 17 / 21) */
 #team .team-identity{padding:15px}
 /* 赛况 starts 16 under the tabs, as on the phone (was 20) */
 .md-pane{padding-top:16px}
}
@media(min-width:901px){
 /* 01 统计 beside 02 事件直播: both heads are the same 56 row (8 above a 48 line), so the two titles share one
    line and both columns start at the same height — without the 21 px nudge */
 .md-live-cols>.md-block:first-child:not(:only-child)>.md-section{min-height:56px;padding-top:8px;padding-bottom:0}
}
/* the footer: on phones 24 above it and 24 inside its top (was 20 / 20); between its links 0 / 16 on phones and
   0 / 24 on PC (was 4 / 20 and 8 / 24) */
@media(max-width:650px){
 body>footer{margin-top:24px;padding-top:24px}
 body>footer>div:first-child{gap:0 16px}
}
@media(min-width:651px){body>footer>div:first-child{gap:0 24px}}

/* E · Shape and depth (JybRadius, JybElevation). */
@media(min-width:901px){
 /* MeGuestHero's stamp is the App's stamp at every width: 4-radius, 1.5 jybGoldSoft, 2 / 8 inside (on PC it
    turned into a 99-radius pill on a hand-typed #d8c18c55 line) */
 #me #member-tag{padding:2px 8px;border:1.5px solid var(--gold-on-dark);border-radius:4px}
}
/* every layer-① face carries the App's btnShadow (JybStateView's compact one had none) */
.blank button,.page-error button{box-shadow:var(--btn-glow)}
/* JybStateView sits 24 / 32 inside its box (JybInsets.empty), like 比赛详情's state; the plain one was 40 / 32 */
.blank{padding:24px 32px}

/* F · One set of press, hover and focus states (the App's InkWell: pressHighlight held, pressSplash on a
   dark face; the web adds hover on a mouse). A tappable card is tinted as a whole, as JybCard's InkWell
   does — no gold frame and no title colour on top (they differed card by card); a layer-① face takes the
   splash on hover and the highlight while pressed, never another text colour. */
#news .news-row:active,.md-news-card:active,.md-gif:active{background:linear-gradient(var(--press),var(--press)),var(--card)}
@media(min-width:901px){#schedule a.schedule-versus:active{background:linear-gradient(var(--press),var(--press)),var(--card)}}
@media(hover:hover){
 #news .news-row:hover .news-text strong,.md-news-card:hover strong,.md-gif:hover strong{color:var(--ink)}
 :is(#news .news-row,.md-news-card,.md-gif):hover{background:linear-gradient(var(--press),var(--press)),var(--card)}
 #schedule a.schedule-versus:hover{border-color:var(--hair)}
 .blank button:hover,.page-error button:hover{color:var(--pill-fg);background:linear-gradient(var(--press-splash),var(--press-splash)),var(--pill-face)}
 #match .md-retry:hover,#data .bb-sheet .md-retry:hover,:is(#me,#login,#lottery,#download) .jbtn:not(:disabled):hover{background:linear-gradient(var(--press-splash),var(--press-splash)),var(--btn-face)}
}
.blank button:active,.page-error button:active{background:linear-gradient(var(--press),var(--press)),var(--pill-face)}
#match .md-retry:active,#data .bb-sheet .md-retry:active,:is(#me,#login,#lottery,#download) .jbtn:not(:disabled):active{background:linear-gradient(var(--press),var(--press)),var(--btn-face)}
/* The lottery's primary on its dark hero (dcPrimaryTint) takes the same splash; while pressed, the highlight. */
@media(hover:hover){#lottery .dc-primary:not(:disabled):hover{background:linear-gradient(var(--press-splash),var(--press-splash)),var(--dc-primary)}}
#lottery .dc-primary:not(:disabled):active{background:linear-gradient(var(--press),var(--press)),var(--dc-primary)}
/* A text action (the App's TextButton: link or club-navy words in a 48 hit) is highlighted in a pill around its
   words, as Material draws it; a secondary face or a chip (layer ③, JybChip) is highlighted on its own face. Before,
   these answered a mouse with nothing at all, or (榜单's chips) with a gold frame and gold words. */
:is(#login .auth-forgot,#login .auth-switch,#lottery .dc-link,#match .md-text-action,#news .news-failed>button,#schedule .schedule-status button,#article .art-state button){border-radius:999px}
#lottery .dc-link{padding:0 8px;margin-inline:-8px}
@media(hover:hover){
 :is(#login .auth-forgot,#login .auth-switch,#lottery .dc-link,#match .md-text-action,#news .news-failed>button,#schedule .schedule-status button,#article .art-state button):hover{background:var(--press)}
 :is(#lottery .dc-refresh,#login .captcha-refresh:not(:disabled),#login .auth-send-code:not(:disabled),#data .data-leagues a:not(.active)):hover{border-color:var(--btn-line);background:linear-gradient(var(--press),var(--press)),var(--card);color:var(--ink)}
 #login .captcha-refresh:not(:disabled):hover{border-color:var(--border-2);color:var(--muted)}
 :is(#lottery .dc-rules,#lottery .dc-support):hover{background:linear-gradient(var(--press),var(--press)),var(--dc-face)}
 #lottery .dc-option:hover input:not(:checked)+span{background:linear-gradient(var(--press),var(--press)),var(--card)}
 /* the folded 已赛 head is a 48 row like 替补's */
 #schedule .past-schedule summary:hover{background:var(--press)}
 /* 赛况 / 阵容 / 前瞻: an idle tab darkens to ink, as 资讯's categories and 足球's status tabs do */
 #match .md-tabs button:not(.active):hover{color:var(--ink)}
}
:is(#login .auth-forgot,#login .auth-switch,#lottery .dc-link,#match .md-text-action,#news .news-failed>button,#schedule .schedule-status button,#article .art-state button):active,#schedule .past-schedule summary:active{background:var(--press)}
:is(#lottery .dc-refresh,#login .captcha-refresh:not(:disabled),#login .auth-send-code:not(:disabled),#data .data-leagues a:not(.active)):active{background:linear-gradient(var(--press),var(--press)),var(--card)}
:is(#lottery .dc-rules,#lottery .dc-support):active{background:linear-gradient(var(--press),var(--press)),var(--dc-face)}
/* one focus ring on the page and its footer: 3 gold-ink, 3 outside — buttons, links and fields had 4
   (app-alignment.css), everything else 3; rows and cards that fill a clipped list keep theirs inside (their own
   rules are more specific). The header, the tab bar and the edge tab keep their own (R20-A). */
:is(main,footer) :is(button,a,input):focus-visible{outline-offset:3px}
/* end R20-B */
/* R20-C match animation ───────────────────────────────────────────────────────────────
   「数据动画也要接上比赛详情」(owner 2026-10-03): the App's animation entry and stage (match_animation_link.dart,
   match_animation_stage.dart, match_detail_glass.dart). The entry keeps MatchAnimationInlineEntry's place and type
   (R18-C: 11/800 at the strip's right end, a 48 hit): 'embed' is a button with ›, 'tab' a link with the external
   glyph. Open, the stage takes the header's place at the frame's own height (MatchDetailHeader
   .animationSurfaceMinHeight 316) on the frame page's ground, with the 72 scrim (the ground at .78, fading in its
   own colour) under the glass ‹ (a 36 circle in a 48 hit, 8 from the side, 4 from the top). Until the frame's
   document arrives the line pitch (88 wide) says so in silver; a failure folds the stage and says so in the App's
   floating note (ink, 13/19, radius 12, 15 from the sides, 10 above the tab bar). Every colour is an App token. */
:root{
 --md-anim-ground:#0e1116;         /* JybTokens.matchAnimGround (= the frame page's own body) */
 --md-anim-scrim:#0e1116c7;        /* JybTokens.matchAnimGround at .78 (MatchDetailGlass.scrimOpacity) */
 --md-anim-scrim-0:#0e111600;      /* JybTokens.matchAnimGround at 0: the scrim fades in its own colour */
 --md-anim-glass:#0912288c;        /* JybTokens.matchAnimGlassFill */
}
#match .md-status :is(a,button).md-anim-note{display:inline-flex;align-items:center;justify-content:flex-end;min-width:48px}
#match .md-status button.md-anim-note{min-height:48px;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--md-theatre-accent);font-size:11px;line-height:16px;font-weight:800}
#match .md-status button.md-anim-note i{flex:none;margin-left:4px;font-size:13px;font-style:normal;font-weight:600;line-height:1}
#match .md-status a.md-anim-note.is-tab svg{flex:none;width:13px;height:13px;margin-left:4px}
#match .md-status button.md-anim-note:focus-visible{outline:2px solid var(--md-theatre-accent);outline-offset:-2px}
.md-page[data-anim=open]>.md-hero{display:none}
.md-anim-stage{position:relative;height:316px;overflow:hidden;background:var(--md-anim-ground);color:var(--md-theatre-ink);outline:0}
.md-anim-picture,.md-anim-wait{position:absolute;inset:0}
.md-anim-frame{display:block;width:100%;height:100%;border:0;background:var(--md-anim-ground)}
.md-anim-wait{display:flex;flex-direction:column;align-items:center;justify-content:center;background:var(--md-anim-ground);color:var(--md-theatre-muted);text-align:center}
.md-anim-stage[data-state=ready] .md-anim-wait{display:none}
.md-anim-wait .md-pitch-figure{width:88px;height:auto;margin-bottom:8px;color:var(--md-border-2)}
.md-anim-wait .md-pitch-figure :is(rect,path,circle){vector-effect:non-scaling-stroke}
.md-anim-wait strong{font-size:12px;line-height:17px;font-weight:600}
.md-anim-wait span{margin-top:4px;font-size:11px;line-height:16px;font-weight:400}
.md-anim-scrim{position:absolute;top:0;left:0;right:0;height:72px;background:linear-gradient(var(--md-anim-scrim),var(--md-anim-scrim-0));pointer-events:none}
.md-anim-back{position:absolute;top:4px;left:8px;display:grid;place-items:center;width:48px;height:48px;color:var(--md-theatre-ink);text-decoration:none}
.md-anim-back>span{display:grid;place-items:center;width:36px;height:36px;border:1px solid var(--md-theatre-rule);border-radius:50%;background:var(--md-anim-glass)}
.md-anim-back .md-icon{width:20px;height:20px}
#match .md-anim-back:focus-visible{outline:2px solid var(--md-theatre-accent);outline-offset:-2px}
.md-anim-toast{position:fixed;left:15px;right:15px;bottom:calc(86px + env(safe-area-inset-bottom,0px));z-index:40;margin:0;padding:14px 16px;border-radius:12px;background:var(--ink);color:var(--on-dark);font-size:13px;line-height:19px}
.md-anim-toast[hidden]{display:none}
@media(min-width:651px){
 .md-anim-stage{border-radius:20px}
 #match .md-status button.md-anim-note{font-size:12px;line-height:17px}
 .md-anim-toast{left:50%;right:auto;bottom:24px;width:min(560px,calc(100% - 48px));transform:translateX(-50%)}
}
/* end R20-C */
/* R20-A nav+header+filter+edge tab+tab bar ───────────────────────────────────────────
   Round 20, part A (owner 2026-10-03, after reviewing QA R19): 比分 · 资讯 · 数据 · 我的 with 数据 third; the 足球
   header's right-hand tool is search and its funnel opens 筛选 as a page of its own; the App download edge tab
   back in its R18 shape, open; and the phone tab bar part of the page. Overrides only, appended last; every colour
   is an existing token, the one new value names its App token. */
:root{
 --sh-3:0px 4px 16px #00000012;      /* JybTokens.sh3 · the tab bar's softer lift over the page it now sits on */
}
/* 足球 header: the funnel (a link to 筛选) keeps the left slot; search takes the far-right slot 显示与排序 had, beside
   the trophy. The funnel's badge is the number of chosen competitions, and 按联赛 lights it too. */
.app-header .app-search{grid-column:5;grid-row:1}
.app-header .app-filter.filtered:after{content:attr(data-count)}
.app-header .app-filter.by-league{color:var(--gold-ink)}
/* 榜单 is the 数据 tab's own page again: a tab root like 资讯 and 我的, no back arrow (R19-H drew one). */
@media(max-width:650px){body[data-page=data] .app-back{visibility:hidden}}

/* JybTabBar, part of the page (owner: 「底部导航设计跟页面融合好」): the App's glass — surface at .82 over blur(22)
   saturate(1.9), a border hairline at .62 — over the page itself, which now runs under the bar and fades into the
   paper only in the bar's own 76 band (JybTokens.tabBarSpace), opaque under the bar's lower part; the lift is the
   App's softer sh3. The band R19-A raised to 134 for its dock row goes back to the bar's (the edge tab left that
   row), and the content keeps R18's room at the end (96, 比分 132 for its pill) so the last line clears both. The
   bar is its own paint and layout boundary, so a scrolled frame redoes only its blur (R19-G measured the cost). */
@media(max-width:650px){
 .mobile-nav{-webkit-backdrop-filter:blur(22px) saturate(1.9);backdrop-filter:blur(22px) saturate(1.9);box-shadow:var(--sh-3);contain:layout paint}
 body:after{height:calc(76px + env(safe-area-inset-bottom));background:linear-gradient(transparent,var(--paper) 70%)}
 body[data-page]{padding-bottom:calc(96px + env(safe-area-inset-bottom))}
 body[data-page=scores]{padding-bottom:calc(132px + env(safe-area-inset-bottom))}
}

/* 筛选 · ScoresFilterScreen: JybUnderlineTabs (48 cells, 15/400 muted → 15/800 ink, the 18×3 act indicator 6 above the
   edge, a hair under the strip), the compact heads (12/600 muted, 16 in, 16 above, 8 under), each competition a
   _LeagueRow (48 high, 16 / 12 inside, the 20 box, 12, the 15 name in its tier's colour and weight, 8, the 13/400 muted
   count; a hair under it; the whole row is the target) — JybSkeletonRow in that shape while the day is read, the
   JybStateView (title, note, the compact primary 重试) when it is empty or failed —, 内容's two equal JybChips with
   their counts and the 12 muted note, the full-width JybSegmented, and the foot: a surface bar with a hair on top,
   JybChip quick choices (32 faces in 48 hits, 赛事 only) left, N 场 (12 muted) and 确定 (the black primary, 48) right,
   wrapping to two lines where one does not fit (the App's OverflowBar). Phones: the page covers the tab bar, as the
   App's pushed route does, the strip stays under the header and the foot on the bottom edge; PC: one 560 card under
   the back link and title, the list scrolling inside it. */
#filter .flt{margin:0;padding:0;border:0}
#filter .flt-tabs{display:flex;height:48px;border-bottom:1px solid var(--hair);background:var(--paper)}
#filter .flt-tabs button{position:relative;flex:1 1 0;min-width:48px;height:48px;min-height:48px;margin:0;padding:0 16px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400;letter-spacing:0}
#filter .flt-tabs button.active{color:var(--ink);font-weight:800}
#filter .flt-tabs button.active:after{content:"";position:absolute;left:calc(50% - 9px);bottom:6px;width:18px;height:3px;border-radius:999px;background:var(--gold-ink)}
#filter .flt-head{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:17px;padding:16px 16px 8px}
#filter .flt-skel-row{display:flex;align-items:center;gap:12px;min-height:48px;padding:12px 16px;border-bottom:1px solid var(--hair)}
#filter .flt-skel{display:block;border-radius:6px;background:linear-gradient(105deg,var(--surface-2) 30%,var(--skel-shine) 50%,var(--surface-2) 70%) 0 0/300% 100%;animation:skel-sweep 1.2s linear infinite}
#filter .flt-skel-box{flex:none;width:20px;height:20px;border-radius:4px}
#filter .flt-skel-name{width:40%;max-width:160px;height:12px}
#filter .flt-skel-count{width:16px;height:12px;margin-left:auto}
@media(prefers-reduced-motion:reduce){#filter .flt-skel{animation:none}}
#filter .flt-chips{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:0 16px}
#filter .flt-toggle{position:relative;isolation:isolate;display:grid;place-items:stretch;min-height:48px;cursor:pointer}
#filter .flt-toggle input{position:absolute;width:1px;height:1px;margin:0;opacity:0;pointer-events:none}
#filter .flt-toggle span{display:flex;align-items:center;justify-content:center;gap:4px;min-height:32px;margin:8px 0;padding:0 12px;border:1px solid var(--btn-line);border-radius:999px;background:var(--card);color:var(--ink);font-size:13px;line-height:19px;font-weight:600;white-space:nowrap}
#filter .flt-toggle small{color:var(--muted);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
#filter .flt-toggle input:checked+span{border-color:transparent;background:var(--pill-face);box-shadow:var(--sh-1);color:var(--pill-fg)}
#filter .flt-toggle input:checked+span small{color:var(--pill-fg)}
#filter .flt-toggle input:disabled+span{border-color:var(--border-2);background:var(--surface-3);color:var(--muted);cursor:default}
#filter .flt-toggle:has(input:focus-visible) span{outline:3px solid var(--gold-ink);outline-offset:2px}
#filter .flt-note{margin:12px 16px 16px;color:var(--muted);font-size:12px;line-height:17px}
#filter .flt-head h2{margin:0;overflow:hidden;font-size:12px;line-height:17px;font-weight:600;letter-spacing:0;color:var(--muted);text-overflow:ellipsis;white-space:nowrap}
#filter .flt-action{display:inline-flex;flex:none;align-items:center;min-width:48px;min-height:48px;margin:-16px -8px;padding:0 8px;color:var(--link);font-size:13px;line-height:19px;font-weight:600;text-decoration:none}
#filter .flt-action:active{background:var(--press)}
#filter .flt-row{position:relative;display:flex;align-items:center;gap:12px;min-height:48px;margin:0;padding:12px 16px;border-bottom:1px solid var(--hair);cursor:pointer}
#filter .flt-row input{position:absolute;width:1px;height:1px;margin:0;opacity:0;pointer-events:none}
#filter .flt-row:has(input:focus-visible){outline:3px solid var(--gold-ink);outline-offset:-3px}
#filter .flt-row:active{background:var(--press)}
#filter .flt-box{display:grid;flex:none;place-items:center;box-sizing:border-box;width:20px;height:20px;border:1px solid var(--btn-line);border-radius:4px;background:none;color:var(--pill-fg)}
#filter .flt-box svg{display:block;width:12px;height:12px;visibility:hidden}
#filter .flt-row input:checked+.flt-box{border-color:var(--ink);background:var(--ink)}
#filter .flt-row input:checked+.flt-box svg{visibility:visible}
#filter .flt-name{flex:1;min-width:0;overflow:hidden;color:var(--lg-t9);font-size:15px;line-height:22px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
#filter .flt-name.lt0{color:var(--live);font-weight:700}
#filter .flt-name.lt1{color:var(--lg-t1);font-weight:700}
#filter .flt-name.lt2{color:var(--lg-t2);font-weight:700}
#filter .flt-count{flex:none;margin-left:-4px;color:var(--muted);font-size:13px;line-height:19px;font-variant-numeric:tabular-nums}
/* R20261014 · 显示与排序's 比赛列表 group (ScoresSettingsScreen: JybListGroup, one JybListRow with its toggle on a surface
   card): a 48 row, the label at the body size in ink, the switch at its end in the theme's colours (jyb_theme.dart
   switchTheme) — on, a surface thumb on the actTrack track inside actLine; off, a muted thumb on the surface inside border2. */
#filter .flt-switches{border-top:1px solid var(--hair);background:var(--card)}
#filter .flt-switch-row{position:relative;display:flex;align-items:center;gap:12px;min-height:48px;margin:0;padding:8px 16px;border-bottom:1px solid var(--hair);cursor:pointer}
#filter .flt-switch-row input{position:absolute;width:1px;height:1px;margin:0;opacity:0;pointer-events:none}
#filter .flt-switch-row:has(input:focus-visible){outline:3px solid var(--gold-ink);outline-offset:-3px}
#filter .flt-switch-row:active{background:var(--press)}
#filter .flt-switch-name{flex:1;min-width:0;color:var(--ink);font-size:15px;line-height:22px;font-weight:400}
#filter .flt-switch{position:relative;flex:none;box-sizing:border-box;width:52px;height:32px;border:2px solid var(--border-2);border-radius:999px;background:var(--card);transition:background-color .15s,border-color .15s}
#filter .flt-switch:after{content:"";position:absolute;top:6px;left:6px;width:16px;height:16px;border-radius:50%;background:var(--muted);transition:top .15s,left .15s,width .15s,height .15s}
#filter .flt-switch-row input:checked+.flt-switch{border-color:var(--act-line);background:var(--act-track)}
#filter .flt-switch-row input:checked+.flt-switch:after{top:2px;left:22px;width:24px;height:24px;background:var(--card)}
@media(prefers-reduced-motion:reduce){#filter .flt-switch,#filter .flt-switch:after{transition:none}}
/* R20261014 · basketball's competitions are a plain tick list in ink (_BasketballLeagues: no football tier) */
#filter .flt-name.plain{color:var(--ink)}
#filter .flt-seg{display:grid;width:auto;margin:0 16px 16px}
#filter .flt-seg span{justify-self:stretch}
#filter .flt-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;padding:8px 16px;border-top:1px solid var(--hair);background:var(--card)}
#filter .flt-quick{display:flex;flex-wrap:wrap;gap:8px}
#filter .flt-chip{position:relative;isolation:isolate;display:grid;place-items:center;min-width:48px;height:48px;min-height:48px;margin:0;padding:0 12px;border:0;border-radius:999px;background:none;box-shadow:none;color:var(--ink);font-size:13px;line-height:19px;font-weight:600;letter-spacing:0;white-space:nowrap}
#filter .flt-chip:before{content:"";position:absolute;inset:8px 0;z-index:-1;border:1px solid var(--btn-line);border-radius:999px;background:var(--card)}
#filter .flt-chip:active:before{background:var(--press)}
#filter .flt-apply{display:flex;align-items:center;gap:12px;margin-left:auto}
#filter .flt-hits{color:var(--muted);font-size:12px;line-height:17px;font-variant-numeric:tabular-nums;white-space:nowrap}
#filter .flt-done{display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;margin:0;padding:0 24px;border:0;border-radius:14px;background:var(--btn-face);box-shadow:var(--btn-glow);color:var(--pill-fg);font:inherit;font-size:15px;line-height:22px;font-weight:600;letter-spacing:.6px;cursor:pointer}
@media(hover:hover){#filter :is(.flt-row,.flt-action):hover{background:var(--press)}#filter .flt-chip:hover:before{background:var(--press)}}
@media(max-width:650px){
 #filter .flt-page>.back{display:none}
 body[data-page=filter]{padding-bottom:0}
 body[data-page=filter] .mobile-nav,body[data-page=filter]:after{display:none}
 #filter .flt{display:flex;flex-direction:column;min-height:calc(100vh - 48px);min-height:calc(100dvh - 48px)}
 #filter .flt-tabs{position:sticky;top:48px;z-index:21}
 #filter .flt-foot{position:sticky;bottom:0;z-index:21;margin-top:auto;padding-bottom:calc(8px + env(safe-area-inset-bottom))}
}
@media(min-width:651px){
 #filter{max-width:var(--narrow);margin-inline:auto}
 #filter .flt-page{padding-top:20px}
 #filter .flt-page>.back{margin:0 0 12px}
 #filter .back+.intro{padding-top:0}
 #filter .flt{max-width:560px;overflow:hidden;border:1px solid var(--hair);border-radius:14px;background:var(--card)}
 #filter .flt-tabs{background:var(--card)}
 #filter .flt-list{max-height:min(56vh,480px);overflow-y:auto;overscroll-behavior:contain}
}

/* R69b (Owner 2026-10-12 「手機網頁版 一張一張看 還是都歪一邊」): the phone pages no longer reserve a 53–56 px lane on the
   right for the App download edge tab — every R20-A/R67 consumer of --edge-table-clearance (shell width, news card, plaza
   post, standings table and notes, match pane, tabs, footer, filter, team, schedule, me, lottery, download, article) was
   removed, so each page is the full width and symmetric like the App; the small folded tab overlays the corner it sits
   in, as the bottom tools already do. The variable is left defined for the short-height block only. */
/* Mobile App download edge tab: a compact default plus a reserved shell edge.
   The original card, explicit choices and 44px targets remain available. */
@media(max-width:650px){
 .app-float.float-c{top:auto;bottom:calc(152px + env(safe-area-inset-bottom));transform:none;width:46px;height:auto;flex-direction:column;border-radius:14px 0 0 14px}
 .app-float.float-c.collapsed{width:45px}
 .app-float.float-c .float-mini{width:18px;height:18px;border-radius:5px}
 /* Data stays horizontally scrollable clear of the fixed download entry. */
 /* 46px tab + 10, snapped to the App's 8-multiple layout grid (JybSpace.snap) so every derived inset lands on it. */
 /* Reserve only the legal copy's right edge; fields, tables and article columns stay full width. */
 /* Focus/scroll targets stop above the fixed tab bar and short-height side entry. */
 html:has(body[data-page=login]){scroll-padding-block:56px calc(160px + env(safe-area-inset-bottom))}
}
@media(max-width:650px){
 .app-float.float-c:not([data-ready=true]){width:45px}
 .app-float.float-c:not([data-ready=true])>button{height:56px;min-height:56px;border:0}
 .app-float.float-c:not([data-ready=true])>a{display:none!important}
 .app-float.float-c:not([data-ready=true]) .float-chevron{display:none}
 .app-float.float-c:not([data-ready=true]) .float-mini{display:block}
 /* Match identity uses the header axis; only reading/data panes reserve the edge tab. */
 /* R19-E (Root 2026-10-11, option A): 阵容 keeps the App's pitch geometry; client.mjs folds the side entry there. */
 /* ...and the folded entry there is a 24-wide grip (the AA minimum target), clear of every touchline player. */
 body:has(#detail-content[data-detail=lineup]) .app-float.float-c.collapsed{width:24px}
}
/* The edge entry belongs to the shell, so page loading and filter routes never hide it.
   Short mobile viewports keep both controls above navigation without an offscreen toggle. */
@media(max-width:650px) and (max-height:480px){
 .app-float.float-c{bottom:calc(96px + env(safe-area-inset-bottom));width:90px;flex-direction:row}
 .app-float.float-c>button{width:44px;min-width:44px;border-bottom:0;border-right:1px solid var(--act-line)}
 .app-float.float-c>a{width:44px;min-height:44px;padding:4px 0;gap:0}
 .app-float.float-c>a .monogram{display:none}
 .app-float.float-c.collapsed{width:45px}
 .app-float.float-c.collapsed>button{height:44px;min-height:44px;border:0}
 .app-float.float-c:not([data-ready=true]){width:45px}
 .app-float.float-c:not([data-ready=true])>button{height:44px;min-height:44px;border:0}
}
/* end R20-A */
/* Page-attached App notice: mobile only, normal flow above the unchanged page header. */
.app-open{display:none}
.app-open[hidden]{display:none}
@media(max-width:650px){
 /* Selected light card: 60px face + 6px breathing room on each side. Owner 2026-10-14 「頂部打開APP色調對比色有問題 跟品牌
    一致性沒做好」: the button was the pre-10-07 gold recipe half-migrated (khaki → pale blue, navy ink, navy rule, a white
    glint) and read as a washed-out chip, 1.2–1.4:1 against the card. It is now the App's primary action (JybPrimaryButton:
    btnGradient navy face, white label, no rule, btnShadow), drawn as a pill on :before so the hit area stays 44 high. The
    card is the App's card on paper (hair outline, no shadow) instead of a typed warm brown shadow. */
 .app-open{display:grid;grid-template-columns:32px minmax(0,1fr) auto 44px;align-items:center;gap:8px;min-height:60px;margin:6px 8px;padding:6px 0 6px 12px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card);box-shadow:none;color:var(--ink)}
 .app-open>img{display:block;width:32px;height:32px;border-radius:9px}
 .app-open-copy{min-width:0}
 .app-open-copy strong,.app-open-copy small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
 .app-open-copy strong{font-size:13px;line-height:19px;font-weight:800;letter-spacing:.02em}
 .app-open-copy small{font-size:11px;line-height:16px;color:var(--muted)}
 .app-open>a,.app-open>button{display:flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0 8px;border:0;border-radius:8px;background:none;box-shadow:none;color:var(--gold-ink);font-size:13px;font-weight:600;line-height:19px;white-space:nowrap;text-decoration:none}
 .app-open>a{position:relative;isolation:isolate;padding:0 16px;border-radius:999px;color:var(--pill-fg);letter-spacing:.04em}
 .app-open>a:before{content:"";position:absolute;inset:4px 0;z-index:-1;border-radius:999px;background:var(--btn-face);box-shadow:var(--btn-glow)}
 .app-open>button{padding:0;color:var(--muted);cursor:pointer}
 .app-open>button svg{width:20px;height:20px}
 .app-open>button:active{background:var(--press)}
 .app-open>a:active:before{filter:brightness(.88)}
 .app-open>button:focus-visible{outline:2px solid var(--gold-ink);outline-offset:-2px}
 .app-open>a:focus-visible{outline:2px solid var(--gold-ink);outline-offset:2px}
 .app-header #app-page-title{position:absolute;grid-column:auto;grid-row:auto;left:50%;top:0;transform:translateX(-50%);max-width:calc(100% - 108px);overflow:hidden;text-overflow:ellipsis;line-height:48px;pointer-events:none}
}
/* end App notice */
/* 资讯详情 · 分享 (Owner 2026-10-04 「…文章頁面…都應該要有分享的功能…」) ───────────────────────────────────────────────
   The App's share glyph and 分享 in link, a text action closing the date row (13/600, a 48 target that keeps the row's
   height, as 筛选's actions do); what it did (copied, or WeChat's own ··· menu) in a one-line toast over the tab bar, the
   ink face the App's snack bars wear. Every colour is an existing token. */
#article .art-meta{align-items:center}
#article .art-share{display:inline-flex;align-items:center;gap:4px;min-width:48px;min-height:48px;margin:-16px -8px -16px auto;padding:0 8px;border:0;border-radius:999px;background:none;box-shadow:none;color:var(--link);font-size:13px;line-height:19px;font-weight:600;letter-spacing:0;cursor:pointer}
#article .art-share svg{display:block;flex:none;width:18px;height:18px}
#article .art-share:active{background:var(--press)}
@media(hover:hover){#article .art-share:hover{background:var(--press)}}
.art-toast{position:fixed;left:16px;right:16px;bottom:calc(86px + env(safe-area-inset-bottom,0px));z-index:40;margin:0;padding:12px 16px;border-radius:12px;background:var(--ink);color:var(--on-dark);font-size:13px;line-height:19px;text-align:center}
@media(min-width:651px){.art-toast{left:50%;right:auto;bottom:24px;width:min(560px,calc(100% - 48px));transform:translateX(-50%)}}
/* end 分享 */
/* Keep navigation feedback quiet; the status text is for screen readers. */
.page-nav-status{position:fixed;left:0;top:0;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;pointer-events:none}
.page-nav-status[hidden]{display:none}
:is(header nav,.mobile-nav) a.pending .nav-label{opacity:.72}

/* Shanghai Dual Home 1.0.0 · C. Reserve the curve below readable hero labels. */
:is(#me .pass-top,#login .auth-hero){padding-bottom:40px}
:is(#me .pass-top,#login .auth-hero)::after{content:"";position:absolute;bottom:0;left:0;right:0;height:24px;background:url('urban-flow.svg') center / 100% 100% no-repeat;pointer-events:none}
#me .pass-card[data-state=member] .pass-top{padding-bottom:40px}
/* Article B uses C's navy/white reading surface without guessing its teams. */
#article .art-imprint{margin:0 0 12px;padding-left:8px;border-left:3px solid var(--link);color:var(--club-navy);font-size:12px;line-height:17px;font-weight:600}
#article .news-article h1{color:var(--club-navy)}
#article .art-meta{padding-bottom:16px;border-bottom:1px solid var(--line)}
/* Passport schedules share the App timeline on desktop and mobile. */
#schedule .schedule-versus{display:grid;grid-template-columns:52px minmax(0,1fr);gap:12px}
/* A stable single column keeps team and period axes readable on a large screen. */
/* R19/R20-B: 比分 shares the 880 page column with 资讯／榜单／我的. P3-18 (2026-10-14): the basketball period table fills its
   row as the App's BasketballScoreGrid does (the team column takes the room, the period cells keep their width); its 680 box
   left about 216 px empty at the right of each row and the live pill floating in the middle. */
/* R66: MatchRow._buildTop — league 1 : status 2 : 1 while live (the pill centred in the middle half), league 1 : clock : 1
   otherwise (the base rule); league names wrap inside their column and wear lgT1／lgT2 (452f5ab68 had pushed the pill
   to the right and painted the names clubNavy). */
#scores .row-top:has(.time.live){grid-template-columns:minmax(0,1fr) minmax(0,2fr) minmax(0,1fr)}
#scores .row-top .time.live{justify-self:center}
#scores .row-league{white-space:normal;overflow:visible;overflow-wrap:anywhere}
#scores .basket-list-grid .team-name{display:inline;white-space:normal;overflow:visible;overflow-wrap:anywhere}
/* P3-18: the basketball detail is the football one's 880 column (#match), as the App draws both details full width */
/* R72 · the App's R76/R77 basketball hero: the football hero's layout (crest and one-line name to each side, the team
   rule at the foot) in the basketball home style: half-court lines, a ring round each crest (home Sharks orange, away
   silver; border 2 + gap 2 round the 34 crest), the home rule, the league name and the live/final status in Sharks
   orange (5.2:1 on the theatre). The name keeps JybType.bodyHeavy's own 15/22 (BasketballMatchHeader _Side). */
.is-basketball .md-team-name{height:22px;line-height:22px}
.md-hero-court{color:var(--sharks-orange)}
.is-basketball .md-meta strong{color:var(--sharks-orange)}
.is-basketball .md-hero .md-crest{margin:4px;outline:2px solid var(--md-theatre-muted);outline-offset:2px}
.is-basketball .md-side-home .md-crest{outline-color:var(--sharks-orange)}
.is-basketball .md-side-home .md-team-rule{background:var(--sharks-orange)}
.is-basketball .md-status.is-active{color:var(--sharks-orange)}
.md-basket-periods>.md-section{padding-inline:0}
.md-basket-periods .md-basket-table{table-layout:fixed}
.md-basket-periods .md-basket-table :is(th,td){padding:10px 2px}
.md-basket-periods .md-basket-table th:first-child{width:30%;min-width:0;padding-left:8px}
.md-basket-periods .md-basket-table thead{font-size:10px}
.md-basket-periods .md-basket-table :is(th,td):last-child{background:var(--surface-2)}

/* Authoritative support documents share the same C8B tokens as product pages.
   The scope deliberately leaves their legal text and inline section markup intact. */
body[data-jyb-support-document]{margin:0;background:var(--paper);color:var(--ink);font-family:"PingFang SC","Microsoft YaHei UI","Microsoft YaHei",sans-serif;line-height:1.85;-webkit-font-smoothing:antialiased}
[data-jyb-support-document] *{box-sizing:border-box}
[data-jyb-support-document] .support-document-header{position:sticky;top:0;z-index:20;background:var(--card);border-bottom:1px solid var(--line)}
.support-document-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;max-width:832px;min-height:80px;margin:auto;padding:12px 28px}
[data-jyb-support-document] a{color:var(--gold-ink)}
.support-document-brand{display:flex;align-items:center;gap:10px;min-width:0;min-height:48px;text-decoration:none;font-size:17px;font-weight:800;line-height:24px}
.support-document-brand img{flex:none;border-radius:9px}
.support-document-brand small{display:block;color:var(--muted);font-size:10px;font-weight:500;letter-spacing:.05em;line-height:16px}
.support-document-back{display:flex;align-items:center;flex:none;min-height:48px;padding:0 12px;border:1px solid var(--line);border-radius:var(--radius-input);font-size:12px;font-weight:600;text-decoration:none}
.support-document-skip{position:fixed;left:16px;top:-100px;padding:12px 16px;background:var(--card);z-index:30}
.support-document-skip:focus{top:12px}
[data-jyb-support-reader]{max-width:776px;margin:28px auto;padding:36px 40px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius-card);box-shadow:var(--sh-1);scroll-margin-top:100px}
[data-jyb-support-document] :is(h1,h2,strong){color:var(--gold-ink)!important}
[data-jyb-support-document] h1{margin:0 0 16px;text-align:left;font-size:26px;line-height:1.45;letter-spacing:-.02em}
[data-jyb-support-document] h2{margin:28px 0 12px!important;font-size:18px!important;line-height:1.6;font-weight:700}
[data-jyb-support-document] :is(p,li){font-size:15px}
[data-jyb-support-document] :is(.upd,.ident,.foot,.icp){color:var(--muted);font-size:12px}
[data-jyb-support-document] .upd{text-align:left;margin:0 0 28px}
[data-jyb-support-document] section{max-width:none!important;margin-bottom:24px!important}
[data-jyb-support-document] :is(.foot,footer){border-color:var(--line);margin-top:28px;padding-top:20px}
[data-jyb-support-document] footer{color:var(--muted);text-align:left}
[data-jyb-support-document] footer nav{display:flex;flex-wrap:wrap;gap:8px 20px}
[data-jyb-support-document] :is(.foot,footer) a{display:inline-flex;align-items:center;min-height:44px}
[data-jyb-support-document] [data-jyb-web-filing]{max-width:776px;margin:20px auto;padding:0 16px 24px;color:var(--muted)}
@media(max-width:650px){
 .support-document-bar{min-height:72px;gap:8px;padding:8px 16px}
 .support-document-brand{font-size:15px;gap:8px}
 .support-document-back{padding:0 10px;font-size:11px}
 [data-jyb-support-reader]{margin:16px 12px;padding:24px 20px;scroll-margin-top:88px}
 [data-jyb-support-document] h1{font-size:22px}
 [data-jyb-support-document] :is(p,li){font-size:14px}
}

/* Keep the original mobile article measure while sharing the shell download rail.
   Move the existing two 20px article insets to the left: the right inset duplicated
   the reserved edge. Headline, metadata, share and body retain one axis and line length.
   Short-height controls keep their existing layout and reading width. */
@media(max-width:650px) and (min-height:481px){
}

/* Public mobile page identity is full width. Only readable rows reserve the download entry.
   The scope deliberately excludes match and all unmeasured page families. */
@media(max-width:650px){
}

/* The remaining measured public shells share the body axis; only reading and action rows
   reserve the persistent entry. Outer gutters are deducted once, never from the whole page. */
@media(max-width:650px){
 body:has(.app-float)>footer{margin-inline:0;width:100%}
}
@media(max-width:600px){
}

/* R66 (Owner 2026-10-11; Root rulings A/B) · phones, the App's 数据 tab:
   - ScoresBottomTools centred 14 above the tab bar as in the App (82 from the bottom, the pre-9f148e8d9 place), the list
     keeping a tail as tall as the group (ScoresQuickPill.listTailSpacer: 48 + 8). ★Owner 2026-10-14 「數據底部的一級跟全部不要有背景用原本方式懸浮在
     頁面上擋道內容也沒關係給我記住這點修復好」: the tools float over the rows with NO band under them (the 10-14 morning's
     paper band, the App's R75, is withdrawn on both); covering a row is accepted, the 56 tail lets the last row scroll clear;
   - the 筛选赛事 of both lists lives in those bottom tools, so the header keeps search only (no trophy: owner 2026-10-04
     「數據頁面上放大鏡旁邊的數據圖標可以移除了」 still stands until the Owner says otherwise);
   - 足球／篮球 are the App's _SportTabs: caption 12, the selected one 600 clubNavy over a 16 × 1 clubNavy line. */
@media(max-width:650px){
 /* floating, centred 14 above the tab bar (82 from the bottom), transparent: no band (Owner 2026-10-14, remember it) */
 #scores .score-dock{position:fixed;left:50%;bottom:calc(82px + env(safe-area-inset-bottom));z-index:23;display:flex;align-items:center;gap:4px;padding:0 4px;transform:translateX(-50%)}
 #scores .score-dock .score-tier{position:static;margin:0}
 #scores .dock-tool{position:relative;display:grid;place-items:center;width:48px;height:48px;color:var(--ink);text-decoration:none}
 #scores .dock-tool:before{content:"";position:absolute;inset:6px;border-radius:50%;background:var(--card);box-shadow:inset 0 0 0 1px var(--club-navy-line)}
 #scores .dock-tool:active:before{background:var(--press)}
 #scores .dock-tool svg{position:relative;width:24px;height:24px}
 #scores .dock-filter.filtered,#scores .dock-sort.by-league{color:var(--gold-ink)}
 #scores .dock-filter.filtered:after{content:attr(data-count);position:absolute;top:4px;right:4px;box-sizing:border-box;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:var(--club-navy);color:var(--pill-fg);font-size:11px;font-weight:700;line-height:16px;text-align:center;font-variant-numeric:tabular-nums}
 #scores:has(.score-dock) #match-list{padding-bottom:56px}
 body[data-page=scores]:has(#scores .dock-filter) .app-header .app-filter{display:none}
 body[data-page=scores] .app-header .score-sport-switch{gap:0;height:48px;padding:0;border-radius:0;background:none}
 /* R69 (Owner 2026-10-12 「顶部的足球篮球这两个文字太小」): the App ScoresHeader pair at the size the eye reads them — 15/600, selected 800 club navy, a 20×2 rule under the word. */
body[data-page=scores] .app-header .score-sport-switch a{flex-direction:column;gap:5px;min-width:56px;height:48px;min-height:48px;padding:0 10px;border-radius:0;color:var(--muted);font-size:15px;font-weight:600;line-height:16px;letter-spacing:.02em}
 body[data-page=scores] .app-header .score-sport-switch a:before{content:none}
 body[data-page=scores] .app-header .score-sport-switch a:after{content:"";width:20px;height:2px;border-radius:1px;background:transparent}
 body[data-page=scores] .app-header .score-sport-switch a[aria-current=page]{color:var(--club-navy);font-weight:800}
 body[data-page=scores] .app-header .score-sport-switch a[aria-current=page]:after{background:var(--club-navy)}
}

/* R67 (Owner 2026-10-11 22:0x 「QA測試站的網頁板逐一給我看過頁面 很多頁面都跑版 給我一並處理好」; Root's 375 sweep and
   W3's three-width census, reports/core-collab-20261011/w3-r67-layout/). App roles first: the plaza action glyphs and the
   basketball period grid (W4, jyb_tokens.dart basketballPeriodLabel / PeriodScore / TotalScore / TotalBand). */
:root{--icon-muted:#535354;--like-on:#e0555f;--bb-period-label:#535354;--bb-period-score:#3e3e3e;--bb-total:#0a2b57;--bb-total-band:#e4ecf6}
/* 广场 is a root tab like 资讯 and 榜单: no back arrow in its header (its topic and fan pages keep theirs). */
body[data-page=plaza] .app-back{visibility:hidden}
/* BasketballScoreGrid: period names micro in PeriodLabel, period points micro in PeriodScore, the 总分 column on its
   TotalBand from the head row through both teams, its figures smallStrong (13/600) in TotalScore (live stays live). */
.basket-list-grid :is(th,td){padding:4px 0}
.basket-list-grid thead :is(th,td){font-size:11px;font-weight:600;color:var(--bb-period-label)}
.basket-list-grid tbody td{font-size:11px;font-weight:600;color:var(--bb-period-score)}
.basket-list-grid :is(th,td):last-child{background:var(--bb-total-band);color:var(--bb-total)}
.basket-list-grid .basket-list-total{font-size:13px;font-weight:600;color:var(--bb-total)}
.basket-list-grid .basket-list-total.live-score{color:var(--live)}
/* The detail page's period table and play-by-play use the same micro step (11/600), never the browser's 'smaller'. */
.md-basket-table th small,.md-basket-periods .md-basket-table thead{font-size:11px;font-weight:600}
.md-basket-events small{font-size:11px;font-weight:600;line-height:16px}
/* JybEditorialType.title is clubNavy (23/1.5/800 and the 16/1.85 body are the App's own reading scale and stay). */
#article .news-article h1{color:var(--club-navy)}
/* ScheduleVersusCard._compactFoot: the venue takes the free width and wraps inside it; the status pill and the chevron
   stay on the same line at the right (the old flex-wrap pushed them under a long venue name). */
#schedule .schedule-body .schedule-foot{flex-wrap:nowrap}
/* 榜单's 足球／篮球 is a sport switch, so it is the App's underline row, not a second row of solid chips (P2-1); the
   league chips under it keep JybChip. On a phone it scrolls away and the chips keep their place under the header. */
#data .data-leagues[aria-label="榜单球种"]{gap:0;height:48px;padding:0;overflow:visible;border-bottom:1px solid var(--hair);background:var(--card)}
#data .data-leagues[aria-label="榜单球种"] a{flex:1 1 auto;height:48px;min-height:48px;padding:0 16px;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);font-size:15px;line-height:22px;font-weight:400}
#data .data-leagues[aria-label="榜单球种"] a.active{border:0;background:none;box-shadow:none;color:var(--ink);font-weight:800}
#data .data-leagues[aria-label="榜单球种"] a:after{content:none}
#data .data-leagues[aria-label="榜单球种"] a.active:after{content:"";inset:auto auto 6px calc(50% - 9px);width:18px;height:3px;border-radius:999px;background:var(--gold-ink)}
#data .data-leagues[aria-label="榜单球种"] a:not(.active):hover{border:0;background:none;color:var(--ink)}
@media(max-width:650px){
 #data .data-leagues[aria-label="榜单球种"]{position:static;margin:0}
 /* 资讯 and 申花赛程 draw the same _SportTabs as 比分 (R66 drew them there only): caption 12, the current one 600
    clubNavy over a 16 × 1 line, no tinted segmented pill. */
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch{gap:0;height:48px;padding:0;border-radius:0;background:none}
 /* R69: 资讯／赛程 headers take the same 15/600 pair, selected 800 over a 20×2 line (was caption 12 over 16×1). */
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch a{flex-direction:column;gap:4px;min-width:48px;height:48px;min-height:48px;padding:0 8px;border-radius:0;color:var(--muted);font-size:15px;font-weight:600;line-height:16px;letter-spacing:.02em}
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch a:before{content:none}
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch a:after{content:"";width:20px;height:2px;border-radius:1px;background:transparent}
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch a[aria-current=page]{color:var(--club-navy);font-weight:800}
 body:is([data-page=news],[data-page=schedule]) .app-header .score-sport-switch a[aria-current=page]:after{background:var(--club-navy)}
 /* P1-3: on 比分 the folded download entry rests in the bottom tools' lane (82 above the foot, beside ScoresBottomTools)
    instead of over the middle of the list, where it covered the 总分 column and the row chevrons. */
 body[data-page=scores] .app-float.float-c{bottom:calc(82px + env(safe-area-inset-bottom))}
 body[data-page=scores] .app-float.float-c.collapsed>button,body[data-page=scores] .app-float.float-c:not([data-ready=true])>button{height:48px;min-height:48px}
 /* The plaza list is the App's full-width list now (no 12 page inset), so its posts reserve the whole entry width. */
 /* Its toolbar keeps its tabs and field clear of the entry, but the card face and the tab rule run to the screen edge
    (the 比分 toolbar's border-image, R20): no paper notch at the top right. */
 #plaza-content>.plaza-toolbar{border-image:linear-gradient(var(--card) 0 0) fill 0/0/0 100vmax}
 #plaza-content>.plaza-toolbar nav{border-bottom:0;border-image:linear-gradient(var(--card) calc(100% - 1px),var(--hair) 0) fill 0/0/0 100vmax}
}
/* Below 360 the five actions borrow the avatar column's width rather than shrink under 48. */
@media(max-width:359px){.plaza-actions{margin-left:-54px}}

/* R68 ④ (Root and W4 P3 on R67): on every phone page the folded download entry rests in the bottom lane, 82 above the foot
   (where 比分's bottom tools sit), instead of in the middle of the right edge over the cards; text keeps its measured right
   clearance, so nothing readable goes under it. Short viewports keep their own row layout (max-height 480). */
@media(max-width:650px) and (min-height:481px){
 .app-float.float-c{bottom:calc(82px + env(safe-area-inset-bottom))}
 .app-float.float-c.collapsed>button,.app-float.float-c:not([data-ready=true])>button{height:48px;min-height:48px}
 /* A match page's tabs can sit in that lane before the reader scrolls (basketball's four on a 640 or 667 high phone), so
    they keep the edge clearance the short layout below already gives them. */
}
/* R68 ④(b) (Root 00:0x, W3 option 1; the 阵容 grip above): 比分's rows run full width like the App's list, so there the
   folded entry, and the same face before the page is ready, is a 24-wide grip (the WCAG 2.5.8 AA minimum target) over the
   least of a score. It is never hidden; open, it is the full entry. */
@media(max-width:650px){
 body[data-page=scores] .app-float.float-c:is(.collapsed,:not([data-ready=true])){width:24px}
 body[data-page=scores] .app-float.float-c:is(.collapsed,:not([data-ready=true]))>button{width:100%;min-width:24px}
}
/* R68 ② · MatchRow's star (match_row.dart): a touch strip on the row's left edge over the main and sub bands — inset 16 +
   star column 32 + gap 8 = 56 wide, the league line stays the row's — that never opens the match; the glyph (16) sits in
   the column, centred on the main band, and the teams start after the strip. Idle muted, starred link, in flight faint. */
#scores .match-item{position:relative}
#scores .match-item>.match .row-main{padding-left:56px}
#scores .match-star{position:absolute;left:0;top:24px;bottom:1px;width:56px;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--muted);cursor:pointer}
#scores .match-star>span{position:absolute;left:16px;top:0;display:grid;place-items:center;width:32px;height:44px;font-size:16px;line-height:1}
#scores .match-star.on{color:var(--link)}
#scores .match-star.pending{color:var(--faint)}
/* the strip touches the screen edge, so its ring is the focus system's inside one (3 gold-ink, 3 in), not clipped outside */
#scores .match-star:focus-visible{outline:3px solid var(--gold-ink);outline-offset:-3px}
/* A row far off screen keeps the place of the whole item: the item has no hairline of its own, so that is the row's 83
   plus the row's 1 px hairline, 84 (the PC rule below counts its 57 the same way). It was 83, copied from `.match`, which
   carries its hairline on top: every row grew 1 px the first time it was drawn, and when the search's whole day put a
   row right above the one the reader was on, the reader's row moved 1 px down as that row was drawn, 2 px for two
   (2026-10-12, Chromium Pixel 7 and WebKit iPhone 15). */
#match-list>.match-item{content-visibility:auto;contain-intrinsic-block-size:auto 84px}

/* R69 basketball 赛况 in the App's R75 A 雷速式 order (Owner 2026-10-12 「至少在已有的功能做到跟APP对齐」):
   01 事件直播 — 重要事件 is a dual-sided axis (home left in viz-home, away right in viz-away, the period + clock pill on
   the axis, 「第N节结束」/「结束」 markers), 事件记录 is the full log; the two radios switch the views in CSS, no script.
   Then 02 技术统计. Every colour is an existing token (BasketballKeyEventAxis: vizHome / vizAway / border / muted). */
.md-basket-axis{padding:0 var(--md-gutter) 8px}
.md-basket-axis-head{display:grid;grid-template-columns:minmax(0,1fr) 32px minmax(0,1fr);align-items:center;padding:8px 0;font-size:13px;line-height:19px;font-weight:600}
.md-basket-axis-head .home{grid-column:1;color:var(--md-viz-home);text-align:center}
.md-basket-axis-head .away{grid-column:3;color:var(--md-viz-away);text-align:center}
.md-basket-axis ol{margin:0;padding:0;list-style:none}
.md-basket-axis li{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);column-gap:8px;align-items:start;padding:4px 0}
.md-basket-axis li.is-marker{grid-template-columns:minmax(0,1fr);justify-items:center}
.md-basket-pill{display:inline-grid;place-items:center;min-height:24px;padding:2px 8px;border:1px solid var(--md-hair);border-radius:999px;color:var(--muted);font-size:11px;line-height:16px;font-variant-numeric:tabular-nums;white-space:nowrap}
.md-basket-axis-side{min-width:0;color:var(--ink);font-size:13px;line-height:19px}
.md-basket-axis-side p{margin:0;overflow-wrap:anywhere}
.md-basket-axis-side b{display:block;font-weight:600;font-variant-numeric:tabular-nums}
.md-basket-axis li.is-home .md-basket-axis-side:first-child{text-align:right}
.md-basket-axis li.is-home b{color:var(--md-viz-home)}
.md-basket-axis li.is-away b{color:var(--md-viz-away)}
.md-basket-axis-empty{margin:0;padding:24px 0;color:var(--muted);font-size:13px;line-height:19px;text-align:center}
/* Owner 2026-10-13 「重要事件時間軸…高度要固定一個可以下滑 在那個區塊下滑不要影響到下面內容」 — the App's
   BasketballEventViewport: the key-event rows and the full 事件记录 sit in one bounded box (45% of the viewport, clamped
   280–440 px, the App's numbers); a short game keeps its content height; scrolling inside never chains to the page. */
.md-basket-axis ol,.md-basket-events{max-height:clamp(280px,45vh,440px);overflow-y:auto;overscroll-behavior:contain;border-bottom:1px solid var(--md-hair);scrollbar-gutter:stable}
.md-basket-pane:has(#md-bevt-all:checked) .md-basket-axis{display:none}
.md-basket-pane:has(#md-bevt-key:checked) .md-basket-log{display:none}

/* R69 · PC (Owner 2026-10-12 「PC版不是另外一个手机版 而是PC界面」; 「整个都歪一边」). One column width for the site header
   and every page (the header used to be 1160 wide against 880 pages, so the brand sat 32 px left of the page's left
   edge; the footer already sat on the 880 column at ≥651), and the football list as a desktop table row — star ·
   league · time · home ⟷ score ⟷ away · chevron — instead of the phone row stretched to 880 (the time floated in the
   middle, the score and chevron hung at the far right). Every row rule is scoped to `.match-item>a.match`, the
   football row; the basketball list (its rows carry no .match-item) keeps its phone layout. Phones (≤650) are
   untouched; every colour is an existing token. Reviewer /reviewer-agent/r69 P1/P2/P3 fixed in r2. */
@media(min-width:901px){
 :root{--pc-col:var(--narrow)}
 .shell.head,main.shell{max-width:calc(var(--pc-col) + 2*var(--shell-pad))}
 #scores,#plaza,#data,#news,#match,#team,#schedule,#lottery,#support,#me{max-width:var(--pc-col);margin-inline:auto}
 #scores .match-item{padding:0}
 /* two fixed rows (24 + 16) and no row gap (app-alignment.css gives .match gap:16px): a match that ends and gains its
    半场 line never changes height, so the off-screen placeholder below is exact (8 + 24 + 16 + 8 + 1 = 57) */
 #scores .match-item>a.match{display:grid;grid-template-columns:44px 168px 80px minmax(0,1fr) 96px minmax(0,1fr) 28px;grid-template-rows:24px 16px;gap:0 12px;align-items:center;min-height:0;padding:8px 0;border-bottom:1px solid var(--row-line)}
 #scores .match-item>a.match .row-top,#scores .match-item>a.match .row-main,#scores .match-item>a.match .teams{display:contents}
 #scores .match-item:hover{background:var(--press)}
 #scores .match-item .match-star{position:absolute;left:0;top:0;bottom:1px;width:44px;height:auto;min-height:0}
 #scores .match-item>a.match .row-league{grid-column:2;grid-row:1;align-self:center;font-size:12px;line-height:17px}
 #scores .match-item>a.match .time{grid-column:3;grid-row:1;font-size:13px;line-height:19px;font-variant-numeric:tabular-nums;color:var(--muted)}
 #scores .match-item>a.match .row-state{grid-column:3;grid-row:2;align-self:start;font-size:11px;line-height:16px}
 #scores .match-item>a.match .teams>.team{min-height:24px}
 #scores .match-item>a.match .teams>.team:first-child{grid-column:4;grid-row:1;flex-direction:row-reverse;justify-content:flex-start}
 #scores .match-item>a.match .teams>.team:first-child .team-name{text-align:right}
 #scores .match-item>a.match .teams>.team:last-child{grid-column:6;grid-row:1}
 #scores .match-item>a.match .teams>.team .team-name{font-size:13px;line-height:19px}
 /* the score reads across (the phone stacks it): "2 – 1"; the base rule's column direction and grid spans are reset */
 #scores .match-item>a.match .score{grid-column:5;grid-row:1;display:flex;flex-direction:row;justify-content:center;align-items:center;gap:0;min-width:0;font-size:17px;font-weight:800;line-height:24px;font-variant-numeric:tabular-nums}
 #scores .match-item>a.match .score>span{display:inline;min-height:0}
 #scores .match-item>a.match .score>span+span:before{content:"–";display:inline;margin:0 6px;color:var(--muted);font-weight:400}
 #scores .match-item>a.match .score.unplayed{font-size:13px;line-height:19px;font-weight:600}
 #scores .match-item>a.match .row-chevron{grid-column:7;grid-row:1;justify-self:center}
 #scores .match-item>a.match .row-sub{grid-column:4/7;grid-row:2;align-self:start;min-height:16px;padding:0;font-size:11px;line-height:16px;text-align:center}
 /* the 一级／全部 rail sits beside the status tabs instead of floating over the last rows. R20261014 (P1-2): the tabs'
    band is a sticky layer (z 29) whose border-image paints white 100vmax to each side, over the rail beside it — the
    rail was there and answered a click, but nothing of it could be seen. It is a sticky layer of its own one step above
    the band, held 8 down (centred in the 48 band) with the tabs, so it stays in sight wherever the list is scrolled. */
 #scores .scores-panel{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center}
 #scores .scores-panel>*{grid-column:1/-1}
 #scores .scores-panel>.toolbar{grid-column:1;grid-row:1}
 #scores .score-tier{grid-column:2;grid-row:1;position:sticky;top:calc(var(--band-top) + 8px);bottom:auto;z-index:30;height:32px;margin:0 0 0 12px}
 /* the off-screen placeholder is the PC row (57), so a row that changes band does not shift the one the reader is on */
 #match-list>.match-item{contain-intrinsic-block-size:auto 57px}
}

/* R69b · phones (Owner 2026-10-12 「手機網頁版 一張一張看 還是都歪一邊」): the floating App download entry is a PC edge tab
   only. On a phone it used to sit over the content or push the content left by its own width; neither is the App, so on
   ≤650 it is not drawn at all — every page is the full width and symmetric (the basketball player table lost its 16 px
   right-only margin with it). /download/ stays a page of its own; 我的 has no direct link to it on a phone. */
@media(max-width:650px){
 .app-float.float-c{display:none!important}
}

/* R71 (reviewer P3 on R70): the basketball 球员 table card keeps the page gutter on both sides on a phone (its right-only
   16 px went with the download lane); the PC live-row time column is 80 wide so the 「67' 下半」 pill fits. */
@media(max-width:650px){
 body[data-page=match] .md-pane>.md-basket-table-wrap{margin-inline:var(--md-gutter)}
}

/* R71 (reviewer P3 on R70; the App since R75 keeps its bottom tools in a band the list ends above): on 比分 the page is at
   least a screen tall and keeps 158 px (tab bar lane + the tools band) under its footer, so the footer links always scroll
   above the fixed 筛选／一级／排序 tools instead of under them, even for a three-match day. */
@media(max-width:650px){
 body[data-page=scores]:has(#scores .score-dock){padding-bottom:calc(158px + env(safe-area-inset-bottom,0px))}
 body[data-page=scores]:has(#scores .score-dock) #main-content{min-height:calc(100vh - 96px)}
 body[data-page=scores]:has(#scores .score-dock) #main-content{min-height:calc(100dvh - 96px)}
}

/* R72 · basketball detail A 三分页去重 (Owner 2026-10-12 「選 A 三分頁去重…並同步網頁版」, the App's R77 BasketballDetailTabs):
   赛况 = 分节比分 (now inside the pane, under the tab bar) + 01 事件直播 + 02 关键数据, three leader cards that summarise the
   player table once (names in the side colours, the value in ink; JybType.micro / smallStrong, surface card, border,
   JybRadius.m) and 查看球员数据 › (smallStrong, actDeep) to 数据; 数据 = 01 球队对比 (names row in the side colours) + 02 球员,
   whose column leaders wear the Sharks-orange pill (JybPinnedTable emphasis: 8 / 2 padding, pill radius, smallStrong). */
.md-basket-pane>.md-basket-periods{padding-top:0}
.md-basket-leader-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;padding:8px var(--md-gutter) 0}
.md-basket-leader-card{min-width:0;padding:8px;border:1px solid var(--md-border);border-radius:12px;background:var(--card)}
#match .md-basket-leader-card h3{color:var(--muted);font-size:11px;line-height:16px;font-weight:600;text-align:center}
.md-basket-leader-side{display:flex;align-items:flex-start;gap:4px;margin-top:4px}
.md-basket-leader-side.is-home{margin-top:8px}
.md-basket-leader-side span{display:-webkit-box;flex:1;min-width:0;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:11px;line-height:16px;font-weight:600;overflow-wrap:anywhere}
.md-basket-leader-side.is-home span{color:var(--md-viz-home)}
.md-basket-leader-side.is-away span{color:var(--md-viz-away)}
.md-basket-leader-side b{flex:none;color:var(--ink);font-size:13px;line-height:19px;font-weight:600;font-variant-numeric:tabular-nums}
.md-basket-leader-side.has-face{display:grid;gap:2px}
.md-basket-leader-who{display:flex;align-items:center;justify-content:space-between;gap:4px}
.md-basket-more{display:flex;justify-content:flex-end;padding:0 var(--md-gutter) 12px}
#md-basket-players{scroll-margin-top:calc(var(--head-h,0px) + 8px)}
/* a phone pins the 48 px tab strip at the top (and the App notice's 48 px header above it when shown): 02 球员 lands under it */
@media(max-width:650px){
 #md-basket-players{scroll-margin-top:56px}
 body[data-page=match]:has(.app-open) #md-basket-players{scroll-margin-top:104px}
}
.md-basket-more button{min-height:48px;padding:0 8px;border:0;background:none;color:var(--md-link);font-size:13px;line-height:19px;font-weight:600;cursor:pointer}
@media(hover:hover){.md-basket-more button:hover{text-decoration:underline}}
.md-basket-table .is-lead{display:inline-block;padding:2px 8px;border-radius:999px;background:var(--sharks-orange-soft);color:var(--sharks-orange-ink);font-weight:600}
.md-stats>.md-basket-sides strong{font-weight:600}
.md-stats>.md-basket-sides strong:first-child{color:var(--md-viz-home)}
.md-stats>.md-basket-sides strong:last-child{color:var(--md-viz-away)}

/* R73 · the hero court is drawn like the App's _CourtPainter, relative to the hero box (arcs .42w / .26w round a centre
   24 below the bottom edge, key .24w × .55h, free-throw circle .06w), one 1.2 px line (JybHeroSize.artworkStroke) at .28,
   clipped to the hero; R73 also draws the App's line under the big score (.md-score-half, the .md-score-sub style). */
.md-hero-court{overflow:hidden;opacity:.28}
.md-hero-court>i{position:absolute;display:block;box-sizing:border-box;border:1.2px solid currentColor}
.md-hero-court>.md-court-arc3,.md-hero-court>.md-court-arc,.md-hero-court>.md-court-ft{aspect-ratio:1;border-radius:50%;transform:translateY(-50%)}
.md-hero-court>.md-court-arc3{left:8%;width:84%;top:calc(100% + 24px)}
.md-hero-court>.md-court-arc{left:24%;width:52%;top:calc(100% + 24px)}
.md-hero-court>.md-court-key{left:38%;width:24%;height:55%;bottom:-24px}
.md-hero-court>.md-court-ft{left:44%;width:12%;top:calc(45% + 24px)}
/* Owner 10-13 F2 · the football hero's half ball (the App's FootballBallPainter): a square 77% of the hero width (r = .385w)
   centred 24 px below the bottom edge, gold-on-dark at .26, one non-scaling 1.2 px line, clipped to the hero. */
.md-hero-ball{overflow:hidden;color:var(--gold-on-dark);opacity:.26}
.md-hero-ball>svg{position:absolute;left:50%;bottom:-24px;width:77%;height:auto;aspect-ratio:1;transform:translate(-50%,50%);overflow:visible}

/* R74 · basketball 数据 / 分析 in step with the App's R78 (Owner 2026-10-12 22:4x 「篮球的比赛详情好像还有一堆数据没妥善显示处理」):
   球队对比 rows are DetailTugRow with no glyph and a bar on every row, shooting values on two lines (made/attempted, rate);
   球员 keeps the App's name column (min(156, 44%), regular weight, one line where it fits); the history groups are
   BasketballMatchRow rows that run to the card edges with the date line, under a centred 展开全部 N 场 / 收起; the row rules
   reach the history through :is(#scores,…), which carries the id weight, so the history-only overrides start with #match. */
.md-basket-tug .md-tug-values{align-items:center}
/* JybPinnedTable: name column min(156, 44% of the table viewport); this auto-layout table ignores % widths and max-width, so it is a min-width */
:is(.md-basket-pane,.md-basket-full)>.md-basket-table-wrap .md-basket-table th:first-child{min-width:min(156px,calc((100vw - 2*var(--md-gutter))*.44))}
:is(.md-basket-pane,.md-basket-full)>.md-basket-table-wrap .md-basket-table tbody th{font-weight:400}
/* P3-15: the player table now sits in .md-basket-scroll (its fade): the same first column and weight there */
.md-basket-full>.md-basket-scroll .md-basket-table th:first-child{min-width:min(156px,calc((100vw - 2*var(--md-gutter))*.44))}
.md-basket-full>.md-basket-scroll .md-basket-table tbody th{font-weight:400}
.basket-history-rows{margin:0 -16px}
#match .basket-history-rows .row-sub:empty{display:none}
#match .basket-history-rows .row-league[class]{font-weight:600;color:var(--muted)}
#match .basket-history-rows .match .time{color:var(--ink)}
#match .basket-history-rows .row-state{justify-self:end}
.basket-history-rows .row-date{display:block;padding:0 16px 8px;color:var(--ink);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.basket-more>summary{display:flex;align-items:center;justify-content:center;min-height:48px;color:var(--md-link);font-size:13px;line-height:19px;font-weight:600;list-style:none;cursor:pointer}
.basket-more>summary::-webkit-details-marker{display:none}
.basket-more>summary::marker{content:""}
.basket-more[open]>summary .basket-more-open,.basket-more:not([open])>summary .basket-more-close{display:none}
.basket-more>summary:focus-visible{outline:3px solid var(--gold-ink);outline-offset:-3px}

/* 2026-10-13 · basketball full wiring, the web side (Owner 「没接的接上去…确保用户可以看到所有资料并排列设计好」, then
   「登陆了都接上去按照我说的做」; docs/engineering/NAMI_BASKETBALL_FULL_WIRING_20261013.md, the approved layout W1–W4 in
   docs/_handoff/design/core-20261013-match-detail/make-wiring.mjs). Web type steps only (11/16, 13/19, 15/22, 20/27); every
   colour is an existing App token. W1 赛况: 看直播 and the 集锦 rail; W2 分析: 04 历史同*统计; W3 数据: the head coaches and the
   球员资料 sheet; W4 篮球榜单: the 赛季 control and 积分榜｜球员榜｜季后赛｜赛制. */
/* W1 · 看直播: the primary pill (pillGradient, pillFg) at the top of 赛况, 48 high, inside the page gutter */
/* (every new box that holds visually hidden .sr words is positioned, so those words stay inside it: in the rail they would
   otherwise belong to .md-page and widen the page by the rail's whole scroll length) */
/* (the App's BasketballLiveEntry: JybPrimaryButton 「看直播 · 版权直播源」 with the play glyph, pill; several sources open their
   list, the App's 选择直播源; the line under it says the tap opens another site) */
.bb-live{margin:0 var(--md-gutter) 12px}
.bb-live-entry{position:relative;display:flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 20px;border-radius:999px;background:var(--pill-face);color:var(--pill-fg);font-size:15px;line-height:22px;font-weight:600;text-decoration:none;list-style:none;cursor:pointer}
.bb-live-entry::-webkit-details-marker{display:none}
.bb-live-entry>svg{display:block;flex:none;width:18px;height:18px}
.bb-live-entry:focus-visible,.bb-live-source:focus-visible{outline:3px solid var(--gold-ink);outline-offset:3px}
.bb-live-sources{display:flex;flex-wrap:wrap;gap:8px;padding-top:8px}
.bb-live-source{position:relative;display:inline-flex;flex:1 1 0;align-items:center;justify-content:center;min-width:96px;min-height:44px;padding:0 16px;border:1px solid var(--club-navy-line);border-radius:999px;background:var(--card);color:var(--ink);font-size:13px;line-height:19px;font-weight:600;text-decoration:none}
@media(hover:hover){.bb-live-source:hover{background:var(--press)}}
.bb-media-note{margin:0;padding:4px 0 0;color:var(--muted);font-size:11px;line-height:16px;text-align:center}
.bb-videos>.bb-media-note{padding:4px var(--md-gutter) 8px;text-align:left}
/* W1 · 集锦: 124 × 70 covers on the dark ground with the length on them, a two-line 13/19 title, 8 apart from the gutter; the rail
   scrolls on its own (never the page) */
.bb-videos{margin-bottom:4px}
.bb-video-rail{display:flex;gap:8px;margin:0;padding:4px var(--md-gutter) 8px;overflow-x:auto;list-style:none;scrollbar-width:none;overscroll-behavior-x:contain}
.bb-video-rail::-webkit-scrollbar{display:none}
.bb-video-rail>li{flex:none;width:124px;min-width:0}
.bb-video{position:relative;display:block;border-radius:10px;color:var(--ink);text-decoration:none}
.bb-video-cover{position:relative;display:grid;place-items:center;width:124px;height:70px;overflow:hidden;border-radius:10px;background:var(--md-anim-ground);color:var(--on-dark)}
.bb-video-cover img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover}
.bb-video-play{position:relative;z-index:1;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--md-anim-scrim)}
.bb-video-play svg{display:block;width:16px;height:16px}
.bb-video-time{position:absolute;right:6px;bottom:6px;z-index:1;padding:0 6px;border-radius:999px;background:var(--md-anim-scrim);color:var(--on-dark);font-size:11px;line-height:16px;font-weight:600;font-variant-numeric:tabular-nums}
.bb-video-title{display:-webkit-box;margin-top:8px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:13px;line-height:19px;font-weight:600;overflow-wrap:anywhere}
.bb-video:focus-visible{outline:3px solid var(--gold-ink);outline-offset:2px}
@media(hover:hover){.bb-video:hover .bb-video-title{color:var(--club-navy)}}
@media(min-width:651px) and (hover:hover) and (pointer:fine){.bb-video-rail{padding-bottom:12px;scrollbar-width:thin;scrollbar-color:var(--md-border-2) transparent}}
/* W2 · 04 历史同*统计: per block each side's name in its role, the rate as a 10-high bar on surface2, 胜-负 · rate in inkSoft; then the
   相似球队 pills (accentSoft) */
.bb-similar-block{padding-bottom:4px}
.bb-similar-block+.bb-similar-block{border-top:1px solid var(--md-hair)}
.bb-similar-row{display:grid;grid-template-columns:minmax(40px,64px) minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 0;font-size:13px;line-height:19px}
.bb-similar-team{overflow:hidden;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
.bb-similar-row.is-home .bb-similar-team{color:var(--md-viz-home)}
.bb-similar-row.is-away .bb-similar-team{color:var(--md-viz-away)}
.bb-similar-bar{display:block;height:10px;overflow:hidden;border-radius:999px;background:var(--surface-2)}
.bb-similar-bar>i{display:block;height:100%;border-radius:inherit}
.bb-similar-row.is-home .bb-similar-bar>i{background:var(--md-viz-home)}
.bb-similar-row.is-away .bb-similar-bar>i{background:var(--md-viz-away)}
.bb-similar-value{color:var(--ink-soft);font-variant-numeric:tabular-nums;white-space:nowrap}
.bb-similar-teams{border-top:1px solid var(--md-hair)}
.bb-pills{display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0 0 4px;list-style:none}
.bb-pills>li{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;border-radius:999px;background:var(--accent-soft);color:var(--ink);font-size:13px;line-height:19px}
.bb-pills>li.bb-pills-more{padding:0 4px;background:none;color:var(--muted)}
/* W3 · the head coaches: one card on top of 数据, the two names in their roles, 主教练 under each (away on the right) */
.bb-coaches{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;margin:0 var(--md-gutter) 4px;padding:12px;border:1px solid var(--md-border);border-radius:12px;background:var(--card)}
.bb-coach{display:grid;align-content:start;min-width:0}
.bb-coach.is-away{text-align:right}
.bb-coach strong{overflow:hidden;font-size:13px;line-height:19px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
.bb-coach.is-home strong{color:var(--md-viz-home)}
.bb-coach.is-away strong{color:var(--md-viz-away)}
.bb-coach span{color:var(--ink-soft);font-size:13px;line-height:19px;overflow-wrap:anywhere}
/* W3 · a player's name opens the sheet: the name keeps its place and type, a clubNavyLine underline says it opens. Like the App,
   the target is the whole top-three card and the whole (at least 48 high) name cell, not the word: the name's ::after fills the
   card / cell around it (both positioned; the table's name column is sticky), while the keyboard ring stays on the name */
.bb-player-link{position:static;display:inline;max-width:100%;min-height:0;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:inherit;font:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:underline;text-decoration-color:var(--club-navy-line);text-decoration-thickness:1px;text-underline-offset:3px;cursor:pointer}
.bb-player-link::after{content:"";position:absolute;inset:0}
.md-top:has(.bb-player-link){position:relative}
.md-basket-table tbody th:has(.bb-player-link){height:48px}
.bb-player-link:focus-visible{outline:2px solid var(--gold-ink);outline-offset:2px}
@media(hover:hover){.bb-player-link:hover{color:var(--club-navy);text-decoration-color:currentColor}}
/* W3 · 球员资料 (the page's one sheet, .md-sheet.is-player): the 60 face on accentSoft, the 20/27 name over the 13/19 muted
   team · number · position line, the 48 ×; the facts as two columns of paper cells (11/16 label over the 15/22 value), this
   game's line in the side's role */
.bb-sheet-head{display:flex;flex:none;align-items:center;gap:12px;padding:8px 4px 0 16px}
.bb-sheet-face{position:relative;display:grid;flex:none;place-items:center;width:60px;height:60px;overflow:hidden;border-radius:50%;background:var(--accent-soft);color:var(--club-navy)}
.bb-sheet-face>svg{width:28px;height:28px}
.bb-sheet-face>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.bb-sheet-title{flex:1;min-width:0}
#match .bb-sheet-title h2,#data .bb-sheet-title h2{margin:0;color:var(--ink);font-size:20px;line-height:27px;font-weight:700;overflow-wrap:anywhere}
#match .bb-sheet-title p,#data .bb-sheet-title p{margin:0;color:var(--muted);font-size:13px;line-height:19px}
#match .bb-sheet-close,#data .bb-sheet-close{display:grid;place-items:center;flex:none;align-self:flex-start;width:48px;height:48px;min-height:48px;margin:0;padding:0;border:0;border-radius:50%;background:none;color:var(--muted)}
#match .bb-sheet-close svg,#data .bb-sheet-close svg{display:block;width:20px;height:20px}
@media(hover:hover){#match .bb-sheet-close:hover,#data .bb-sheet-close:hover{background:var(--press)}}
.bb-sheet-facts{flex:1 1 auto;min-height:0;padding:16px 16px 24px;overflow-y:auto;overscroll-behavior:contain}
.bb-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}
.bb-facts>div{min-width:0;padding:8px 12px;border-radius:10px;background:var(--paper)}
.bb-facts dt{color:var(--muted);font-size:11px;line-height:16px}
.bb-facts dd{margin:0;color:var(--ink);font-size:15px;line-height:22px;font-weight:600;overflow-wrap:anywhere}
#match .bb-sheet-note,#data .bb-sheet-note{margin:0;padding:8px 0;color:var(--muted);font-size:13px;line-height:19px;text-align:center}
.bb-sheet-error{display:flex;flex-direction:column;align-items:center}
#match .bb-sheet-game,#data .bb-sheet-game{margin:16px 0 0;font-size:13px;line-height:19px;font-weight:600;text-align:center}
.bb-sheet-game.is-home{color:var(--md-viz-home)}
.bb-sheet-game.is-away{color:var(--md-viz-away)}
/* 2026-10-14: opened from 球员榜 the sheet ends with the board's per-game line, in ink */
.bb-sheet-game.is-board{color:var(--ink)}
/* W4 · 篮球榜单: the league chips have the row to themselves (sticky under the phone header, as the chips were); 2026-10-14: the 赛季
   control has its own row under them (beside the chips it sat over the last ones on a 360 phone — 「亚得里亚海」), with
   「2026-2027 赛季尚未开赛」 after it or, when both do not fit, under it. The four panes reuse the board tabs (JybUnderlineTabs,
   #data .data-modes) */
.bb-board-bar{display:flex;align-items:center;gap:8px;min-width:0}
#data .bb-board-bar>.data-leagues{flex:1 1 auto;min-width:0}
.bb-season-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px;min-width:0;padding:0 16px 8px}
.bb-season{display:flex;flex:none;align-items:center;max-width:100%;min-width:0}
.bb-season-note{margin:0;color:var(--muted);font-size:12px;line-height:17px}
.bb-season-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
/* 积分榜: a phase whose groups are all 0-0 is one quiet line (「常规赛尚未开赛」), not a table of zeros */
.bb-pending{margin:0;padding:12px 16px 0;color:var(--muted);font-size:13px;line-height:19px}
/* a 球员榜 name opens 球员资料: the whole line is its hit area, as on the match page's player cards */
.bb-leader:has(.bb-player-link){position:relative}
/* the App's season pill (neutral, chip-high, 13/19 600 ink, the muted chevron); the browser's own list lies over it, transparent,
   a 48 hit like the chips' */
.bb-season-pick{position:relative;display:flex;align-items:center;border-radius:999px}
.bb-season-face{display:inline-flex;align-items:center;gap:4px;min-height:32px;padding:0 8px 0 12px;border:1px solid var(--btn-line);border-radius:999px;background:var(--card);color:var(--ink);font-size:13px;line-height:19px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.bb-season-face>svg{display:block;flex:none;width:16px;height:16px;color:var(--icon-muted)}
.bb-season-pick select{position:absolute;inset:-8px -4px;width:calc(100% + 8px);height:calc(100% + 16px);margin:0;padding:0;border:0;opacity:0;font-size:16px;cursor:pointer}
.bb-season-pick:has(select:focus-visible) .bb-season-face{outline:3px solid var(--gold-ink);outline-offset:2px}
@media(hover:hover){.bb-season-pick:hover .bb-season-face{background:linear-gradient(var(--press),var(--press)),var(--card)}}
@media(max-width:650px){
 #data .bb-board-bar{position:sticky;top:48px;z-index:3;background:var(--paper)}
 #data .bb-board-bar>.data-leagues{position:static}
 /* on a phone the panes keep the page gutter like the chips (积分榜's group heads and tables sat on the screen edge: the match
    page's --md-gutter is not defined here) */
 #data .bb-board-panel{--md-gutter:16px}
 #data .bb-board-panel .md-basket-table-wrap{margin-inline:16px}
 #data .bb-board-panel .standings-notes{padding-inline:16px}
}
@media(min-width:651px){.bb-season-row,.bb-pending{padding-inline:0}}
.bb-board-panel{min-width:0;padding-bottom:16px}
/* W4 · 球员榜: category chips (32 faces in 48 hits, clubNavyLine, the chosen one on accentSoft), then one card of ranked rows */
.bb-metrics{display:flex;gap:8px;padding:12px 16px 8px;overflow-x:auto;scrollbar-width:none}
.bb-metrics::-webkit-scrollbar{display:none}
.bb-metrics button{position:relative;flex:none;min-height:32px;margin:0;padding:0 12px;border:1px solid var(--club-navy-line);border-radius:999px;background:var(--card);box-shadow:none;color:var(--ink);font-size:13px;line-height:19px;font-weight:400}
.bb-metrics button:after{content:"";position:absolute;inset:-8px -4px}
.bb-metrics button.active{background:var(--accent-soft);font-weight:600}
/* (the App's BasketballLeadersBoard / _LeaderLine: a 球员｜球队 segmented switch when teams were ranked; the season note; per line
   the rank in 15/22 heavy (the top three in Sharks-orange ink, the rest faint), the 32 face or crest, the 13/19 name over the 11/16
   「team · N 场」, a 72-wide clubNavyLine bar measured against the best average, the average over 场均) */
.bb-who{display:inline-grid;grid-template-columns:1fr 1fr;align-items:center;height:36px;margin:8px 16px 0;padding:0 3px;border:1px solid var(--row-line);border-radius:999px;background:var(--surface-2)}
.bb-who button{position:relative;display:grid;place-items:center;min-width:56px;height:28px;min-height:0;margin:0;padding:0 12px;border:0;border-radius:999px;background:none;box-shadow:none;color:var(--ink);font-size:13px;line-height:19px;font-weight:600}
.bb-who button:after{content:"";position:absolute;inset:-10px 0}
.bb-who button.active{background:var(--pill-face);box-shadow:var(--sh-1);color:var(--pill-fg)}
@media(hover:hover){.bb-who button:not(.active):hover{background:var(--press)}}
.bb-note{margin:0;padding:8px 16px 0;color:var(--muted);font-size:13px;line-height:19px}
.bb-board-none{margin:0;padding:32px 16px;color:var(--muted);font-size:13px;line-height:19px;text-align:center}
.bb-leaders{margin:12px 16px 0;padding:0 12px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card);list-style:none}
.bb-leader{display:grid;grid-template-columns:minmax(28px,auto) 32px minmax(0,1fr) 72px auto;align-items:center;gap:8px;min-height:56px;padding:8px 0}
.bb-leader+.bb-leader{border-top:1px solid var(--row-line)}
.bb-rank{color:var(--faint);font-size:15px;line-height:22px;font-weight:800;font-variant-numeric:tabular-nums}
.bb-rank.is-top{color:var(--sharks-orange-ink)}
.bb-face,.bb-crest{position:relative;display:grid;place-items:center;width:32px;height:32px;overflow:hidden;color:var(--icon-muted)}
.bb-face{border-radius:50%;background:var(--accent-soft);color:var(--club-navy)}
.bb-face>svg,.bb-crest>svg{width:18px;height:18px}
.bb-face>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.bb-crest>img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.bb-leader-name{display:grid;min-width:0;margin-left:4px}
.bb-leader-name strong{overflow:hidden;color:var(--ink);font-size:13px;line-height:19px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
.bb-leader-name small{overflow:hidden;color:var(--muted);font-size:11px;line-height:16px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}
.bb-leader-bar{display:block;height:8px}
.bb-leader-bar>i{display:block;height:100%;border-radius:999px;background:var(--club-navy-line)}
.bb-leader-value{display:grid;justify-items:end;min-width:40px;margin-left:4px}
.bb-leader-value b{color:var(--ink);font-size:20px;line-height:27px;font-weight:800;font-variant-numeric:tabular-nums}
.bb-leader-value small{color:var(--muted);font-size:11px;line-height:16px;font-weight:600}
@media(max-width:359px){.bb-leader{grid-template-columns:minmax(28px,auto) 32px minmax(0,1fr) auto}.bb-leader-bar{display:none}}
/* W4 · 季后赛: the bracket's name, then one column per round (a 11/16 muted head, 8 apart), a later round's ties spread between their
   feeders; a tie is a small card of two lines, the winner's in ink with its wins in the home role; the bracket scrolls on its own */
/* (the App's BasketballBracketBoard: the 13/19 caption, each tree's 15/22 heavy name, round heads 11/16 heavy, columns at least 84
   sharing the width when they fit; a series card on surface with the border, 13/19, the winner's line 600 ink and the loser's
   muted once decided) */
.bb-bracket-caption{margin:0;padding:12px 16px 0;color:var(--muted);font-size:13px;line-height:19px}
.bb-bracket{padding:16px 16px 0}
#data .bb-bracket-name{margin:0 0 8px;color:var(--ink);font-size:15px;line-height:22px;font-weight:800}
.bb-bracket-scroll{overflow-x:auto;overscroll-behavior-x:contain;padding-bottom:4px}
.bb-bracket-scroll:focus-visible{outline:3px solid var(--gold-ink);outline-offset:2px}
.bb-rounds{display:grid;grid-template-columns:repeat(var(--bb-rounds),minmax(84px,1fr));gap:8px;min-width:min-content}
.bb-round{display:flex;flex-direction:column;min-width:0}
#data .bb-round h4{margin:0 0 8px;color:var(--muted);font-size:11px;line-height:16px;font-weight:800;text-align:center}
.bb-round>ol{display:flex;flex:1;flex-direction:column;justify-content:space-around;gap:8px;margin:0;padding:0;list-style:none}
.bb-tie{display:grid;padding:4px 8px;border:1px solid var(--md-border);border-radius:8px;background:var(--card)}
.bb-tie-row{display:flex;align-items:center;justify-content:space-between;gap:4px;color:var(--ink);font-size:13px;line-height:19px;font-weight:400}
.bb-tie-row>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bb-tie-row>b{flex:none;font-weight:inherit;font-variant-numeric:tabular-nums}
.bb-tie-row.is-winner{font-weight:600}
.bb-tie-row.is-out{color:var(--muted)}
/* W4 · 赛制: one card of plain text, the provider's section lines as 13/19 heads, the 13/19 inkSoft paragraphs, the seasons it covers */
.bb-rules{margin:12px 16px 0;padding:16px;border:1px solid var(--hair);border-radius:var(--radius-card);background:var(--card)}
#data .bb-rules h3{margin:16px 0 0;color:var(--ink);font-size:15px;line-height:22px;font-weight:600}
#data .bb-rules h3:first-child{margin-top:0}
#data .bb-rules p{margin:4px 0 0;color:var(--ink-soft);font-size:13px;line-height:19px;overflow-wrap:anywhere}
#data .bb-rules p:first-child{margin-top:0}
@media(min-width:651px){.bb-metrics,.bb-bracket,.bb-bracket-caption,.bb-note,.bb-board-none{padding-inline:0}.bb-leaders,.bb-rules,.bb-who{margin-inline:0}}

/* 2026-10-14 · 广场 media (Owner 「網頁版廣場的圖片跟影片顯示問題沒對其APP的做法」): the App's roles for what sits on a
   photo or a video and for the media viewer (jyb_tokens.dart), and the one plaza media corner (jyb_shape.dart). */
:root{
 --photo-scrim:#0000009e;          /* JybTokens.photoScrim · round faces and chips over a photo or a video (black 62%) */
 --photo-scrim-ink:#ffffff;        /* JybTokens.photoScrimInk · the 长图 and i / n chip text */
 --icon-on-photo:#ffffff;          /* JybTokens.iconOnPhoto · glyphs on those faces */
 --lightbox:#000000;               /* JybTokens.lightboxGround · the image viewer and the full-screen video */
 --video-placeholder:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3ClinearGradient id='g' gradientUnits='userSpaceOnUse' x1='50%25' y1='0%25' x2='50%25' y2='100%25'%3E%3Cstop offset='0' stop-color='%232a2c31'/%3E%3Cstop offset='1' stop-color='%2316171a'/%3E%3C/linearGradient%3E%3Crect width='100%25' height='100%25' fill='url(%23g)'/%3E%3C/svg%3E") 0 0/100% 100% no-repeat; /* JybTokens.videoPlaceholderFill · a video before its first frame */
 --radius-media:12px;              /* JybRadius.media (= JybRadius.m) · every plaza media surface */
 --scrim:#1e1e1e80;                /* JybTokens.scrim · the barrier under the plaza post menu (showJybSheet barrierColor) */
}
