:root {
    --bg: #0f0f0f;
    --panel: #141414;
    --text: #e5e5e5;
    --muted: #a1a1a1;
    --brand: #e50914;
    --card: #1b1b1b;
    /* safe area insets */
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --nav-bg: rgba(0, 0, 0, 0.9);
    --hud-p: 0;
    /* 0..1 progress */
    --hud-gap: 6px;
    /* micro gap under Telegram buttons */
    --hud-underlay: calc(16px * (1 - var(--hud-p)));
    --tab-offset: 18px;
    /* lower bottom nav by this many px */
}

* {
    box-sizing: border-box;
}

html {
    /* Mobile browsers auto-boost font sizes for readability based on the
       viewport width of the surrounding block — and re-run that heuristic
       after an orientation change, so text (e.g. episode titles) would come
       back from a landscape->portrait rotation rendered larger than before
       even though nothing in our CSS changed. Locks every font-size to
       exactly what we specify, regardless of orientation. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

#colorBloom {
    position: fixed;
    top: -60px;
    right: -40px;
    width: 140vw;
    height: 140vw;
    pointer-events: none;
    /* keep the ambient glow behind ALL content — with z-index 0 this fixed
       element painted on top of in-flow content and fogged the posters */
    z-index: -1;
    background: radial-gradient(ellipse at 100% 0%, var(--bloom-color, transparent) 0%, transparent 65%);
    opacity: 0;
    transition: opacity 1.2s ease;
}

#colorBloom.visible {
    opacity: 1;
}

html,
body {
    height: 100%;
}

/* Dark base lives on <html>, not <body>, so the color bloom (a z-index:-1
   child of <body>) shows through a transparent <body> at every scroll
   position — including the very top — while still sitting behind the cards. */
html {
    background: var(--bg);
}

body {
    margin: 0;
    font-family: 'Poppins', system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
    background: transparent;
    color: var(--text);
    overscroll-behavior-y: none;
    overflow-x: hidden;
    scrollbar-width: none;
    /* Firefox */
    -ms-overflow-style: none;
    /* IE/Edge */
}

/* Disable selection, long-press callouts and tap highlight across the app */
html,
body,
#app {
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

*:not(input):not(textarea):not([contenteditable="true"]) {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
}

img {
    -webkit-user-drag: none;
    user-drag: none;
}


/* Search Page header */
/* ── Search page ── */
.search-page {
    background: #0f0f0f;
}

.search-header {
    position: fixed;
    top: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 8px);
    left: 0;
    right: 0;
    z-index: 16;
    padding: 0 16px 10px;
    background: transparent;
    /* glass underlay extends from top of screen to bottom of header */
    transition: background 0.3s ease,
                transform 0.3s ease, padding-top 0.3s ease, top 0.3s ease;
    will-change: transform;
}

.search-header.scrolled {
    top: 0;
    padding-top: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 8px);
    background: rgba(18, 18, 18, 0.96);
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

.searchbar-wrap {
    position: relative;
    display: flex;
    align-items: center;
    background: #2a2a2a;
    border-radius: 12px;
    height: 46px;
    padding: 0 12px;
    gap: 8px;
}

.searchbar-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    color: rgba(255,255,255,0.45);
}

.searchbar-wrap input {
    flex: 1;
    background: none;
    border: none;
    outline: none;
    color: #fff;
    font-size: 15px;
    font-family: inherit;
    caret-color: var(--brand);
}

.searchbar-wrap input::placeholder {
    color: rgba(255,255,255,0.4);
}

.searchbar-clear {
    flex-shrink: 0;
    background: none;
    border: none;
    color: rgba(255,255,255,0.45);
    font-size: 14px;
    padding: 4px;
    cursor: pointer;
    line-height: 1;
}

.searchbar-clear.hidden { display: none; }

.search-content {
    padding: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 72px) 16px
             calc(20px + var(--safe-bottom));
}

.search-section-title {
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    margin: 0 0 12px;
}

/* grid of poster cards */
.search-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}

.search-grid .recommend-card {
    width: 100%;
    height: 0;
    padding-bottom: 148%;
    position: relative;
    border-radius: 8px;
    overflow: hidden;
    display: block;
    text-decoration: none;
}

.search-grid .recommend-card img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

/* list of results */
.search-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.search-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.search-item-poster {
    flex-shrink: 0;
    width: 60px;
    height: 88px;
    border-radius: 8px;
    overflow: hidden;
    background: #1a1a1a;
}

.search-item-poster img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

.search-item-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    cursor: pointer;
}

