/* ==========================================================================
   Ragnarok Idol 2026 — ประกาศรายชื่อผู้ประกวด (announce.html)
   Layers on top of style.css + landing-responsive.css; only the pieces this
   page adds live here (hero nav, vote-round tabs, round intro + reward,
   and the Female / Male contestant panels).
   ========================================================================== */

/* ---------------------------------- HERO -------------------------------
   A short key-visual band instead of index.html's full-screen hero: the
   logo + title sit on the left, the character art fills the right. Clipped
   so the 2000px-wide character art can't spill into the section below. */
.announce-page .hero {
    height: clamp(460px, 43vw, 880px);
    /* landing-responsive.css gives the tablet hero a 680px min-height because
     index.html needs a tall stage there. That min-height beat the height
     above and left a bare band of bg-hero under the character art, which
     is sized off the viewport width. Drop it so the band stays 43vw. */
    min-height: 0;
    overflow: hidden;
    z-index: 3; /* above .mid (z-index 2), which is pulled up under the hero */
}
/* the art has to stay taller than the hero band (43vw) so it always covers
   it: width / 1.777 >= 43vw means the width can never drop below ~77vw. */
.announce-page .hero__idol {
    left: 68%;
    top: 0;
    width: max(980px, 82vw);
}

.ann-hero__content {
    position: absolute;
    left: 2%;
    /* anchored by its top edge, not centred: the block's height changes with
     the logo size, so a centred anchor pushed the logo off the top of the
     hero at the shorter (clamped) heights. */
    top: 20%;
    z-index: 6;
    width: min(560px, 32%);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.55));
}

.ann-hero__logo-wrap {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
}
    /* the shared .hero__logo-glow is sized for index's much larger logo */
    .ann-hero__logo-wrap .hero__logo-glow {
        width: 130%;
        height: 110%;
        left: -15%;
    }

.ann-hero__logo {
    position: relative;
    z-index: 1;
    width: 100%;
    height: auto;
    display: block;
}

.ann-hero__title {
    margin: 6px 0 0;
    color: var(--White, white);
    font-family: var(--font-th);
    font-size: clamp(26px, 2.4vw, 44px);
    font-weight: 700;
    line-height: 1.2;
    /* thicker dark stroke + a tight black shadow under the glow, so the
     title reads against the busy key visual instead of sinking into it */
    -webkit-text-stroke: 6px #0b2455;
    paint-order: stroke fill;
    text-shadow: 0 0 16px rgba(70, 165, 255, 0.95), 0 0 34px rgba(70, 165, 255, 0.6), 0 3px 0 rgba(11, 36, 85, 0.95), 0 5px 12px rgba(0, 0, 0, 0.75);
}

.ann-hero__sub {
    margin: 10px 0 0;
    padding: 5px 16px;
    border-radius: 999px;
    background: rgba(9, 23, 54, 0.55);
    color: #fff;
    font-family: var(--font-th);
    font-size: clamp(12px, 0.95vw, 18px);
    font-weight: 600;
    line-height: 1.5;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.9);
    /* one line — the block's width is set by the logo, so let this run wider
     than it and stay centred on the logo rather than wrapping */
    white-space: nowrap;
}

/* ------------------------------ SECTION SHELL -------------------------- */
/* The wave now lives in the hero, so .mid no longer needs to be pulled up
   under it — and its two absolutely-positioned decoration layers
   (bubble.png / animals.png) are taller than this page's content, which
   would otherwise stretch the document's scrollable area into a tall band
   of empty background below the last section. */
.announce-page .mid {
    top: 0;
    margin-top: -180px;
    padding-top: 0;
    /* ปล่อยให้ล้นได้ เพื่อให้คลื่นคาดหัว section โผล่ขึ้นไปคร่อมรอยต่อ hero/mid ได้
       (z-index สู้ overflow ไม่ได้ ต้องเลิก clip ที่ตัวนี้อย่างเดียว)
       ของเดิมที่ clip ไว้ก็เพื่อกันเลเยอร์ฟอง/สัตว์น้ำยืดหน้าเว็บ ซึ่งย้ายไป
       clip ที่ .mid__critters แทนแล้ว ได้ขอบเขตเท่ากันเป๊ะเพราะมัน inset: 0 */
    overflow: visible;
    z-index: 9;
}

.announce-page .mid__critters {
    overflow: hidden;
}

/* ---- คลื่นคาดหัว .mid ปิดรอยต่อ hero / mid ----
   ขึ้นเฉพาะรอบประกาศผู้ชนะ เพราะรอบนั้นเปลี่ยนพื้นหลังเป็น bg-winner.png
   ซึ่งขอบบนเป็นเส้นตรง ส่วนรอบอื่นใช้ bg-body-content.png ที่มีคลื่นอยู่ใน
   ภาพอยู่แล้ว ถ้าใส่ทุกรอบจะกลายเป็นคลื่นซ้อนกันสองชั้น
   (ใช้คลาสเดียวกับที่สลับพื้นหลัง เงื่อนไขจะได้ไม่หลุดจากกัน)

   top: 0 = ขอบบนของ .mid ซึ่งก็คือรอยต่อที่ตาเห็น แล้วยกขึ้นไปคร่อมด้วย
   translateY ที่เป็น % ของตัวภาพเอง จึงเลื่อนถูกสัดส่วนทุกความกว้างจอ
   ส่วนที่ล้นขึ้นไปเหนือรอยต่อโผล่ได้เพราะ .announce-page .mid ตั้ง
   overflow: visible ไว้ (ย้ายการ clip ไปที่ .mid__critters แทน) */
.announce-page .mid__wave--top {
    display: none;
}

body.is-winner-round .mid__wave--top {
    display: block;
    top: 0;
    z-index: 8;
    transform: translateY(-40%);
}

.roster {
    width: 1920px;
    box-sizing: border-box;
    padding: 280px 260px 140px;
    position: relative;
    scroll-margin-top: 60px;
}

.roster__inner {
    width: 100%;
    /* the whole section — round intro and contestant panels alike — is capped
     here, so narrowing this one value keeps both blocks the same width */
    max-width: 1160px;
    margin-inline: auto;
}

/* ---------------------- vote-round tabs (3 buttons) --------------------
   Same button art as the contest-detail tabs on index.html (.detail__tab). */
.roster__tabs {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 20px;
    flex-wrap: wrap;
}

.roster__tab {
    appearance: none;
    border: none;
    cursor: pointer;
    width: 250px;
    height: 64px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    background: url("../images/button-tab.png") center / 100% 100% no-repeat;
    color: var(--White, white);
    font-family: var(--font-th);
    transition: transform 0.15s ease, filter 0.15s ease;
}

.roster__tab-stage {
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 1.4px;
    opacity: 0.8;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}

.roster__tab-name {
    font-family: var(--font-kanit);
    font-size: 19px;
    font-style: italic;
    font-weight: 700;
    letter-spacing: 0.4px;
    line-height: 1.1;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.45);
}

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

.roster__tab.is-active {
    background-image: url("../images/button-tab-active.png");
    width: 268px;
    height: 80px;
    filter: drop-shadow(0 0 14px rgba(255, 205, 100, 0.55));
}

    .roster__tab.is-active .roster__tab-stage {
        opacity: 0.95;
        font-size: 12px;
    }

    .roster__tab.is-active .roster__tab-name {
        font-size: 22px;
    }

/* ==========================================================================
   ROUND HEADLINE (.vote-head) — big date + copy, sits between the tabs and
   the contestant panels.
   ========================================================================== */
.roster__head {
    position: relative;
    z-index: 5;
}

.vote-head {
    margin-top: 46px;
    text-align: center;
}

.vote-head__date {
    color: var(--White, white);
    font-family: var(--font-kanit);
    font-size: clamp(34px, 3.4vw, 58px);
    font-style: italic;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: 0.5px;
    -webkit-text-stroke: 4px #0f2f7a;
    paint-order: stroke fill;
    text-shadow: 0 0 18px rgba(110, 255, 255, 0.95), 0 0 38px rgba(70, 165, 255, 0.7), 0 4px 6px rgba(0, 0, 0, 0.5);
}

.vote-head__lead {
    margin-top: 10px;
    color: #fff;
    font-family: var(--font-th);
    font-size: clamp(16px, 1.35vw, 22px);
    font-weight: 700;
    line-height: 1.55;
    text-shadow: 0 2px 8px rgba(4, 20, 60, 0.85), 0 0 16px rgba(9, 23, 54, 0.7);
}

.vote-head__highlight {
    display: inline-block;
    margin-top: 18px;
    padding: 12px 34px;
    border: 2px solid var(--cyan);
    border-radius: 18px;
    background: rgba(9, 23, 54, 0.72);
    box-shadow: 0 0 22px rgba(110, 255, 255, 0.45), inset 0 0 18px rgba(110, 255, 255, 0.12);
}

.vote-head__highlight-line {
    color: var(--cyan);
    font-family: var(--font-th);
    font-size: clamp(15px, 1.25vw, 20px);
    font-weight: 700;
    line-height: 1.5;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
}

/* ---------------------- round details (rules + rewards) ---------------- */
.vote-intro {
    margin-top: 46px;
}

.vote-intro__body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
}
/* The copy fills the row and the badge sits flush right, so this block lines
   up with the contestant panels above it — both live in the same
   .roster__inner cap. */
.vote-intro__copy {
    flex: 1 1 auto;
    min-width: 0;
}


/* ---- เงื่อนไขการโหวต ---- */
.vote-terms {
    margin-top: 22px;
}

.vote-terms__title {
    margin: 0 0 10px;
    color: var(--cyan);
    font-family: var(--font-th);
    font-size: 18px;
    font-weight: 700;
    text-shadow: 0 0 10px rgba(110, 255, 255, 0.5);
}

.vote-terms__line {
    color: rgba(255, 255, 255, 0.9);
    font-family: var(--font-th);
    font-size: 15px;
    font-weight: 200;
    line-height: 1.7;
}

