// ==UserScript== // @name Douban Plus // @namespace https://github.com/ZlatanCN/douban-plus // @version 1.3.3 // @author Gabriel Zhu // @description 适配 ScriptCat 和 Tampermonkey 的豆瓣电影详情页增强脚本,用 Preact 重排 Apple TV 风格暗色界面,并保留豆瓣原生登录、标记和跳转能力。 // @license MIT // @include https://accounts.douban.com/passport/login* // @match *://movie.douban.com/subject/* // @match *://accounts.douban.com/passport/login* // @exclude *://movie.douban.com/subject/*/all_photos // @exclude *://movie.douban.com/subject/*/photos* // @exclude *://movie.douban.com/subject/*/photos[?]* // @exclude *://movie.douban.com/subject/*/comments* // @exclude *://movie.douban.com/subject/*/comments[?]* // @exclude *://movie.douban.com/subject/*/reviews* // @exclude *://movie.douban.com/subject/*/reviews[?]* // @connect douban.com // @connect movie.douban.com // @connect graphql.imdb.com // @connect www.rottentomatoes.com // @connect www.metacritic.com // @grant GM_addStyle // @grant GM_xmlhttpRequest // @run-at document-start // ==/UserScript== (function() { "use strict"; var s$2 = new Set(); var _css = async (t) => { if (s$2.has(t)) return; s$2.add(t); ((c) => { if (typeof GM_addStyle === "function") GM_addStyle(c); else (document.head || document.documentElement).appendChild(document.createElement("style")).append(c); })(t); }; var styles_default = "/* ATV stylesheet manifest.\n Keep this file as the single CSS entry imported from main.ts.\n Files are ordered to preserve the original cascade from the former giant stylesheet.\n Do not wrap these imports in @layer: this userscript runs inside Douban pages,\n and unlayered host author CSS would outrank layered ATV normal declarations. */\n\n:root {\n --atv-bg-primary: #000;\n --atv-bg-secondary: #1c1c1e;\n --atv-bg-tertiary: #2c2c2e;\n --atv-bg-elevated: rgb(255 255 255 / 6%);\n --atv-text-primary: #fff;\n --atv-text-secondary: rgb(255 255 255 / 72%);\n --atv-text-tertiary: rgb(255 255 255 / 45%);\n --atv-accent: #41be5d;\n --atv-accent-bright: #4cd97a;\n --atv-accent-glow: rgb(65 190 93 / 35%);\n --atv-rating-gold: #ffb800;\n --atv-border-subtle: rgb(255 255 255 / 8%);\n --atv-border-medium: rgb(255 255 255 / 16%);\n --atv-radius-sm: 8px;\n --atv-radius-md: 12px;\n --atv-radius-lg: 16px;\n --atv-radius-xl: 24px;\n --atv-ease-out: cubic-bezier(0.23, 1, 0.32, 1);\n --atv-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);\n --atv-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);\n --atv-duration-press: 160ms;\n --atv-duration-hover: 160ms;\n --atv-duration-feedback: 200ms;\n --atv-duration-content: 300ms;\n --atv-duration-overlay: 200ms;\n --atv-duration-modal-backdrop: 400ms;\n --atv-duration-modal-surface: 350ms;\n}\n\nbody > #wrapper {\n display: none !important;\n}\n\nbody {\n padding: 0 !important;\n margin: 0 !important;\n background: #000 !important;\n}\n\n#db-global-nav,\n#db-nav-movie {\n display: none !important;\n}\n\n[id^=\"dale_\"],\n[class*=\"dale_\"] {\n display: none !important;\n}\n\n#atv-douban-root {\n position: relative;\n min-height: 100vh;\n animation: atv-fadein var(--atv-duration-feedback) var(--atv-ease-out)\n forwards;\n background: var(--atv-bg-primary);\n color: var(--atv-text-primary);\n font-family:\n -apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"PingFang SC\",\n \"Helvetica Neue\", \"Microsoft YaHei\", Inter, system-ui, sans-serif;\n font-feature-settings: \"ss01\", \"cv11\";\n line-height: 1.5;\n opacity: 0;\n}\n\n@keyframes atv-fadein {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n#atv-douban-root *,\n#atv-douban-root *::before,\n#atv-douban-root *::after {\n box-sizing: border-box;\n}\n\n#atv-douban-root a {\n color: inherit;\n text-decoration: none;\n}\n\n#atv-douban-root a:hover {\n background: transparent;\n}\n\n#atv-douban-root img {\n display: block;\n max-width: 100%;\n}\n\n/* ---------- Sticky nav ---------- */\n\n.atv-stickynav {\n position: fixed;\n z-index: 9999;\n top: 0;\n right: 0;\n left: 0;\n display: flex;\n height: 56px;\n box-sizing: border-box;\n align-items: center;\n justify-content: space-between;\n padding: 0 max(28px, 5vw);\n border-bottom: 1px solid rgb(255 255 255 / 6%);\n background: rgb(10 10 12 / 95%);\n font-family:\n -apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"PingFang SC\",\n \"Helvetica Neue\", \"Microsoft YaHei\", Inter, system-ui, sans-serif;\n gap: 24px;\n opacity: 0;\n pointer-events: none;\n transform: translateY(-100%);\n}\n\n/* Frosted glass effect only when NOT actively scrolling — Apple-style.\n The backdrop-filter forces per-frame compositing; dropping it during\n scroll eliminates the main source of scroll jank. */\n\n.atv-stickynav.is-visible:not(.is-scrolling) {\n -webkit-backdrop-filter: saturate(180%) blur(24px);\n backdrop-filter: saturate(180%) blur(24px);\n background: rgb(10 10 12 / 74%);\n}\n\n.atv-stickynav.is-visible {\n pointer-events: auto;\n}\n\n.atv-stickynav-title {\n overflow: hidden;\n min-width: 0;\n flex: 0 1 auto;\n color: #fff;\n font-size: 16px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.atv-stickynav-jumps {\n position: relative;\n display: flex;\n flex: 0 0 auto;\n gap: 24px;\n}\n\n.atv-stickynav-jumps a {\n position: relative;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.02em;\n transition: color var(--atv-duration-feedback) ease;\n white-space: nowrap;\n}\n\n#atv-douban-root .atv-stickynav-jumps a {\n color: rgb(255 255 255 / 70%);\n}\n\n#atv-douban-root .atv-stickynav-jumps a:hover {\n background: transparent;\n color: var(--atv-accent-bright);\n}\n\n#atv-douban-root .atv-stickynav-jumps a.is-active {\n color: var(--atv-accent-bright);\n}\n\n.atv-stickynav-marker {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 2px;\n background: var(--atv-accent-bright);\n transform: translateX(0);\n transition:\n transform var(--atv-duration-feedback) var(--atv-ease-in-out),\n width var(--atv-duration-feedback) var(--atv-ease-in-out);\n}\n\n@media (width <= 768px) {\n .atv-stickynav-title {\n font-size: 14px;\n }\n\n .atv-stickynav-jumps {\n gap: 14px;\n }\n\n .atv-stickynav-jumps a {\n font-size: 12px;\n }\n}\n\n/* The sliding active marker jumps to the active item without sliding\n motion under reduced-motion preference. */\n\n@media (prefers-reduced-motion: reduce) {\n .atv-stickynav-marker {\n transition: none;\n }\n}\n\n/* ---------- Subject switcher ---------- */\n\n.atv-stickynav-subject-switcher {\n position: relative;\n flex: 0 0 auto;\n margin-left: auto;\n}\n\n.atv-subject-switcher-trigger,\n.atv-subject-switcher-close,\n.atv-subject-search-fallback,\n.atv-subject-suggestion {\n border: 0;\n appearance: none;\n color: inherit;\n cursor: pointer;\n font: inherit;\n}\n\n.atv-subject-switcher-trigger {\n display: inline-flex;\n height: 34px;\n align-items: center;\n padding: 0 13px;\n border: 1px solid var(--atv-border-subtle);\n border-radius: 999px;\n background: rgb(255 255 255 / 7%);\n color: var(--atv-text-secondary);\n font-size: 13px;\n font-weight: 600;\n gap: 7px;\n letter-spacing: 0.01em;\n transition:\n background var(--atv-duration-hover) ease,\n border-color var(--atv-duration-hover) ease,\n color var(--atv-duration-hover) ease;\n}\n\n.atv-subject-switcher-trigger:hover,\n.atv-subject-switcher-trigger:focus-visible {\n border-color: rgb(255 255 255 / 22%);\n background: rgb(255 255 255 / 12%);\n color: var(--atv-text-primary);\n outline: none;\n}\n\n.atv-subject-switcher-expanded {\n position: relative;\n display: flex;\n width: min(44vw, 520px);\n height: 38px;\n align-items: center;\n border: 1px solid rgb(255 255 255 / 22%);\n border-radius: 999px;\n background: rgb(255 255 255 / 10%);\n box-shadow: 0 12px 32px rgb(0 0 0 / 28%);\n}\n\n.atv-stickynav.has-subject-switcher-open .atv-stickynav-jumps {\n display: none;\n}\n\n.atv-stickynav.has-subject-switcher-open .atv-stickynav-subject-switcher {\n position: absolute;\n left: 50%;\n margin: 0;\n transform: translateX(-50%);\n}\n\n.atv-stickynav.has-subject-switcher-open .atv-subject-switcher-expanded {\n width: min(56vw, 620px);\n}\n\n.atv-subject-switcher-search-icon {\n display: inline-flex;\n flex: 0 0 auto;\n margin-left: 13px;\n color: var(--atv-text-tertiary);\n}\n\n.atv-subject-switcher-input {\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0 8px;\n border: 0;\n background: transparent;\n color: var(--atv-text-primary);\n font: inherit;\n font-size: 14px;\n outline: 0;\n}\n\n.atv-subject-switcher-input::placeholder {\n color: var(--atv-text-tertiary);\n}\n\n.atv-subject-switcher-close {\n height: 24px;\n padding: 0 9px;\n border-radius: 999px;\n margin-right: 6px;\n background: rgb(255 255 255 / 10%);\n color: var(--atv-text-tertiary);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.05em;\n}\n\n.atv-subject-switcher-close:hover,\n.atv-subject-switcher-close:focus-visible {\n background: rgb(255 255 255 / 18%);\n color: var(--atv-text-primary);\n outline: none;\n}\n\n.atv-subject-suggestion-rail {\n position: absolute;\n top: calc(100% + 10px);\n right: 0;\n overflow: hidden;\n width: 100%;\n border: 1px solid rgb(255 255 255 / 12%);\n border-radius: var(--atv-radius-md);\n background: rgb(21 21 23 / 96%);\n box-shadow: 0 24px 56px rgb(0 0 0 / 48%);\n}\n\n.atv-subject-suggestion {\n position: relative;\n display: flex;\n width: 100%;\n min-height: 70px;\n align-items: center;\n padding: 8px 18px 8px 9px;\n background: transparent;\n text-align: left;\n transition: background var(--atv-duration-hover) ease;\n}\n\n.atv-subject-suggestion + .atv-subject-suggestion {\n border-top: 1px solid rgb(255 255 255 / 7%);\n}\n\n.atv-subject-suggestion:hover,\n.atv-subject-suggestion.is-active {\n background: rgb(255 255 255 / 8%);\n}\n\n.atv-subject-suggestion:focus-visible {\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: -2px;\n}\n\n.atv-subject-suggestion-poster {\n position: relative;\n overflow: hidden;\n width: 36px;\n height: 54px;\n flex: 0 0 auto;\n border-radius: 4px;\n background: var(--atv-bg-tertiary);\n}\n\n.atv-subject-suggestion-poster img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.atv-subject-suggestion-copy {\n display: grid;\n min-width: 0;\n margin-left: 12px;\n gap: 4px;\n}\n\n.atv-subject-suggestion-title,\n.atv-subject-suggestion-original,\n.atv-subject-suggestion-metadata {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.atv-subject-suggestion-title {\n color: var(--atv-text-primary);\n font-size: 14px;\n font-weight: 650;\n letter-spacing: 0.01em;\n}\n\n.atv-subject-suggestion-metadata {\n margin-left: 7px;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.atv-subject-suggestion-original {\n color: var(--atv-text-secondary);\n font-size: 12px;\n}\n\n.atv-subject-suggestion-marker {\n position: absolute;\n top: 11px;\n bottom: 11px;\n left: 52px;\n width: 2px;\n border-radius: 2px;\n background: var(--atv-accent-bright);\n box-shadow: 0 0 12px var(--atv-accent-glow);\n opacity: 0;\n transform: scaleY(0.3);\n transform-origin: center;\n transition:\n opacity var(--atv-duration-hover) ease,\n transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-subject-suggestion-rail.is-keyboard-navigating .atv-subject-suggestion,\n.atv-subject-suggestion-rail.is-keyboard-navigating\n .atv-subject-suggestion-marker {\n transition: none;\n}\n\n.atv-subject-suggestion.is-active .atv-subject-suggestion-marker {\n opacity: 1;\n transform: scaleY(1);\n}\n\n.atv-subject-suggestion-skeletons {\n display: grid;\n padding: 9px;\n gap: 7px;\n}\n\n.atv-subject-suggestion-skeletons span {\n display: block;\n height: 54px;\n border-radius: 6px;\n background: rgb(255 255 255 / 6%);\n}\n\n.atv-subject-search-fallback {\n display: block;\n width: 100%;\n padding: 15px 18px;\n background: transparent;\n color: var(--atv-text-secondary);\n font-size: 13px;\n text-align: left;\n}\n\n.atv-subject-search-fallback:hover,\n.atv-subject-search-fallback:focus-visible {\n background: rgb(255 255 255 / 8%);\n color: var(--atv-text-primary);\n outline: none;\n}\n\n@media (width <= 768px) {\n .atv-subject-switcher-expanded {\n width: min(78vw, 520px);\n }\n\n .atv-subject-switcher.is-open .atv-subject-suggestion-rail {\n right: -8px;\n width: calc(100vw - 24px);\n }\n\n .atv-stickynav.has-subject-switcher-open .atv-stickynav-title {\n display: none;\n }\n\n .atv-stickynav.has-subject-switcher-open .atv-stickynav-subject-switcher {\n position: relative;\n left: auto;\n width: 100%;\n margin: 0;\n transform: none;\n }\n\n .atv-stickynav.has-subject-switcher-open .atv-subject-switcher-expanded {\n width: 100%;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-subject-suggestion-marker {\n transition: none;\n }\n}\n\n/* ---------- Hero ---------- */\n\n.atv-hero {\n position: relative;\n display: flex;\n overflow: visible;\n min-height: 75vh;\n flex-direction: column;\n padding: 132px max(28px, 5vw) 56px;\n isolation: isolate;\n}\n\n.atv-hero-inner-section {\n flex: 0 0 auto;\n}\n\n.atv-hero-bg {\n position: absolute;\n z-index: -4;\n top: 0;\n right: 0;\n left: 0;\n overflow: hidden;\n height: 75vh;\n background: #000;\n}\n\n.atv-hero-still {\n position: absolute;\n backface-visibility: hidden;\n background-position: center 30%;\n background-repeat: no-repeat;\n background-size: cover;\n inset: 0;\n transform: scale(1.04);\n}\n\n.atv-hero-still.is-thumb {\n filter: blur(12px) saturate(1.12) brightness(0.84);\n transform: scale(1.14);\n}\n\n.atv-hero-still.is-hd {\n filter: saturate(1.08) brightness(0.88);\n opacity: 0;\n transition: opacity var(--atv-duration-content) var(--atv-ease-out);\n}\n\n.atv-hero-still.is-hd.is-loaded {\n animation: atv-kenburns 22s linear forwards;\n opacity: 1;\n}\n\n.atv-hero-still.is-poster {\n background-position: center 22%;\n filter: blur(60px) saturate(1.25) brightness(0.78);\n transform: scale(1.25);\n}\n\n@keyframes atv-kenburns {\n from {\n transform: scale(1.04) translate(0, 0);\n }\n\n to {\n transform: scale(1.1) translate(-1.8%, -1.2%);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-hero-still.is-hd {\n transition: opacity var(--atv-duration-feedback) ease;\n }\n\n .atv-hero-still.is-hd.is-loaded {\n animation: none;\n transform: scale(1.04);\n }\n}\n\n.atv-hero-vignette {\n position: absolute;\n z-index: -3;\n top: 0;\n right: 0;\n left: 0;\n height: 75vh;\n background: radial-gradient(\n 120% 90% at 70% 30%,\n transparent 0%,\n rgb(0 0 0 / 55%) 100%\n );\n}\n\n.atv-hero-overlay-x {\n position: absolute;\n z-index: -2;\n top: 0;\n right: 0;\n left: 0;\n height: 75vh;\n background: linear-gradient(\n to right,\n rgb(0 0 0 / 96%) 0%,\n rgb(0 0 0 / 82%) 32%,\n rgb(0 0 0 / 50%) 62%,\n rgb(0 0 0 / 35%) 100%\n );\n}\n\n.atv-hero-overlay-y {\n position: absolute;\n z-index: -1;\n top: 0;\n right: 0;\n left: 0;\n height: 75vh;\n background: linear-gradient(\n to bottom,\n rgb(0 0 0 / 45%) 0%,\n transparent 28%,\n transparent 55%,\n #000 100%\n );\n}\n\n.atv-hero-inner {\n display: flex;\n width: 100%;\n max-width: 1100px;\n align-items: flex-start;\n margin: 0 auto;\n gap: 56px;\n}\n\n.atv-poster-card {\n display: flex;\n overflow: hidden;\n width: 360px;\n flex: 0 0 auto;\n padding: 0;\n border: none;\n border-radius: var(--atv-radius-lg);\n appearance: none;\n aspect-ratio: 2 / 3;\n background: var(--atv-bg-tertiary);\n box-shadow:\n 0 24px 60px rgb(0 0 0 / 60%),\n 0 0 0 1px var(--atv-border-subtle) inset;\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-poster-card img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.atv-poster-placeholder {\n width: 100%;\n height: 100%;\n}\n\n.atv-hero-info {\n min-width: 0;\n flex: 1 1 auto;\n}\n\n.atv-hero-title {\n margin: 0 0 8px;\n color: #fff;\n font-size: clamp(44px, 5.5vw, 72px);\n font-weight: 700;\n letter-spacing: -0.02em;\n line-height: 1.05;\n text-shadow:\n 0 2px 20px rgb(0 0 0 / 70%),\n 0 0 60px rgb(0 0 0 / 30%);\n}\n\n.atv-hero-orig {\n margin-bottom: 22px;\n color: var(--atv-text-secondary);\n font-size: clamp(18px, 1.6vw, 22px);\n font-weight: 400;\n letter-spacing: -0.01em;\n opacity: 0.85;\n}\n\n.atv-rank-label {\n display: inline-block;\n width: fit-content;\n max-width: 100%;\n margin: 0 0 25px;\n color: var(--atv-text-primary);\n text-decoration: none;\n}\n\n.atv-rank-label-entry {\n display: grid;\n min-height: 34px;\n align-items: center;\n padding: 5px 8px 5px 12px;\n border-left: 2px solid var(--atv-rating-gold);\n background: linear-gradient(\n 90deg,\n rgb(255 184 0 / 14%) 0%,\n rgb(255 184 0 / 0%) 86%\n );\n column-gap: 12px;\n grid-template-columns: auto minmax(0, 1fr) auto;\n}\n\n.atv-rank-label-entry strong {\n color: var(--atv-rating-gold);\n font-family: ui-monospace, SFMono-Regular, \"Cascadia Code\", monospace;\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n font-weight: 700;\n letter-spacing: -0.04em;\n white-space: nowrap;\n}\n\n.atv-rank-label-title {\n overflow: hidden;\n color: var(--atv-text-secondary);\n font-size: 14px;\n font-weight: 400;\n letter-spacing: -0.01em;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.atv-rank-label-arrow {\n color: var(--atv-text-tertiary);\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-rank-label:hover,\n.atv-rank-label:focus-visible {\n outline: none;\n}\n\n.atv-rank-label:hover .atv-rank-label-entry,\n.atv-rank-label:focus-visible .atv-rank-label-entry {\n border-left-color: #ffd166;\n background: linear-gradient(\n 90deg,\n rgb(255 184 0 / 22%) 0%,\n rgb(255 184 0 / 0%) 86%\n );\n}\n\n@media (hover: hover) and (pointer: fine) {\n .atv-rank-label:hover .atv-rank-label-arrow {\n color: var(--atv-text-primary);\n transform: translateX(3px);\n }\n}\n\n@media (width <= 480px) {\n .atv-rank-label {\n margin-bottom: 21px;\n }\n\n .atv-rank-label-entry {\n max-width: min(100%, 340px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-rank-label-arrow {\n transition: none;\n }\n\n .atv-rank-label:hover .atv-rank-label-arrow {\n transform: none;\n }\n}\n\n.atv-hero-meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n margin-bottom: 24px;\n color: var(--atv-text-secondary);\n font-size: 13px;\n font-weight: 500;\n gap: 10px 14px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n}\n\n.atv-first-broadcast-platform {\n display: inline-flex;\n align-items: center;\n}\n\n.atv-first-broadcast-platform-mark {\n display: inline-flex;\n width: 32px;\n height: 32px;\n align-items: center;\n justify-content: center;\n border: 1px solid rgb(255 255 255 / 13%);\n border-radius: 9px;\n background: rgb(255 255 255 / 8%);\n color: #fff;\n}\n\n.atv-first-broadcast-platform-mark.is-catalog svg {\n width: 22px;\n height: 22px;\n fill: currentcolor;\n}\n\n.atv-first-broadcast-platform-mark.is-intrinsic svg {\n width: 22px;\n height: 22px;\n fill: initial;\n}\n\n.atv-first-broadcast-platform-mark.is-wordmark {\n width: 68px;\n}\n\n.atv-first-broadcast-platform-mark.is-wordmark svg {\n width: 52px;\n height: 20px;\n}\n\n.atv-first-broadcast-platform-mark.is-surface-paper {\n border-color: rgb(255 255 255 / 34%);\n background: #d9dce3;\n box-shadow: inset 0 1px 0 rgb(255 255 255 / 56%);\n}\n\n.atv-first-broadcast-platform.is-unknown {\n color: var(--atv-text-tertiary);\n font-size: 11px;\n letter-spacing: 0.08em;\n text-transform: none;\n}\n\n.atv-screen-reader-only {\n position: absolute;\n overflow: hidden;\n width: 1px;\n height: 1px;\n padding: 0;\n border: 0;\n margin: -1px;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.atv-meta-dot {\n display: inline-flex;\n align-items: center;\n}\n\n.atv-meta-dot + .atv-meta-dot::before {\n margin-right: 14px;\n color: var(--atv-text-tertiary);\n content: \"·\";\n}\n\n.atv-meta-chips {\n display: inline-flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.atv-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 11px;\n border: 1px solid var(--atv-border-subtle);\n border-radius: 999px;\n -webkit-backdrop-filter: blur(8px);\n backdrop-filter: blur(8px);\n background: var(--atv-bg-elevated);\n color: var(--atv-text-secondary);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.02em;\n text-transform: none;\n}\n\n/* ── Ratings Panel ──────────────────────────────── */\n\n/* Unified card presenting Douban + IMDb + RT side by side */\n\n.atv-rating-panel {\n display: flex;\n width: fit-content;\n min-width: 320px;\n flex-wrap: wrap;\n align-items: stretch;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: var(--atv-radius-md);\n margin-bottom: 28px;\n gap: 0;\n}\n\n.atv-rating-panel-douban,\n.atv-rating-panel-imdb,\n.atv-rating-panel-rt,\n.atv-rating-panel-mc {\n display: grid;\n flex: 1;\n padding: 16px 24px 14px;\n grid-template-rows: 28px 44px 20px 1fr;\n place-items: center center;\n text-align: center;\n transition: background var(--atv-duration-feedback) ease;\n}\n\n.atv-rating-panel-douban:hover,\n.atv-rating-panel-imdb:hover,\n.atv-rating-panel-rt:hover,\n.atv-rating-panel-mc:hover {\n background: rgb(255 255 255 / 3%);\n}\n\n.atv-rating-panel-douban {\n border-right: 1px solid rgb(255 255 255 / 6%);\n}\n\n.atv-rating-panel-imdb {\n border-right: 1px solid rgb(255 255 255 / 6%);\n}\n\n.atv-rating-panel-mc {\n border-right: 1px solid rgb(255 255 255 / 6%);\n}\n\n.atv-rating-panel-logo {\n display: inline-flex;\n align-items: center;\n align-self: center;\n opacity: 0.85;\n transition: opacity var(--atv-duration-feedback) ease;\n}\n\n.atv-rating-panel-logo:hover {\n opacity: 1;\n}\n\n.atv-rating-panel-logo svg {\n display: block;\n}\n\n.atv-rating-panel .atv-rating-panel-score {\n color: var(--atv-text-primary);\n font-family:\n \"SF Pro Display\",\n -apple-system,\n BlinkMacSystemFont,\n system-ui,\n sans-serif;\n font-size: 38px;\n font-weight: 700;\n letter-spacing: -0.03em;\n line-height: 1;\n}\n\n/* ── MC Score color by range ────────────────────── */\n\n.atv-rating-panel-score.is-high {\n color: #3bb33b;\n}\n\n.atv-rating-panel-score.is-medium {\n color: #ffb800;\n}\n\n.atv-rating-panel-score.is-low {\n color: #fa320a;\n}\n\n/* ── MC label row (score bar + Chinese word label) ── */\n\n.atv-mc-label-row {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.atv-mc-bar-track {\n display: inline-block;\n overflow: hidden;\n width: 40px;\n height: 4px;\n flex-shrink: 0;\n border-radius: 2px;\n background: rgb(255 255 255 / 10%);\n}\n\n.atv-mc-bar-fill {\n display: block;\n height: 100%;\n border-radius: 2px;\n}\n\n.atv-mc-bar-fill.is-high {\n background: #3bb33b;\n}\n\n.atv-mc-bar-fill.is-medium {\n background: #ffb800;\n}\n\n.atv-mc-bar-fill.is-low {\n background: #fa320a;\n}\n\n.atv-mc-word-label {\n color: var(--atv-text-tertiary);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.02em;\n line-height: 1;\n white-space: nowrap;\n}\n\n.atv-rating-stars {\n display: inline-flex;\n color: var(--atv-rating-gold);\n gap: 2px;\n}\n\n.atv-rating-stars svg {\n display: block;\n}\n\n/* ── RT Score Row (values side by side) ─────────── */\n\n.atv-rt-score-row,\n.atv-rt-label-row,\n.atv-rt-count-row {\n display: grid;\n width: 100%;\n align-items: center;\n gap: 8px;\n grid-template-columns: 1fr auto 1fr;\n}\n\n.atv-rt-score-value {\n font-family:\n \"SF Pro Display\",\n -apple-system,\n BlinkMacSystemFont,\n system-ui,\n sans-serif;\n font-size: 30px;\n font-weight: 700;\n letter-spacing: -0.03em;\n line-height: 1;\n}\n\n.atv-rt-score-value.is-fresh {\n color: var(--atv-text-primary);\n}\n\n.atv-rt-score-row > .atv-rt-score-value.is-rotten:first-child {\n color: rgb(255 107 91 / 85%);\n}\n\n.atv-rt-score-row > .atv-rt-score-value.is-rotten:last-child {\n color: rgb(255 167 38 / 85%);\n}\n\n.atv-rt-score-row > .atv-rt-score-value:first-child {\n justify-self: center;\n text-align: right;\n}\n\n.atv-rt-score-row > .atv-rt-score-value:last-child {\n justify-self: center;\n text-align: left;\n}\n\n/* ── RT Label Row (icons + text) ────────────────── */\n\n.atv-rt-label-row {\n gap: 8px;\n grid-template-columns: 1fr 1fr;\n}\n\n.atv-rt-label-item {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n}\n\n.atv-rt-label-row > .atv-rt-label-item:first-child {\n justify-self: center;\n}\n\n.atv-rt-label-row > .atv-rt-label-item:last-child {\n justify-self: center;\n}\n\n.atv-rt-score-icon {\n display: inline-flex;\n width: 16px;\n height: 16px;\n color: var(--atv-text-tertiary);\n opacity: 0.7;\n}\n\n.atv-rt-score-icon svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.atv-rt-label-item.is-critics.is-fresh .atv-rt-score-icon {\n color: #ff6b5b;\n opacity: 1;\n}\n\n.atv-rt-label-item.is-critics.is-rotten .atv-rt-score-icon {\n color: #50b85e;\n opacity: 0.6;\n}\n\n.atv-rt-label-item.is-audience.is-fresh .atv-rt-score-icon {\n color: #ffb800;\n opacity: 1;\n}\n\n.atv-rt-label-item.is-audience.is-rotten .atv-rt-score-icon {\n color: #888;\n opacity: 0.6;\n}\n\n.atv-rt-score-label {\n color: var(--atv-text-tertiary);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n\n/* ── Shared count text (Douban / IMDb) ──────────── */\n\n.atv-rating-panel-count {\n color: var(--atv-text-tertiary);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n\n/* ── RT Count Row (e.g. 评价 300 | 50,000) ──────── */\n\n.atv-rt-count-row {\n gap: 8px;\n grid-template-columns: 1fr 1fr;\n}\n\n.atv-rt-count-value {\n color: var(--atv-text-tertiary);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n\n.atv-rt-count-row > .atv-rt-count-value:first-child {\n justify-self: center;\n}\n\n.atv-rt-count-row > .atv-rt-count-value:last-child {\n justify-self: center;\n}\n\n/* ── RT Divider ─────────────────────────────────── */\n\n.atv-rt-divider {\n width: 1px;\n flex-shrink: 0;\n align-self: stretch;\n margin: 2px 0;\n background: rgb(255 255 255 / 12%);\n}\n\n@media (width <= 768px) {\n .atv-rating-panel .atv-rating-panel-score {\n font-size: 32px;\n }\n\n .atv-rating-panel-douban,\n .atv-rating-panel-imdb,\n .atv-rating-panel-rt,\n .atv-rating-panel-mc {\n padding: 12px 14px 10px;\n grid-template-rows: 24px 38px 18px 1fr;\n }\n\n .atv-rt-score-value {\n font-size: 26px;\n }\n\n .atv-rt-score-icon {\n width: 14px;\n height: 14px;\n }\n\n .atv-rt-score-label {\n font-size: 10px;\n }\n\n .atv-mc-bar-track {\n width: 32px;\n }\n\n .atv-mc-word-label {\n font-size: 10px;\n }\n\n .atv-rating-panel {\n min-width: 0;\n }\n}\n\n.atv-rating-empty {\n padding: 10px 0;\n color: var(--atv-text-tertiary);\n font-size: 13px;\n letter-spacing: 0.03em;\n}\n\n/* ── Skeleton (loading) ─────────────────────────── */\n\n.atv-rating-panel-skeleton {\n width: 120px;\n height: 22px;\n border-radius: 4px;\n background: rgb(255 255 255 / 6%);\n}\n\n.atv-actions {\n display: flex;\n flex-wrap: wrap;\n margin-bottom: 26px;\n gap: 12px;\n}\n\n.atv-btn {\n display: inline-flex;\n height: 44px;\n align-items: center;\n padding: 0 22px;\n border: none;\n border-radius: 999px;\n appearance: none;\n background: none;\n color: inherit;\n cursor: pointer;\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n gap: 8px;\n letter-spacing: 0.01em;\n -webkit-tap-highlight-color: transparent;\n transition:\n transform var(--atv-duration-press) var(--atv-ease-out),\n background var(--atv-duration-feedback) ease,\n color var(--atv-duration-feedback) ease;\n}\n\n.atv-btn:active {\n transform: scale(0.97);\n}\n\n.atv-btn-primary {\n background: var(--atv-accent);\n box-shadow: 0 8px 24px var(--atv-accent-glow);\n color: #fff;\n}\n\n.atv-btn-secondary {\n border: 1px solid var(--atv-border-medium);\n backdrop-filter: blur(10px);\n background: var(--atv-bg-elevated);\n color: var(--atv-text-primary);\n}\n\n.atv-btn.is-active {\n border-color: transparent;\n background: var(--atv-accent);\n box-shadow: 0 6px 20px var(--atv-accent-glow);\n color: #fff;\n}\n\n.atv-hero-summary {\n margin-top: 16px;\n}\n\n.atv-hero-teaser {\n display: -webkit-box;\n overflow: hidden;\n max-width: 660px;\n margin: 0 0 12px;\n -webkit-box-orient: vertical;\n color: var(--atv-text-secondary);\n font-size: 15px;\n line-height: 1.75;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.atv-hero-teaser.is-clamped {\n -webkit-line-clamp: 3;\n}\n\n.atv-hero-more {\n display: inline-flex;\n align-items: center;\n padding: 0;\n border: none;\n appearance: none;\n background: none;\n color: var(--atv-accent-bright);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n font-weight: 600;\n gap: 6px;\n letter-spacing: 0.02em;\n}\n\n.atv-hero-more:hover {\n color: var(--atv-accent);\n}\n\n.atv-hero-more svg {\n transition: transform var(--atv-duration-hover) var(--atv-ease-in-out);\n}\n\n.atv-hero-more.is-open svg {\n transform: rotate(180deg);\n}\n\n/* ---------- Section ---------- */\n\n.atv-section {\n max-width: 1280px;\n padding: 52px max(28px, 5vw);\n margin: 0 auto;\n contain-intrinsic-size: auto 400px;\n content-visibility: auto;\n scroll-margin-top: 64px;\n}\n\n.atv-section + .atv-section {\n padding-top: 0;\n}\n\n.atv-section-h {\n position: relative;\n display: flex;\n align-items: center;\n padding-left: 16px;\n margin: 0 0 24px;\n font-size: 24px;\n font-weight: 700;\n letter-spacing: -0.01em;\n}\n\n.atv-section-h::before {\n position: absolute;\n top: 50%;\n left: 0;\n width: 4px;\n height: 24px;\n border-radius: 2px;\n background: var(--atv-accent);\n content: \"\";\n transform: translateY(-50%);\n}\n\n.atv-section-h-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n margin-bottom: 24px;\n gap: 16px;\n}\n\n.atv-section-h-row .atv-section-h {\n margin-bottom: 0;\n}\n\n.atv-section-more {\n flex: 0 0 auto;\n color: var(--atv-text-tertiary);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.02em;\n transition: color var(--atv-duration-feedback) ease;\n white-space: nowrap;\n}\n\n.atv-section-more:hover {\n color: var(--atv-accent-bright);\n}\n\n.atv-section-more:focus-visible {\n color: var(--atv-accent-bright);\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: 3px;\n}\n\n/* ---------- Section reveal on scroll ---------- */\n\n/* Below-the-fold sections start offset and fade in once they enter the\n viewport. The motion here is opacity + a small translateY only. */\n\n.atv-section-reveal {\n opacity: 0;\n transform: translateY(12px);\n}\n\n.atv-section-reveal.is-revealed {\n opacity: 1;\n transform: none;\n transition:\n opacity var(--atv-duration-content) var(--atv-ease-out),\n transform var(--atv-duration-content) var(--atv-ease-out);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-section-reveal,\n .atv-section-reveal.is-revealed {\n opacity: 1;\n transform: none;\n transition: none;\n }\n}\n\n/* ---------- Carousel ---------- */\n\n.atv-carousel {\n display: flex;\n padding: 4px 4px 16px;\n margin: 0 -4px;\n contain: paint layout;\n gap: 16px;\n overflow-x: auto;\n scroll-behavior: smooth;\n scroll-snap-type: x mandatory;\n scrollbar-width: none;\n}\n\n.atv-carousel::-webkit-scrollbar {\n display: none;\n}\n\n/* ---------- Page scrollbar ---------- */\n\n:root {\n color-scheme: dark;\n}\n\n::-webkit-scrollbar {\n width: 5px;\n height: 5px;\n}\n\n::-webkit-scrollbar-track {\n background: #1c1c1e;\n}\n\n::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #3a3a3c;\n}\n\n::-webkit-scrollbar-thumb:hover {\n background: #48484a;\n}\n\n::-webkit-scrollbar-corner {\n background: transparent;\n}\n\n* {\n scrollbar-color: #3a3a3c #1c1c1e;\n scrollbar-width: thin;\n}\n\n/* ---------- Series ---------- */\n\n.atv-series-card {\n min-width: 0;\n flex: 0 0 158px;\n cursor: pointer;\n scroll-snap-align: start;\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n/* ── Active season (user is currently on this season's page) ── */\n\n.atv-series-card.is-active .atv-series-poster {\n box-shadow:\n inset 0 0 0 2px var(--atv-accent),\n 0 0 20px var(--atv-accent-glow);\n}\n\n.atv-series-card.is-active .atv-series-info::after {\n width: 20px;\n opacity: 1;\n}\n\n/* ── Poster ── */\n\n.atv-series-poster {\n position: relative;\n overflow: hidden;\n width: 100%;\n border-radius: var(--atv-radius-sm);\n aspect-ratio: 2 / 3;\n background: var(--atv-bg-tertiary);\n}\n\n/* Poster bottom gradient overlay (Apple TV+ style depth) */\n\n.atv-series-poster::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 45%;\n background: linear-gradient(to top, rgb(0 0 0 / 55%) 0%, transparent 100%);\n content: \"\";\n pointer-events: none;\n}\n\n.atv-series-poster img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* ── Rating badge (overlay on poster top-right) ── */\n\n.atv-series-badge {\n position: absolute;\n z-index: 1;\n top: 8px;\n right: 8px;\n display: flex;\n min-width: 28px;\n height: 22px;\n align-items: center;\n justify-content: center;\n padding: 0 7px;\n border-radius: 20px;\n backdrop-filter: blur(4px);\n background: rgb(0 0 0 / 65%);\n color: #fff;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.02em;\n line-height: 1;\n}\n\n/* ── Info row ── */\n\n.atv-series-info {\n position: relative;\n margin-top: 10px;\n}\n\n.atv-series-info::after {\n display: block;\n width: 100%;\n height: 2px;\n border-radius: 1px;\n margin-top: 4px;\n background: var(--atv-accent);\n content: \"\";\n opacity: 0;\n transform: scaleX(0);\n transform-origin: left;\n transition: opacity var(--atv-duration-hover) ease;\n}\n\n.atv-series-title {\n display: block;\n overflow: hidden;\n color: var(--atv-text-primary);\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.01em;\n line-height: 1.3;\n text-overflow: ellipsis;\n transition: color var(--atv-duration-feedback) ease;\n white-space: nowrap;\n}\n\n/* ---------- Cast ---------- */\n\n.atv-cast-card {\n min-width: 0;\n flex: 0 0 160px;\n cursor: pointer;\n scroll-snap-align: start;\n text-align: center;\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-cast-avatar {\n width: 160px;\n height: 160px;\n border: 2px solid transparent;\n border-radius: 50%;\n background-color: var(--atv-bg-tertiary);\n background-position: center top;\n background-size: cover;\n}\n\n.atv-cast-name {\n overflow: hidden;\n margin-top: 16px;\n color: var(--atv-text-primary);\n font-size: 16px;\n font-weight: 600;\n line-height: 1.3;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.atv-cast-role {\n display: -webkit-box;\n overflow: hidden;\n margin-top: 4px;\n -webkit-box-orient: vertical;\n color: rgb(255 255 255 / 55%);\n font-size: 13px;\n font-weight: 400;\n -webkit-line-clamp: 2;\n line-height: 1.35;\n}\n\n/* ---------- Photos ---------- */\n\n.atv-photos {\n gap: 12px;\n}\n\n.atv-photo-tile {\n display: flex;\n overflow: hidden;\n flex: 0 0 400px;\n padding: 0;\n border: none;\n border-radius: var(--atv-radius-md);\n appearance: none;\n aspect-ratio: 16 / 9;\n background: var(--atv-bg-tertiary);\n cursor: pointer;\n scroll-snap-align: start;\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-photo-tile.is-portrait {\n flex: 0 0 240px;\n aspect-ratio: 3 / 4;\n}\n\n.atv-photo-tile img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* ---------- Recommendations ---------- */\n\n.atv-recs {\n display: grid;\n gap: 24px;\n grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));\n}\n\n.atv-rec-card {\n cursor: pointer;\n}\n\n.atv-rec-poster {\n overflow: hidden;\n width: 100%;\n border-radius: var(--atv-radius-sm);\n aspect-ratio: 2 / 3;\n background: var(--atv-bg-tertiary);\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-rec-poster img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n@media (hover: hover) and (pointer: fine) {\n .atv-series-card:hover .atv-series-title {\n color: var(--atv-accent-bright);\n }\n}\n\n.atv-rec-title {\n display: -webkit-box;\n overflow: hidden;\n margin-top: 12px;\n -webkit-box-orient: vertical;\n color: var(--atv-text-primary);\n font-size: 15px;\n font-weight: 600;\n -webkit-line-clamp: 2;\n text-overflow: ellipsis;\n}\n\n/* ---------- Info grid ---------- */\n\n.atv-info-grid {\n display: grid;\n gap: 16px 32px;\n grid-template-columns: 200px 1fr;\n}\n\n.atv-info-label {\n padding-top: 2px;\n color: rgb(255 255 255 / 55%);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.atv-info-value {\n color: var(--atv-text-primary);\n font-size: 15px;\n font-weight: 400;\n line-height: 1.5;\n overflow-wrap: break-word;\n}\n\n.atv-info-value a {\n border-bottom: 1px solid var(--atv-border-medium);\n color: var(--atv-text-primary);\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease;\n}\n\n.atv-info-value a:hover {\n border-color: var(--atv-accent-bright);\n color: var(--atv-accent-bright);\n}\n\n/* ---------- Streaming ---------- */\n\n.atv-stream-row {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.atv-stream-card {\n --atv-stream-brand: var(--atv-accent-bright);\n\n position: relative;\n display: inline-flex;\n max-width: 240px;\n height: 52px;\n align-items: center;\n padding: 0 20px 0 14px;\n border: 1px solid var(--atv-border-medium);\n border-radius: var(--atv-radius-md);\n background: var(--atv-bg-elevated);\n color: var(--atv-text-primary);\n cursor: pointer;\n font-family: inherit;\n font-size: 20px;\n font-weight: 600;\n gap: 11px;\n letter-spacing: 0.01em;\n -webkit-tap-highlight-color: transparent;\n transition:\n background var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n/* Center-glow overlay — subtle brand bloom from card center */\n\n.atv-stream-card::after {\n position: absolute;\n border-radius: inherit;\n background: radial-gradient(\n circle at center,\n var(--atv-stream-brand, var(--atv-accent-bright)) 0%,\n transparent 70%\n );\n content: \"\";\n inset: 0;\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--atv-duration-feedback) ease;\n}\n\n/* ── Combined SVG cards ── */\n\n.atv-stream-card-combined {\n height: 52px;\n padding: 0 16px;\n gap: 0;\n}\n\n.atv-stream-card-combined svg {\n display: block;\n width: auto;\n max-width: 160px;\n height: 32px;\n}\n\n.atv-stream-logo.is-catalog svg {\n display: block;\n width: 18px;\n height: 18px;\n fill: currentcolor;\n}\n\n.atv-stream-logo.is-intrinsic svg {\n display: block;\n width: 18px;\n height: 18px;\n fill: initial;\n}\n\n.atv-stream-vendor-icon {\n display: block;\n width: 32px;\n height: 32px;\n flex: 0 0 auto;\n object-fit: contain;\n}\n\n.atv-stream-logo {\n display: inline-flex;\n overflow: hidden;\n width: 32px;\n height: 32px;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 9px;\n background:\n linear-gradient(180deg, rgb(255 255 255 / 12%), rgb(255 255 255 / 0%)),\n rgb(255 255 255 / 5%);\n box-shadow:\n inset 0 1px 0 rgb(255 255 255 / 12%),\n 0 8px 18px rgb(0 0 0 / 18%);\n color: var(--atv-stream-brand, var(--atv-accent-bright));\n}\n\n.atv-stream-logo.is-surface-paper {\n border-color: rgb(255 255 255 / 34%);\n background: #d9dce3;\n box-shadow:\n inset 0 1px 0 rgb(255 255 255 / 56%),\n 0 8px 18px rgb(0 0 0 / 18%);\n}\n\n.atv-stream-logo-fallback {\n display: inline-flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n color: currentcolor;\n font-size: 15px;\n font-weight: 800;\n line-height: 1;\n text-transform: uppercase;\n}\n\n.atv-stream-name {\n overflow: hidden;\n min-width: 0;\n text-overflow: ellipsis;\n transition: color var(--atv-duration-feedback) ease;\n white-space: nowrap;\n}\n\n.atv-stream-card:focus-visible {\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: 3px;\n}\n\n/* ---------- Comments ---------- */\n\n.atv-comments {\n display: grid;\n gap: 18px;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n}\n\n.atv-comment-card {\n display: flex;\n flex-direction: column;\n padding: 18px 20px;\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: var(--atv-radius-md);\n background: #121214;\n transition:\n transform var(--atv-duration-hover) var(--atv-ease-out),\n border-color var(--atv-duration-hover) ease;\n}\n\n.atv-comment-top {\n display: flex;\n align-items: center;\n margin-bottom: 14px;\n gap: 12px;\n}\n\n.atv-comment-avatar {\n display: flex;\n overflow: hidden;\n width: 36px;\n height: 36px;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n border: 1.5px solid rgb(255 255 255 / 6%);\n border-radius: 50%;\n background-color: var(--atv-accent);\n background-position: center;\n background-size: cover;\n box-shadow: 0 1px 3px rgb(0 0 0 / 12%);\n color: #fff;\n font-size: 15px;\n font-weight: 600;\n transition: border-color var(--atv-duration-feedback) ease;\n}\n\n.atv-comment-meta {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 6px;\n}\n\n.atv-comment-author,\na.atv-comment-author {\n overflow: hidden;\n color: var(--atv-text-primary);\n font-size: 14px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\na.atv-comment-author:hover {\n background: none;\n color: var(--atv-text-primary);\n}\n\n.atv-comment-stars {\n display: inline-flex;\n align-items: center;\n color: var(--atv-rating-gold);\n gap: 2px;\n}\n\n.atv-comment-stars svg {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n.atv-comment-body {\n position: relative;\n display: flex;\n width: 100%;\n flex: 1 1 auto;\n flex-direction: column;\n padding: 0;\n border: none;\n margin: 0 0 14px;\n appearance: none;\n background: none;\n color: rgb(255 255 255 / 85%);\n cursor: pointer;\n font: inherit;\n font-size: 15px;\n line-height: 1.5;\n overflow-wrap: break-word;\n text-align: left;\n}\n\n.atv-comment-body-text {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 4;\n overflow-wrap: break-word;\n}\n\n.atv-comment-foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n font-weight: 500;\n gap: 12px;\n letter-spacing: 0.02em;\n}\n\n.atv-comment-votes {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 100px;\n background: none;\n color: var(--atv-text-tertiary);\n cursor: pointer;\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n gap: 5px;\n letter-spacing: 0.02em;\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n.atv-comment-votes:hover {\n border-color: rgb(65 190 93 / 20%);\n background: rgb(65 190 93 / 4%);\n color: var(--atv-accent);\n}\n\n.atv-comment-votes:focus-visible {\n outline: 2px solid rgb(65 190 93 / 75%);\n outline-offset: 3px;\n}\n\n.atv-comment-votes:active {\n transform: scale(0.97);\n}\n\n.atv-comment-votes.is-voted {\n border-color: rgb(65 190 93 / 25%);\n background: rgb(65 190 93 / 6%);\n color: var(--atv-accent);\n}\n\n.atv-comment-votes svg {\n display: block;\n width: 13px;\n height: 13px;\n}\n\n.atv-vote-count {\n font-variant-numeric: tabular-nums;\n}\n\n/* ---------- Comment Expand Overlay ---------- */\n\n.atv-comment-foot-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.atv-comment-expand {\n display: none;\n width: 22px;\n height: 22px;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 50%;\n appearance: none;\n backdrop-filter: blur(4px);\n background: rgb(0 0 0 / 30%);\n color: var(--atv-text-tertiary);\n cursor: pointer;\n font: inherit;\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n.atv-comment-card.has-overflow .atv-comment-expand {\n display: inline-flex;\n}\n\n.atv-comment-expand:hover {\n border-color: var(--atv-accent);\n background: rgb(65 190 93 / 10%);\n color: var(--atv-accent);\n}\n\n.atv-comment-expand:active {\n transform: scale(0.97);\n}\n\n.atv-comment-expand svg {\n display: block;\n width: 12px;\n height: 12px;\n}\n\n/* ── Overlay ── */\n\n.atv-comment-overlay {\n position: fixed;\n z-index: 10000;\n display: flex;\n width: 100vw;\n height: 100vh;\n align-items: center;\n justify-content: center;\n padding: 24px;\n border: none;\n margin: 0;\n background: rgb(0 0 0 / 72%);\n inset: 0;\n}\n\n.atv-comment-overlay-inner {\n position: relative;\n width: 100%;\n max-width: 580px;\n max-height: 80vh;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 20px;\n background: #121214;\n box-shadow: 0 24px 80px rgb(0 0 0 / 55%);\n overflow-y: auto;\n}\n\n.atv-modal-close.atv-comment-overlay-close {\n position: absolute;\n z-index: 2;\n top: 16px;\n right: 16px;\n width: 32px;\n height: 32px;\n border-color: rgb(255 255 255 / 10%);\n background: rgb(255 255 255 / 6%);\n color: rgb(255 255 255 / 60%);\n}\n\n.atv-modal-close.atv-comment-overlay-close:hover {\n border-color: rgb(255 255 255 / 20%);\n background: rgb(255 255 255 / 12%);\n color: #fff;\n}\n\n.atv-modal-close.atv-comment-overlay-close svg {\n width: 16px;\n height: 16px;\n}\n\n.atv-comment-overlay-top {\n display: flex;\n align-items: center;\n padding: 28px 28px 0;\n gap: 14px;\n}\n\n.atv-comment-overlay-avatar {\n display: flex;\n overflow: hidden;\n width: 44px;\n height: 44px;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--atv-border-subtle);\n border-radius: 50%;\n background-color: var(--atv-accent);\n background-position: center;\n background-size: cover;\n box-shadow: 0 2px 6px rgb(0 0 0 / 15%);\n color: #fff;\n font-size: 18px;\n font-weight: 600;\n transition:\n border-color var(--atv-duration-feedback) ease,\n box-shadow var(--atv-duration-feedback) ease;\n}\n\n.atv-comment-overlay-meta {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 6px;\n}\n\n.atv-comment-overlay-author,\na.atv-comment-overlay-author {\n overflow: hidden;\n color: var(--atv-text-primary);\n font-size: 16px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\na.atv-comment-overlay-author:hover {\n background: none;\n color: var(--atv-text-primary);\n}\n\n.atv-comment-overlay-stars {\n display: inline-flex;\n color: var(--atv-rating-gold);\n gap: 2px;\n}\n\n.atv-comment-overlay-stars svg {\n display: block;\n width: 16px;\n height: 16px;\n}\n\n.atv-comment-overlay-body {\n padding: 20px 28px;\n color: rgb(255 255 255 / 85%);\n font-size: 15px;\n line-height: 1.75;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.atv-comment-overlay-foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 28px 28px;\n}\n\n.atv-comment-overlay-time {\n color: var(--atv-text-tertiary);\n font-size: 13px;\n font-weight: 500;\n letter-spacing: 0.02em;\n}\n\n.atv-comment-overlay-votes {\n display: inline-flex;\n align-items: center;\n padding: 6px 14px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 100px;\n appearance: none;\n background: rgb(255 255 255 / 4%);\n color: var(--atv-text-tertiary);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n gap: 5px;\n letter-spacing: 0.02em;\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n.atv-comment-overlay-votes:hover {\n border-color: rgb(65 190 93 / 20%);\n background: rgb(65 190 93 / 4%);\n color: var(--atv-accent);\n}\n\n.atv-comment-overlay-votes:focus-visible {\n outline: 2px solid rgb(65 190 93 / 75%);\n outline-offset: 3px;\n}\n\n.atv-comment-overlay-votes:active {\n transform: scale(0.97);\n}\n\n.atv-comment-overlay-votes.is-voted {\n border-color: rgb(65 190 93 / 25%);\n background: rgb(65 190 93 / 6%);\n color: var(--atv-accent);\n}\n\n.atv-comment-overlay-votes svg {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n/* ---------- Poster Modal ---------- */\n\n.atv-poster-card {\n cursor: pointer;\n}\n\n.atv-modal-overlay,\n.atv-comment-overlay,\n.atv-interest-modal,\n.atv-login-modal,\n.atv-review-modal {\n -webkit-backdrop-filter: blur(16px) saturate(1.15);\n backdrop-filter: blur(16px) saturate(1.15);\n}\n\n.atv-modal-overlay {\n position: fixed;\n z-index: 10000;\n display: flex;\n width: 100vw;\n height: 100vh;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: none;\n margin: 0;\n background: rgb(0 0 0 / 78%);\n inset: 0;\n}\n\n.atv-modal-img {\n max-width: 90vw;\n max-height: 90vh;\n border-radius: var(--atv-radius-lg);\n box-shadow: 0 40px 80px rgb(0 0 0 / 75%);\n object-fit: contain;\n}\n\n.atv-modal-accent-bar {\n position: absolute;\n z-index: 1;\n top: 0;\n right: 0;\n left: 0;\n height: 3px;\n background: linear-gradient(\n to right,\n transparent,\n var(--atv-accent) 15%,\n var(--atv-accent) 85%,\n transparent\n );\n opacity: 1;\n}\n\n.atv-modal-close {\n position: fixed;\n z-index: 10001;\n top: 24px;\n right: 24px;\n display: flex;\n width: 44px;\n height: 44px;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid rgb(255 255 255 / 18%);\n border-radius: 50%;\n appearance: none;\n background: rgb(255 255 255 / 8%);\n color: #fff;\n cursor: pointer;\n font: inherit;\n -webkit-tap-highlight-color: transparent;\n touch-action: manipulation;\n transition:\n transform var(--atv-duration-press) var(--atv-ease-out),\n color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease;\n}\n\n.atv-modal-close:hover {\n border-color: rgb(255 255 255 / 30%);\n background: rgb(255 255 255 / 16%);\n color: #fff;\n}\n\n.atv-modal-close:active {\n transform: scale(0.97);\n}\n\n.atv-modal-close svg {\n display: block;\n}\n\n/* ---------- Video modal spinner ---------- */\n\n@keyframes atv-spin {\n from {\n transform: rotate(0deg);\n }\n\n to {\n transform: rotate(360deg);\n }\n}\n\n.atv-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid rgb(255 255 255 / 20%);\n border-radius: 50%;\n border-top-color: #41be5d;\n animation: atv-spin 0.8s linear infinite;\n}\n\n.atv-modal-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n color: #fff;\n font-size: 15px;\n gap: 16px;\n}\n\n/* ---------- Footer spacer ---------- */\n\n.atv-footer-spacer {\n height: 64px;\n}\n\n/* ---------- Login Prompt Modal ---------- */\n\ndialog::backdrop {\n background: transparent;\n}\n\n.atv-login-modal {\n position: fixed;\n z-index: 10000;\n display: flex;\n width: 100vw;\n min-height: 100vh;\n align-items: center;\n justify-content: center;\n padding: max(24px, env(safe-area-inset-top))\n max(24px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom))\n max(24px, env(safe-area-inset-left));\n border: none;\n margin: 0;\n background: rgb(0 0 0 / 72%);\n inset: 0;\n overscroll-behavior: contain;\n}\n\n.atv-login-modal-inner {\n position: relative;\n overflow: auto;\n width: min(100%, 424px);\n max-height: min(736px, calc(100dvh - 48px));\n box-sizing: border-box;\n padding: 30px 22px 22px;\n border: 1px solid rgb(255 255 255 / 10%);\n border-radius: 20px;\n background: var(--atv-bg-secondary);\n box-shadow:\n inset 0 1px 0 rgb(255 255 255 / 8%),\n 0 24px 80px rgb(0 0 0 / 55%);\n color: var(--atv-text-primary);\n font-family:\n -apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"PingFang SC\",\n \"Helvetica Neue\", \"Microsoft YaHei\", Inter, system-ui, sans-serif;\n scrollbar-width: none;\n text-align: center;\n}\n\n.atv-login-modal-inner::-webkit-scrollbar {\n display: none;\n}\n\n.atv-modal-close.atv-login-modal-close {\n position: absolute;\n z-index: 2;\n top: 12px;\n right: 12px;\n width: 32px;\n height: 32px;\n border-color: rgb(255 255 255 / 10%);\n background: rgb(255 255 255 / 6%);\n color: rgb(255 255 255 / 60%);\n}\n\n.atv-modal-close.atv-login-modal-close:hover {\n border-color: rgb(255 255 255 / 20%);\n background: rgb(255 255 255 / 12%);\n color: #fff;\n}\n\n.atv-login-modal-title {\n margin: 0 42px 6px;\n color: var(--atv-text-primary);\n font-size: 18px;\n font-weight: 650;\n line-height: 1.35;\n text-wrap: balance;\n}\n\n.atv-login-modal-desc {\n max-width: 300px;\n margin: 0 auto 14px;\n color: var(--atv-text-tertiary);\n font-size: 13px;\n line-height: 1.55;\n text-wrap: pretty;\n}\n\n.atv-login-modal-status {\n min-height: 20px;\n margin: 8px 0 0;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n line-height: 1.5;\n}\n\n.atv-login-modal-status[hidden] {\n display: none;\n}\n\n.atv-login-modal-native {\n position: relative;\n overflow: hidden;\n width: 100%;\n box-sizing: border-box;\n padding: 10px;\n border-radius: 16px;\n margin-top: 10px;\n}\n\n.atv-login-modal-native::before {\n position: absolute;\n z-index: 2;\n border-radius: 10px;\n background: rgb(255 255 255 / 3.5%);\n content: \"\";\n inset: 10px;\n opacity: 1;\n pointer-events: none;\n transition: opacity var(--atv-duration-feedback) ease;\n}\n\n.atv-login-modal-native:empty {\n min-height: 360px;\n}\n\n.atv-login-modal-native[aria-busy=\"true\"] {\n min-height: 360px;\n}\n\n.atv-login-modal-native.is-ready::before {\n opacity: 0;\n}\n\n.atv-login-modal-native > iframe,\n.atv-login-modal-iframe {\n position: relative;\n z-index: 1;\n display: block !important;\n overflow: hidden !important;\n width: 340px !important;\n max-width: 100% !important;\n height: 448px !important;\n max-height: calc(100vh - 168px) !important;\n box-sizing: border-box !important;\n border: 0 !important;\n border-radius: 10px !important;\n margin: 0 auto !important;\n background: #fff !important;\n box-shadow: none !important;\n\n /* Cross-origin iframe dark-mode override (first-principles):\n invert(0.89) maps white #fff → #1c1c1c, which matches\n --atv-bg-secondary: #1c1c1e within 2 RGB points — no more\n pure-black void. Text #333 → #bbb, borders #e0 → #343434.\n hue-rotate(180deg) counter-rotates the color shift from\n invert so green stays green-ish and blue stays blue-ish.\n invert(0.89) is the precise value calculated to hit the\n existing modal surface color while keeping text readable. */\n filter: invert(0.89) hue-rotate(180deg) !important;\n opacity: 0;\n transition: opacity var(--atv-duration-feedback) ease;\n}\n\n.atv-login-modal-native.is-ready > iframe {\n opacity: 1;\n}\n\n.atv-login-modal-close:focus-visible {\n outline: 2px solid var(--atv-accent);\n outline-offset: 3px;\n}\n\n/* ---------- Interest Modal ---------- */\n\n.atv-interest-modal {\n position: fixed;\n z-index: 10000;\n display: flex;\n width: 100vw;\n height: 100vh;\n align-items: center;\n justify-content: center;\n padding: 24px;\n border: none;\n margin: 0;\n background: rgb(0 0 0 / 72%);\n inset: 0;\n}\n\n.atv-interest-modal-inner {\n position: relative;\n width: 100%;\n max-width: 380px;\n max-height: 90vh;\n border: 1px solid rgb(255 255 255 / 10%);\n border-radius: 20px;\n background: var(--atv-bg-secondary);\n box-shadow: 0 24px 80px rgb(0 0 0 / 55%);\n overflow-y: auto;\n}\n\n.atv-interest-modal-header {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 48px 0;\n}\n\n.atv-interest-modal-header-title {\n color: var(--atv-text-primary);\n font-size: 16px;\n font-weight: 600;\n letter-spacing: 0.01em;\n}\n\n.atv-modal-close.atv-interest-modal-close {\n position: absolute;\n z-index: 2;\n top: 14px;\n right: 14px;\n width: 32px;\n height: 32px;\n border-color: rgb(255 255 255 / 10%);\n background: rgb(255 255 255 / 6%);\n color: rgb(255 255 255 / 60%);\n}\n\n.atv-modal-close.atv-interest-modal-close:hover {\n border-color: rgb(255 255 255 / 20%);\n background: rgb(255 255 255 / 12%);\n color: #fff;\n}\n\n.atv-modal-close.atv-interest-modal-close:active {\n border-color: rgb(255 255 255 / 30%);\n background: rgb(255 255 255 / 16%);\n}\n\n.atv-interest-modal-body {\n padding: 16px 20px 20px;\n}\n\n.atv-interest-modal-statuses {\n position: relative;\n display: grid;\n padding: 3px;\n border-radius: 999px;\n margin-bottom: 20px;\n background: rgb(255 255 255 / 6%);\n gap: 0;\n grid-template-columns: repeat(var(--atv-interest-status-count), 1fr);\n}\n\n.atv-interest-modal-status-indicator {\n position: absolute;\n top: 3px;\n bottom: 3px;\n left: 3px;\n width: calc((100% - 6px) / var(--atv-interest-status-count));\n border-radius: 999px;\n background: rgb(255 255 255 / 12%);\n pointer-events: none;\n transform: translateX(calc(var(--atv-interest-status-index) * 100%));\n transition: transform var(--atv-duration-feedback) var(--atv-ease-in-out);\n}\n\n.atv-interest-modal-status {\n position: relative;\n z-index: 1;\n display: inline-flex;\n height: 36px;\n flex: 1;\n align-items: center;\n justify-content: center;\n padding: 0 12px;\n border: none;\n border-radius: 999px;\n appearance: none;\n background: transparent;\n color: var(--atv-text-tertiary);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.01em;\n -webkit-tap-highlight-color: transparent;\n transition: color var(--atv-duration-feedback) ease;\n}\n\n.atv-interest-modal-status:hover {\n color: var(--atv-text-secondary);\n}\n\n.atv-interest-modal-status.is-active {\n color: #fff;\n}\n\n.atv-interest-modal-stars {\n display: flex;\n justify-content: center;\n margin-bottom: 24px;\n gap: 6px;\n}\n\n.atv-interest-modal-star {\n display: flex;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n appearance: none;\n background: none;\n color: rgb(255 255 255 / 20%);\n cursor: pointer;\n transition:\n color var(--atv-duration-feedback) ease,\n transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-interest-modal-star.is-full {\n color: var(--atv-rating-gold);\n}\n\n.atv-interest-modal-star svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.atv-interest-modal-comment {\n display: block;\n width: 100%;\n min-height: 64px;\n box-sizing: border-box;\n padding: 10px 14px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 10px;\n margin-bottom: 16px;\n background: rgb(255 255 255 / 4%);\n color: var(--atv-text-primary);\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n resize: vertical;\n -webkit-tap-highlight-color: transparent;\n transition:\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease;\n}\n\n.atv-interest-modal-comment::placeholder {\n color: var(--atv-text-tertiary);\n}\n\n.atv-interest-modal-comment:focus {\n border-color: rgb(255 255 255 / 20%);\n background: rgb(255 255 255 / 6%);\n outline: none;\n}\n\n.atv-interest-modal-submit {\n display: flex;\n width: 100%;\n height: 44px;\n align-items: center;\n justify-content: center;\n padding: 0 24px;\n border: none;\n border-radius: 999px;\n margin-bottom: 10px;\n appearance: none;\n background: var(--atv-accent);\n color: #fff;\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n -webkit-font-smoothing: antialiased;\n font-weight: 600;\n letter-spacing: 0.01em;\n -webkit-tap-highlight-color: transparent;\n transition:\n background var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n.atv-interest-modal-submit:hover {\n background: var(--atv-accent-bright);\n}\n\n.atv-interest-modal-submit:active {\n transform: scale(0.97);\n}\n\n.atv-interest-modal-submit:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.atv-interest-modal-remove {\n display: flex;\n width: 100%;\n height: 36px;\n align-items: center;\n justify-content: center;\n padding: 0 24px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 999px;\n margin-bottom: 4px;\n appearance: none;\n background: transparent;\n color: var(--atv-text-tertiary);\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.02em;\n -webkit-tap-highlight-color: transparent;\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease;\n}\n\n.atv-interest-modal-remove:hover {\n border-color: rgb(255 255 255 / 15%);\n background: rgb(255 255 255 / 4%);\n color: var(--atv-text-secondary);\n}\n\n.atv-interest-modal-remove:active {\n background: rgb(255 255 255 / 8%);\n}\n\n.atv-interest-modal-error {\n border-radius: 10px;\n color: #ff453a;\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n}\n\n.atv-interest-modal-error:empty {\n display: none;\n}\n\n.atv-interest-modal-error:not(:empty) {\n padding: 8px 16px;\n margin-top: 8px;\n background: rgb(255 69 58 / 8%);\n}\n\n/* ---------- Interest Panel (S3 marked state) ---------- */\n\n.atv-interest-panel {\n display: flex;\n width: 100%;\n flex-direction: column;\n gap: 10px;\n}\n\n.atv-interest-panel-header {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 12px;\n}\n\n.atv-interest-badge {\n cursor: pointer;\n}\n\n.atv-interest-panel-stars {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n}\n\n.atv-interest-panel-stars svg {\n display: block;\n width: 18px;\n height: 18px;\n}\n\n.atv-interest-panel-date {\n color: var(--atv-text-tertiary);\n font-size: 13px;\n letter-spacing: 0.02em;\n}\n\n.atv-interest-panel-comment {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n padding: 6px 0 2px;\n color: var(--atv-text-secondary);\n font-size: 14px;\n font-style: italic;\n gap: 8px;\n line-height: 1.6;\n}\n\n.atv-useful-badge {\n display: inline-flex;\n align-items: center;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n font-style: normal;\n gap: 3px;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n\n/* ---------- Trailer Tile ---------- */\n\n.atv-trailer-tile {\n position: relative;\n overflow: hidden;\n flex: 0 0 400px;\n border-radius: var(--atv-radius-md);\n aspect-ratio: 16 / 9;\n background: var(--atv-bg-tertiary);\n background-position: center;\n background-size: cover;\n cursor: pointer;\n scroll-snap-align: start;\n transition: transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-trailer-play-overlay {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgb(0 0 0 / 12%);\n inset: 0;\n}\n\n.atv-trailer-play-btn {\n display: flex;\n width: 56px;\n height: 56px;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n background: rgb(0 0 0 / 60%);\n}\n\n.atv-trailer-play-btn svg {\n display: block;\n width: 24px;\n height: 24px;\n margin-left: 3px;\n color: #fff;\n}\n\n.atv-trailer-label {\n position: absolute;\n bottom: 12px;\n left: 12px;\n padding: 4px 10px;\n border-radius: 6px;\n backdrop-filter: blur(4px);\n background: rgb(0 0 0 / 60%);\n color: #fff;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ---------- Video Modal ---------- */\n\n.atv-modal-overlay.is-video {\n backdrop-filter: none;\n background: #000;\n}\n\n.atv-modal-video {\n display: block;\n max-width: 95vw;\n max-height: 90vh;\n border-radius: var(--atv-radius-lg);\n box-shadow: 0 40px 80px rgb(0 0 0 / 75%);\n}\n\n/* ---------- Reviews ---------- */\n\n.atv-reviews {\n display: grid;\n gap: 20px;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n}\n\n.atv-review-card {\n position: relative;\n display: flex;\n flex-direction: column;\n padding: 22px;\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: var(--atv-radius-md);\n appearance: none;\n background: #121214;\n color: inherit;\n cursor: pointer;\n font: inherit;\n -webkit-tap-highlight-color: transparent;\n text-align: left;\n touch-action: manipulation;\n transition:\n transform var(--atv-duration-hover) var(--atv-ease-out),\n border-color var(--atv-duration-hover) ease;\n}\n\n.atv-review-open-button {\n position: absolute;\n z-index: 0;\n padding: 0;\n border: 0;\n border-radius: var(--atv-radius-md);\n appearance: none;\n background: transparent;\n cursor: pointer;\n inset: 0;\n}\n\n.atv-review-content {\n position: relative;\n z-index: 1;\n display: contents;\n}\n\n.atv-review-card:active {\n box-shadow: none;\n transform: translateY(0);\n}\n\n.atv-review-card:focus-visible {\n border-color: rgb(65 190 93 / 45%);\n box-shadow: 0 0 0 5px rgb(65 190 93 / 12%);\n outline: 2px solid var(--atv-accent);\n outline-offset: 4px;\n}\n\n.atv-review-open-button:focus-visible {\n outline: 2px solid var(--atv-accent);\n outline-offset: 4px;\n}\n\n.atv-review-top {\n display: flex;\n align-items: center;\n margin-bottom: 12px;\n gap: 10px;\n pointer-events: none;\n}\n\n.atv-review-avatar {\n display: flex;\n width: 36px;\n height: 36px;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n border: 1.5px solid rgb(255 255 255 / 6%);\n border-radius: 50%;\n background: var(--atv-accent);\n background-position: center;\n background-size: cover;\n color: #fff;\n font-size: 14px;\n font-weight: 600;\n}\n\n.atv-review-meta {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 3px;\n pointer-events: none;\n}\n\n.atv-review-author {\n position: relative;\n z-index: 2;\n overflow: hidden;\n color: var(--atv-text-primary);\n font-size: 14px;\n font-weight: 600;\n pointer-events: auto;\n text-decoration: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.atv-review-author:hover {\n color: var(--atv-accent);\n}\n\n.atv-review-stars {\n display: inline-flex;\n align-items: center;\n color: var(--atv-rating-gold);\n gap: 2px;\n}\n\n.atv-review-stars svg {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n.atv-review-title {\n display: -webkit-box;\n overflow: hidden;\n margin-bottom: 8px;\n -webkit-box-orient: vertical;\n color: #f0f0f0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n -webkit-line-clamp: 2;\n line-height: 1.35;\n pointer-events: none;\n}\n\n.atv-review-excerpt {\n display: -webkit-box;\n overflow: hidden;\n flex: 1;\n margin-bottom: 14px;\n -webkit-box-orient: vertical;\n color: rgb(255 255 255 / 72%);\n font-size: 14px;\n -webkit-line-clamp: 4;\n line-height: 1.7;\n pointer-events: none;\n}\n\n.atv-review-foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-top: 14px;\n border-top: 1px solid rgb(255 255 255 / 5%);\n gap: 8px;\n pointer-events: none;\n}\n\n.atv-review-time {\n color: rgb(255 255 255 / 35%);\n font-size: 12px;\n font-weight: 400;\n letter-spacing: 0.02em;\n}\n\n.atv-review-readmore {\n color: var(--atv-accent);\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.04em;\n opacity: 0;\n pointer-events: none;\n transform: translateX(-3px);\n transition:\n opacity var(--atv-duration-hover) var(--atv-ease-out),\n transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-review-card:focus-visible .atv-review-readmore {\n opacity: 0.7;\n transform: translateX(0);\n}\n\n.atv-review-card:has(.atv-review-open-button:focus-visible) {\n border-color: rgb(65 190 93 / 45%);\n box-shadow: 0 0 0 5px rgb(65 190 93 / 12%);\n}\n\n.atv-review-card:has(.atv-review-open-button:focus-visible)\n .atv-review-readmore {\n opacity: 0.7;\n transform: translateX(0);\n}\n\n.atv-review-actions {\n position: relative;\n z-index: 2;\n display: flex;\n margin-left: auto;\n gap: 6px;\n pointer-events: auto;\n}\n\n.atv-vote-btn {\n display: inline-flex;\n align-items: center;\n padding: 5px 12px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: 100px;\n appearance: none;\n background: rgb(255 255 255 / 3%);\n color: rgb(255 255 255 / 55%);\n cursor: pointer;\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n gap: 5px;\n line-height: 1;\n transition:\n color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n transform var(--atv-duration-press) var(--atv-ease-out);\n white-space: nowrap;\n}\n\n.atv-vote-btn:hover {\n border-color: var(--atv-accent);\n background: rgb(65 190 93 / 6%);\n color: var(--atv-accent);\n}\n\n.atv-vote-btn:focus-visible {\n outline: 2px solid rgb(65 190 93 / 75%);\n outline-offset: 3px;\n}\n\n.atv-vote-btn:active {\n transform: scale(0.97);\n}\n\n.atv-vote-btn.is-lg {\n padding: 8px 20px;\n font-size: 14px;\n}\n\n.atv-vote-btn svg {\n display: block;\n width: 11px;\n height: 11px;\n transform-box: fill-box;\n transform-origin: center;\n}\n\n.atv-vote-btn.down:hover {\n border-color: #ff453a;\n background: rgb(255 69 58 / 6%);\n color: #ff453a;\n}\n\n.atv-vote-btn.down svg {\n transform: rotate(180deg);\n}\n\n.atv-vote-btn.is-voted {\n border-color: rgb(65 190 93 / 20%);\n background: rgb(65 190 93 / 6%);\n color: var(--atv-accent);\n cursor: default;\n}\n\n.atv-vote-btn.down.is-voted {\n border-color: rgb(255 69 58 / 22%);\n background: rgb(255 69 58 / 6%);\n color: #ff453a;\n}\n\n/* ---------- Review Modal ---------- */\n\n.atv-review-modal {\n position: fixed;\n z-index: 10000;\n display: flex;\n width: 100vw;\n height: 100vh;\n align-items: center;\n justify-content: center;\n padding: 48px;\n border: none;\n margin: 0;\n background: rgb(0 0 0 / 72%);\n inset: 0;\n}\n\n.atv-review-modal .atv-modal-close {\n position: absolute;\n z-index: 2;\n top: 16px;\n right: 16px;\n width: 32px;\n height: 32px;\n border-color: rgb(255 255 255 / 10%);\n background: rgb(255 255 255 / 6%);\n color: rgb(255 255 255 / 60%);\n}\n\n.atv-review-modal .atv-modal-close:hover {\n border-color: rgb(255 255 255 / 20%);\n background: rgb(255 255 255 / 12%);\n color: #fff;\n}\n\n.atv-review-modal-scroll {\n position: relative;\n width: 100%;\n max-width: 800px;\n max-height: 85vh;\n padding: 48px 56px 32px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: var(--atv-radius-lg);\n background: #121214;\n box-shadow: 0 24px 80px rgb(0 0 0 / 55%);\n overflow-y: auto;\n scrollbar-color: rgb(255 255 255 / 12%) transparent;\n scrollbar-width: thin;\n}\n\n.atv-review-modal-header {\n padding-bottom: 14px;\n border-bottom: 1px solid rgb(255 255 255 / 5%);\n margin-bottom: 16px;\n}\n\n.atv-review-modal-title {\n margin-bottom: 4px;\n color: #f0f0f0;\n font-size: 24px;\n font-weight: 600;\n letter-spacing: -0.01em;\n line-height: 1.32;\n}\n\n.atv-review-modal-title:focus {\n outline: none;\n}\n\n.atv-review-modal-byline {\n display: flex;\n align-items: center;\n margin-top: 4px;\n gap: 10px;\n}\n\n.atv-review-modal-avatar {\n display: flex;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n border: 1.5px solid rgb(255 255 255 / 6%);\n border-radius: 50%;\n background: var(--atv-accent);\n background-position: center;\n background-size: cover;\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n}\n\n.atv-review-modal-byline-text {\n display: flex;\n align-items: center;\n font-size: 13px;\n gap: 4px;\n line-height: 1;\n}\n\n.atv-review-modal-byline-name {\n color: var(--atv-text-secondary);\n}\n\n.atv-review-modal-byline-time {\n color: var(--atv-text-tertiary);\n}\n\n.atv-review-modal-body {\n color: rgb(255 255 255 / 82%);\n font-size: 16px;\n line-height: 1.85;\n}\n\n.atv-review-modal-body h2 {\n margin-bottom: 16px;\n color: #f0f0f0;\n font-size: 20px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.atv-review-modal-body h2 a {\n background: transparent;\n color: inherit;\n text-decoration: none;\n}\n\n.atv-review-modal-body h2 a:hover {\n background: transparent;\n color: var(--atv-accent);\n}\n\n.atv-review-modal-body p {\n margin-bottom: 16px;\n}\n\n.atv-review-modal-body blockquote {\n padding: 16px 20px;\n border-radius: 0 var(--atv-radius-sm) var(--atv-radius-sm) 0;\n border-left: 3px solid var(--atv-accent);\n margin: 20px 0;\n background: rgb(255 255 255 / 3%);\n color: rgb(255 255 255 / 82%);\n}\n\n.atv-review-modal-body blockquote p {\n margin-bottom: 8px;\n}\n\n.atv-review-modal-body blockquote p:last-child {\n margin-bottom: 0;\n}\n\n.atv-review-modal-body blockquote cite,\n.atv-review-modal-body blockquote footer {\n display: block;\n margin-top: 8px;\n color: var(--atv-text-tertiary);\n font-size: 13px;\n font-style: normal;\n font-weight: 500;\n}\n\n.atv-review-modal-body blockquote cite::before,\n.atv-review-modal-body blockquote footer::before {\n content: \"\\2014\\00a0\";\n}\n\n.atv-review-modal-body blockquote blockquote {\n border-left-color: rgb(255 255 255 / 20%);\n margin-left: 0;\n background: rgb(255 255 255 / 6%);\n}\n\n/* ---------- Group discussions ---------- */\n\n.atv-discussion-board {\n overflow: hidden;\n border: 1px solid rgb(255 255 255 / 7%);\n border-radius: var(--atv-radius-lg);\n background: #121214;\n}\n\n.atv-discussion-row {\n position: relative;\n display: grid;\n overflow: hidden;\n min-height: 66px;\n align-items: center;\n padding: 16px 22px;\n border-bottom: 1px solid rgb(255 255 255 / 6%);\n gap: 3px 24px;\n grid-template-columns: minmax(0, 1fr) minmax(106px, max-content) 17px;\n grid-template-rows: auto auto;\n isolation: isolate;\n}\n\n.atv-discussion-row:last-child {\n border-bottom: 0;\n}\n\n.atv-discussion-row::before {\n position: absolute;\n top: 14px;\n bottom: 14px;\n left: 0;\n width: 3px;\n border-radius: 0 3px 3px 0;\n background: var(--atv-accent);\n content: \"\";\n opacity: 0;\n transform: scaleY(0.35);\n transition:\n opacity var(--atv-duration-feedback) ease,\n transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-discussion-topic-link {\n position: absolute;\n z-index: 1;\n border-radius: inherit;\n inset: 0;\n}\n\n.atv-discussion-topic-link:focus-visible {\n outline: 2px solid var(--atv-accent);\n outline-offset: -3px;\n}\n\n.atv-discussion-title {\n position: relative;\n z-index: 2;\n overflow: hidden;\n margin: 0;\n color: rgb(255 255 255 / 90%);\n font-size: 16px;\n font-weight: 600;\n grid-column: 1;\n grid-row: 1;\n letter-spacing: -0.01em;\n line-height: 1.45;\n pointer-events: none;\n text-overflow: ellipsis;\n transition: color var(--atv-duration-feedback) ease;\n white-space: nowrap;\n}\n\n.atv-discussion-copy {\n display: contents;\n pointer-events: none;\n}\n\n.atv-discussion-meta {\n display: contents;\n}\n\n.atv-discussion-author {\n position: relative;\n z-index: 2;\n display: block;\n overflow: hidden;\n width: fit-content;\n max-width: 100%;\n margin-top: 4px;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n grid-column: 1;\n grid-row: 2;\n line-height: 1.35;\n pointer-events: auto;\n text-decoration: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\na.atv-discussion-author:hover {\n text-decoration: underline;\n}\n\na.atv-discussion-author:focus-visible {\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: 2px;\n text-decoration: underline;\n}\n\n.atv-discussion-activity {\n position: relative;\n z-index: 2;\n display: grid;\n min-width: 106px;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n gap: 3px;\n grid-column: 2;\n grid-row: 1 / span 2;\n line-height: 1.35;\n pointer-events: none;\n text-align: right;\n transition: color var(--atv-duration-feedback) ease;\n}\n\n.atv-discussion-time {\n display: grid;\n font-variant-numeric: tabular-nums;\n gap: 1px;\n white-space: nowrap;\n}\n\n.atv-discussion-footer {\n margin-top: 14px;\n text-align: right;\n}\n\n.atv-discussion-footer a {\n color: var(--atv-text-secondary);\n font-size: 13px;\n text-decoration: none;\n transition: color var(--atv-duration-feedback) ease;\n}\n\n.atv-discussion-footer a:hover,\n.atv-discussion-footer a:focus-visible {\n color: var(--atv-accent-bright);\n text-decoration: underline;\n}\n\n.atv-discussion-footer a:focus-visible {\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: 3px;\n}\n\n.atv-discussion-arrow {\n position: relative;\n z-index: 2;\n color: var(--atv-accent-bright);\n font-size: 17px;\n grid-column: 3;\n grid-row: 1 / span 2;\n opacity: 0.35;\n pointer-events: none;\n transform: translate(-3px, 3px);\n transition:\n opacity var(--atv-duration-feedback) ease,\n transform var(--atv-duration-hover) var(--atv-ease-out);\n}\n\n.atv-discussion-row:has(.atv-discussion-topic-link:focus-visible)::before,\n.atv-discussion-row:has(.atv-discussion-author:focus-visible)::before {\n opacity: 1;\n transform: scaleY(1);\n}\n\n.atv-discussion-row:hover .atv-discussion-title,\n.atv-discussion-row:has(.atv-discussion-topic-link:focus-visible)\n .atv-discussion-title,\n.atv-discussion-row:has(.atv-discussion-author:focus-visible)\n .atv-discussion-title {\n color: #fff;\n}\n\n.atv-discussion-row:hover .atv-discussion-activity,\n.atv-discussion-row:has(.atv-discussion-topic-link:focus-visible)\n .atv-discussion-activity,\n.atv-discussion-row:has(.atv-discussion-author:focus-visible)\n .atv-discussion-activity {\n color: var(--atv-accent-bright);\n}\n\n.atv-discussion-row:has(.atv-discussion-topic-link:focus-visible)\n .atv-discussion-arrow,\n.atv-discussion-row:has(.atv-discussion-author:focus-visible)\n .atv-discussion-arrow {\n opacity: 1;\n transform: none;\n}\n\n@media (width <= 768px) {\n .atv-discussion-row {\n min-height: 0;\n align-items: start;\n padding: 14px 16px;\n gap: 6px 14px;\n grid-template-columns: minmax(0, 1fr) 17px;\n grid-template-rows: auto;\n }\n\n .atv-discussion-copy {\n position: relative;\n z-index: 2;\n display: block;\n min-width: 0;\n grid-column: 1;\n pointer-events: none;\n }\n\n .atv-discussion-title {\n overflow-wrap: anywhere;\n text-overflow: clip;\n white-space: normal;\n }\n\n .atv-discussion-meta {\n display: flex;\n min-width: 0;\n flex-wrap: wrap;\n align-items: center;\n margin-top: 6px;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n gap: 8px;\n line-height: 1.35;\n }\n\n .atv-discussion-author {\n min-width: 0;\n max-width: 100%;\n flex: 0 1 auto;\n margin-top: 0;\n }\n\n .atv-discussion-activity {\n display: flex;\n min-width: 0;\n align-items: center;\n color: inherit;\n font-size: inherit;\n gap: 8px;\n line-height: inherit;\n text-align: left;\n }\n\n .atv-discussion-author + .atv-discussion-activity::before {\n width: 1px;\n height: 1em;\n background: rgb(255 255 255 / 18%);\n content: \"\";\n }\n\n .atv-discussion-time {\n display: inline-flex;\n gap: 3px;\n }\n\n .atv-discussion-arrow {\n align-self: center;\n grid-column: 2;\n grid-row: 1;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-discussion-row::before,\n .atv-discussion-title,\n .atv-discussion-activity,\n .atv-discussion-arrow,\n .atv-discussion-footer a {\n transition: none;\n }\n\n .atv-discussion-row::before,\n .atv-discussion-arrow {\n transform: none;\n }\n}\n\n/* ── Review content images (Douban image-container) ── */\n\n.atv-review-modal-body .image-container {\n margin: 24px 0;\n clear: both;\n}\n\n.atv-review-modal-body .image-container.image-float-left {\n max-width: 50%;\n margin: 8px 24px 8px 0;\n float: left;\n}\n\n.atv-review-modal-body .image-container.image-float-right {\n max-width: 50%;\n margin: 8px 0 8px 24px;\n float: right;\n}\n\n.atv-review-modal-body .image-wrapper {\n overflow: hidden;\n border-radius: var(--atv-radius-sm);\n line-height: 0;\n}\n\n.atv-review-modal-body .image-wrapper img {\n display: block;\n width: auto;\n max-width: 100%;\n height: auto;\n margin: 0 auto;\n}\n\n.atv-review-modal-body .image-caption-wrapper {\n margin-top: 8px;\n text-align: center;\n}\n\n.atv-review-modal-body .image-caption {\n display: inline-block;\n color: var(--atv-text-tertiary);\n font-size: 13px;\n font-style: italic;\n font-weight: 400;\n letter-spacing: 0.02em;\n line-height: 1.6;\n}\n\n/* ── Review content subject reference (Douban subject-container) ── */\n\n.atv-review-modal-body .subject-container {\n overflow: hidden;\n padding-left: 2px;\n border: 1px solid rgb(255 255 255 / 8%);\n border-radius: var(--atv-radius-md);\n border-left: 2px solid var(--atv-accent);\n margin: 24px 0;\n background: linear-gradient(\n 105deg,\n rgb(65 190 93 / 7%),\n rgb(18 18 20 / 94%) 42%\n );\n}\n\n.atv-review-modal-body .subject-wrapper > a,\n.atv-review-modal-body .subject-wrapper > a:link,\n.atv-review-modal-body .subject-wrapper > a:visited {\n display: grid;\n padding: 12px;\n border-bottom: 0;\n background: transparent;\n color: inherit;\n gap: 12px;\n grid-template-columns: 56px minmax(0, 1fr);\n text-decoration: none;\n transition: none;\n}\n\n.atv-review-modal-body .subject-wrapper > a:hover,\n.atv-review-modal-body .subject-wrapper > a:active {\n border-bottom: 0;\n background: rgb(255 255 255 / 3%);\n color: inherit;\n}\n\n.atv-review-modal-body .subject-wrapper > a:focus-visible {\n outline: 2px solid var(--atv-accent-bright);\n outline-offset: -2px;\n}\n\n.atv-review-modal-body .subject-cover {\n overflow: hidden;\n width: 56px;\n height: 84px;\n border-radius: 5px;\n background: var(--atv-bg-tertiary);\n box-shadow: 0 8px 20px rgb(0 0 0 / 30%);\n}\n\n.atv-review-modal-body .subject-cover img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.atv-review-modal-body .subject-info {\n display: flex;\n min-width: 0;\n flex-direction: column;\n justify-content: center;\n}\n\n.atv-review-modal-body .subject-title {\n display: flex;\n min-width: 0;\n flex-wrap: wrap;\n align-items: baseline;\n color: var(--atv-text-primary);\n font-size: 16px;\n font-weight: 650;\n gap: 4px;\n letter-spacing: 0.01em;\n line-height: 1.35;\n}\n\n.atv-review-modal-body .title-tail {\n color: var(--atv-text-tertiary);\n font-size: 13px;\n font-weight: 500;\n}\n\n.atv-review-modal-body .subject-rating {\n display: flex;\n align-items: center;\n margin-top: 7px;\n gap: 1px;\n line-height: 1;\n}\n\n.atv-review-modal-body .rating-star1::before,\n.atv-review-modal-body .rating-star2::before,\n.atv-review-modal-body .rating-star0::before {\n content: \"★\";\n font-size: 13px;\n}\n\n.atv-review-modal-body .rating-star1::before {\n color: var(--atv-rating-gold);\n}\n\n.atv-review-modal-body .rating-star2::before {\n background: linear-gradient(\n 90deg,\n var(--atv-rating-gold) 50%,\n rgb(255 255 255 / 18%) 50%\n );\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n\n.atv-review-modal-body .rating-star0::before {\n color: rgb(255 255 255 / 18%);\n}\n\n.atv-review-modal-body .rating-score {\n margin-left: 6px;\n color: var(--atv-text-secondary);\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.atv-review-modal-body .subject-summary {\n margin-top: 7px;\n color: var(--atv-text-tertiary);\n font-size: 12px;\n line-height: 1.55;\n}\n\n.atv-review-modal-body .subject-caption-wrapper {\n padding: 0 12px 12px 80px;\n}\n\n.atv-review-modal-body .subject-caption {\n color: var(--atv-text-secondary);\n font-size: 12px;\n font-style: italic;\n line-height: 1.55;\n}\n\n/* ── Review content links (Douban a.link / generic) ── */\n\n.atv-review-modal-body a:link,\n.atv-review-modal-body a:visited {\n border-bottom: 1px solid rgb(65 190 93 / 25%);\n background: transparent;\n color: var(--atv-accent);\n overflow-wrap: break-word;\n text-decoration: none;\n transition:\n border-color var(--atv-duration-feedback) ease,\n color var(--atv-duration-feedback) ease;\n}\n\n.atv-review-modal-body a:hover,\n.atv-review-modal-body a:active {\n border-bottom-color: var(--atv-accent-bright);\n background: transparent;\n color: var(--atv-accent-bright);\n}\n\n/* ============================================\n 7. Review Content Typography — All Elements\n Target ALL HTML tags that may appear inside\n Douban review rich-text content.\n ============================================ */\n\n/* --- Headings --- */\n\n.atv-review-modal-body h3 {\n margin: 28px 0 12px;\n color: var(--atv-text-primary);\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.atv-review-modal-body h4 {\n margin: 24px 0 10px;\n color: var(--atv-text-primary);\n font-size: 16px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n.atv-review-modal-body h5,\n.atv-review-modal-body h6 {\n margin: 20px 0 8px;\n color: var(--atv-text-secondary);\n font-size: 14px;\n font-weight: 600;\n line-height: 1.4;\n}\n\n/* --- Horizontal Rule --- */\n\n.atv-review-modal-body hr {\n height: 0;\n border: none;\n border-top: 1px solid var(--atv-border-subtle);\n margin: 28px 0;\n}\n\n/* --- Lists --- */\n\n.atv-review-modal-body ul,\n.atv-review-modal-body ol {\n padding-left: 24px;\n margin: 0 0 16px;\n line-height: 1.7;\n}\n\n.atv-review-modal-body ul {\n list-style: disc;\n}\n\n.atv-review-modal-body ol {\n list-style: decimal;\n}\n\n.atv-review-modal-body li {\n margin-bottom: 6px;\n line-height: 1.7;\n}\n\n.atv-review-modal-body li:last-child {\n margin-bottom: 0;\n}\n\n/* --- Inline Text Semantics --- */\n\n.atv-review-modal-body strong,\n.atv-review-modal-body b {\n color: rgb(255 255 255 / 92%);\n font-weight: 700;\n}\n\n.atv-review-modal-body em,\n.atv-review-modal-body i {\n font-style: italic;\n}\n\n.atv-review-modal-body small {\n color: var(--atv-text-tertiary);\n font-size: 0.85em;\n}\n\n.atv-review-modal-body q {\n font-style: italic;\n}\n\n.atv-review-modal-body q::before {\n content: \"\\201C\";\n}\n\n.atv-review-modal-body q::after {\n content: \"\\201D\";\n}\n\n.atv-review-modal-body u {\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: 2px;\n}\n\n.atv-review-modal-body s,\n.atv-review-modal-body del {\n color: var(--atv-text-tertiary);\n text-decoration: line-through;\n}\n\n.atv-review-modal-body sup {\n font-size: 0.75em;\n line-height: 1;\n vertical-align: super;\n}\n\n.atv-review-modal-body sub {\n font-size: 0.75em;\n line-height: 1;\n vertical-align: sub;\n}\n\n/* --- Code --- */\n\n.atv-review-modal-body code {\n padding: 2px 6px;\n border-radius: 4px;\n background: rgb(255 255 255 / 6%);\n font-family:\n \"SF Mono\", Monaco, \"Cascadia Code\", \"JetBrains Mono\", \"Fira Code\", Consolas,\n monospace;\n font-size: 0.9em;\n overflow-wrap: break-word;\n}\n\n.atv-review-modal-body pre {\n padding: 16px 20px;\n border: 1px solid var(--atv-border-subtle);\n border-radius: var(--atv-radius-sm);\n margin: 0 0 20px;\n background: rgb(0 0 0 / 40%);\n line-height: 1.6;\n -webkit-overflow-scrolling: touch;\n overflow-x: auto;\n}\n\n.atv-review-modal-body pre code {\n padding: 0;\n background: none;\n font-size: 14px;\n word-break: normal;\n}\n\n/* --- Tables --- */\n\n.atv-review-modal-body table {\n width: 100%;\n margin: 20px 0;\n border-collapse: collapse;\n line-height: 1.6;\n}\n\n.atv-review-modal-body thead {\n border-bottom: 2px solid var(--atv-border-medium);\n}\n\n.atv-review-modal-body th {\n padding: 10px 14px;\n color: var(--atv-text-primary);\n font-weight: 600;\n text-align: left;\n white-space: nowrap;\n}\n\n.atv-review-modal-body td {\n padding: 10px 14px;\n border-bottom: 1px solid var(--atv-border-subtle);\n color: rgb(255 255 255 / 82%);\n}\n\n.atv-review-modal-body tbody tr:last-child td {\n border-bottom: none;\n}\n\n.atv-review-modal-body .review-content,\n.atv-review-modal-body .review-content p,\n.atv-review-modal-body .review-content div,\n.atv-review-modal-body .review-content span {\n color: rgb(255 255 255 / 82%);\n}\n\n.atv-review-modal-body .spoiler-tip {\n margin-bottom: 12px;\n color: #ff9f0a;\n font-size: 13px;\n font-weight: 600;\n}\n\n.atv-review-modal-body .main-hd {\n display: flex;\n align-items: center;\n margin-bottom: 16px;\n gap: 10px;\n}\n\n.atv-review-modal-body .main-hd a.name {\n color: var(--atv-accent);\n font-size: 14px;\n font-weight: 500;\n text-decoration: none;\n}\n\n.atv-review-modal-body .main-hd a.name:hover {\n text-decoration: underline;\n}\n\n.atv-review-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-top: 20px;\n border-top: 1px solid rgb(255 255 255 / 4%);\n margin-top: 28px;\n}\n\n.atv-review-modal-votes {\n display: flex;\n gap: 14px;\n}\n\n.atv-review-modal-link {\n display: flex;\n align-items: center;\n}\n\n#atv-douban-root .atv-review-modal-link-a {\n background: transparent;\n color: rgb(255 255 255 / 50%);\n font-size: 13px;\n text-decoration: none;\n transition: color var(--atv-duration-feedback) ease;\n}\n\n#atv-douban-root .atv-review-modal-link-a:link,\n#atv-douban-root .atv-review-modal-link-a:visited {\n background: transparent;\n color: rgb(255 255 255 / 50%);\n}\n\n#atv-douban-root .atv-review-modal-link-a:hover,\n#atv-douban-root .atv-review-modal-link-a:active {\n background: transparent;\n color: var(--atv-accent);\n}\n\n.atv-review-modal-stars {\n display: inline-flex;\n align-items: center;\n margin: 0 0 4px;\n color: var(--atv-rating-gold);\n gap: 2px;\n}\n\n.atv-review-modal-stars svg {\n display: block;\n width: 14px;\n height: 14px;\n}\n\n.atv-review-modal-body.is-skeleton {\n position: relative;\n min-height: 140px;\n color: transparent;\n}\n\n.atv-review-modal-body.is-skeleton::before,\n.atv-review-modal-body.is-skeleton::after {\n display: block;\n height: 14px;\n border-radius: 4px;\n background: rgb(255 255 255 / 6%);\n content: \"\";\n}\n\n.atv-review-modal-body.is-skeleton::before {\n width: 92%;\n margin-bottom: 14px;\n}\n\n.atv-review-modal-body.is-skeleton::after {\n width: 68%;\n}\n\n.atv-review-modal-body.is-error {\n display: flex;\n min-height: 140px;\n align-items: center;\n justify-content: center;\n color: var(--atv-text-tertiary);\n text-align: center;\n}\n\n.atv-review-modal-error {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 14px;\n}\n\n.atv-review-modal-error p {\n margin: 0;\n}\n\n.atv-review-modal-retry {\n display: inline-flex;\n min-height: 34px;\n align-items: center;\n justify-content: center;\n padding: 0 18px;\n border: 1px solid rgb(255 255 255 / 10%);\n border-radius: 999px;\n appearance: none;\n background: rgb(255 255 255 / 4%);\n color: var(--atv-text-secondary);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n font-weight: 600;\n transition:\n color var(--atv-duration-feedback) ease,\n border-color var(--atv-duration-feedback) ease,\n background var(--atv-duration-feedback) ease;\n}\n\n.atv-review-modal-retry:hover,\n.atv-review-modal-retry:focus-visible {\n border-color: rgb(65 190 93 / 35%);\n background: rgb(65 190 93 / 8%);\n color: var(--atv-accent);\n}\n\n.atv-review-modal-retry:focus-visible,\n.atv-review-modal .atv-modal-close:focus-visible,\n#atv-douban-root .atv-review-modal-link-a:focus-visible {\n outline: 2px solid var(--atv-accent);\n outline-offset: 3px;\n}\n\n/* ---------- Responsive ---------- */\n\n@media (width <= 1024px) {\n .atv-hero {\n min-height: 64vh;\n padding: 104px 24px 48px;\n }\n\n .atv-hero-inner {\n flex-direction: column;\n align-items: flex-start;\n gap: 28px;\n }\n\n .atv-poster-card {\n width: 220px;\n }\n\n .atv-section {\n padding: 44px 24px;\n }\n\n .atv-info-grid {\n column-gap: 24px;\n grid-template-columns: 160px 1fr;\n }\n}\n\n@media (width <= 768px) {\n .atv-hero {\n min-height: 56vh;\n padding: 88px 20px 40px;\n }\n\n .atv-poster-card {\n width: 180px;\n }\n\n .atv-section {\n padding: 36px 20px;\n }\n\n .atv-info-grid {\n grid-template-columns: 1fr;\n row-gap: 4px;\n }\n\n .atv-info-label {\n padding-top: 12px;\n }\n\n .atv-recs {\n gap: 18px;\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n }\n\n .atv-cast-card {\n flex-basis: 120px;\n }\n\n .atv-cast-avatar {\n width: 120px;\n height: 120px;\n }\n\n .atv-series-card {\n flex-basis: 120px;\n }\n\n .atv-photo-tile {\n flex-basis: 280px;\n }\n\n .atv-photo-tile.is-portrait {\n flex-basis: 170px;\n }\n\n .atv-rating-panel .atv-rating-panel-score {\n font-size: 32px;\n }\n\n .atv-rating-panel-douban,\n .atv-rating-panel-imdb,\n .atv-rating-panel-rt,\n .atv-rating-panel-mc {\n padding: 12px 14px 10px;\n }\n\n .atv-rating-panel {\n min-width: 0;\n }\n\n .atv-comments {\n grid-template-columns: 1fr;\n }\n\n .atv-comment-overlay-inner {\n max-width: 95vw;\n border-radius: 16px;\n }\n\n .atv-comment-overlay-top {\n padding: 24px 20px 0;\n }\n\n .atv-comment-overlay-body {\n padding: 16px 20px;\n font-size: 14px;\n }\n\n .atv-comment-overlay-foot {\n padding: 0 20px 24px;\n }\n\n .atv-reviews {\n grid-template-columns: 1fr;\n }\n\n .atv-review-modal-scroll {\n max-width: 100vw;\n max-height: 92vh;\n padding: 24px 18px 22px;\n border-radius: 20px 20px 0 0;\n }\n\n .atv-review-modal {\n align-items: flex-end;\n padding: 0;\n overscroll-behavior: contain;\n }\n\n .atv-review-modal .atv-modal-close {\n top: 14px;\n right: 14px;\n }\n\n .atv-review-modal-body blockquote {\n padding: 12px 14px;\n margin: 16px 0;\n }\n\n .atv-review-modal-body blockquote blockquote {\n padding: 10px 12px;\n }\n\n .atv-review-modal-body .image-container {\n margin: 16px 0;\n }\n\n .atv-review-modal-body .image-container.image-float-left,\n .atv-review-modal-body .image-container.image-float-right {\n max-width: 100%;\n margin: 16px 0;\n float: none;\n }\n\n .atv-review-modal-body .subject-wrapper > a {\n padding: 10px;\n gap: 10px;\n grid-template-columns: 44px minmax(0, 1fr);\n }\n\n .atv-review-modal-body .subject-cover {\n width: 44px;\n height: 66px;\n }\n\n .atv-review-modal-body .subject-title {\n font-size: 15px;\n }\n\n .atv-review-modal-body .subject-caption-wrapper {\n padding: 0 10px 10px 66px;\n }\n\n /* Review content typography — responsive */\n .atv-review-modal-body h3 {\n margin-top: 22px;\n }\n\n .atv-review-modal-body h4 {\n margin-top: 18px;\n }\n\n .atv-review-modal-body hr {\n margin: 22px 0;\n }\n\n .atv-review-modal-body pre {\n padding: 12px 16px;\n }\n\n .atv-review-modal-body th,\n .atv-review-modal-body td {\n padding: 8px 10px;\n }\n\n .atv-login-modal {\n align-items: flex-end;\n padding: 16px;\n }\n\n .atv-login-modal-inner {\n width: 100%;\n padding: 28px 20px 20px;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-section {\n animation: none;\n }\n\n .atv-trailer-tile,\n .atv-trailer-tile:hover {\n filter: none;\n transform: none;\n }\n\n .atv-trailer-play-overlay {\n transition: none;\n }\n\n .atv-trailer-play-btn {\n transition: none;\n }\n\n .atv-trailer-tile:hover .atv-trailer-play-btn {\n box-shadow: none;\n transform: none;\n }\n\n .atv-modal-overlay.is-open .atv-modal-video {\n transform: none;\n }\n\n .atv-review-card,\n .atv-review-card:hover,\n .atv-review-card:active {\n box-shadow: none;\n transform: none;\n transition: none;\n }\n\n .atv-review-modal-scroll {\n transform: none;\n transition: none;\n }\n\n .atv-review-modal.is-open .atv-review-modal-scroll {\n transform: none;\n }\n\n .atv-review-modal {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n transition: none;\n }\n\n /* Modal overlay fades */\n .atv-modal-overlay,\n .atv-comment-overlay,\n .atv-interest-modal,\n .atv-login-modal {\n transition: none;\n }\n\n .atv-login-modal-inner,\n .atv-login-modal.is-open .atv-login-modal-inner {\n transform: none;\n transition: none;\n }\n\n /* Accent edge glow */\n .atv-modal-accent-bar {\n transform: scaleX(1);\n transition: none;\n }\n}\n\n@media (width <= 768px) {\n .atv-trailer-tile {\n flex-basis: 280px;\n }\n}\n\n/* Cross-experience motion policy: pointer capability and motion preferences. */\n\n@media (hover: hover) and (pointer: fine) {\n .atv-btn-primary:hover {\n background: var(--atv-accent-bright);\n transform: translateY(-1px);\n }\n\n .atv-btn-secondary:hover {\n background: rgb(255 255 255 / 12%);\n transform: translateY(-1px);\n }\n\n .atv-comment-card:hover {\n border-color: rgb(255 255 255 / 12%);\n }\n\n .atv-review-card:hover {\n border-color: rgb(255 255 255 / 12%);\n }\n\n .atv-review-card:hover .atv-review-readmore {\n opacity: 0.7;\n transform: translateX(0);\n }\n\n .atv-stream-card:not(.atv-stream-card-combined):hover::after {\n opacity: 0.18;\n }\n\n .atv-stream-card:hover {\n border-color: rgb(255 255 255 / 18%);\n background: rgb(255 255 255 / 9%);\n }\n\n .atv-interest-modal-star:hover {\n transform: scale(1.15);\n }\n\n .atv-discussion-row:hover::before {\n opacity: 1;\n transform: scaleY(1);\n }\n\n .atv-discussion-row:hover .atv-discussion-arrow {\n opacity: 1;\n transform: none;\n }\n}\n\n.atv-hero-teaser-content {\n display: block;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .atv-carousel {\n scroll-behavior: auto;\n }\n\n .atv-spinner {\n animation: none;\n }\n\n .atv-modal-accent-bar {\n opacity: 1;\n }\n\n .atv-btn-primary:hover,\n .atv-btn-secondary:hover,\n .atv-btn:active,\n .atv-modal-close:active,\n .atv-poster-card:hover,\n .atv-comment-card:hover,\n .atv-comment-votes:active,\n .atv-comment-overlay-votes:active,\n .atv-comment-expand:active,\n .atv-review-card:hover,\n .atv-review-card:hover .atv-review-readmore,\n .atv-review-card:focus-visible .atv-review-readmore,\n .atv-review-card:has(.atv-review-open-button:focus-visible)\n .atv-review-readmore,\n .atv-vote-btn:active,\n .atv-stream-card:hover,\n .atv-interest-modal-star:hover,\n .atv-interest-modal-submit:active,\n .atv-discussion-row:hover::before,\n .atv-discussion-row:has(.atv-discussion-topic-link:focus-visible)::before,\n .atv-discussion-row:has(.atv-discussion-author:focus-visible)::before,\n .atv-series-card:hover,\n .atv-cast-card:hover,\n .atv-photo-tile:hover,\n .atv-rec-card:hover .atv-rec-poster,\n .atv-trailer-tile:hover,\n .atv-hero-more.is-open svg {\n transform: none;\n }\n\n .atv-interest-modal-status-indicator {\n opacity: 0;\n transform: none;\n }\n\n .atv-interest-modal-status.is-active {\n background: rgb(255 255 255 / 12%);\n }\n}\n\n/* ---------- Accessibility: reduced transparency ---------- */\n\n@media (prefers-reduced-transparency: reduce) {\n .atv-stickynav.is-visible:not(.is-scrolling) {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n background: #0a0a0c;\n }\n\n .atv-modal-overlay,\n .atv-comment-overlay,\n .atv-interest-modal,\n .atv-login-modal,\n .atv-review-modal {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n background: rgb(0 0 0 / 90%);\n }\n\n .atv-btn-secondary {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n .atv-chip {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n .atv-series-badge {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n background: rgb(0 0 0 / 80%);\n }\n\n .atv-trailer-label {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n background: rgb(0 0 0 / 80%);\n }\n\n .atv-comment-expand {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n}\n\n/* ---------- Accessibility: high contrast ---------- */\n\n@media (prefers-contrast: more) {\n .atv-modal-overlay,\n .atv-comment-overlay,\n .atv-interest-modal,\n .atv-login-modal,\n .atv-review-modal {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n background: rgb(0 0 0 / 92%);\n }\n\n .atv-comment-card,\n .atv-review-card,\n .atv-stream-card,\n .atv-chip,\n .atv-comment-votes {\n border-color: rgb(255 255 255 / 25%);\n }\n\n .atv-discussion-row {\n border-bottom-color: rgb(255 255 255 / 25%);\n }\n\n .atv-chip {\n color: var(--atv-text-primary);\n }\n\n .atv-comment-expand {\n border-color: rgb(255 255 255 / 25%);\n background: rgb(0 0 0 / 50%);\n }\n\n .atv-btn-secondary {\n border-color: rgb(255 255 255 / 30%);\n background: rgb(255 255 255 / 12%);\n }\n\n .atv-series-badge {\n background: rgb(0 0 0 / 85%);\n }\n\n .atv-trailer-label {\n background: rgb(0 0 0 / 85%);\n }\n}\n\n/* ---------- Card press states ---------- */\n\n.atv-discussion-row {\n transition: transform var(--atv-duration-press) var(--atv-ease-out);\n}\n\n.atv-poster-card:active {\n transform: scale(0.97);\n}\n\n.atv-stream-card:active {\n transform: scale(0.97);\n}\n\n.atv-photo-tile:active {\n transform: scale(0.97);\n}\n\n.atv-cast-card:active {\n transform: scale(0.97);\n}\n\n.atv-series-card:active {\n transform: scale(0.97);\n}\n\n.atv-comment-card:active {\n transform: scale(0.97);\n}\n\n.atv-discussion-row:active {\n transform: scale(0.97);\n}\n"; var LOGIN_FRAME_STYLE_ID = "atv-login-frame-theme"; var LOGIN_FRAME_CSS = ` :root { color-scheme: dark; --atv-login-bg: #1c1c1e; --atv-login-bg-elevated: rgba(255, 255, 255, 0.06); --atv-login-border: rgba(255, 255, 255, 0.12); --atv-login-border-strong: rgba(65, 190, 93, 0.32); --atv-login-text: #ffffff; --atv-login-text-muted: rgba(255, 255, 255, 0.64); --atv-login-text-faint: rgba(255, 255, 255, 0.42); --atv-login-accent: #41be5d; --atv-login-accent-bright: #4cd97a; --atv-login-danger: #ff6b6b; } html, body { box-sizing: border-box !important; min-width: 0 !important; margin: 0 !important; color: var(--atv-login-text) !important; background: var(--atv-login-bg) !important; } *, *::before, *::after { box-sizing: inherit !important; } body, button, input, select, textarea { font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "PingFang SC", "Helvetica Neue", "Microsoft YaHei", Inter, system-ui, sans-serif !important; } a, a:link, a:visited { color: var(--atv-login-accent) !important; text-decoration: none !important; background: transparent !important; } a:hover, a:active { color: var(--atv-login-accent-bright) !important; background: transparent !important; } a:focus-visible, button:focus-visible, input:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--atv-login-accent) !important; outline-offset: 2px !important; } .account-body, .account-main, .account-form, .login-wrap, .login-box { box-sizing: border-box !important; max-width: 100% !important; color: var(--atv-login-text) !important; background: transparent !important; box-shadow: none !important; } .account-body { width: 100% !important; min-width: 0 !important; padding: 0 0 10px !important; } .account-body-tabs, .account-tabcon-start, .account-tabcon-quick, .account-quick, .account-form { width: 100% !important; } .account-body-tabs { margin-bottom: 16px !important; } .account-body-tabs ul, .account-tab, .tab-start, .tab-quick { border-color: var(--atv-login-border) !important; } .account-tab a, .account-tab span, .account-tab-phone, .account-tab-account, .account-tab-scan { color: var(--atv-login-text-muted) !important; background: transparent !important; transition: color 180ms ease, border-color 180ms ease !important; } .account-tab a.on, .account-tab span.on, .account-tab-phone.on, .account-tab-account.on, .account-tab-scan.on, .account-tab .active { color: var(--atv-login-text) !important; border-color: var(--atv-login-accent) !important; } .account-tab-switch, .account-tab-switch-icon, .quick.icon-switch, .start.icon-switch { filter: saturate(0.4) brightness(1.8) !important; } .account-form-tips, .account-form-error, .account-form-err, .account-error, .error, .tips, .tip { line-height: 1.5 !important; } .account-form-tips { color: var(--atv-login-text-muted) !important; } .account-form-error, .account-form-err, .account-error, .error { color: var(--atv-login-danger) !important; } .account-form-field, .account-form-field-phone, .account-form-field-code, .account-form-field-password, .account-form-field-submit { box-sizing: border-box !important; } .account-form-field, .account-form-field-phone, .account-form-field-code, .account-form-field-password, .global-phone-input-input { min-height: 44px !important; color: var(--atv-login-text) !important; background: var(--atv-login-bg-elevated) !important; border-color: var(--atv-login-border) !important; border-radius: 10px !important; } .account-form-field:focus-within, .account-form-field-phone:focus-within, .account-form-field-code:focus-within, .account-form-field-password:focus-within, .global-phone-input-input:focus-within { border-color: var(--atv-login-border-strong) !important; box-shadow: 0 0 0 3px rgba(65, 190, 93, 0.12) !important; } .account-form-field input, .account-form-field-phone input, .account-form-field-code input, .account-form-field-password input, .global-phone-input-input input, input[type="text"], input[type="password"], input[type="tel"], input[type="phone"] { min-height: 42px !important; color: var(--atv-login-text) !important; caret-color: var(--atv-login-accent) !important; background: transparent !important; border-color: transparent !important; box-shadow: none !important; } .account-form-field input::placeholder, .account-form-field-phone input::placeholder, .account-form-field-code input::placeholder, .account-form-field-password input::placeholder, input::placeholder { color: var(--atv-login-text-faint) !important; } .account-form-field-area-code, .account-form-field-label, .account-form-raw, .account-form-tip, .account-form-tips, .account-form-ft, .account-form-3rd, .account-form-3rd-hd, .global-phone-input-area { color: var(--atv-login-text-muted) !important; } .account-form-field-area-code, .global-phone-input-area, .account-form-field-code { border-color: var(--atv-login-border) !important; } .account-form-field-submit .btn, .account-form-field-submit button, .account-form-field-submit input[type="submit"], .btn, .btn-phone, .btn-account, .btn-submit, .btn-account { color: #fff !important; background: var(--atv-login-accent) !important; border-color: var(--atv-login-accent) !important; border-radius: 999px !important; box-shadow: 0 10px 26px rgba(65, 190, 93, 0.24) !important; } .account-form-field-submit .btn:hover, .account-form-field-submit button:hover, .account-form-field-submit input[type="submit"]:hover, .btn:hover, .btn-phone:hover, .btn-account:hover, .btn-submit:hover, .btn-account:hover { color: #fff !important; background: var(--atv-login-accent-bright) !important; border-color: var(--atv-login-accent-bright) !important; } .account-form-3rd, .account-form-ft { border-color: var(--atv-login-border) !important; } .account-form-3rd a, .account-form-3rd .link-3rd, .link-3rd-wx, .link-3rd-wb, .link-3rd-qq { background-color: rgba(255, 255, 255, 0.06) !important; border-color: var(--atv-login-border) !important; filter: grayscale(1) brightness(1.4) !important; } .account-quick, .account-quick .qrcode, .account-quick .qr-code, .account-quick img, .qrcode, .qr-code { color: var(--atv-login-text-muted) !important; background-color: transparent !important; border-color: var(--atv-login-border) !important; } .account-quick img, .qrcode img, .qr-code img { border-radius: 12px !important; } @media (max-width: 380px) { .account-body { padding-right: 0 !important; padding-left: 0 !important; } .account-form-field, .account-form-field-phone, .account-form-field-code, .account-form-field-password, .global-phone-input-input { border-radius: 9px !important; } } `; var isDoubanLoginFrame = (loc = window.location) => loc.hostname === "accounts.douban.com" && loc.pathname.startsWith("/passport/login"); var installLoginFrameTheme = (doc = document) => { if (doc.querySelector(`#${LOGIN_FRAME_STYLE_ID}`)) return; const style = doc.createElement("style"); style.id = LOGIN_FRAME_STYLE_ID; style.textContent = LOGIN_FRAME_CSS; (doc.head ?? doc.documentElement).append(style); }, n, l$1, u$2, i$2, r$1, o$2, e$1, f$2, c$1, a$1, s$1, h$1, p$1, v$1, y$1, d$1 = {}, w$1 = [], _$1 = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i, g$1 = Array.isArray; function m$1(n, l) { for (var u in l) n[u] = l[u]; return n; } function b(n) { n && n.parentNode && n.parentNode.removeChild(n); } function k$1(l, u, t) { var i, r, o, e = {}; for (o in u) "key" == o ? i = u[o] : "ref" == o ? r = u[o] : e[o] = u[o]; if (arguments.length > 2 && (e.children = arguments.length > 3 ? n.call(arguments, 2) : t), "function" == typeof l && null != l.defaultProps) for (o in l.defaultProps) void 0 === e[o] && (e[o] = l.defaultProps[o]); return x$1(l, e, i, r, null); } function x$1(n, t, i, r, o) { var e = { type: n, props: t, key: i, ref: r, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o ? ++u$2 : o, __i: -1, __u: 0 }; return null == o && null != l$1.vnode && l$1.vnode(e), e; } function S(n) { return n.children; } function C$1(n, l) { this.props = n, this.context = l; } function $$1(n, l) { if (null == l) return n.__ ? $$1(n.__, n.__i + 1) : null; for (var u; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) return u.__e; return "function" == typeof n.type ? $$1(n) : null; } function I(n) { if (n.__P && n.__d) { var u = n.__v, t = u.__e, i = [], r = [], o = m$1({}, u); o.__v = u.__v + 1, l$1.vnode && l$1.vnode(o), q$1(n.__P, o, u, n.__n, n.__P.namespaceURI, 32 & u.__u ? [t] : null, i, null == t ? $$1(u) : t, !!(32 & u.__u), r), o.__v = u.__v, o.__.__k[o.__i] = o, D$1(i, o, r), u.__e = u.__ = null, o.__e != t && P(o); } } function P(n) { if (null != (n = n.__) && null != n.__c) return n.__e = n.__c.base = null, n.__k.some(function(l) { if (null != l && null != l.__e) return n.__e = n.__c.base = l.__e; }), P(n); } function A$1(n) { (!n.__d && (n.__d = !0) && i$2.push(n) && !H.__r++ || r$1 != l$1.debounceRendering) && ((r$1 = l$1.debounceRendering) || o$2)(H); } function H() { try { for (var n, l = 1; i$2.length;) i$2.length > l && i$2.sort(e$1), n = i$2.shift(), l = i$2.length, I(n); } finally { i$2.length = H.__r = 0; } } function L(n, l, u, t, i, r, o, e, f, c, a) { var s, h, p, v, y, _, g, m = t && t.__k || w$1, b = l.length; for (f = T$1(u, l, m, f, b), s = 0; s < b; s++) null != (p = u.__k[s]) && (h = -1 != p.__i && m[p.__i] || d$1, p.__i = s, _ = q$1(n, p, h, i, r, o, e, f, c, a), v = p.__e, p.ref && h.ref != p.ref && (h.ref && J(h.ref, null, p), a.push(p.ref, p.__c || v, p)), null == y && null != v && (y = v), (g = !!(4 & p.__u)) || h.__k === p.__k ? (f = j$1(p, f, n, g), g && h.__e && (h.__e = null)) : "function" == typeof p.type && void 0 !== _ ? f = _ : v && (f = v.nextSibling), p.__u &= -7); return u.__e = y, f; } function T$1(n, l, u, t, i) { var r, o, e, f, c, a = u.length, s = a, h = 0; for (n.__k = new Array(i), r = 0; r < i; r++) null != (o = l[r]) && "boolean" != typeof o && "function" != typeof o ? ("string" == typeof o || "number" == typeof o || "bigint" == typeof o || o.constructor == String ? o = n.__k[r] = x$1(null, o, null, null, null) : g$1(o) ? o = n.__k[r] = x$1(S, { children: o }, null, null, null) : void 0 === o.constructor && o.__b > 0 ? o = n.__k[r] = x$1(o.type, o.props, o.key, o.ref ? o.ref : null, o.__v) : n.__k[r] = o, f = r + h, o.__ = n, o.__b = n.__b + 1, e = null, -1 != (c = o.__i = O(o, u, f, s)) && (s--, (e = u[c]) && (e.__u |= 2)), null == e || null == e.__v ? (-1 == c && (i > a ? h-- : i < a && h++), "function" != typeof o.type && (o.__u |= 4)) : c != f && (c == f - 1 ? h-- : c == f + 1 ? h++ : (c > f ? h-- : h++, o.__u |= 4))) : n.__k[r] = null; if (s) for (r = 0; r < a; r++) null != (e = u[r]) && 0 == (2 & e.__u) && (e.__e == t && (t = $$1(e)), K(e, e)); return t; } function j$1(n, l, u, t) { var i, r; if ("function" == typeof n.type) { for (i = n.__k, r = 0; i && r < i.length; r++) i[r] && (i[r].__ = n, l = j$1(i[r], l, u, t)); return l; } n.__e != l && (t && (l && n.type && !l.parentNode && (l = $$1(n)), u.insertBefore(n.__e, l || null)), l = n.__e); do l = l && l.nextSibling; while (null != l && 8 == l.nodeType); return l; } function O(n, l, u, t) { var i, r, o, e = n.key, f = n.type, c = l[u], a = null != c && 0 == (2 & c.__u); if (null === c && null == e || a && e == c.key && f == c.type) return u; if (t > (a ? 1 : 0)) { for (i = u - 1, r = u + 1; i >= 0 || r < l.length;) if (null != (c = l[o = i >= 0 ? i-- : r++]) && 0 == (2 & c.__u) && e == c.key && f == c.type) return o; } return -1; } function z$1(n, l, u) { "-" == l[0] ? n.setProperty(l, null == u ? "" : u) : n[l] = null == u ? "" : "number" != typeof u || _$1.test(l) ? u : u + "px"; } function N(n, l, u, t, i) { var r, o; n: if ("style" == l) if ("string" == typeof u) n.style.cssText = u; else { if ("string" == typeof t && (n.style.cssText = t = ""), t) for (l in t) u && l in u || z$1(n.style, l, ""); if (u) for (l in u) t && u[l] == t[l] || z$1(n.style, l, u[l]); } else if ("o" == l[0] && "n" == l[1]) r = l != (l = l.replace(s$1, "$1")), o = l.toLowerCase(), l = o in n || "onFocusOut" == l || "onFocusIn" == l ? o.slice(2) : l.slice(2), n.l || (n.l = {}), n.l[l + r] = u, u ? t ? u[a$1] = t[a$1] : (u[a$1] = h$1, n.addEventListener(l, r ? v$1 : p$1, r)) : n.removeEventListener(l, r ? v$1 : p$1, r); else { if ("http://www.w3.org/2000/svg" == i) l = l.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s"); else if ("width" != l && "height" != l && "href" != l && "list" != l && "form" != l && "tabIndex" != l && "download" != l && "rowSpan" != l && "colSpan" != l && "role" != l && "popover" != l && l in n) try { n[l] = null == u ? "" : u; break n; } catch (n) {} "function" == typeof u || (null == u || !1 === u && "-" != l[4] ? n.removeAttribute(l) : n.setAttribute(l, "popover" == l && 1 == u ? "" : u)); } } function V(n) { return function(u) { if (this.l) { var t = this.l[u.type + n]; if (null == u[c$1]) u[c$1] = h$1++; else if (u[c$1] < t[a$1]) return; return t(l$1.event ? l$1.event(u) : u); } }; } function q$1(n, u, t, i, r, o, e, f, c, a) { var s, h, p, v, y, d, _, k, x, M, $, I, P, A, H, T, j = u.type; if (void 0 !== u.constructor) return null; 128 & t.__u && (c = !!(32 & t.__u), o = [f = u.__e = t.__e]), (s = l$1.__b) && s(u); n: if ("function" == typeof j) { h = e.length; try { if (x = u.props, M = j.prototype && j.prototype.render, $ = (s = j.contextType) && i[s.__c], I = s ? $ ? $.props.value : s.__ : i, t.__c ? k = (p = u.__c = t.__c).__ = p.__E : (M ? u.__c = p = new j(x, I) : (u.__c = p = new C$1(x, I), p.constructor = j, p.render = Q), $ && $.sub(p), p.state || (p.state = {}), p.__n = i, v = p.__d = !0, p.__h = [], p._sb = []), M && null == p.__s && (p.__s = p.state), M && null != j.getDerivedStateFromProps && (p.__s == p.state && (p.__s = m$1({}, p.__s)), m$1(p.__s, j.getDerivedStateFromProps(x, p.__s))), y = p.props, d = p.state, p.__v = u, v) M && null == j.getDerivedStateFromProps && null != p.componentWillMount && p.componentWillMount(), M && null != p.componentDidMount && p.__h.push(p.componentDidMount); else { if (M && null == j.getDerivedStateFromProps && x !== y && null != p.componentWillReceiveProps && p.componentWillReceiveProps(x, I), u.__v == t.__v || !p.__e && null != p.shouldComponentUpdate && !1 === p.shouldComponentUpdate(x, p.__s, I)) { u.__v != t.__v && (p.props = x, p.state = p.__s, p.__d = !1), u.__e = t.__e, u.__k = t.__k, u.__k.some(function(n) { n && (n.__ = u); }), w$1.push.apply(p.__h, p._sb), p._sb = [], p.__h.length && e.push(p); break n; } null != p.componentWillUpdate && p.componentWillUpdate(x, p.__s, I), M && null != p.componentDidUpdate && p.__h.push(function() { p.componentDidUpdate(y, d, _); }); } if (p.context = I, p.props = x, p.__P = n, p.__e = !1, P = l$1.__r, A = 0, M) p.state = p.__s, p.__d = !1, P && P(u), s = p.render(p.props, p.state, p.context), w$1.push.apply(p.__h, p._sb), p._sb = []; else do p.__d = !1, P && P(u), s = p.render(p.props, p.state, p.context), p.state = p.__s; while (p.__d && ++A < 25); p.state = p.__s, null != p.getChildContext && (i = m$1(m$1({}, i), p.getChildContext())), M && !v && null != p.getSnapshotBeforeUpdate && (_ = p.getSnapshotBeforeUpdate(y, d)), H = null != s && s.type === S && null == s.key ? E(s.props.children) : s, f = L(n, g$1(H) ? H : [H], u, t, i, r, o, e, f, c, a), p.base = u.__e, u.__u &= -161, p.__h.length && e.push(p), k && (p.__E = p.__ = null); } catch (n) { if (e.length = h, u.__v = null, c || null != o) { if (n.then) { for (u.__u |= c ? 160 : 128; f && 8 == f.nodeType && f.nextSibling;) f = f.nextSibling; null != o && (o[o.indexOf(f)] = null), u.__e = f; } else if (null != o) for (T = o.length; T--;) b(o[T]); } else u.__e = t.__e; u.__k ??= t.__k || [], n.then || B$1(u), l$1.__e(n, u, t); } } else null == o && u.__v == t.__v ? (u.__k = t.__k, u.__e = t.__e) : f = u.__e = G(t.__e, u, t, i, r, o, e, c, a); return (s = l$1.diffed) && s(u), 128 & u.__u ? void 0 : f; } function B$1(n) { n && (n.__c && (n.__c.__e = !0), n.__k && n.__k.some(B$1)); } function D$1(n, u, t) { for (var i = 0; i < t.length; i++) J(t[i], t[++i], t[++i]); l$1.__c && l$1.__c(u, n), n.some(function(u) { try { n = u.__h, u.__h = [], n.some(function(n) { n.call(u); }); } catch (n) { l$1.__e(n, u.__v); } }); } function E(n) { return "object" != typeof n || null == n || n.__b > 0 ? n : g$1(n) ? n.map(E) : void 0 !== n.constructor ? null : m$1({}, n); } function G(u, t, i, r, o, e, f, c, a) { var s, h, p, v, y, w, _, m = i.props || d$1, k = t.props, x = t.type; if ("svg" == x ? o = "http://www.w3.org/2000/svg" : "math" == x ? o = "http://www.w3.org/1998/Math/MathML" : o || (o = "http://www.w3.org/1999/xhtml"), null != e) { for (s = 0; s < e.length; s++) if ((y = e[s]) && "setAttribute" in y == !!x && (x ? y.localName == x : 3 == y.nodeType)) { u = y, e[s] = null; break; } } if (null == u) { if (null == x) return document.createTextNode(k); u = document.createElementNS(o, x, k.is && k), c && (l$1.__m && l$1.__m(t, e), c = !1), e = null; } if (null == x) m === k || c && u.data == k || (u.data = k); else { if (e = "textarea" == x && null != k.defaultValue ? null : e && n.call(u.childNodes), !c && null != e) for (m = {}, s = 0; s < u.attributes.length; s++) m[(y = u.attributes[s]).name] = y.value; for (s in m) y = m[s], "dangerouslySetInnerHTML" == s ? p = y : "children" == s || s in k || "value" == s && "defaultValue" in k || "checked" == s && "defaultChecked" in k || N(u, s, null, y, o); for (s in k) y = k[s], "children" == s ? v = y : "dangerouslySetInnerHTML" == s ? h = y : "value" == s ? w = y : "checked" == s ? _ = y : c && "function" != typeof y || m[s] === y || N(u, s, y, m[s], o); if (h) c || p && (h.__html == p.__html || h.__html == u.innerHTML) || (u.innerHTML = h.__html), t.__k = []; else if (p && (u.innerHTML = ""), L("template" == t.type ? u.content : u, g$1(v) ? v : [v], t, i, r, "foreignObject" == x ? "http://www.w3.org/1999/xhtml" : o, e, f, e ? e[0] : i.__k && $$1(i, 0), c, a), null != e) for (s = e.length; s--;) b(e[s]); c && "textarea" != x || (s = "value", "progress" == x && null == w ? u.removeAttribute("value") : null != w && (w !== u[s] || "progress" == x && !w || "option" == x && w != m[s]) && N(u, s, w, m[s], o), s = "checked", null != _ && _ != u[s] && N(u, s, _, m[s], o)); } return u; } function J(n, u, t) { try { if ("function" == typeof n) { var i = "function" == typeof n.__u; i && n.__u(), i && null == u || (n.__u = n(u)); } else n.current = u; } catch (n) { l$1.__e(n, t); } } function K(n, u, t) { var i, r; if (l$1.unmount && l$1.unmount(n), (i = n.ref) && (i.current && i.current != n.__e || J(i, null, u)), null != (i = n.__c)) { if (i.componentWillUnmount) try { i.componentWillUnmount(); } catch (n) { l$1.__e(n, u); } i.base = i.__P = i.__n = null; } if (i = n.__k) for (r = 0; r < i.length; r++) i[r] && K(i[r], u, t || "function" != typeof n.type); t || b(n.__e), n.__c = n.__ = n.__e = void 0; } function Q(n, l, u) { return this.constructor(n, u); } function R(u, t, i) { var r, o, e, f; t == document && (t = document.documentElement), l$1.__ && l$1.__(u, t), o = (r = "function" == typeof i) ? null : i && i.__k || t.__k, e = [], f = [], q$1(t, u = (!r && i || t).__k = k$1(S, null, [u]), o || d$1, d$1, t.namespaceURI, !r && i ? [i] : o ? null : t.firstChild ? n.call(t.childNodes) : null, e, !r && i ? i : o ? o.__e : t.firstChild, r, f), D$1(e, u, f), u.props.children = null; } function X(n) { function l(n) { var u, t; return this.getChildContext || (u = new Set(), (t = {})[l.__c] = this, this.getChildContext = function() { return t; }, this.componentWillUnmount = function() { u = null; }, this.shouldComponentUpdate = function(n) { this.props.value != n.value && u.forEach(function(n) { n.__e = !0, A$1(n); }); }, this.sub = function(n) { u.add(n); var l = n.componentWillUnmount; n.componentWillUnmount = function() { u && u.delete(n), l && l.call(n); }; }), n.children; } return l.__c = "__cC" + y$1++, l.__ = n, l.Provider = l.__l = (l.Consumer = function(n, l) { return n.children(l); }).contextType = l, l; } n = w$1.slice, l$1 = { __e: function(n, l, u, t) { for (var i, r, o; l = l.__;) if ((i = l.__c) && !i.__) try { if ((r = i.constructor) && null != r.getDerivedStateFromError && (i.setState(r.getDerivedStateFromError(n)), o = i.__d), null != i.componentDidCatch && (i.componentDidCatch(n, t || {}), o = i.__d), o) return i.__E = i; } catch (l) { n = l; } throw n; } }, u$2 = 0, C$1.prototype.setState = function(n, l) { var u = null != this.__s && this.__s != this.state ? this.__s : this.__s = m$1({}, this.state); "function" == typeof n && (n = n(m$1({}, u), this.props)), n && m$1(u, n), null != n && this.__v && (l && this._sb.push(l), A$1(this)); }, C$1.prototype.forceUpdate = function(n) { this.__v && (this.__e = !0, n && this.__h.push(n), A$1(this)); }, C$1.prototype.render = S, i$2 = [], o$2 = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e$1 = function(n, l) { return n.__v.__b - l.__v.__b; }, H.__r = 0, f$2 = Math.random().toString(8), c$1 = "__d" + f$2, a$1 = "__a" + f$2, s$1 = /(PointerCapture)$|Capture$/i, h$1 = 0, p$1 = V(!1), v$1 = V(!0), y$1 = 0; var $ = (selector, ctx) => (ctx ?? document).querySelector(selector); var $$ = (selector, ctx) => [...(ctx ?? document).querySelectorAll(selector)]; var safeText = (el) => el ? (el.textContent ?? "").trim() : ""; var extractAwards = (doc) => $$("ul.award", doc).map((ul) => { const lis = $$("li", ul); const orgEl = lis[0] ? $("a", lis[0]) : null; const org = lis[0] ? safeText(lis[0]) : ""; const name = lis[1] ? safeText(lis[1]) : ""; const personEl = lis[2] ? $("a", lis[2]) : null; const person = lis[2] ? safeText(lis[2]) : ""; return { name, org, orgLink: orgEl ? orgEl.href : "", person, personLink: personEl ? personEl.href : "" }; }).filter((a) => a.org); var RE_SLASH_SEP = /\s*\/\s*/gu; var RE_WS_GLOBAL = /\s+/gu; var RE_COLON_WS = /[::\s]/gu; var RE_YEAR_TRAIL = /\(\d{4}\)\s*$/u; var RE_H1_YEAR = /\((?\d{4})\)\s*$/u; var RE_WS = /\s+/u; var RE_YEAR = /(?\d{4})/u; var RE_NON_DIGIT = /\D/gu; var RE_HSPACE = /[ \t]+/gu; var RE_NL_MULTI = /\n{3,}/gu; var RE_IMDB_ID = /(?tt\d+)/u; var RE_BG_URL = /url\(["']?(?[^"')]+)["']?\)/u; var RE_SUBJECT_ID = /subject\/(?\d+)/u; var RE_ALLSTAR = /allstar(?\d{2})/u; var RE_HTTP = /^https?:\/\//u; var RE_ONLINE_VIDEO = /online-video/u; var RE_INTEREST_ACTIVE = /done|active|on\b|j_a\b/u; var RE_IMDB_LINK = /^tt\d+$/u; var RE_SEASON_SUFFIX = /\d$/u; var RE_SEASON_EP = /^第[一二三四五六七八九十百\d]+[季集]\s*/u; var RE_PLAY_SOURCES = /sources\[(?\d+)\]\s*=\s*\[\s*\{play_link:\s*"(?[^"]+)"/gu; var RE_SOURCES_SCRIPT = /\bsources\s*\[/u; var upgradePoster = (url) => { if (!url) return null; return encodeURI(url.replace("/s_ratio_poster/", "/l_ratio_poster/").replace("s_ratio_poster", "l_ratio_poster")); }; var upgradePhoto = (url) => { if (!url) return null; return encodeURI(url.replace("/sqxs/", "/large/").replace("/m/", "/l/")); }; var extractTitle = (doc) => { const h1 = $("#content h1", doc); const full = safeText($("span[property=\"v:itemreviewed\"]", h1 ?? doc)) || safeText(h1).replace(RE_YEAR_TRAIL, "").trim(); let primary = full; let original = ""; const idx = full.search(RE_WS); if (idx > 0) { primary = full.slice(0, idx).trim(); original = full.slice(idx).trim().replace(RE_SEASON_EP, ""); } return { full, original, primary }; }; var extractYear = (doc) => { const m = safeText($("#content h1 .year", doc)).match(RE_YEAR); return m ? m[1] : ""; }; var extractPoster = (doc) => { const img = $("#mainpic img", doc) || $("a.nbgnbg img", doc); if (!img) return null; return upgradePoster(img.src || img.dataset.src || ""); }; var extractSubjectId = (doc) => { const m = (doc.defaultView?.location.pathname ?? "").match(RE_SUBJECT_ID); return m ? m[1] : ""; }; var MAX_DISCUSSION_TOPICS = 10; var DOUBAN_ORIGIN = "https://www.douban.com/"; var TOPIC_PATH = /^\/(?:group\/topic\/\d+|subject\/\d+\/discussion\/\d+)\/?$/u; var DISCUSSION_COLLECTION_PATH = /^\/subject\/\d+\/discussion\/?$/u; var COLLECTION_PATH = /^\/(?:group\/\d+|subject\/\d+\/discussion)\/?$/u; var START_DISCUSSION_PATH = /^\/(?:group\/\d+|subject\/\d+\/discussion\/create|register)\/?$/u; var AUTHOR_PROFILE_PATH = /^\/people\/[^/]+\/?$/u; var DISCUSSION_TIMESTAMP = /^(?\d{4}-\d{2}-\d{2})\s+(?