.search-item-title {
    font-size: 14px;
    font-weight: 500;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.search-item-type {
    font-size: 12px;
    color: rgba(255,255,255,0.45);
}

.search-item-play {
    flex-shrink: 0;
    background: none;
    border: none;
    padding: 4px;
    color: #fff;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.search-item-play svg {
    width: 36px;
    height: 36px;
    display: block;
}

/* Center icon in Telegram header area */
.tg-center-icon {
    position: fixed;
    top: calc(var(--safe-top) - 10px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 13;
    pointer-events: none;
}

.tg-center-icon-img {
    width: 100px;
    height: 100px;
    display: block;
}

body::-webkit-scrollbar {
    /* WebKit */
    width: 0;
    height: 0;
}

html {
    scrollbar-width: none;
    overscroll-behavior-y: none;
}

html::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* Topbar */
.topbar {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: var(--safe-top, 0px) 16px 10px;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 16;
    background: transparent;
    transition: background 0.45s ease;
}

.topbar.glass {
    background: rgba(28, 28, 28, 0.94);
    border-bottom: 1px solid #222;
}

.topbar-title {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    text-align: center;
    letter-spacing: -0.3px;
    height: var(--tg-ui-top, 52px);
    display: flex;
    align-items: center;
    justify-content: center;
}

.icon-btn {
    background: transparent;
    border: 0;
    color: #fff;
    font-size: 18px;
}

.icon-img {
    width: 40px;
    height: 40px;
    display: block;
}

.topbar-chips-wrap {
    overflow: hidden;
    max-height: 44px;
    opacity: 1;
    transition: max-height 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.32s ease;
}

.topbar.collapsed .topbar-chips-wrap {
    max-height: 0;
    opacity: 0;
    transition: max-height 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.28s ease;
}

.topbar-chips {
    display: flex;
    gap: 8px;
    flex-wrap: nowrap;
    justify-content: center;
    align-items: center;
    padding-bottom: 2px;
    overflow-x: auto;
    scrollbar-width: none;
}

/* Despite the gaps, the row reads as one capsule: corners facing the row's
   own ends stay fully round, corners facing a neighboring chip are only
   softly rounded — like the Netflix Series/Films/New&Hot/Categories row. */
.topbar-chips .chip {
    border-radius: 14px;
}

/* 18px (not 999px) on purpose: mixing a huge radius with a small one in the
   same shorthand on a short element makes the browser's corner-overlap
   correction scale ALL corners down together (since one side's radii sum
   would hugely exceed the box height), collapsing the small 14px corner
   to near-zero. 18px is already >= half the chip's height, so it reads as
   fully round without triggering that correction. */
.topbar-chips .chip:first-child {
    border-radius: 18px 14px 14px 18px;
}

.topbar-chips .chip:last-child {
    border-radius: 14px 18px 18px 14px;
}

.topbar-chips::-webkit-scrollbar {
    display: none;
}

.search-chip {
    width: 40px;
    height: 40px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.search-chip .icon-img {
    width: 18px;
    height: 18px;
}

.chip {
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 999px;
    color: #fff;
    padding: 7px 16px;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    /* top edge catches a highlight, like a light source from above; fades
       out toward the bottom instead of an even border all the way round */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
    transition: background 0.35s ease, border-color 0.35s ease,
                transform 0.2s ease, box-shadow 0.35s ease;
    will-change: transform;
}

.chip:active {
    background: rgba(255, 255, 255, 0.13);
    transform: scale(0.95);
}

/* Сериалы / Фильмы / Жанры on the home page: press flips to a solid white
   chip with black text instead of the default translucent press state. */
.topbar-chips .chip:not(.search-chip) {
    /* background/color deliberately NOT transitioned: a quick tap can be
       shorter than even a 140ms fade, so an animated press-in could revert
       before it ever finishes turning white. Snapping instantly guarantees
       the flash is visible for the full (however brief) press; only the
       scale keeps an eased transition for the tactile feel. */
    transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}

.topbar-chips .chip:not(.search-chip):active,
.topbar-chips .chip:not(.search-chip).chip-pressed {
    background: #fff;
    color: #000;
    transform: scale(0.95);
}

.chip.active {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.4);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.15);
    color: #fff;
    font-weight: 600;
}

/* Full-screen loading spinner */
#pageLoader {
    position: fixed;
    inset: 0;
    background: #0f0f0f;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 999;
    transition: opacity 0.25s ease;
}
#pageLoader.hidden {
    opacity: 0;
    pointer-events: none;
}
.loader-ring {
    width: 40px;
    height: 40px;
    border: 3px solid rgba(255,255,255,0.12);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin 0.75s linear infinite;
}
@keyframes spin {
    to { transform: rotate(360deg); }
}