.vote-terms__line--sub {
    padding-left: 18px;
    color: rgba(255, 255, 255, 0.78);
    font-size: 14px;
}

/* ---- ของรางวัลสำหรับผู้เข้าร่วมโหวต ---- */
.vote-prizes {
    margin-top: 24px;
}

.vote-prizes__title {
    margin: 0 0 10px;
    color: var(--cyan);
    font-family: var(--font-th);
    font-size: 18px;
    font-weight: 700;
    text-shadow: 0 0 10px rgba(110, 255, 255, 0.5);
}

.vote-prizes__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.prize-box {
    padding: 14px 18px;
    box-sizing: border-box;
    border: 1px solid rgba(110, 255, 255, 0.45);
    border-radius: 14px;
    background: rgba(9, 23, 54, 0.55);
}

.prize-box__title {
    margin-bottom: 6px;
    color: var(--White, white);
    font-family: var(--font-th);
    font-size: 15px;
    font-weight: 700;
}

.prize-box__line {
    color: rgba(255, 255, 255, 0.85);
    font-family: var(--font-th);
    font-size: 14px;
    font-weight: 200;
    line-height: 1.6;
}

.vote-prizes__note {
    margin: 12px 0 0;
    color: rgba(255, 255, 255, 0.7);
    font-family: var(--font-th);
    font-size: 13px;
    font-weight: 200;
    line-height: 1.6;
}
/* ---- voter reward: one ready-made badge image (images/announce/) ---- */
.vote-reward {
    flex: 0 0 auto;
    width: 270px;
    margin: 0;
}

.vote-reward__badge {
    display: block;
    width: 100%;
    height: auto;
    filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.35));
}

/* ------------------------- contestant panels --------------------------- */
.roster__panels {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 34px;
    margin-top: 70px;
}

.idol-panel {
    position: relative;
    padding: 40px 22px 28px;
    box-sizing: border-box;
    border-radius: 26px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}

.idol-panel--female {
    background: linear-gradient(180deg, #c9a6f2 0%, #f39ad8 100%);
}

.idol-panel--male {
    background: linear-gradient(180deg, #8fa9f6 0%, #ab9cf2 100%);
}

/* faint dot texture, like the mockup's panel background */
.idol-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 26px;
    background-image: radial-gradient(rgba(255, 255, 255, 0.35) 1.5px, transparent 1.6px);
    background-size: 14px 14px;
    opacity: 0.5;
    pointer-events: none;
}

.idol-panel > * {
    position: relative;
    z-index: 1;
}

.idol-panel__title {
    position: absolute;
    left: 20px;
    top: -40px;
    z-index: 2;
    margin: 0;
    padding: 10px 30px;
    border-radius: 16px;
    color: #fff;
    font-family: var(--font-th);
    font-size: 24px;
    font-weight: 700;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

.idol-panel--female .idol-panel__title {
    background: linear-gradient(135deg, #d3a3ef, #b98ce8);
    /* box-shadow: 0 6px 16px rgba(120, 60, 160, 0.35); */
}

.idol-panel--male .idol-panel__title {
    background: linear-gradient(135deg, #7f9bf3, #6f8ae8);
    /* box-shadow: 0 6px 16px rgba(50, 80, 180, 0.35); */
}

/* white board that holds the cards */
.idol-panel__board {
    padding: 16px;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.9);
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.9), 0 4px 14px rgba(0, 0, 0, 0.12);
}

.idol-panel__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    justify-items: center;
    gap: 18px 16px;
}

.idol-panel__empty {
    padding: 40px 10px;
    color: #4a5a99;
    font-family: var(--font-th);
    font-size: 16px;
    text-align: center;
}

/* ---- one contestant ----
   The artwork in assets/images/idol/ is a finished 1:1 card: photo, star
   frame, name and the "ผลงาน" label are all baked in. So the markup is just
   the image, and the whole thing is the link — everything below is the
   sparkle/glow treatment layered on top of it. */
.idol-card {
    position: relative;
    display: block;
    width: 100%;
    /* the card art is 236px square — cap the cell below that so it is always
     scaled down (never upscaled and soft) and the panel stays compact */
    max-width: 196px;
    aspect-ratio: 1 / 1;
    border-radius: 14px;
    text-decoration: none;
    animation: idolCardIn 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
    transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.25s ease;
    filter: drop-shadow(0 3px 8px rgba(60, 40, 120, 0.28));
}

    .idol-card:hover,
    .idol-card:focus-visible {
        transform: translateY(-6px) scale(1.035) rotate(-0.6deg);
        filter: drop-shadow(0 10px 20px rgba(60, 40, 120, 0.38)) drop-shadow(0 0 16px rgba(255, 180, 240, 0.85));
        outline: none;
    }

.idol-card--disabled {
    cursor: default;
}

.idol-card__photo {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    border-radius: 14px;
}
    /* no photo supplied yet — show the event logo, centred and dimmed */
    .idol-card__photo.is-placeholder {
        object-fit: contain;
        padding: 16%;
        box-sizing: border-box;
        background: linear-gradient(160deg, #e8d5f8, #cfe3fb);
        opacity: 0.6;
    }

/* soft aura that breathes behind the card, and brightens on hover */
.idol-card__glow {
    position: absolute;
    inset: -8%;
    z-index: 0;
    border-radius: 24px;
    background: radial-gradient(circle at 50% 50%, rgba(255, 190, 245, 0.65) 0%, rgba(180, 220, 255, 0.35) 45%, rgba(255, 255, 255, 0) 72%);
    opacity: 0.45;
    pointer-events: none;
    animation: idolAura 3.6s ease-in-out infinite alternate;
}

.idol-card:hover .idol-card__glow,
.idol-card:focus-visible .idol-card__glow {
    opacity: 0.95;
}

/* diagonal shine that sweeps across the photo on hover */
.idol-card__sheen {
    position: absolute;
    inset: 0;
    z-index: 2;
    overflow: hidden;
    border-radius: 14px;
    pointer-events: none;
}

    .idol-card__sheen::before {
        content: "";
        position: absolute;
        top: -60%;
        left: -75%;
        width: 45%;
        height: 220%;
        transform: rotate(18deg) translateX(0);
        background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.75) 50%, rgba(255, 255, 255, 0) 100%);
        opacity: 0;
    }

.idol-card:hover .idol-card__sheen::before,
.idol-card:focus-visible .idol-card__sheen::before {
    animation: idolSheen 0.85s ease-out;
}

/* four-point twinkles drifting around the card */
.idol-card__sparkles {
    position: absolute;
    inset: -6%;
    z-index: 3;
    pointer-events: none;
}

    .idol-card__sparkles i {
        position: absolute;
        display: block;
        background: linear-gradient(140deg, #ffffff 0%, #ffe6fb 45%, #b8ecff 100%);
        clip-path: polygon(50% 0%, 58% 42%, 100% 50%, 58% 58%, 50% 100%, 42% 58%, 0% 50%, 42% 42%);
        opacity: 0;
        filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.9));
        animation: idolTwinkle 2.8s ease-in-out infinite;
    }

        .idol-card__sparkles i:nth-child(1) {
            width: 18px;
            height: 18px;
            left: 4%;
            top: 8%;
            animation-delay: 0s;
        }

        .idol-card__sparkles i:nth-child(2) {
            width: 12px;
            height: 12px;
            right: 6%;
            top: 22%;
            animation-delay: 0.6s;
        }

        .idol-card__sparkles i:nth-child(3) {
            width: 15px;
            height: 15px;
            right: 2%;
            bottom: 20%;
            animation-delay: 1.2s;
        }

        .idol-card__sparkles i:nth-child(4) {
            width: 10px;
            height: 10px;
            left: 12%;
            bottom: 8%;
            animation-delay: 1.8s;
        }
/* hover makes them all pop brighter and faster */
.idol-card:hover .idol-card__sparkles i,
.idol-card:focus-visible .idol-card__sparkles i {
    animation-duration: 1.2s;
    filter: drop-shadow(0 0 7px rgba(255, 255, 255, 1));
}