/* --- Boot welcome (first-time onboarding) --- */
.boot-welcome {
    position: fixed;
    inset: 0;
    z-index: 1200;
    /* above #app and #pageLoader (999) so the app never flashes underneath */
    background: #0f0f0f;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 24px calc(32px + var(--safe-bottom));
    text-align: center;
    opacity: 1;
    transition: opacity 0.5s ease;
}
.boot-welcome.hidden {
    opacity: 0;
    pointer-events: none;
}
.boot-welcome-center {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.boot-welcome-logo {
    width: 92px;
    height: 92px;
    margin-bottom: 18px;
    opacity: 0;
    transform: translateY(10px);
    animation: bootFadeUp 0.6s ease 0.05s forwards;
}
.boot-welcome-greeting {
    margin: 0;
    font-size: 17px;
    font-weight: 400;
    color: var(--muted);
    opacity: 0;
    transform: translateY(10px);
    animation: bootFadeUp 0.6s ease 0.22s forwards;
}
.boot-welcome-name {
    margin: 0;
    font-size: 30px;
    font-weight: 600;
    color: #fff;
    opacity: 0;
    transform: translateY(10px);
    animation: bootFadeUp 0.6s ease 0.34s forwards;
}
.boot-welcome-continue {
    width: 100%;
    max-width: 420px;
    padding: 15px 20px;
    border: none;
    border-radius: 12px;
    background: var(--brand);
    color: #fff;
    font-size: 16px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    opacity: 0;
    transform: translateY(10px);
    animation: bootFadeUp 0.6s ease 0.52s forwards;
    transition: transform 0.12s ease, filter 0.12s ease;
}
.boot-welcome-continue:active {
    transform: scale(0.97);
    filter: brightness(0.9);
}

@keyframes bootFadeUp {
    to { opacity: 1; transform: translateY(0); }
}

/* --- Boot welcome-back (returning user, fades over the app) --- */
.boot-welcome-back {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(15, 15, 15, 0.72);
    -webkit-backdrop-filter: blur(7px);
    backdrop-filter: blur(7px);
    opacity: 1;
    transition: opacity 0.9s ease;
}
.boot-welcome-back.hidden {
    opacity: 0;
    pointer-events: none;
}
.boot-welcome-back-center {
    text-align: center;
    padding: 0 24px;
}
.boot-welcome-back-greeting {
    margin: 0 0 4px;
    font-size: 16px;
    font-weight: 400;
    color: var(--muted);
    opacity: 0;
    animation: bootFadeUp 0.5s ease 0.1s forwards;
}
.boot-welcome-back-name {
    margin: 0;
    font-size: 27px;
    font-weight: 600;
    color: #fff;
    opacity: 0;
    animation: bootFadeUp 0.5s ease 0.22s forwards;
}

/* 18+ age gate */
.age-gate {
    position: fixed;
    inset: 0;
    background: #0f0f0f;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.age-gate-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    text-align: center;
    width: 100%;
    max-width: 320px;
}

.age-gate-text {
    font-size: 20px;
    font-weight: 600;
    color: #fff;
    margin: 0;
}

.age-gate-actions {
    display: flex;
    gap: 12px;
    width: 100%;
}

.age-gate-actions .btn {
    flex: 1;
}

.age-gate-back {
    width: 100%;
}

/* Skeleton shimmer */
@keyframes shimmer {
    0%   { background-position: -200% center; }
    100% { background-position: 200% center; }
}
.skeleton {
    background: linear-gradient(90deg,
        rgba(255,255,255,0.06) 25%,
        rgba(255,255,255,0.13) 50%,
        rgba(255,255,255,0.06) 75%);
    background-size: 200% auto;
    animation: shimmer 1.4s linear infinite;
    border-radius: 8px;
}
.skeleton-hero {
    width: 100%;
    aspect-ratio: 2/3;
    max-height: 60vw;
    border-radius: 0;
}
.skeleton-card {
    width: 26vw;
    height: 38vw;
    flex-shrink: 0;
    border-radius: 8px;
}
.skeleton-row {
    display: flex;
    gap: 10px;
    padding: 4px 16px 12px 4px;
    overflow: hidden;
}
.skeleton-title {
    height: 18px;
    width: 120px;
    border-radius: 6px;
    margin: 16px 4px 8px;
}

/* Page header for Serials / Films */
.page-topbar {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: var(--safe-top, 0px) 16px 10px;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 16;
    background: transparent;
    transition: background 0.45s ease;
}

.page-topbar.glass {
    background: rgba(28, 28, 28, 0.94);
    border-bottom: 1px solid #222;
}

.page-topbar-title {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    text-align: center;
    letter-spacing: -0.3px;
    height: var(--tg-ui-top, 52px);
    display: flex;
    align-items: center;
    justify-content: center;
}

.page-chips-wrap {
    overflow: hidden;
    max-height: 48px;
    opacity: 1;
    transition: max-height 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.32s ease;
}

.page-topbar.collapsed .page-chips-wrap {
    max-height: 0;
    opacity: 0;
    transition: max-height 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.28s ease;
}

.page-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
    padding-bottom: 2px;
}

.chip-lg {
    padding: 11px 22px;
    font-size: 16px;
}

.chip-md {
    padding: 9px 16px;
    font-size: 14px;
}

.brand {
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--brand);
}

.search input {
    background: var(--panel);
    border: 1px solid #222;
    color: var(--text);
    padding: 10px 12px;
    border-radius: 8px;
    width: 260px;
}

.content {
    padding: calc(var(--safe-top, 0px) + var(--tg-ui-top, 52px) + 6px + 44px + 10px) 16px calc(100px + var(--safe-bottom) + var(--tab-offset));
}

.content .hero {
    margin-top: 0;
}

.section-title {
    margin: 16px 4px 4px;
    font-size: 16px;
    color: #fff;
}