@keyframes idolCardIn {
    from {
        opacity: 0;
        transform: translateY(18px) scale(0.94);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes idolAura {
    from {
        transform: scale(0.94);
    }

    to {
        transform: scale(1.06);
    }
}

@keyframes idolSheen {
    from {
        transform: rotate(18deg) translateX(0);
        opacity: 0;
    }

    25% {
        opacity: 1;
    }

    to {
        transform: rotate(18deg) translateX(420%);
        opacity: 0;
    }
}

@keyframes idolTwinkle {
    0%, 100% {
        opacity: 0;
        transform: scale(0.4) rotate(0deg);
    }

    45% {
        opacity: 1;
        transform: scale(1) rotate(45deg);
    }

    70% {
        opacity: 0.25;
        transform: scale(0.7) rotate(70deg);
    }
}

@media (prefers-reduced-motion: reduce) {
    .idol-card,
    .idol-card__glow,
    .idol-card__sparkles i {
        animation: none;
    }

    .idol-card__sparkles i {
        opacity: 0.75;
    }

    .idol-card:hover {
        transform: none;
    }
}

/* ---- "โหวตเลย !" button under each panel ---- */
.idol-panel__cta {
    display: flex;
    justify-content: center;
    margin-top: 20px;
}

.vote-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 210px;
    padding: 12px 40px;
    border: 3px solid #fff;
    border-radius: 999px;
    background: linear-gradient(180deg, #ffffff 0%, #f4e2fb 55%, #ffd6f2 100%);
    color: #3348b8;
    font-family: var(--font-kanit);
    font-size: 26px;
    font-style: italic;
    font-weight: 700;
    text-decoration: none;
    text-shadow: 0 2px 0 rgba(255, 255, 255, 0.9);
    box-shadow: 0 6px 16px rgba(80, 40, 140, 0.32), 0 0 18px rgba(255, 255, 255, 0.55);
    transition: transform 0.15s ease, filter 0.15s ease;
}

    .vote-btn:hover,
    .vote-btn:focus-visible {
        transform: translateY(-2px) scale(1.02);
        filter: brightness(1.05);
    }

.vote-btn--disabled {
    background: rgba(255, 255, 255, 0.55);
    color: #7d84b5;
    box-shadow: none;
    cursor: default;
}

    .vote-btn--disabled:hover {
        transform: none;
        filter: none;
    }


/* ==========================================================================
   RESPONSIVE — mirrors the breakpoints in landing-responsive.css

   NOTE on the hero/roster spacing: .announce-page .mid is pulled up under
   the hero (margin-top), and .roster's padding-top has to cover that pull
   plus the gap you actually want below the hero. Change them as a pair —
   a padding-top smaller than the pull hides the tabs behind the hero,
   which sits above .mid on z-index.
   ========================================================================== */

/* .viewport is a fixed 1920px canvas centred and cropped at these widths, so
   anything pinned by percentage drifts off the real window edges. Re-anchor
   the hero title block and the section gutters to the visible window. */
/* At and above 1920 the canvas stops growing (.viewport is a fixed 1920px,
   centred), so vw units would keep scaling the art past the artboard. Pin
   the same 43% / 82% proportions to that fixed width instead. */
@media (min-width: 1920px) {
    .announce-page .hero {
        height: 826px;
    }

    .announce-page .hero__idol {
        width: 1574px;
        left: 68%;
    }
}

@media (min-width: 1400px) and (max-width: 1919px) {
    .ann-hero__content {
        left: calc((1920px - 100vw) / 2 + 60px);
    }

    .announce-page .hero__idol {
        left: calc((1920px - 100vw) / 2 + 68vw);
    }

    .roster {
        padding-left: calc((1920px - 100vw) / 2 + 40px);
        padding-right: calc((1920px - 100vw) / 2 + 40px);
    }
}

@media (min-width: 861px) and (max-width: 1399px) {
    /* .mid keeps the -180px pull from the base rule → 80px below the hero. */
    .roster {
        width: 100%;
        padding: 260px 30px 90px;
    }

    /* smaller key visual so it stops crowding the title block */
    .announce-page .hero__idol {
        width: max(900px, 84vw);
        left: 70%;
    }

    .ann-hero__content {
        left: 3%;
        width: min(360px, 34%);
    }

    .roster__tabs {
        gap: 12px;
    }

    .roster__tab {
        width: 186px;
        height: 52px;
    }

    .roster__tab-stage {
        font-size: 9px;
        letter-spacing: 1px;
    }

    .roster__tab-name {
        font-size: 15px;
    }

    .roster__tab.is-active {
        width: 198px;
        height: 60px;
    }

        .roster__tab.is-active .roster__tab-stage {
            font-size: 10px;
        }

        .roster__tab.is-active .roster__tab-name {
            font-size: 17px;
        }

    .vote-reward {
        width: 220px;
    }

    .vote-terms__title, .vote-prizes__title {
        font-size: 16px;
    }

    .vote-terms__line {
        font-size: 14px;
    }

    .vote-terms__line--sub {
        font-size: 13px;
    }

    .prize-box {
        padding: 12px 14px;
    }

    .prize-box__title {
        font-size: 14px;
    }

    .prize-box__line, .vote-prizes__note {
        font-size: 13px;
    }

    .roster__panels {
        gap: 24px;
        margin-top: 56px;
    }

    .idol-panel {
        padding: 36px 16px 24px;
    }

    .idol-panel__title {
        font-size: 19px;
        padding: 8px 22px;
        left: 16px;
        top: -18px;
    }

    .idol-panel__board {
        padding: 12px;
    }

    .idol-panel__grid {
        gap: 14px 12px;
    }

    .idol-card {
        max-width: 168px;
    }

    .vote-btn {
        min-width: 170px;
        padding: 10px 30px;
        font-size: 22px;
    }
}

@media (max-width: 860px) {
    /* Phones drop the character art (landing-responsive.css hides .hero__stage
     and swaps in hero-mb.png), so the title block flows in normal document
     order and the hero grows to fit it. With no fixed hero height to tuck
     .mid under, drop the pull entirely and space the tabs normally. */
    .announce-page .hero {
        height: auto;
        min-height: 380px;
    }

    .announce-page .mid {
        margin-top: -220px;
    }

    .roster {
        width: 100%;
        padding: 300px 16px 60px;
    }

    .ann-hero__content {
        position: relative;
        left: auto;
        top: auto;
        width: min(288px, 78vw);
        margin: 0 auto;
        padding: 170px 0 25px;
    }

    .ann-hero__sub {
        white-space: normal;
    }
    /* keep the bar the same height as the .page margin that reserves its band */
    .roidol-topbar {
        padding: 0 16px;
        gap: 18px;
    }

    .roidol-topbar__link {
        font-size: 13px;
    }

    .roster__tabs {
        gap: 8px;
    }

    .roster__tab {
        width: min(31vw, 124px);
        height: 48px;
    }

    .roster__tab-stage {
        font-size: 8px;
        letter-spacing: 0.6px;
    }

    .roster__tab-name {
        font-size: 13px;
    }

    .roster__tab.is-active {
        width: min(33vw, 132px);
        height: 54px;
    }

        .roster__tab.is-active .roster__tab-stage {
            font-size: 9px;
        }

        .roster__tab.is-active .roster__tab-name {
            font-size: 14px;
        }

    .vote-intro {
        margin-top: 30px;
    }

    .vote-intro__body {
        flex-direction: column;
        align-items: center;
        gap: 24px;
        margin-top: 24px;
    }
    /* the row layout stretches the copy; in a column that flex-grow is
     meaningless, so pin it back to its content width */
    .vote-intro__copy {
        flex: 0 1 auto;
        width: 100%;
        text-align: center;
    }

    .vote-reward {
        width: min(100%, 240px);
    }

    .vote-terms {
        margin-top: 18px;
        text-align: left;
    }

    .vote-terms__title, .vote-prizes__title {
        font-size: 15px;
    }

    .vote-terms__line {
        font-size: 13px;
    }

    .vote-terms__line--sub {
        font-size: 12px;
        padding-left: 14px;
    }

    .vote-prizes {
        margin-top: 18px;
        text-align: left;
    }

    .vote-prizes__grid {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    .prize-box {
        padding: 11px 13px;
    }

    .prize-box__title {
        font-size: 13px;
    }

    .prize-box__line {
        font-size: 12px;
    }

    .vote-prizes__note {
        font-size: 12px;
    }

    .idol-card__sparkles i:nth-child(1) {
        width: 13px;
        height: 13px;
    }

    .idol-card__sparkles i:nth-child(2) {
        width: 9px;
        height: 9px;
    }

    .idol-card__sparkles i:nth-child(3) {
        width: 11px;
        height: 11px;
    }

    .idol-card__sparkles i:nth-child(4) {
        width: 8px;
        height: 8px;
    }

    .roster__panels {
        grid-template-columns: 1fr;
        gap: 44px;
        margin-top: 50px;
    }

    .idol-panel {
        padding: 34px 12px 22px;
        border-radius: 20px;
    }

        .idol-panel::before {
            border-radius: 20px;
        }

    .idol-panel__title {
        font-size: 17px;
        padding: 7px 18px;
        left: 14px;
        top: -16px;
    }

    .idol-panel__board {
        padding: 10px;
        border-radius: 14px;
    }

    .idol-panel__grid {
        gap: 12px 10px;
    }

    .idol-card {
        max-width: 160px;
    }

    .vote-btn {
        min-width: 160px;
        padding: 9px 26px;
        font-size: 20px;
        border-width: 2px;
    }
}

@media (max-width: 480px) {
    /* Keep the pair in step with the 860px block: .mid is pulled up 220px
     under the hero, so .roster's padding-top must clear that pull before it
     adds any gap of its own — a smaller value hides the tabs and the round
     intro behind the hero, which sits above .mid on z-index. */
    .roster {
        padding: 280px 12px 50px;
    }

    .ann-hero__content {
        padding: 150px 0 22px;
    }

    .ann-hero__title {
        -webkit-text-stroke-width: 3px;
    }

    .roster__tabs {
        gap: 6px;
    }

    .roster__tab {
        width: min(31vw, 112px);
        height: 44px;
    }

    .roster__tab-name {
        font-size: 12px;
    }

    .roster__tab.is-active {
        width: min(33vw, 118px);
        height: 50px;
    }

        .roster__tab.is-active .roster__tab-name {
            font-size: 13px;
        }

    .vote-intro {
        margin-top: 22px;
    }

    .vote-terms__line {
        font-size: 12.5px;
    }

    .prize-box {
        padding: 10px 12px;
    }

    .prize-box__title {
        font-size: 12.5px;
    }

    .prize-box__line {
        font-size: 11.5px;
    }

    .vote-prizes__note {
        font-size: 11.5px;
    }

    .idol-panel__grid {
        gap: 10px 8px;
    }

    .idol-card {
        max-width: 140px;
    }

    .vote-btn {
        min-width: 140px;
        padding: 8px 20px;
        font-size: 18px;
    }
}

/* ==========================================================================
   EXTRA SPARKLE — a slow drifting bokeh inside each panel board, and a
   shimmer that runs across the "โหวตเลย !" button.
   ========================================================================== */
.idol-panel__board {
    position: relative;
    overflow: hidden;
}

    .idol-panel__board::after {
        content: "";
        position: absolute;
        inset: -20%;
        z-index: 0;
        pointer-events: none;
        background-image: radial-gradient(circle, rgba(255, 255, 255, 0.9) 0 2px, transparent 3px), radial-gradient(circle, rgba(255, 214, 250, 0.9) 0 1.5px, transparent 2.5px), radial-gradient(circle, rgba(196, 240, 255, 0.9) 0 2px, transparent 3px);
        background-size: 180px 180px, 130px 130px, 220px 220px;
        background-position: 10px 20px, 70px 90px, 140px 40px;
        opacity: 0.55;
        animation: boardBokeh 14s ease-in-out infinite alternate;
    }

.idol-panel__grid,
.idol-panel__empty {
    position: relative;
    z-index: 1;
}

@keyframes boardBokeh {
    from {
        transform: translate3d(0, 0, 0);
        opacity: 0.35;
    }

    to {
        transform: translate3d(-18px, -26px, 0);
        opacity: 0.7;
    }
}

.vote-btn {
    position: relative;
    overflow: hidden;
}

    .vote-btn::after {
        content: "";
        position: absolute;
        top: -50%;
        left: -60%;
        width: 40%;
        height: 200%;
        transform: rotate(20deg);
        background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 0) 100%);
        animation: voteBtnShimmer 3.4s ease-in-out infinite;
        pointer-events: none;
    }

.vote-btn--disabled::after {
    display: none;
}

@keyframes voteBtnShimmer {
    0%, 65% {
        transform: rotate(20deg) translateX(0);
        opacity: 0;
    }

    70% {
        opacity: 1;
    }

    100% {
        transform: rotate(20deg) translateX(520%);
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .idol-panel__board::after,
    .vote-btn::after {
        animation: none;
    }
}

/* ==========================================================================
   ดาวฟุ้งฟิ้ง — a drifting star field over the hero and the roster section.
   Pure CSS: a 5-point clip-path over a radial gradient, so `is-outline` /
   `is-cyan` read as glowing hollow stars and `is-solid` as a filled one.
   ========================================================================== */
.ann-stars {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
}

.ann-stars--hero {
    z-index: 4;
}
/* over the character art, under the title */
/* .mid__critters (bubble/animals) sits at z-index 1 inside .mid, and .sections
   above it is z-index auto so it never makes a stacking context of its own —
   a star field at 0 lost to the critters layer and got painted over. */
.ann-stars--roster {
    z-index: 3;
}
/* keep the real content above the roster's star field */
.roster__inner {
    position: relative;
    z-index: 5;
}

.ann-stars i {
    position: absolute;
    display: block;
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    opacity: 0;
    animation: annStarDrift 11s ease-in-out infinite alternate, annStarTwinkle 2.6s ease-in-out infinite;
}

    .ann-stars i.is-outline {
        background: radial-gradient(closest-side, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0.95) 62%, rgba(255, 170, 235, 0.95) 80%, rgba(255, 170, 235, 0) 100%);
        filter: drop-shadow(0 0 9px rgba(255, 140, 230, 0.95));
    }

    .ann-stars i.is-cyan {
        background: radial-gradient(closest-side, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0.95) 62%, rgba(140, 235, 255, 0.95) 80%, rgba(140, 235, 255, 0) 100%);
        filter: drop-shadow(0 0 9px rgba(110, 225, 255, 0.95));
    }

    .ann-stars i.is-solid {
        background: linear-gradient(150deg, #ffffff 0%, #ffe3fa 55%, #c9f0ff 100%);
        filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.95));
    }

    /* scattered placement — size, spot, drift distance and rhythm all vary so
   the field never reads as a repeating pattern */
    .ann-stars i:nth-child(1) {
        width: 54px;
        height: 54px;
        left: 6%;
        top: 12%;
        --dx: 10px;
        --dy: -18px;
        animation-delay: 0s, 0s;
    }

    .ann-stars i:nth-child(2) {
        width: 26px;
        height: 26px;
        left: 17%;
        top: 62%;
        --dx: -12px;
        --dy: -14px;
        animation-delay: -2.4s, -0.7s;
    }

    .ann-stars i:nth-child(3) {
        width: 24px;
        height: 24px;
        left: 27%;
        top: 28%;
        --dx: 8px;
        --dy: -22px;
        animation-delay: -4.1s, -1.5s;
    }

    .ann-stars i:nth-child(4) {
        width: 40px;
        height: 40px;
        left: 41%;
        top: 78%;
        --dx: 14px;
        --dy: -12px;
        animation-delay: -1.3s, -2.2s;
    }

    .ann-stars i:nth-child(5) {
        width: 22px;
        height: 22px;
        left: 55%;
        top: 16%;
        --dx: -10px;
        --dy: -20px;
        animation-delay: -5.6s, -3.0s;
    }

    .ann-stars i:nth-child(6) {
        width: 22px;
        height: 22px;
        left: 66%;
        top: 54%;
        --dx: 12px;
        --dy: -16px;
        animation-delay: -3.2s, -0.4s;
    }

    .ann-stars i:nth-child(7) {
        width: 48px;
        height: 48px;
        left: 79%;
        top: 24%;
        --dx: -14px;
        --dy: -20px;
        animation-delay: -6.8s, -2.6s;
    }

    .ann-stars i:nth-child(8) {
        width: 20px;
        height: 20px;
        left: 91%;
        top: 70%;
        --dx: 9px;
        --dy: -14px;
        animation-delay: -0.8s, -3.7s;
    }

    .ann-stars i:nth-child(9) {
        width: 34px;
        height: 34px;
        left: 12%;
        top: 88%;
        --dx: -11px;
        --dy: -18px;
        animation-delay: -7.5s, -1.1s;
    }

    .ann-stars i:nth-child(10) {
        width: 26px;
        height: 26px;
        left: 47%;
        top: 41%;
        --dx: 13px;
        --dy: -15px;
        animation-delay: -4.9s, -2.9s;
    }

    .ann-stars i:nth-child(11) {
        width: 44px;
        height: 44px;
        left: 71%;
        top: 90%;
        --dx: -9px;
        --dy: -21px;
        animation-delay: -2.0s, -1.8s;
    }

    .ann-stars i:nth-child(12) {
        width: 24px;
        height: 24px;
        left: 88%;
        top: 44%;
        --dx: 11px;
        --dy: -13px;
        animation-delay: -6.1s, -3.4s;
    }