/* Hero poster */
.hero {
    position: relative;
    width: 340px;
    /* bottom margin needs room for .hero-glass-btn hanging 26px below the
       poster's own edge, plus the usual breathing room past that. */
    margin: 106px auto 40px;
}

.page-content {
    padding-top: calc(var(--safe-top, 0px) + var(--tg-ui-top, 52px) + 6px + 48px + 10px);
}

.page-content.no-chips {
    padding-top: calc(var(--safe-top, 0px) + var(--tg-ui-top, 52px) + 2px);
}

.page-content .hero {
    margin-top: 0;
}

/* Clipping/rounding lives here now (not on .hero) so .hero-info's buttons,
   positioned to straddle the bottom edge, aren't cut off by it. */
.hero-media {
    border-radius: 16px;
    overflow: hidden;
    background: #111;
}

.hero-media img {
    width: 100%;
    aspect-ratio: 2/3;
    height: auto;
    max-height: 70vh;
    display: block;
    object-fit: cover;
    image-rendering: auto;
}

/* Shop hero: same size/position as the home hero (.hero), but a swipeable,
   auto-advancing carousel of plain poster images instead of one anime with
   action buttons — see setupShopHero() in main.js. */
.shop-hero-track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    border-radius: 16px;
    background: #111;
}

.shop-hero-track::-webkit-scrollbar { width: 0; height: 0; }

.shop-hero-slide {
    flex: 0 0 100%;
    min-width: 0; /* flex items default to min-width:auto — without this, the
                     slide grows to the image's intrinsic width instead of
                     being clipped to the track */
    scroll-snap-align: start;
}

.shop-hero-slide img {
    width: 100%;
    aspect-ratio: 2/3;
    height: auto;
    max-height: 70vh;
    display: block;
    object-fit: cover;
}

/* Overlaid on the poster itself (not a row below it) — sits outside
   .shop-hero-track so it isn't clipped by the track's own overflow. */
.shop-hero-dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 14px;
    display: flex;
    justify-content: center;
    gap: 6px;
    pointer-events: none;
}

.shop-hero-dot {
    width: 16px;
    height: 5px;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.4);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    transition: background 0.2s ease, width 0.2s ease;
}

.shop-hero-dot.active {
    width: 24px;
    background: #fff;
}

.shop-section-title {
    margin: 24px 0 4px;
    text-align: center;
    color: #fff;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* Buttons straddle the poster's bottom edge — half sitting on the art,
   half hanging below it — instead of floating fully on top of it.
   -21px is half of .hero-glass-btn's 42px height. */
.hero-info {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -21px;
    text-align: center;
    padding: 0;
    background: none;
}

.hero-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
}

.hero-glass-btn {
    width: 138px;
    height: 42px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: 999px;
    border: 1px solid rgba(58, 58, 60, 0.5);
    background: rgba(58, 58, 60, 0.55);
    backdrop-filter: blur(14px) saturate(150%);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.15);
    color: #fff;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    transition: transform 0.15s ease, background 0.2s ease;
}

.hero-btn-label {
    white-space: nowrap;
}

.hero-glass-btn svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.hero-glass-btn:active {
    transform: scale(0.92);
    background: rgba(58, 58, 60, 0.75);
}

.hero-glass-btn .hero-check {
    display: none;
}

.hero-glass-btn.active .hero-plus {
    display: none;
}

.hero-glass-btn.active .hero-check {
    display: block;
}

.hero-label-added {
    display: none;
}

.hero-glass-btn.active .hero-label-add {
    display: none;
}

.hero-glass-btn.active .hero-label-added {
    display: block;
}

.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border: 1px solid #333;
    padding: 10px 14px;
    border-radius: 10px;
    text-decoration: none;
    font-weight: 600;
}

.btn.primary {
    background: #ffffff;
    color: #000;
    border-color: #fff;
}

.btn.active {
    background: rgba(255,255,255,0.22);
    color: #fff;
    border-color: rgba(255,255,255,0.4);
}

.row-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 36vw;
    gap: 10px;
    overflow-x: auto;
    padding: 6px 4px 16px;
    scroll-snap-type: x mandatory;
}

.row-grid::-webkit-scrollbar {
    display: none;
}

.row-grid {
    scrollbar-width: none;
}

@media (min-width: 768px) {
    .row-grid {
        grid-auto-columns: 220px;
    }
}

.card {
    background: var(--card);
    border-radius: 10px;
    overflow: hidden;
    position: relative;
    scroll-snap-align: start;
    transition: transform 0.2s ease;
}

.card:hover {
    transform: translateY(-2px);
}

.card img {
    width: 100%;
    height: 180px;
    object-fit: cover;
    display: block;
    background: #222;
}

.card .info {
    padding: 8px 10px 10px;
}

.card .title {
    margin: 0 0 4px;
    font-size: 14px;
    line-height: 1.3;
}

.card .meta {
    color: var(--muted);
    font-size: 12px;
}

.modal.hidden {
    display: none;
}