/* the hero band is short and busy — keep its stars smaller and softer */
.ann-stars--hero i {
    transform-origin: center;
}

    .ann-stars--hero i:nth-child(1) {
        width: 38px;
        height: 38px;
    }

    .ann-stars--hero i:nth-child(4) {
        width: 28px;
        height: 28px;
    }

    .ann-stars--hero i:nth-child(7) {
        width: 32px;
        height: 32px;
    }

@keyframes annStarDrift {
    from {
        translate: 0 0;
    }

    to {
        translate: var(--dx, 10px) var(--dy, -16px);
    }
}

@keyframes annStarTwinkle {
    0% {
        opacity: 0.28;
        scale: 0.70;
        rotate: -8deg;
    }

    30% {
        opacity: 1;
        scale: 1.16;
        rotate: 3deg;
    }

    42% {
        opacity: 0.40;
        scale: 0.92;
        rotate: 5deg;
    }

    56% {
        opacity: 1;
        scale: 1.08;
        rotate: 8deg;
    }

    100% {
        opacity: 0.28;
        scale: 0.70;
        rotate: -8deg;
    }
}

@media (max-width: 860px) {
    /* fewer, smaller stars so they don't crowd the narrow layout */
    .ann-stars i {
        transform: scale(0.62);
    }

        .ann-stars i:nth-child(n + 9) {
            display: none;
        }
}

@media (prefers-reduced-motion: reduce) {
    .ann-stars i {
        animation: none;
        opacity: 0.5;
    }
}

/* ==========================================================================
   ผลโหวต Real Time (.live-poll) + กล่อง QR (.live-cta)
   แทรกอยู่ใน .idol-panel เหนือ .idol-panel__board — สีของกราฟและพิลหัวข้อ
   รับมาจาก .idol-panel--female / --male เหมือนหัวข้อแผงด้านบน
   ========================================================================== */
.live-poll {
  position: relative;
  margin-bottom: 14px;
  /* เว้นที่ให้ชื่อผู้ประกวดใต้แท่งที่แสดงตลอด */
  padding: 14px 0px 48px;
  box-sizing: border-box;
  border-radius: 18px;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.75), 0 4px 14px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}
/* พื้นหลังกล่องเป็นภาพสำเร็จใน images/announce/ (มีดาวอยู่ในภาพแล้ว
   จึงไม่ต้องมีเลเยอร์ลายดาวซ้อนทับอีกชั้น)

   ชื่อไฟล์กับสีสลับกับที่คิด — ยึดตามสีจริง:
     bg-ff.png = ชมพู/ม่วง  → female
     bg-f.png  = ฟ้า        → male

   ใช้ size 100% 100% (ไม่ใช่ cover) เพราะภาพฝังมุมโค้งมาในไฟล์อยู่แล้ว
   ต้องให้มุมของภาพตรงกับมุมของกล่องพอดี ถ้าใช้ cover มุมโค้งจะโดนครอปหาย
   สัดส่วนภาพ 968x668 (1.45) ใกล้เคียงกล่องจริงมาก การยืดจึงแทบไม่เห็น
   ส่วนสีพื้นด้านหลังไว้กันภาพโหลดไม่ทัน/โหลดไม่ขึ้น */
.idol-panel--female .live-poll {
  background: #f7c8e8 url("../images/announce/bg-ff.png") 0 0 / 100% 100% no-repeat;
}

.idol-panel--male .live-poll {
  background: #bdd1fb url("../images/announce/bg-f.png") 0 0 / 100% 100% no-repeat;
}