.modal {
    position: fixed;
    inset: 0;
}

.modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
}

.modal-card {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(860px, 92vw);
    background: var(--panel);
    border: 1px solid #222;
    border-radius: 14px;
    overflow: hidden;
    display: grid;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .modal-card {
        grid-template-columns: 1fr 1.2fr;
    }
}

.modal-card img {
    width: 100%;
    height: 280px;
    object-fit: cover;
}

.modal-info {
    padding: 16px;
}

.modal-info h3 {
    margin: 0 0 6px;
}

.muted {
    color: var(--muted);
}

.cta {
    display: inline-block;
    margin-top: 10px;
    background: var(--brand);
    color: white;
    padding: 10px 14px;
    border-radius: 10px;
    text-decoration: none;
}

.close {
    position: absolute;
    top: 8px;
    right: 8px;
    background: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 18px;
}

/* Bottom navigation — a row of individual gray circles floating directly on
   the page, no shared bar/strip behind them and no text labels. */
.bottom-nav {
    /* Fixed to the true viewport bottom (not the old negative-offset hack,
       which pushed the bar past the edge by --tab-offset and relied on that
       exactly canceling out extra bottom padding — brittle across different
       safe-area insets). A flat 16px + the real safe-area inset lifts the
       row a bit off the very edge the same way on every device. */
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 14px;
    padding: 6px 10px calc(16px + var(--safe-bottom));
    background: none;
    border-top: 0;
}

.nav-item {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--muted);
    text-align: center;
    padding: 4px 0;
    flex: 0 0 auto;
}

.nav-item .nav-icon {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 50px;
    height: 50px;
    margin: 0 auto;
    border-radius: 50%;
    background: #3a3a3c;
    /* Shop/Anirae+'s icon is intentionally bigger than this circle (see
       below) and meant to spill past its edge rather than get clipped —
       everything else stays smaller than the circle so this is a no-op
       for them. */
    overflow: visible;
    transition: transform 0.2s ease, background 0.2s ease;
}

/* One uniform size + white tint for the whole icon set (home / shop /
   Anirae+). The old per-icon 24/60px overrides made them look mismatched. */
/* Bottom-nav icons (home/shop/plus), native colours (keeps the shop's red
   star). Cropped SVGs render evenly at one size — kept small so the random
   button stands out as the emphasised centre. */
.nav-icon-img {
    width: 21px;
    height: 21px;
    display: inline-block;
    vertical-align: middle;
}


/* Random = the emphasised centre button: notably larger circle + glyph so it
   reads as the primary action against the smaller, uniform side icons. */
.nav-item .nav-icon-random {
    width: 66px;
    height: 66px;
}
.nav-icon-random svg {
    width: 42px;
    height: 42px;
}

.nav-item .nav-label {
    display: none;
}

/* Admin entry (profile, admins only) — styled by .profile-gear; this only
   controls its admins-only visibility. */
.admin-btn.hidden { display: none; }

/* Stays enlarged for as long as this tab is the active one — not just a
   transient tap flash — since setupBottomNav() (main.js) keeps .active on
   exactly one button until another is pressed. */
.nav-item.active .nav-icon {
    background: #55555a;
    transform: scale(1.14);
}

.nav-profile-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 38px;
    line-height: 1;
    width: 46px;
    height: 46px;
    margin: 0 auto;
}

/* Avatar fills almost the whole 44px chip (2px ring of the grey circle left
   showing around it) so the profile photo reads clearly. */
.nav-profile-icon img {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.nav-item.active .nav-profile-icon img {
    outline: 2px solid #fff;
    outline-offset: 1px;
}

/* Categories sheet */
.categories-sheet.hidden {
    display: none;
}

.categories-sheet {
    position: fixed;
    inset: 0;
    z-index: 30;
    overscroll-behavior: contain;
}

.categories-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px) saturate(120%);
}

.categories-panel {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-rows: 1fr auto;
    padding: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 16px) 16px calc(28px + var(--safe-bottom));
}

.categories-list {
    list-style: none;
    margin: 0;
    padding: 0 6px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
}

.categories-list li {
    font-size: 20px;
    color: rgba(255, 255, 255, 0.9);
    padding: 14px 6px;
}

.categories-list li.muted {
    color: rgba(255, 255, 255, 0.6);
}

.categories-close {
    justify-self: center;
    appearance: none;
    border: 0;
    background: #ffffff;
    color: #000;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    font-size: 22px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

@media (min-width: 768px) {
    .categories-list li {
        font-size: 22px;
    }
}

/* ── Top 10 row ── */
.top10-track {
    display: flex;
    align-items: flex-end;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 8px 16px 12px 4px;
    gap: 16px;
}

.top10-track::-webkit-scrollbar { display: none; }

/* card = [number][poster] in a row, poster overlaps number on its left */
.top10-card {
    display: flex;
    align-items: flex-end;
    flex-shrink: 0;
    scroll-snap-align: start;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

/* big number on the LEFT */
.top10-num {
    flex-shrink: 0;
    font-size: 28vw;
    font-weight: 900;
    line-height: 0.85;
    text-align: left;
    color: transparent;
    -webkit-text-stroke: 2px rgba(255,255,255,0.9);
    letter-spacing: -2px;
    z-index: 0;
    user-select: none;
    align-self: flex-end;
    padding-bottom: 0;
}

/* poster on the RIGHT, pulls left to overlap the number */
.top10-poster {
    flex-shrink: 0;
    width: 26vw;
    height: 38vw;
    margin-left: -4vw;
    margin-right: 0;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: -3px 4px 14px rgba(0,0,0,0.7);
    border-bottom: 3px solid var(--brand);
    z-index: 1;
    position: relative;
}

.top10-poster img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

@media (min-width: 768px) {
    .top10-num  { width: 70px; font-size: 100px; }
    .top10-poster { width: 130px; height: 190px; margin-left: -36px; }
}

/* ── Рекомендации ── */
.recommend-track {
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 4px 16px 12px 4px;
    gap: 10px;
}

.recommend-track::-webkit-scrollbar { display: none; }

.recommend-card {
    flex-shrink: 0;
    scroll-snap-align: start;
    width: 26vw;
    height: 38vw;
    border-radius: 8px;
    overflow: hidden;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    box-shadow: 2px 4px 12px rgba(0,0,0,0.6);
}

.recommend-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

/* Empty-state placeholder: a real-card-sized hollow poster frame (profile
   sections show these until actual posters land there). */
.recommend-card.poster-ghost {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.10);
    box-shadow: none;
}

/* Continue-watching card: poster + a progress bar of the unfinished episode
   (clipped to the card's rounded corners by the card's overflow:hidden).
   Deliberately larger than the regular poster cards (~1.3x) — the "keep
   watching" row is the primary action, so it reads bigger on both the home
   and the profile. Keeps the poster aspect ratio (38/26). */
.continue-card {
    position: relative;
    width: 34vw;
    height: 50vw;
}
.continue-progress {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 4px;
    background: rgba(255, 255, 255, 0.28);
}
.continue-progress i { display: block; height: 100%; background: var(--brand); }

/* Centred play icon — same liquid-glass circle as the anime page episodes. */
.continue-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.continue-play .play-circle {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: rgba(25, 25, 25, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.25);
    -webkit-backdrop-filter: blur(10px) saturate(150%);
    backdrop-filter: blur(10px) saturate(150%);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.15);
    display: flex;
    align-items: center;
    justify-content: center;
}
.continue-play .play-circle svg { width: 20px; height: 20px; margin-left: 2px; display: block; }

@media (min-width: 768px) {
    .recommend-card { width: 130px; height: 190px; }
    .continue-card { width: 170px; height: 248px; }
}

/* Netflix-style tap transition, built by playPosterExpandNav() (img-util.js):
   a cloned poster image, sized/positioned exactly over the tapped card, that
   grows edge-to-edge (cropping, like object-fit: cover) with a light blur
   right before navigating to anime.html. transform+filter on one small node
   — cheap on GPU, unlike a continuous full-screen backdrop-filter blur. */
/* Press feedback: a poster card dips in a touch while a finger is held on it.
   Transition on the base class so it eases both in (press) and back (release). */
.poster-pressable {
    transition: transform 130ms ease-out;
}
.poster-pressable.poster-pressed {
    transform: scale(0.94);
}

/* The dark rectangle that springs open from a tapped card to fill the whole
   screen, then hands off to the anime page's loading skeleton. Solid colour
   (the page background), so it can scale non-uniformly to every edge without
   any image to distort. Scales from its centre (default origin). */
.poster-expand-clone {
    position: fixed;
    overflow: hidden;
    z-index: 9999;
    pointer-events: none;
    background: #0f0f0f;
    /* Fallback grow (the WAAPI dip-spring in img-util.js drives it where
       supported). Duration matches POSTER_EXPAND_MS. */
    transition: transform 430ms cubic-bezier(0.16, 1, 0.3, 1),
                border-radius 430ms ease-out;
    will-change: transform;
}

/* Sits behind .poster-expand-clone and blurs + dims the grid as the rect
   springs open over it, for depth. One-shot (~0.4s on tap), not the continuous
   scroll-time blur removed earlier for heat. */
.poster-expand-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9998;
    pointer-events: none;
    background: rgba(8, 8, 10, 0.55);
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    opacity: 0;
    transition: opacity 380ms ease;
}

/* The anime detail page opens as a full-screen layer (an iframe) OVER the
   current page instead of navigating to it. The page underneath stays alive,
   so Back just removes this layer — instant, same scroll — and the close
   animation can shrink it back into the poster it came from. */
#animeOverlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: #0f0f0f;
    opacity: 0;
    pointer-events: none;
    will-change: transform, opacity;
}
#animeOverlay.shown {
    opacity: 1;
    pointer-events: auto;
}
#animeOverlay iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
    background: #0f0f0f;
}

/* Fade-to-black overlay used by the slide-up transition (playSlideUpNav) so
   the screen goes black right as it cuts over to the anime page. */