/* พิลเปล่า ๆ ตามภาพต้นแบบ — ไม่มีจุด LIVE นำหน้าข้อความ */
.live-poll__head {
  position: relative;
  z-index: 1;
  display: inline-block;
  margin-bottom: 6px;
  padding: 9px 24px;
  border-radius: 0px 50px 50px 0;
  color: #fff;
  font-family: var(--font-th);
  font-size: 18px;
  font-weight: 700;
  text-shadow: 0 2px 5px rgba(0, 0, 0, 0.22);
}
.idol-panel--female .live-poll__head { background: linear-gradient(135deg, #e878c2, #d45cae); }
.idol-panel--male   .live-poll__head { background: linear-gradient(135deg, #6f8ae8, #5a76dd); }

/* ---- กราฟแท่ง ----
   .live-poll__col สูงเป็น % ของกรอบนี้ (สคริปต์ใส่ inline มาให้ แท่งสูงสุด
   = LIVE_MAX_BAR ใน announce.js) ที่เหลือด้านบนเว้นไว้ให้รูปวงกลม */
.live-poll__chart {
  position: relative;
  z-index: 1;
  height: 300px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 24px;
}

.live-poll__bar {
  flex: 1 1 0;
  min-width: 0;
  max-width: 78px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.live-poll__col {
  position: relative;
  width: 100%;
  /* คะแนน 0 ก็ยังต้องมีแท่งเตี้ย ๆ ให้เห็นรูปกับเลขอันดับ */
  min-height: 76px;
  box-sizing: border-box;
  padding: 8px 4px 10px;
  border-radius: 12px 12px 5px 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.live-poll__fill {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  /* ประกายที่ไหลขึ้น (::after) ต้องถูกตัดที่ขอบแท่ง ไม่ล้นออกไปเหนือหัวแท่ง */
  overflow: hidden;
  transform-origin: bottom;
  animation: livePollGrow 0.75s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.idol-panel--female .live-poll__fill {
  background: linear-gradient(180deg, #f78fd0 0%, #e8579f 100%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.45);
}
.idol-panel--male .live-poll__fill {
  background: linear-gradient(180deg, #8ab0f7 0%, #4f74de 100%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.4);
}

/* รูปวงกลมลอยเหนือหัวแท่ง — absolute จาก bottom:100% ของแท่ง จึงขยับขึ้น-ลง
   ตามความสูงของแท่งเองโดยไม่กินพื้นที่ใน flex */
/* กรอบนี้เป็นแค่ตัวกำหนดตำแหน่ง — วงกลมกับเส้นขอบอยู่ที่ <img> เพื่อให้
   มงกุฎและประกายดาวของอันดับ 1 ยื่นออกมานอกวงกลมได้ ไม่ถูก overflow ตัด */
.live-poll__avatar {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) rotate(-11deg);
  margin-bottom: 9px;
  width: 56px;
  height: 56px;
}
/* วงกลมที่ครอปรูป — ตัวนี้ clip, ตัว .live-poll__avatar ข้างนอกไม่ clip
   เพื่อให้มงกุฎกับประกายดาวของอันดับ 1 ยื่นออกมานอกวงกลมได้ */
.live-poll__face {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  box-sizing: border-box;
  overflow: hidden;
  border: 3px solid #fff;
  border-radius: 50%;
  background: #efe6fb;
  box-shadow: 0 4px 10px rgba(60, 40, 120, 0.28);
}
/* การ์ดผู้ประกวดเป็นภาพ 1:1 เท่ากับวงกลมพอดี ฉะนั้น object-fit: cover จะไม่
   ครอปอะไรเลย — เห็นทั้งการ์ดรวมถึงแถบชื่อที่ก้นการ์ด ต้องซูมเข้าไปเอง
   scale 1.5 + origin 50%/34% = เห็นราวสองในสามส่วนบนของการ์ด คือช่วงใบหน้า */
.live-poll__face img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  transform: scale(1.5);
  transform-origin: 50% 34%;
}

.live-poll__rank {
  position: relative;
  z-index: 1;
  color: #fff;
  font-family: var(--font-kanit);
  font-size: 26px;
  font-style: italic;
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

/* ขีดแทนอันดับตอนยังไม่มีคะแนน — หรี่ลงหน่อยเพื่อไม่ให้เด่นเท่าเลขอันดับจริง */
.live-poll__rank.is-empty {
  opacity: 0.5;
  font-size: 22px;
}

.live-poll__pct {
  position: relative;
  z-index: 1;
  color: #fff;
  font-family: var(--font-th);
  font-size: 14px;
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

@keyframes livePollGrow {
  from { transform: scaleY(0.02); opacity: 0.4; }
  to   { transform: scaleY(1);    opacity: 1; }
}

/* ---- กล่อง QR + ปุ่มโหวต ---- */
.live-cta {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
  padding: 14px 16px;
  box-sizing: border-box;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.9), 0 4px 14px rgba(0, 0, 0, 0.12);
}

.live-cta__qr {
  flex: 0 0 120px;
  width: 120px;
  height: 120px;
  box-sizing: border-box;
  border-radius: 10px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #fff;
}

.live-cta__qr-img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
}

/* กรอบเปล่ารอไฟล์ QR — ให้เต็มช่อง 120px เพื่อกันพื้นที่ไว้เท่าของจริง */
.live-cta__qr-empty {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  border: 2px dashed #9aa8d8;
  border-radius: 10px;
  color: #7d8ab8;
  font-family: var(--font-th);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
}

.live-cta__copy {
  flex: 1 1 auto;
  min-width: 0;
  padding-right: 122px;
}

.live-cta__title {
  color: #2b3f9e;
  font-family: var(--font-th);
  font-size: 21px;
  font-weight: 700;
  line-height: 1.3;
}

.live-cta__line {
  color: #4a5a99;
  font-family: var(--font-th);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.55;
}

.live-cta__line--hint { color: #7482ac; }

.live-cta__action {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 9px;
}
/* ปุ่มเดิม (.vote-btn) ย่อลงให้พอดีในกล่อง แทนที่จะพาดเต็มความกว้างแผง */
.live-cta .vote-btn {
     min-width: 119px;
    padding: 4px 20px;
    font-size: 21px;
    border-width: 2px;
    font-size: 16px;
}
/* สถานะ "ยังไม่เปิดโหวต" เดิมเป็นสีขาวโปร่ง — บนกล่องขาวนี้จะจมหายไปหมด
   เหลือแต่ตัวหนังสือลอย จึงเปลี่ยนเป็นพิลเทาอ่อนให้ยังเห็นเป็นปุ่ม */
.live-cta .vote-btn--disabled {
  border-color: #dfe3f2;
  background: #eef0f8;
  color: #8b93bd;
  text-shadow: none;
}

/* รูปของรางวัลและชื่อใต้รูป: ตรึงขอบขวาให้กล่องชาย/หญิงสูงเท่ากัน */
.live-cta__sticker {
  position: absolute;
  right: 12px;
  top: 50%;
  translate: 0 -50%;
  width: 116px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  pointer-events: none;
}

.live-cta__sticker-name {
  width: 100%;
  height: 2.8em;
  color: #4a5a99;
  font-family: var(--font-th);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  overflow: hidden;
}

.live-cta__sticker-burst {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, #fff3b0 0%, #ffd76a 100%);
  clip-path: polygon(50% 0%, 60% 17%, 76% 8%, 78% 26%, 96% 26%, 88% 42%, 100% 55%, 84% 62%, 92% 79%, 74% 79%, 72% 97%, 56% 87%, 44% 100%, 34% 84%, 18% 92%, 18% 74%, 2% 70%, 12% 56%, 0% 44%, 16% 36%, 8% 20%, 26% 21%, 28% 4%, 42% 13%);
  filter: drop-shadow(0 3px 6px rgba(120, 80, 20, 0.3));
}

.live-cta__sticker-label {
  position: absolute;
  left: 50%;
  top: -4px;
  transform: translateX(-50%) rotate(-8deg);
  z-index: 2;
  color: #d4408f;
  font-family: var(--font-th);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  text-shadow: 0 1px 0 #fff, 0 0 5px rgba(255, 255, 255, 0.9);
}

.live-cta__sticker-img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

.live-cta__sticker-qty {
  position: absolute;
  right: 0;
  bottom: 2px;
  z-index: 2;
  color: #5a3a00;
  font-family: var(--font-kanit);
  font-size: 12px;
  font-weight: 700;
}

@media (prefers-reduced-motion: reduce) {
  .live-poll__fill { animation: none; }
}

/* ------------------------------ responsive ----------------------------- */
@media (min-width: 861px) and (max-width: 1399px) {
  .live-poll { padding: 12px 0 42px; }
  .live-poll__name { width: 80px; font-size: 10.5px; top: calc(100% + 6px); }
  .live-poll__head { font-size: 15px; padding: 6px 16px; }
  .live-poll__chart { height: 210px; gap: 17px; }
  .live-poll__bar { max-width: 64px; }
  .live-poll__avatar { width: 46px; height: 46px; margin-bottom: 7px; }
  .live-poll__face { border-width: 2px; }
  .live-poll__rank { font-size: 21px; }
  .live-poll__pct { font-size: 12px; }
  .live-cta { gap: 12px; padding: 12px 13px; }
  .live-cta__qr { flex-basis: 96px; width: 96px; height: 96px; }
  .live-cta__title { font-size: 18px; }
  .live-cta__line { font-size: 13px; }
  .live-cta .vote-btn { min-width: 128px; padding: 7px 20px; font-size: 18px; }
  .live-cta__sticker { width: 88px; right: 8px; }
  .live-cta__copy { padding-right: 92px; }
}

@media (max-width: 860px) {
  .live-poll { padding: 12px 0 40px; border-radius: 14px; }
  .live-poll__name { width: 76px; font-size: 10px; top: calc(100% + 6px); }
  .live-poll__head { font-size: 15px; padding: 6px 15px; }
  .live-poll__chart { height: 200px; gap: 15px; }
  .live-poll__bar { max-width: 62px; }
  .live-poll__avatar { width: 44px; height: 44px; margin-bottom: 7px; }
  .live-poll__face { border-width: 2px; }
  .live-poll__col { min-height: 64px; }
  .live-poll__rank { font-size: 20px; }
  .live-poll__pct { font-size: 12px; }

  /* กล่อง QR แคบเกินกว่าจะวางสองคอลัมน์ — ซ้อนเป็นแถวเดียวและจัดกลาง */
  .live-cta {
    flex-direction: column;
    gap: 12px;
    padding: 13px 12px;
    border-radius: 14px;
    text-align: center;
  }
  .live-cta__qr { flex-basis: auto; width: 132px; height: 132px; }
  .live-cta__copy { width: 100%; }
  .live-cta__title { font-size: 18px; }
  .live-cta__line { font-size: 13px; }
  .live-cta__action { justify-content: center; }
  .live-cta .vote-btn { min-width: 140px; padding: 8px 22px; font-size: 18px; }
  .live-cta__sticker { position: static; translate: none; width: 104px; margin: 6px auto 0; }
  .live-cta__copy { padding-right: 0; }
}

@media (max-width: 480px) {
  .live-poll__chart { height: 176px; gap: 11px; }
  .live-poll__bar { max-width: 54px; }
  .live-poll__avatar { width: 38px; height: 38px; margin-bottom: 6px; }
  .live-poll__col { min-height: 56px; padding: 6px 3px 8px; }
  .live-poll__rank { font-size: 17px; }
  .live-poll__pct { font-size: 11px; }
  .live-cta__qr { width: 118px; height: 118px; }
  .live-cta__title { font-size: 16px; }
  .live-cta__line { font-size: 12px; }
  .live-cta .vote-btn { min-width: 128px; font-size: 17px; }
}

/* ==========================================================================
   ลูกเล่นของช่องผลโหวต — จุด LIVE กระพริบที่หัวข้อ, ประกายไหลบนแท่ง,
   ฟองอากาศลอยขึ้นในแท่ง, มงกุฎ + ประกายดาวของอันดับ 1, ชื่อโผล่ตอน hover
   (ตัวเลข % วิ่งขึ้นจาก 0 ทำใน announce.js — countUpPcts)
   ========================================================================== */

/* ---- ประกายวิ้ง ๆ ในแท่ง ----
   เดิมเป็นแถบแสงขาววิ่งขึ้น ซึ่งอ่านเป็น "ฝ้าวาว" พาดทับสีแท่ง เปลี่ยนมาโรย
   ดาวประกายแทน ใช้ไฟล์ลายเดียวกับที่เคยใช้เป็นพื้นหลังกล่อง (poll-stars.svg)
   .live-poll__fill มี overflow: hidden + border-radius อยู่แล้ว ดาวจึงถูกตัด
   ให้อยู่ในทรงแท่งพอดี ไม่ล้นออกมา */
.live-poll__fill::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: url("../images/announce/poll-stars.svg") 0 0 / 130px 108px repeat;
  opacity: 0.45;
  animation: livePollTwinkle 2.8s ease-in-out infinite alternate;
  pointer-events: none;
}

/* เลื่อนจุดเริ่มลายและหน่วงจังหวะกะพริบของแต่ละแท่งให้ไม่ตรงกัน
   ไม่งั้นทุกแท่งจะวิ้งพร้อมกันเป๊ะ ดูเป็นภาพเดียวกันกะพริบ */
.live-poll__bar:nth-child(2) .live-poll__fill::after { background-position: 38px 22px; animation-delay: -0.7s; }
.live-poll__bar:nth-child(3) .live-poll__fill::after { background-position: 74px 52px; animation-delay: -1.5s; }
.live-poll__bar:nth-child(4) .live-poll__fill::after { background-position: 18px 74px; animation-delay: -2.2s; }

@keyframes livePollTwinkle {
  from { opacity: 0.25; }
  to   { opacity: 0.8; }
}


/* ---- อันดับ 1: วงแหวนทอง + มงกุฎ + ประกายดาว ---- */
.live-poll__bar--lead .live-poll__face {
  border-color: #ffe4a0;
  box-shadow: 0 0 0 2px rgba(255, 199, 92, 0.9), 0 0 9px rgba(255, 205, 100, 0.55), 0 4px 10px rgba(60, 40, 120, 0.3);
  animation: leadRing 2.4s ease-in-out infinite;
}

@keyframes leadRing {
  0%, 100% { box-shadow: 0 0 0 2px rgba(255, 199, 92, 0.8), 0 0 7px rgba(255, 205, 100, 0.45), 0 4px 10px rgba(60, 40, 120, 0.3); }
  50%      { box-shadow: 0 0 0 3px rgba(255, 214, 120, 1),  0 0 14px rgba(255, 205, 100, 0.7), 0 4px 10px rgba(60, 40, 120, 0.3); }
}

/* มงกุฎอยู่นิ่ง ให้ "วิ้ง" ด้วยแสงแทนการขยับตัว

   ตัวมงกุฎเป็นไฟล์ภาพ images/announce/crown.png (โปร่งใส 27x20)
   ตั้งกล่องเท่าขนาดไฟล์จริงเพื่อให้คมที่สุด ไม่โดนขยายจนเบลอ

   "วิ้ง" ทำด้วยการวาบ filter (สว่างขึ้น + เรืองแสงทองสั้น ๆ) ไม่ใช่แถบไฮไลต์
   วิ่งผ่านแบบเดิม เพราะแถบไฮไลต์ต้องมี mask ตัดให้อยู่ในทรงมงกุฎ ซึ่ง
   Chromium บล็อก mask ที่อ้างไฟล์ภายนอกเมื่อเปิดผ่าน file:// (นับเป็นคนละ
   origin) แล้วมงกุฎจะหายไปทั้งอันตอนเปิดจากเครื่อง — filter ไม่ติดข้อจำกัดนี้

   หมายเหตุ: ไซต์ NB โหลด Font Awesome 4.7.0 ซึ่งยังไม่มี fa-crown
   (เพิ่มมาตอน FA 5) จึงดึงจากตรงนั้นไม่ได้ถ้าไม่อัปเวอร์ชัน */
.live-poll__crown {
  position: absolute;
  left: 50%;
  top: -20px;
  z-index: 2;
  width: 27px;
  height: 20px;
  transform: translateX(-13%) rotate(15deg);
  background: url("../images/announce/crown.png") center / contain no-repeat;
  filter: drop-shadow(0 2px 3px rgba(150, 95, 10, 0.45));
}
/* มงกุฎไม่มีอนิเมชันของตัวเองแล้ว — ขยับตามกล่อง .live-poll__avatar ที่ลอย
   ขึ้น-ลง (liveBob) เพราะเป็นลูกของกล่องนั้น */

.live-poll__sparks {
  position: absolute;
  inset: -26%;
  z-index: 1;
  pointer-events: none;
}

.live-poll__sparks i {
  position: absolute;
  display: block;
  background: linear-gradient(140deg, #ffffff 0%, #fff2c4 50%, #ffd166 100%);
  clip-path: polygon(50% 0%, 58% 42%, 100% 50%, 58% 58%, 50% 100%, 42% 58%, 0% 50%, 42% 42%);
  opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255, 236, 170, 0.95));
  animation: leadSpark 2.2s ease-in-out infinite;
}

.live-poll__sparks i:nth-child(1) { width: 14px; height: 14px; left: -4%;  top: 6%;  animation-delay: 0s;    }
.live-poll__sparks i:nth-child(2) { width: 10px; height: 10px; right: -2%; top: 30%; animation-delay: 0.7s;  }
.live-poll__sparks i:nth-child(3) { width: 12px; height: 12px; left: 28%;  top: -8%; animation-delay: 1.4s;  }

@keyframes leadSpark {
  0%, 100% { opacity: 0;    transform: scale(0.4) rotate(0deg); }
  45%      { opacity: 1;    transform: scale(1)   rotate(45deg); }
  70%      { opacity: 0.25; transform: scale(0.7) rotate(70deg); }
}

/* ---- เลขอันดับเด้งเข้ามาพร้อมแท่ง ---- */
.live-poll__rank {
  animation: liveRankIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  /* ผูกกับ LIVE_BAR_DELAY (0.42s) ใน announce.js + เผื่อให้แท่งเริ่มขึ้นก่อน */
  animation-delay: 0.67s;
}

@keyframes liveRankIn {
  from { opacity: 0; transform: translateY(8px) scale(0.6); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}

/* ชื่อผู้ประกวดอยู่ใต้แท่งตลอด; hover ยกแท่งขึ้นเล็กน้อย */
.live-poll__bar {
  cursor: default;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.25s ease;
}

.live-poll__bar:hover {
  transform: translateY(-5px);
  filter: brightness(1.06) saturate(1.05);
}

.live-poll__name {
  position: absolute;
  left: 50%;
  top: calc(100% + 8px);
  z-index: 4;
  transform: translateX(-50%);
  width: 96px;
  height: 2.6em;
  color: #3f5091;
  font-family: var(--font-th);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  overflow: hidden;
  pointer-events: none;
}

/* ---- ป้ายชื่อโผล่ใต้แท่ง จึงต้องไม่ถูกกรอบกราฟตัดทิ้ง ---- */
.live-poll {
  overflow: visible;
}
/* พื้นหลังดาวยังต้องอยู่ในมุมโค้งของกรอบเหมือนเดิม */
.live-poll::before {
  border-radius: inherit;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .live-poll__fill::after,
  .live-poll__bar--lead .live-poll__face,
  .live-poll__sparks i,
  .live-poll__rank {
    animation: none;
  }

  .live-poll__sparks i     { opacity: 0.8; }
  .live-poll__bar:hover    { transform: none; }
}

@media (max-width: 860px) {
  /* ย่อด้วย width/height ได้แล้วเพราะมงกุฎเป็นไฟล์ภาพ (background-size:
     contain ย่อรูปตามกล่องให้เอง) — ต้องคง transform ชุดเดียวกับจอใหญ่ไว้
     ไม่งั้นมุมเอียงกับจุดวางจะกระโดดตอนข้าม breakpoint */
  .live-poll__crown {
    top: -16px;
    width: 21px;
    height: 16px;
    transform: translateX(-13%) rotate(15deg);
  }
  .live-poll__sparks i:nth-child(1) { width: 11px; height: 11px; }
  .live-poll__sparks i:nth-child(2) { width: 8px;  height: 8px;  }
  .live-poll__sparks i:nth-child(3) { width: 9px;  height: 9px;  }
}

/* ==========================================================================
   เอฟเฟกต์ตอนช่องผลโหวตเข้ามาในจอ (.is-revealing → .is-in)

   .is-revealing ถูกใส่โดย announce.js (revealLive) = สคริปต์รับหน้าที่เผย
   บล็อกนี้แล้ว จากนั้น IntersectionObserver ค่อยใส่ .is-in ให้ตอนเลื่อนมาถึง

   สังเกตว่ากฎซ่อน/พักทุกข้อผูกกับ .is-revealing ทั้งหมด ไม่ใช่ผูกกับตัวบล็อก
   ตรง ๆ — ถ้า JS ไม่ทำงาน คลาสนี้จะไม่มี กราฟก็แสดงเต็มทันที กระดานผลโหวต
   ต้องไม่หายไปเพราะสคริปต์พลาด
   ========================================================================== */

/* ---- ทั้งกล่องเลื่อนขึ้น + จางเข้า (กล่อง QR ตามมาทีหลังเล็กน้อย) ---- */
/* กล่องเข้าที่ให้เสร็จภายใน ~0.45 วิ แล้วแท่งค่อยเริ่มงอกที่ 0.42 วิ
   (LIVE_BAR_DELAY ใน announce.js) จะได้อ่านเป็นสองจังหวะ ไม่ใช่ก้อนเดียว */
.live-poll.is-revealing,
.live-cta.is-revealing {
  opacity: 0;
  transform: translateY(26px) scale(0.965);
  transition: opacity 0.38s ease, transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

.live-cta.is-revealing { transition-delay: 0.14s; }

.live-poll.is-revealing.is-in,
.live-cta.is-revealing.is-in {
  opacity: 1;
  transform: none;
}

/* ---- พักแอนิเมชันในกราฟไว้จนกล่องเข้ามาในจอ ----
   แท่งจะได้ไม่งอกทิ้งไปตอนที่ยังอยู่ใต้จอ แล้วผู้ใช้เลื่อนมาเจอแท่งนิ่ง ๆ */
.live-poll.is-revealing .live-poll__fill,
.live-poll.is-revealing .live-poll__fill::after,
.live-poll.is-revealing .live-poll__rank,
.live-poll.is-revealing .live-poll__avatar,
.live-poll.is-revealing .live-poll__face,
.live-poll.is-revealing .live-poll__sparks i,
.live-poll.is-revealing .live-poll__aura {
  animation-play-state: paused;
}

.live-poll.is-revealing.is-in .live-poll__fill,
.live-poll.is-revealing.is-in .live-poll__fill::after,
.live-poll.is-revealing.is-in .live-poll__rank,
.live-poll.is-revealing.is-in .live-poll__avatar,
.live-poll.is-revealing.is-in .live-poll__face,
.live-poll.is-revealing.is-in .live-poll__sparks i,
.live-poll.is-revealing.is-in .live-poll__aura {
  animation-play-state: running;
}

/* ---- พิลหัวข้อเลื่อนเข้าจากซ้าย ---- */
.live-poll.is-revealing .live-poll__head {
  opacity: 0;
  transform: translateX(-14px);
  transition: opacity 0.45s ease 0.1s, transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s;
}

.live-poll.is-revealing.is-in .live-poll__head {
  opacity: 1;
  transform: none;
}

/* ---- รูปวงกลมเด้งขึ้นมาไล่ทีละแท่ง (announce.js ใส่ animation-delay inline) ----
   keyframe ต้องคง translateX(-50%) ไว้ทุกเฟรม เพราะ transform นี้คือตัวจัดให้
   รูปอยู่กลางแท่ง ไม่ใช่แค่เอฟเฟกต์

   ตัวที่สอง (liveBob) คือลอยขึ้น-ลงเบา ๆ ตลอดเวลาหลังเข้าที่แล้ว
   มงกุฎกับประกายดาวเป็นลูกของกล่องนี้ จึงขยับตามไปด้วยเป็นชุดเดียวกัน

   liveBob ใช้ property `translate` ไม่ใช่ `transform` เพราะสองตัวนี้เป็นคนละ
   property กัน ประกอบกันได้โดยไม่ตีกัน — ถ้าใช้ transform ทั้งคู่ ตัวหลังใน
   ลิสต์จะทับตัวหน้าทิ้ง แล้ว liveAvatarIn จะไม่ทำงาน
   (animation-delay inline มีค่าเดียว จึงใช้กับทั้งสองอนิเมชัน = แต่ละแท่ง
    ลอยไม่พร้อมกัน ตามจังหวะที่มันโผล่เข้ามา) */
.live-poll__avatar {
  animation: liveAvatarIn 0.62s cubic-bezier(0.34, 1.56, 0.64, 1) both,
             liveBob 2.4s ease-in-out infinite alternate;
}

@keyframes liveAvatarIn {
  0%   { opacity: 0; transform: translateX(-50%) translateY(12px) scale(0.45); }
  60%  { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1.12); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1); }
}

@keyframes liveBob {
  from { translate: 0 0; }
  to   { translate: 0 -5px; }
}

/* ความเร็วลอยของแต่ละแท่งไม่เท่ากัน — เฟสเริ่มต้นที่ JS กระจายให้แล้วกัน
   ไม่ให้ลอยพร้อมกันตอนเริ่ม ส่วนความเร็วที่ต่างกันกันไม่ให้มันค่อย ๆ ไหล
   มาตรงกันทีหลัง ค่าแรกคือ liveAvatarIn ต้องคงไว้เท่าเดิมทุกบรรทัด
   เพราะ animation-duration เป็นลิสต์ ถ้าใส่ค่าเดียวจะไปทับตัวแรกด้วย */
.live-poll__bar:nth-child(1) .live-poll__avatar { animation-duration: 0.62s, 2.4s; }
.live-poll__bar:nth-child(2) .live-poll__avatar { animation-duration: 0.62s, 3.1s; }
.live-poll__bar:nth-child(3) .live-poll__avatar { animation-duration: 0.62s, 2.7s; }
.live-poll__bar:nth-child(4) .live-poll__avatar { animation-duration: 0.62s, 3.4s; }

/* ---- แสงกวาดผ่านกล่องหนึ่งครั้งตอนเปิด ---- */
.live-poll.is-revealing::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(104deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 62%);
  background-size: 280% 100%;
  background-repeat: no-repeat;
  background-position: 150% 0;
  opacity: 0;
}

.live-poll.is-revealing.is-in::after {
  animation: livePollWipe 1.15s ease-out 0.2s both;
}

@keyframes livePollWipe {
  0%   { background-position: 150% 0; opacity: 0; }
  20%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { background-position: -50% 0; opacity: 0; }
}

/* ==========================================================================
   ออร่าของแท่งอันดับ 1 — แสงทองฟุ้งอยู่หลังแท่ง หายใจเบา ๆ
   วางเป็น element แยก (.live-poll__aura) แทน ::before เพราะ .live-poll__col
   ใช้ ::before/::after ไม่ได้แล้ว และ z-index: -1 จะถูกจำกัดอยู่ใน
   .live-poll__chart (z-index: 1) ทำให้ออร่าอยู่หลังแท่งแต่ยังทับพื้นหลังกล่อง
   ========================================================================== */
/* เกาะขอบแท่งไว้ใกล้ ๆ — อ่านเป็นขอบเรืองทอง ไม่ใช่ฝ้าฟุ้งกินพื้นที่กล่อง */
.live-poll__aura {
  position: absolute;
  inset: -14px -13px -8px;
  z-index: -1;
  border-radius: 20px;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 60%, rgba(255, 238, 186, 0.7) 0%, rgba(255, 210, 112, 0.42) 34%, rgba(255, 196, 90, 0.16) 60%, rgba(255, 190, 80, 0) 82%);
  animation: leadAura 3s ease-in-out infinite alternate;
}

@keyframes leadAura {
  from { opacity: 0.6; transform: scale(0.97); }
  to   { opacity: 0.95; transform: scale(1.02); }
}

/* แสงเรืองที่ตัวแท่งเอง เพื่อให้แท่งอันดับ 1 เด่นออกมาจากพื้นหลังกล่อง
   คุมรัศมีให้แคบ เป็นเส้นขอบเรืองแทนการฟุ้งออกไปไกล */
.idol-panel--female .live-poll__bar--lead .live-poll__fill {
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 0 0 2px rgba(255, 216, 130, 0.85), 0 0 12px rgba(255, 200, 100, 0.5);
}

.idol-panel--male .live-poll__bar--lead .live-poll__fill {
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.45), 0 0 0 2px rgba(255, 216, 130, 0.8), 0 0 12px rgba(255, 200, 100, 0.45);
}

/* วงแหวนทองกระเพื่อมออกหนึ่งครั้ง ตอนแท่งอันดับ 1 งอกจนสุด */
.live-poll__bar--lead .live-poll__avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 50%;
  border: 3px solid rgba(255, 214, 120, 0.95);
  opacity: 0;
  pointer-events: none;
}

.live-poll.is-revealing.is-in .live-poll__bar--lead .live-poll__avatar::after {
  animation: leadPop 1.1s ease-out 1.25s both;
}

@keyframes leadPop {
  from { opacity: 0.95; transform: scale(1); }
  to   { opacity: 0;    transform: scale(2.1); }
}

@media (prefers-reduced-motion: reduce) {
  /* revealLive() ไม่ใส่ .is-revealing เลยในโหมดนี้ จึงไม่มีอะไรถูกซ่อนอยู่แล้ว
     เหลือแค่ปิดแอนิเมชันที่เล่นเองของออร่ากับรูปวงกลม */
  .live-poll__aura,
  .live-poll__avatar {
    animation: none;
  }

  .live-poll__aura { opacity: 0.9; }
}

@media (max-width: 860px) {
.live-poll__aura { inset: -16px -12px -10px; border-radius: 20px; }
}

/* GNJOY snapshot state: show real voter count only when one vote per user. */
.live-poll__meta { display: block; margin-top: 3px; font-size: 12px; font-weight: 500; }

/* ป้ายและวงแหวนของผู้ที่อยู่ในอันดับผ่านเข้ารอบ */
.live-poll__pass {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 7px;
  z-index: 3;
  padding: 3px 11px;
  border-radius: 999px;
  background: linear-gradient(180deg, #fff8dc 0%, #ffeaa9 100%);
  color: #8a6318;
  font-family: var(--font-th);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
  box-shadow: 0 2px 5px rgba(90, 60, 10, 0.28);
}

.live-poll__bar--lead .live-poll__pass { margin-bottom: 24px; }

.live-poll__bar--pass:not(.live-poll__bar--lead) .live-poll__face {
  border-color: #ffe4a0;
  box-shadow: 0 0 0 2px rgba(255, 199, 92, 0.75), 0 4px 10px rgba(60, 40, 120, 0.3);
}

@media (max-width: 1399px) {
  .live-poll__pass { font-size: 10px; padding: 2px 9px; margin-bottom: 6px; }
  .live-poll__bar--lead .live-poll__pass { margin-bottom: 20px; }
}

@media (max-width: 860px) {
  .live-poll__pass { font-size: 9.5px; padding: 2px 8px; }
  .live-poll__bar--lead .live-poll__pass { margin-bottom: 18px; }
}

/* ==========================================================================
   ตารางกำหนดการแสดง (.vote-schedule) — ใช้ในรอบ FINAL VOTE
   สองคอลัมน์: ซ้าย = ชาย (ฟ้า) ขวา = หญิง (ชมพู) รับสีจาก --male / --female
   ========================================================================== */
.vote-schedule {
  margin-bottom: 34px;
}

.vote-schedule__title {
  margin-bottom: 10px;
  color: var(--cyan);
  font-family: var(--font-th);
  font-size: 22px;
  font-weight: 700;
  text-shadow: 0 0 10px rgba(110, 255, 255, 0.5);
}

/* แถบวัน-สถานที่ใต้หัวข้อ */
.vote-schedule__when {
  display: inline-block;
  margin-bottom: 16px;
  padding: 7px 18px;
  border: 1px solid rgba(110, 255, 255, 0.45);
  border-radius: 999px;
  background: rgba(9, 23, 54, 0.55);
  color: #eaf2ff;
  font-family: var(--font-th);
  font-size: 15px;
  font-weight: 700;
}

.vote-schedule__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.vote-schedule__col {
  border: 2px solid;
  border-radius: 14px;
  overflow: hidden;
}

.vote-schedule__col--male { border-color: rgba(110, 200, 255, 0.55); }
.vote-schedule__col--female { border-color: rgba(255, 150, 220, 0.55); }

/* แต่ละแถว: ช่องเวลาเป็นพื้นทึบ ช่องรายการเป็นพื้นโปร่ง
   เส้นคั่นใช้ border-top ของแถวถัดไป จะได้ไม่มีเส้นเกินที่ขอบบน-ล่าง */
.vote-schedule__row {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  align-items: stretch;
}

.vote-schedule__row + .vote-schedule__row {
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}

.vote-schedule__time {
  padding: 9px 10px;
  color: #fff;
  font-family: var(--font-th);
  font-size: 14px;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
}

.vote-schedule__col--male .vote-schedule__time { background: rgba(38, 86, 168, 0.75); }
.vote-schedule__col--female .vote-schedule__time { background: rgba(150, 52, 120, 0.7); }

.vote-schedule__act {
  padding: 9px 14px;
  background: rgba(9, 23, 54, 0.45);
  color: rgba(255, 255, 255, 0.92);
  font-family: var(--font-th);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
}

.vote-schedule__act b {
  color: #fff;
  font-weight: 700;
}
.vote-schedule__col--male .vote-schedule__act b { color: #a9d8ff; }
.vote-schedule__col--female .vote-schedule__act b { color: #ffb3e4; }

/* ---- หัวข้อคั่นกลางบล็อกเงื่อนไข (บรรทัดที่ขึ้นต้นด้วย "#") ----
   ขนาดและเงาตัวอักษรเท่ากับ .vote-terms__title ทุก breakpoint
   ต่างกันแค่ margin-top ที่ต้องเว้นจากบรรทัดก่อนหน้า */
.vote-terms__subtitle {
  margin: 18px 0 8px;
  color: var(--cyan);
  font-family: var(--font-th);
  font-size: 18px;
  font-weight: 700;
  text-shadow: 0 0 10px rgba(110, 255, 255, 0.5);
}

/* ---- หัวข้อย่อยชั้นที่ 2 (บรรทัดที่ขึ้นต้นด้วย "--") ---- */
.vote-terms__line--sub2 {
  padding-left: 38px;
  color: rgba(255, 255, 255, 0.7);
  font-size: 13.5px;
}

@media (min-width: 861px) and (max-width: 1399px) {
  .vote-schedule__title { font-size: 19px; }
  .vote-schedule__when { font-size: 14px; padding: 6px 15px; }
  .vote-schedule__row { grid-template-columns: 104px minmax(0, 1fr); }
  .vote-schedule__time, .vote-schedule__act { font-size: 13px; padding: 8px 10px; }
  .vote-terms__subtitle { font-size: 16px; }
  .vote-terms__line--sub2 { font-size: 12.5px; padding-left: 32px; }
}

@media (max-width: 860px) {
  /* จอแคบวางสองคอลัมน์แล้วช่องรายการจะบีบจนอ่านไม่ออก — ซ้อนกันแทน */
  .vote-schedule__grid { grid-template-columns: 1fr; gap: 12px; }
  .vote-schedule__title { font-size: 17px; }
  .vote-schedule__when { font-size: 13px; padding: 6px 14px; }
  .vote-schedule__row { grid-template-columns: 96px minmax(0, 1fr); }
  .vote-schedule__time, .vote-schedule__act { font-size: 12.5px; padding: 8px 9px; }
  .vote-terms__subtitle { font-size: 15px; margin-top: 14px; }
  .vote-terms__line--sub2 { font-size: 12px; padding-left: 28px; }
}

@media (max-width: 480px) {
  .vote-schedule__row { grid-template-columns: 86px minmax(0, 1fr); }
  .vote-schedule__time, .vote-schedule__act { font-size: 11.5px; }
  .vote-terms__line--sub2 { font-size: 11.5px; padding-left: 24px; }
}

/* ==========================================================================
   ประกาศผู้ชนะ (.winner) — ใช้ในรอบ FINAL VOTE
   การ์ดสองใบเป็นภาพสำเร็จ (รูป ชื่อ ริบบิ้นอันดับ 1 อยู่ในไฟล์แล้ว)
   CSS ตรงนี้จึงมีแค่การจัดวาง ขนาด และจังหวะโผล่เข้ามา
   ========================================================================== */
/* .roster__panels ปกติเป็นกริด 2 คอลัมน์ (แผงหญิง | แผงชาย) — รอบผู้ชนะมี
   บล็อกเดียวที่ต้องกินเต็มความกว้าง จึงปลดกริดออก (คลาสใส่โดย renderPanels) */
.roster__panels.is-winner {
  display: block;
}

.winner {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 46px;
}

.winner__title {
  width: min(430px, 72%);
  height: auto;
  display: block;
  margin-bottom: 26px;
  filter: drop-shadow(0 6px 18px rgba(8, 20, 60, 0.6));
  animation: winnerTitleIn 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.winner__cards {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: 48px;
  flex-wrap: wrap;
}

.winner__card {
  margin: 0;
  animation: winnerCardIn 0.75s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.winner__card img {
  width: 100%;
  height: auto;
  display: block;
  /* ไฟล์การ์ดสูง 500px เท่ากันทั้งคู่ แต่กว้างไม่เท่ากัน (452 / 490)
     คุมด้วยความสูงจึงได้ขนาดที่ตาอ่านว่าเท่ากัน ไม่ใช่กว้างเท่ากัน */
  max-height: 440px;
  width: auto;
  filter: drop-shadow(0 12px 28px rgba(6, 16, 48, 0.55));
}

@keyframes winnerTitleIn {
  from { opacity: 0; transform: translateY(-16px) scale(0.92); }
  to   { opacity: 1; transform: none; }
}

@keyframes winnerCardIn {
  from { opacity: 0; transform: translateY(28px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

/* ---- พื้นหลังฉากเวทีของรอบประกาศผู้ชนะ ----
   .mid เดิมเป็น bg-body-content.png ยืดเต็มส่วน (100% 100%)
   ภาพเวทีสูง 2231px ถ้ายืดแบบเดียวกันจะเพี้ยนเมื่อเนื้อหายาว/สั้นกว่านั้น
   จึงวางไว้ชิดบนตามสัดส่วนจริง (100% auto) ไม่ยืดเต็ม และไม่มีสีรองพื้น
   ส่วนที่เลยภาพลงไปจึงเห็นสีพื้นของ body ตามปกติ */
body.is-winner-round .mid {
  background: url("../images/announce/bg-winner.png") top center / 100% auto no-repeat;
}

/* keyframes ทั้งสองตัวเป็น fill: both เริ่มที่ opacity 0 — ถ้าไม่ปิดในโหมดนี้
   การ์ดจะค้างมองไม่เห็นในเบราว์เซอร์ที่ไม่เล่นอนิเมชัน */
@media (prefers-reduced-motion: reduce) {
  .winner__title,
  .winner__card {
    animation: none;
  }
}

@media (min-width: 861px) and (max-width: 1399px) {
  .winner__title { width: min(360px, 76%); margin-bottom: 20px; }
  .winner__cards { gap: 32px; }
  .winner__card img { max-height: 360px; }
}

@media (max-width: 860px) {
  .winner { margin-bottom: 34px; }
  .winner__title { width: min(300px, 80%); margin-bottom: 16px; }
  /* จอแคบวางสองใบเรียงกันแล้วการ์ดจะเล็กจนอ่านชื่อไม่ออก — ซ้อนกันแทน */
  .winner__cards { flex-direction: column; align-items: center; gap: 24px; }
  .winner__card img { max-height: none; width: min(300px, 78vw); }
}