.poster-expand-blackout {
    position: fixed;
    inset: 0;
    background: #000;
    z-index: 10000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 110ms ease-in;
}

/* "Page slides up" transition for the hero poster / Top 10 cards, built by
   playSlideUpNav() (img-util.js): a solid full-screen sheet rising from
   below, as if the anime page itself is arriving from the bottom edge. */
.page-slideup-sheet {
    position: fixed;
    inset: 0;
    background: var(--bg, #0f0f0f);
    z-index: 10000;
    pointer-events: none;
    transform: translateY(100%);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4);
    transition: transform 650ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
}

.page-slideup-sheet.visible {
    transform: translateY(0);
}

/* The current screen recedes slightly (shrinks) while fading all the way to
   black, like Netflix's own version of this transition — instead of sitting
   perfectly still (or just dimly tinted) underneath the rising sheet. */
#app.page-recede {
    transition: transform 650ms cubic-bezier(0.4, 0, 0.2, 1), filter 650ms ease-out;
    transform: scale(0.94);
    filter: brightness(0);
}

/* prevent background scroll while sheet is open */
html.lock-scroll,
body.lock-scroll {
    overflow: hidden !important;
    height: 100%;
}

/* ── Profile page ── */
.profile-page {
    position: fixed;
    inset: 0;
    /* Scrolls the full height (not cut short above the nav) so the last
       section bleeds through the nav's own transparent background instead
       of stopping dead into a flat, contentless gap — matches how the home
       page's .content behaves. The nav-clearance instead lives as bottom
       padding on .profile-content, below. */
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    /* Fullscreen fixed overlay — never chain its scroll to the document
       behind it. Without this, a pan that reaches the top/bottom edge can get
       claimed by the (unscrollable) page rubber-band and the gesture dies
       until the finger restarts. */
    overscroll-behavior-y: contain;
    /* This is its own fixed scroll container, so the global body/html
       scrollbar-hiding doesn't reach it — hide its scrollbar here too. */
    scrollbar-width: none;
    -ms-overflow-style: none;
    background: var(--bg);
    z-index: 5;
    padding-top: 0; /* the hero header goes full-bleed to the top */
}

.profile-page::-webkit-scrollbar { width: 0; height: 0; }

.profile-page.hidden { display: none; }

.plus-page-wrap {
    position: fixed;
    /* Scrolls the full height (not cut short above the nav) so content
       bleeds through the nav's own transparent background instead of the
       page stopping dead into a flat black gap above it — same fix as the
       profile page's identical clipping bug (see .profile-page). */
    inset: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    background: var(--bg);
    z-index: 5;
}

.plus-page-wrap::-webkit-scrollbar { width: 0; height: 0; }

.plus-page-wrap.hidden { display: none; }

/* Anirae+'s content is fully static (fits without scrolling, CTA pinned to
   the bottom) — no reason to allow scroll/bounce on it. Scoped to this page
   only; Shop reuses .plus-page-wrap too and still needs to scroll. */
#plusPage {
    overflow: hidden;
}

/* ── Profile hero header ── */
.profile-hero {
    position: relative;
    width: 100%;
    /* The fixed .page-topbar above sits at this same safe-top + tg-ui-top
       band — the avatar block starts right below it, at the same height
       the settings gear (also absolutely positioned) sits at. */
    padding-top: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 6px);
    overflow: hidden;
}
.profile-hero-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    /* Empty for now — the uploaded photo lands here (background-image from JS). */
}
.profile-hero-actions {
    position: absolute;
    top: calc(var(--safe-top) + var(--tg-ui-top, 52px) + 6px);
    right: 14px;
    display: flex;
    gap: 10px;
    z-index: 3;
}
.profile-gear {
    width: 38px;
    height: 38px;
    margin: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(0, 0, 0, 0.38);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: #fff;
    cursor: pointer;
    padding: 0;
}
.profile-gear:active { transform: scale(0.92); }
.profile-gear svg { width: 19px; height: 19px; }

.profile-hero-info {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 20px 10px;
}
.profile-avatar-wrap {
    position: relative; /* anchors the edit button below */
    flex-shrink: 0;
    width: 88px;
    height: 88px;
    border-radius: 50%;
    padding: 2px;
    background: var(--brand); /* thin solid red ring, no glow */
}

/* Change-avatar affordance: sits on the avatar's bottom-right corner and
   reopens the same picker used on first run. Bordered with the page bg so it
   reads as a separate chip against the photo. */
.profile-avatar-edit {
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 30px;
    height: 30px;
    padding: 0;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 3px solid var(--bg);
    background: var(--brand);
    color: #fff;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.profile-avatar-edit:active {
    transform: scale(0.9);
}

.profile-avatar-edit svg {
    width: 14px;
    height: 14px;
}
.profile-avatar {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    border: 3px solid var(--bg);
    background: #2a2a2a;
}
.profile-meta {
    flex: 1;
    min-width: 0;
    /* The info row sits at the same height as the gear button — keep the name
       from running underneath it. */
    padding-right: 44px;
}
/* Admins see a second circle (shield) — clear both buttons. */
.profile-hero:has(.admin-btn:not(.hidden)) .profile-meta { padding-right: 92px; }
.profile-name {
    font-size: 19px;
    font-weight: 700;
    color: #fff;
    letter-spacing: -0.2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.profile-level { margin-top: 6px; }
.profile-level-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--brand);
}
.profile-level-label b { color: #fff; font-weight: 600; }
.profile-xp-bar {
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.16);
    overflow: hidden;
    margin: 6px 0 5px;
    max-width: 150px; /* the level bar is short, not full-width */
}
.profile-xp-bar i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: linear-gradient(90deg, var(--brand), #ff5964);
}
.profile-xp-text { font-size: 11px; color: var(--muted); }
.profile-xp-text b { color: var(--brand); font-weight: 600; }

.profile-sub {
    font-size: 13px;
    color: var(--muted);
}

.profile-content {
    /* Bottom padding clears the floating (transparent-background) nav bar —
       matches .content's pattern on the home page, so the last section
       scrolls up behind the nav instead of the page stopping short of it. */
    padding: 10px 0 calc(100px + var(--safe-bottom));
}

.profile-section {
    margin-bottom: 8px;
}

/* Profile rows line up with the section title's 16px left edge (the shared
   .recommend-track only has 4px there) — applies to ghost placeholders and
   real poster rows alike, so everything sits flush. scroll-padding-left keeps
   that 16px if snap ever returns here.
   scroll-snap-type: none — the profile scrolls in its OWN fixed container
   (not the document, like the home page does), and WebKit has a gesture-
   arbitration bug with a mandatory-snap horizontal scroller nested inside a
   non-root vertical scroller: a slow vertical pan that starts on a row gets
   eaten by the row's snap logic, so the page sticks dead until the finger
   restarts. Fast flicks lock the vertical axis before snap claims the touch,
   which is why only slow scrolling stalled. */
.profile-section .recommend-track {
    padding-left: 16px;
    scroll-padding-left: 16px;
    scroll-snap-type: none;
}

.profile-section-title {
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    margin: 0 16px 10px;
    padding-top: 8px;
}

/* ── Anirae+ subscription page ── */
.plus-page {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* .plus-page-wrap (the fixed, nav-clearing scroll container) has a
       definite height — filling it lets .plus-cta's margin-top:auto push
       the button all the way down to sit right above the bottom nav. */
    min-height: 100%;
}

/* Ambient premium glows behind the content */
.plus-glow {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    z-index: 0;
    filter: blur(60px);
}
.plus-glow-red {
    top: 260px;
    left: 30%;
    width: 440px;
    height: 440px;
    transform: translateX(-50%);
    background: radial-gradient(circle, rgba(229, 9, 20, 0.5) 0%, rgba(229, 9, 20, 0) 70%);
}
/* CTA — same pill size/shape as the home hero's Смотреть/Буду смотреть
   (.hero-glass-btn: 138x42, radius:999px), just solid white/black instead
   of dark glass. Pinned to the bottom of .plus-page (absolute, not
   flex margin-top:auto — that fought the percentage min-height above in a
   way that left it floating short of the bottom), right above the nav. */
.plus-cta {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(100px + var(--safe-bottom));
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 0 16px;
}
.plus-btn {
    width: 138px;
    height: 42px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: 999px;
    border: 1px solid #fff;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    color: #000;
    cursor: pointer;
    background: #fff;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    transition: transform 0.15s ease, background 0.2s ease;
}
.plus-btn:active { transform: scale(0.92); background: #e5e5e5; }
.plus-btn:disabled { opacity: 0.6; }

/* Plan picker */
.plus-plans {
    width: 100%;
    max-width: 360px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 4px;
}

.plus-plans-title {
    margin: 0 4px 6px;
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.plan-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    background: rgba(255, 255, 255, 0.05);
    border: 1.5px solid rgba(255, 255, 255, 0.1);
    border-radius: 14px;
    padding: 14px 16px;
    text-align: left;
    color: #fff;
    font-family: inherit;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.plan-card.selected {
    background: rgba(229, 9, 20, 0.12);
    border-color: var(--brand);
}

.plan-radio {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.3);
    transition: border-color 0.2s ease, background 0.2s ease;
}

.plan-card.selected .plan-radio {
    border-color: var(--brand);
    background: var(--brand);
    box-shadow: inset 0 0 0 3px #0f0f0f, inset 0 0 0 5px var(--brand);
}

.plan-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.plan-name {
    font-size: 16px;
    font-weight: 600;
}

.plan-permonth {
    font-size: 13px;
    color: var(--muted);
}

.plan-total {
    font-size: 17px;
    font-weight: 700;
    color: #fff;
    flex-shrink: 0;
}

.plan-badge {
    position: absolute;
    top: -10px;
    right: 14px;
    background: var(--brand);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.plan-badge-best {
    background: #ffd700;
    color: #1a1a1a;
}