* {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

.bt-icon {
    display: inline-block;
    flex: 0 0 auto;
    font-size: var(--bt-icon-size);
    width: 1em;
    height: 1em;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
}

.bt-icon--brand {
    stroke: none;
    fill: currentColor;
}

html,
body {
    background-color: var(--color-surface-page);
    scroll-behavior: auto;
    scrollbar-color: rgba(108, 117, 125, 0.75) transparent;
    scrollbar-width: thin;
    /* scrollbar-gutter: stable; */
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {
    width: 4px !important;
    height: 4px !important;
    background: transparent;
}

html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track {
    border: 0;
    background: transparent;
}

html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb {
    border: 0;
    border-radius: 999px;
    background: rgba(108, 117, 125, 0.75);
}

html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover {
    background: rgba(73, 80, 87, 0.9);
}

html::-webkit-scrollbar-corner,
body::-webkit-scrollbar-corner {
    background: transparent;
}

/* Reserve and calculate the native scrollbar while the opaque loader still covers
   the page, but keep its thumb invisible until the page reveal actually begins. */
html.is-preparing-page-scroll,
html.is-preparing-page-scroll body {
    scrollbar-color: transparent transparent;
}

html.is-preparing-page-scroll::-webkit-scrollbar-thumb,
html.is-preparing-page-scroll body::-webkit-scrollbar-thumb {
    background: transparent;
}

body {
    width: 100%;
    margin: 0;
    background-color: var(--color-surface-page);
    font-family: var(--font);
    overflow-x: hidden;
}

body.menu-open,
body.menu-closing {
    overflow: hidden;
}

body.is-loading {
    height: 100%;
    overflow: hidden;
}

.back-to-top {
    --back-to-top-progress: 0deg;

    position: fixed;
    right: max(var(--space-5), env(safe-area-inset-right));
    bottom: max(var(--space-5), env(safe-area-inset-bottom));
    z-index: 240;
    width: var(--touch-target-md);
    height: var(--touch-target-md);
    display: inline-grid;
    place-items: center;
    padding: 0;
    isolation: isolate;
    overflow: hidden;
    border: var(--border-width-1) solid var(--alpha-ink-12);
    border-radius: 50%;
    color: var(--color-text-primary);
    background: color-mix(in srgb, var(--color-surface-page) 88%, #ffffff);
    /* box-shadow: 0 var(--space-2) var(--space-6) var(--alpha-ink-16); */
    opacity: 0;
    pointer-events: none;
    transform: translateY(var(--space-3)) scale(0.94);
    transition:
        opacity var(--duration-standard) var(--ease-standard),
        transform var(--duration-standard) var(--ease-standard),
        color var(--duration-fast) var(--ease-standard),
        background-color var(--duration-fast) var(--ease-standard),
        border-color var(--duration-fast) var(--ease-standard);

    &::before,
    &::after {
        content: '';
        position: absolute;
        border-radius: inherit;
        pointer-events: none;
    }

    &::before {
        inset: -1px;
        z-index: 0;
        background: var(--spectrum);
        -webkit-mask:
            radial-gradient(farthest-side, transparent calc(100% - var(--border-width-6)), #000 0),
            conic-gradient(from -90deg, #000 var(--back-to-top-progress), transparent 0);
        -webkit-mask-composite: source-in;
        mask:
            radial-gradient(farthest-side, transparent calc(100% - var(--border-width-6)), #000 0),
            conic-gradient(from -90deg, #000 var(--back-to-top-progress), transparent 0);
        mask-composite: intersect;
        opacity: 0;
    }

    &::after {
        inset: var(--space-1);
        z-index: 1;
        background: color-mix(in srgb, var(--color-surface-page) 88%, #ffffff);
    }

    .bt-icon {
        position: relative;
        z-index: 2;
        width: var(--bt-icon-size);
        height: var(--bt-icon-size);
        transform: rotate(-45deg);
        stroke-width: 2;
        opacity: 0;
        transition: opacity var(--duration-fast) var(--ease-standard);
    }

    &:hover {
        color: var(--color-surface-page);
        border-color: var(--color-text-primary);
        background: var(--color-text-primary);

        &::after {
            background: var(--color-text-primary);
        }
    }

    &:focus-visible {
        opacity: 1;
        pointer-events: auto;
        outline: var(--border-width-2) solid var(--color-accent-primary);
        outline-offset: var(--space-1);
    }
}

.back-to-top.is-progress {
    pointer-events: none;
    border-color: transparent;
    background: transparent;
    box-shadow: none;

    &::before {
        opacity: 1;
    }

    &::after {
        background: transparent;
    }
}

.back-to-top.is-ready {
    --back-to-top-progress: 360deg;

    animation: back-to-top-ready-pop var(--duration-slow) var(--ease-standard) both;

    .bt-icon {
        opacity: 1;
    }
}

@keyframes back-to-top-ready-pop {
    0% {
        transform: translateY(var(--space-4)) scale(0.82);
    }

    62% {
        transform: translateY(calc(var(--space-1) * -1)) scale(1.06);
    }

    100% {
        transform: translateY(0) scale(1);
    }
}

@media (prefers-reduced-motion: reduce) {
    .back-to-top.is-ready {
        animation: none;
    }
}

.back-to-top.is-visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0) scale(1);
}

.back-to-top.is-visible.is-progress {
    pointer-events: none;
}

body.is-loading .back-to-top,
body.menu-open .back-to-top,
body.menu-closing .back-to-top {
    opacity: 0;
    pointer-events: none;
    transform: translateY(var(--space-3)) scale(0.94);
}

/* ---------- Early Bird floating offer ----------
   ใช้ภาษาเดียวกับ section อื่นของเว็บ: การ์ดพื้นขาวเส้นขอบบาง คั่นแต่ละส่วนด้วยเส้น hairline
   (ไม่ซ้อนกล่องในกล่อง) ป้ายหัวเป็น eyebrow เซริฟตัวใหญ่แบบ .bt-section-subtext
   เส้นสเปกตรัมด้านบนคือแอคเซนต์เดียวกับเส้นใต้แท็บ ส่วนสีน้ำเงินเก็บไว้ที่ราคาอย่างเดียว
   เหมือนช่องราคาที่ถูกเลือกในตาราง Ticket */
.early-bird-float {
    position: fixed;
    right: max(var(--space-5), env(safe-area-inset-right));
    bottom: max(var(--space-5), env(safe-area-inset-bottom));
    z-index: 250;
    /* แถบหัวการ์ดดึงขอบด้วย margin ลบเท่าค่านี้ ประกาศเป็นตัวแปรเพื่อให้ทั้งสองค่าตรงกันเสมอ */
    --early-bird-float-pad: var(--space-4);

    width: auto;
    /* width: min(calc(100% - var(--space-12)), 280px); */
    padding: var(--early-bird-float-pad);
    overflow: hidden;
    border-radius: var(--radius-1);
    color: var(--color-text-primary);
    background: var(--color-surface-popover);
    box-shadow: 0 var(--space-3) var(--space-8) var(--alpha-ink-12);
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity var(--duration-standard) var(--ease-standard),
        transform var(--duration-standard) var(--ease-standard),
        box-shadow var(--duration-fast) var(--ease-standard);
}

/* พื้นหลังชุดเดียวกับ .ticket__plan-ribbon (คัดลอกค่ามาตรง ๆ) แล้วดึงเต็มขอบการ์ดด้วย margin ลบ
   เท่ากับ padding ของการ์ด ให้เป็นแถบคาดหัวการ์ดเหมือนริบบิ้นของแพ็กเกจ Ticket
   พื้นเข้มจึงต้องสลับสีตัวอักษรเป็นชุด inverse ตามที่ริบบิ้นทำ */
.early-bird-float__header {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin: calc(var(--early-bird-float-pad) * -1) calc(var(--early-bird-float-pad) * -1) 0;
    padding: var(--space-1) var(--space-2) var(--space-1) var(--space-4);
    color: var(--color-text-inverse);
    background: linear-gradient(180deg, #19274A 0%, #020B1E 100%);
    border-radius: var(--radius-1) var(--radius-1) var(--radius-0) var(--radius-0);
}

/* แสงทองและเส้นเรืองด้านบน คัดลอกจาก .ticket__plan-ribbon ทั้งชุด
   ต้องมี position/isolation/overflow ที่ตัวแถบ (ด้านบน) เหมือนริบบิ้น
   ไม่งั้น z-index: -1 จะหลุดไปอยู่หลังพื้นการ์ดและ glow จะไม่ถูกตัดขอบ */
.early-bird-float__header::before,
.early-bird-float__header::after {
    content: "";
    position: absolute;
    pointer-events: none;
}

.early-bird-float__header::before {
    inset: calc(var(--space-4) * -1) var(--space-8) auto;
    z-index: -1;
    height: calc(100% + var(--space-8));
    background:
        radial-gradient(ellipse at 50% 0%, rgba(244, 221, 178, 0.3) 0%, rgba(214, 171, 104, 0.16) 36%, transparent 74%);
    filter: blur(10px);
    opacity: 0.94;
}

.early-bird-float__header::after {
    top: 0;
    left: 50%;
    z-index: -1;
    width: min(72%, 280px);
    height: var(--border-width-1);
    background: linear-gradient(90deg,
            transparent 0%,
            rgba(244, 221, 178, 0.18) 14%,
            rgba(231, 201, 151, 0.82) 50%,
            rgba(214, 171, 104, 0.22) 86%,
            transparent 100%);
    box-shadow:
        0 0 14px rgba(231, 201, 151, 0.34),
        0 0 24px rgba(214, 171, 104, 0.16);
    opacity: 0.86;
    transform: translateX(-50%);
}

.early-bird-float__offer {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    color: inherit;
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-small-line-height);
}

/* ป้ายส่วนลดชุดเดียวกันใช้ซ้ำหลังราคาเดิมในการ์ด Ticket
   (selector ของ Ticket ต้องเจาะจงพอชนะ .ticket__price span ที่ย่อ/ขยายฟอนต์ตาม breakpoint) */
.early-bird-float__discount,
.ticket .ticket__price .ticket__price-save {
    display: inline-block;
    padding: 6px var(--space-2);
    border-radius: var(--radius-1);
    color: var(--color-neutral-0);
    background: var(--color-danger-600);
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    white-space: nowrap;
}

/* ชุดเดียวกับ .cookie-banner__dismiss (คัดลอกค่ามาตรง ๆ) */
.early-bird-float__toggle {
    width: var(--space-10);
    height: var(--space-10);
    padding: 0;
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    border: 0;
    border-radius: var(--radius-round);
    color: var(--color-text-secondary);
    background: transparent;
    cursor: pointer;
    transition:
        color var(--duration-fast) var(--ease-standard),
        background-color var(--duration-fast) var(--ease-standard);
}

/* ปุ่มอยู่บนแถบหัวพื้นเข้ม สีชุดของ cookie banner (หมึกบนพื้นสว่าง) จะจมหายไป
   จึงสลับเป็นชุด inverse เฉพาะสี ส่วนขนาด/รูปทรง/จังหวะ transition คงตามต้นฉบับ */
.early-bird-float__header .early-bird-float__toggle {
    color: var(--color-text-inverse);
}

.early-bird-float__toggle:hover {
    color: var(--color-text-primary);
    /* background: var(--alpha-ink-06); */
}

/* hover ของต้นฉบับเป็นฟิล์มหมึกจาง ๆ บนพื้นสว่าง บนแถบเข้มจึงใช้ฟิล์มขาวแทนให้เห็นผลเหมือนกัน */
.early-bird-float__header .early-bird-float__toggle:hover {
    color: var(--color-text-inverse);
    /* background: var(--alpha-white-12); */
}

.early-bird-float__toggle:focus-visible {
    outline: var(--border-width-2) solid var(--color-focus-ring);
    outline-offset: var(--space-1);
}

.early-bird-float__toggle-icon {
    width: var(--space-2);
    height: var(--space-2);
    border-right: var(--border-width-2) solid currentColor;
    border-bottom: var(--border-width-2) solid currentColor;
    transform: rotate(45deg);
    transition: transform var(--duration-standard) var(--ease-standard);
}

.early-bird-float__body {
    max-height: 360px;
    margin-top: var(--space-3);
    overflow: hidden;
    opacity: 1;
    transition:
        max-height var(--duration-slow) var(--ease-standard),
        margin-top var(--duration-standard) var(--ease-standard),
        opacity var(--duration-fast) var(--ease-standard);
}

/* ชื่อบัตร (ซ้าย) กับราคา (ขวา) วางคู่กันในแถวเดียว ส่วนที่เหลือกินความกว้างเต็ม
   วางตำแหน่งทุกชิ้นชัดเจน ไม่พึ่ง auto-placement เพื่อไม่ให้ลำดับใน HTML ทำให้ช่องเพี้ยน */
/* คอลัมน์ซ้ายกว้างเท่าข้อความที่ยาวที่สุดในบล็อกชื่อบัตร (บัตร ULTIMATE) พอดี
   พื้นที่ที่เหลือไปอยู่ในคอลัมน์ราคา ซึ่งจัดราคาชิดขวาไว้ ตำแหน่งที่เห็นจึงเหมือนเดิม */
.early-bird-float__body-inner {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: var(--space-3);
}

.early-bird-float__plan-name {
    grid-area: 1 / 1;
}

/* ราคาอยู่แถวเดียวกับบล็อกชื่อบัตร ชิดขวา */
.early-bird-float__price {
    grid-area: 1 / 2;
    justify-self: end;
    align-self: self-start;
    align-items: flex-end;
}

.early-bird-float__countdown-label,
.early-bird-float__countdown,
.early-bird-float__action {
    grid-column: 1 / -1;
}

.early-bird-float__countdown-label {
    padding-top: var(--space-3);
    border-top: var(--rule-width-subtle) solid var(--color-border-faint);
}

/* ชื่อแพ็กเกจใช้ค่าเดียวกับหัวการ์ด Ticket: .ticket__plan-index (คำว่า "บัตร") และ .ticket__plan-header h3 (ULTIMATE)
   "บัตร" เป็น span ใน <p> ชื่อบัตร แต่แสดงเป็นบรรทัดของตัวเองด้านบน ULTIMATE
   จึงต้องคืนฟอนต์/ระยะตัวอักษรของตัวเอง ไม่รับ Baskervville กับ tracking ของชื่อบัตร */
.early-bird-float__plan-index {
    margin: var(--space-0) var(--space-0) var(--space-1);
    display: block;
    font-family: var(--font);
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-small-line-height);
    letter-spacing: 0;
    text-transform: uppercase;
}

.early-bird-float__plan-name {
    margin: 0;
    font-family: 'Baskervville', var(--font-family-base);
    font-size: var(--font-size-20);
    font-weight: var(--font-weight-regular);
    /* 1.2 เท่ากับที่หัวการ์ด Ticket คำนวณได้ (h3 รับค่ามาจากกฎหัวข้อรวม) */
    line-height: 1.2;
    letter-spacing: var(--section-heading-tracking);
    text-transform: uppercase;
}

/* จำนวนวันต่อท้าย ULTIMATE ในบรรทัดเดียวกัน ตัวเล็กกว่าเพื่อไม่แย่งน้ำหนักกับชื่อบัตร */
.early-bird-float__plan-name small {
    font-family: var(--font);
    letter-spacing: 0;
    font-size: var(--font-size-14);
    font-weight: var(--font-weight-regular);
    padding-left: var(--space-1);
}

/* จำนวนวัน ราคาเดิม และราคา Early Bird อยู่บรรทัดเดียวกัน เรียงตามเส้นฐานตัวอักษร
   ขนาดของแต่ละชิ้นยังเท่ากับช่องราคาที่ถูกเลือกในตาราง Ticket (.ticket__price.is-active) */
.early-bird-float__price {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
    /* ชิดขวาเพราะบล็อกราคาอยู่ฝั่งขวาของชื่อบัตร ราคาเดิมกับราคาใหม่จะได้ตรงขอบขวาเดียวกัน */
    align-items: flex-end;
    gap: var(--space-0);
    font-variant-numeric: tabular-nums;
}

/* = .ticket__price-day */
/* = .ticket__price-original */
.early-bird-float__price del {
    color: var(--color-text-inverse-muted);
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-small-line-height);
    text-decoration-thickness: var(--border-width-1);
    margin-bottom: 2px;
}

/* = .ticket__price strong ที่สถานะ is-active (ราคาเดิมอยู่ก่อนหน้า จึงไม่มี margin-top เหมือนกฎ .ticket__price-original+strong) */
.early-bird-float__price strong {
    color: var(--color-blue-600);
    font-size: calc(var(--font-size-24) - 2px);
    ;
    font-weight: var(--font-weight-medium);
    line-height: 1.2;
    letter-spacing: 0;
    white-space: nowrap;
}

/* = หน่วยเงินใน .ticket__price strong small */
.early-bird-float__price strong small {
    color: var(--color-text-muted);
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-medium);
}

.early-bird-float__countdown-label {
    margin: var(--space-3) 0 0;
    color: var(--color-text-muted);
    font-size: 10px;
    line-height: var(--section-small-line-height);
}

.early-bird-float__countdown {
    display: grid;
    margin-top: var(--space-3);
    font-variant-numeric: tabular-nums;
}

/* กลไกเดียวกับ countdown ใน hero: คอลัมน์กว้างเท่ากัน ตัวเลขกับหน่วยอยู่กลางคอลัมน์
   และเส้นคั่นอยู่กลางช่องไฟพอดี (ดู ::after ด้านล่าง) ระยะสองข้างเส้นจึงเท่ากัน */
.early-bird-float__countdown-values {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-6);
}

.early-bird-float__countdown-unit {
    position: relative;
    min-width: 0;
    display: grid;
    justify-items: center;
    gap: var(--space-1);
}

/* เส้น-ดาวคั่นตัวเลขชุดเดียวกับ countdown ใน hero (หมุนตั้งเหมือนกัน)
   left: 100% + ครึ่งหนึ่งของ gap แล้วเลื่อนกลับครึ่งตัวเอง = จุดกึ่งกลางช่องไฟเป๊ะ */
.early-bird-float__countdown-unit:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 50%;
    /* ครึ่งหนึ่งของ gap (space-6) เส้นคั่นจึงอยู่กลางช่องไฟพอดี — เปลี่ยน gap ต้องเปลี่ยนค่านี้ตาม */
    left: calc(100% + var(--space-3));
    width: var(--space-10);
    height: calc(var(--space-10) / var(--bt-hero-countdown-divider-ratio));
    background: url('../images/line-star-countdown.webp') center / contain no-repeat;
    transform: translate(-50%, -50%) rotate(90deg);
    transform-origin: center;
}

.early-bird-float__countdown-unit strong {
    font-size: var(--font-size-16);
    font-weight: var(--font-weight-medium);
    line-height: 1;
}

.early-bird-float__countdown-unit small {
    color: var(--color-text-muted);
    font-size: 10px;
    font-weight: var(--font-weight-regular);
    line-height: 1;
}

.early-bird-float__countdown-status {
    display: none;
    min-height: var(--space-8);
    align-items: center;
    color: var(--color-text-secondary);
    font-size: var(--font-size-16);
    font-weight: var(--font-weight-regular);
    line-height: 1.3;
}

.early-bird-float__countdown.is-status .early-bird-float__countdown-values {
    display: none;
}

.early-bird-float__countdown.is-status .early-bird-float__countdown-status {
    display: flex;
}

/* ความสูง/padding มาจาก .bt-action-button--sm ของระบบ ส่วนฟอนต์ย่อเหลือ 12px เฉพาะปุ่มนี้
   (ผูก selector กับ --sm ไว้เพื่อให้ชนะกฎของระบบ โดยไม่แตะปุ่ม --sm อื่นในหน้า) */
.early-bird-float__action {
    width: 100%;
    margin-top: var(--space-4);
}

.early-bird-float__action.bt-action-button--sm {
    font-size: var(--font-size-12);
}

/* ปุ่มดำล้วน (ไม่มีขอบ spectrum) ทุกปุ่มในเว็บ: สีพื้นสว่างกว่าปุ่ม primary ปกติหนึ่งระดับ (900 → 800)
   ไม่ให้กลืนกับพื้นมืด (เช่น section playbook) และ hover ขึ้นอีกหนึ่งระดับ (700)
   ตัวปุ่มแต่ละที่ยังตั้ง border/background = --bt-action-fill ในกฎของตัวเองเหมือนเดิม */
:is(.early-bird-float__action,
    .ticket__action,
    .playbook__action-link,
    .cookie-banner__button,
    .playbook-steps__action .bt-action-button,
    .playbook-ticket__action).bt-action-button--primary {
    --bt-action-fill: var(--color-neutral-800);

    &:hover {
        --bt-action-fill: var(--color-neutral-700);
    }
}

/* Match the solid black treatment used by the Ultimate ticket action. */
.early-bird-float__action.bt-action-button--primary {
    border-color: var(--bt-action-fill);
    background: var(--bt-action-fill);
}

/* ย่อแล้วเหลือแค่แถบหัว ตัด padding ล่างออกไม่ให้มีแถบพื้นขาวค้างใต้ริบบิ้น */
.early-bird-float.is-collapsed {
    padding-bottom: 0;
    box-shadow: 0 var(--space-2) var(--space-6) var(--alpha-ink-12);
}

.early-bird-float.is-collapsed .early-bird-float__body {
    max-height: 0;
    margin-top: 0;
    opacity: 0;
    pointer-events: none;
}

.early-bird-float.is-collapsed .early-bird-float__toggle-icon {
    transform: rotate(225deg);
}

body.is-loading .early-bird-float,
body.menu-open .early-bird-float,
body.menu-closing .early-bird-float {
    opacity: 0;
    pointer-events: none;
    transform: translateY(var(--space-4));
}

/* Keep Back to top above the offer while preserving its original visibility logic. */
@media (min-width:576px) {
    .back-to-top {
        right: max(var(--space-5), env(safe-area-inset-right));
        bottom: calc(max(var(--space-5), env(safe-area-inset-bottom)) + var(--early-bird-float-height, 246px) + var(--space-3));
    }
}

@media (max-width:575px) {
    .early-bird-float {
        right: 50%;
        bottom: calc(var(--space-10) + var(--space-6) + max(var(--space-3), env(safe-area-inset-bottom)));
        transform: translateX(50%);
        width: calc(100% - var(--space-24));
    }

    /* JS keeps this height variable in sync while the offer expands and collapses. */
    .back-to-top {
        right: max(var(--space-3), env(safe-area-inset-right));
        bottom: calc(var(--space-10) + var(--space-6) + max(var(--space-3), env(safe-area-inset-bottom)) + var(--early-bird-float-height, 58px) + var(--space-3));
    }
}

@media (max-width:359px) {
    .early-bird-float {
        --early-bird-float-pad: var(--space-3);
    }

    .early-bird-float__price strong {
        font-size: var(--font-size-24);
    }
}

@media (prefers-reduced-motion: reduce) {

    .early-bird-float,
    .early-bird-float__body,
    .early-bird-float__toggle-icon {
        transition-duration: var(--duration-reduced);
    }

}

/* ---------- แถบปุ่มลอยชิดขอบล่าง (จอ <=575px เท่านั้น) ---------- */
.mobile-cta-bar {
    display: none;
}

@media (max-width:575px) {
    .mobile-cta-bar {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-3);
        position: fixed;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 220;
        padding: var(--space-3) var(--space-4) max(var(--space-3), env(safe-area-inset-bottom));
        background: var(--color-surface-page);
        box-shadow: 0 calc(var(--space-1) * -1) var(--space-6) var(--alpha-ink-12);
        opacity: 0;
        pointer-events: none;
        transform: translateY(100%);
        transition:
            opacity var(--duration-standard) var(--ease-standard),
            transform var(--duration-standard) var(--ease-standard);

        /* padding แคบกว่า --xl ปกติ เพื่อให้ปุ่มสองตัวเรียงกันได้ครบบนจอ 360px
           โดยยังคงขนาดตัวอักษร 16px ไว้ (ต่างจากปุ่มบนแถบ header ที่ย่อเหลือ 14px) */
        .bt-action-button--header {
            padding-inline: var(--space-4);
        }

        /* .bt-action-button {
            flex: 1;
        } */
    }

    .mobile-cta-bar.is-visible {
        opacity: 1;
        pointer-events: auto;
        transform: translateY(0);
    }

    body.is-loading .mobile-cta-bar,
    body.menu-open .mobile-cta-bar,
    body.menu-closing .mobile-cta-bar {
        opacity: 0;
        pointer-events: none;
        transform: translateY(100%);
    }

    /* วางเหนือทั้งแถบ CTA และกล่อง Early Bird โดย JS อัปเดตความสูงกล่องให้ตรงกับสถานะ */
    .back-to-top {
        bottom: calc(var(--space-10) + var(--space-6) + max(var(--space-3), env(safe-area-inset-bottom)) + var(--early-bird-float-height, 72px) + var(--space-3));
    }
}

/* หน้าที่ไม่มีกล่อง Early Bird (หน้า playbook หรือตอนปิดกล่องไว้) ปุ่มกลับไปอยู่มุมล่างตามปกติ */
body:is(.playbook-page, :not(:has(.early-bird-float))) .back-to-top {
    right: max(var(--space-5), env(safe-area-inset-right));
    bottom: max(var(--space-5), env(safe-area-inset-bottom));
}

@media (max-width:575px) {
    body:is(.playbook-page, :not(:has(.early-bird-float))) .back-to-top {
        right: max(var(--space-3), env(safe-area-inset-right));
        bottom: calc(var(--space-10) + var(--space-6) + max(var(--space-3), env(safe-area-inset-bottom)));
    }
}

p {
    font-family: var(--font);
}

h1,
h2,
h3,
h4,
h5,
h6,
.headline {
    font-family: var(--headline);
    letter-spacing: 0;
}

button,
a {
    -webkit-tap-highlight-color: transparent;
}

button {
    font-family: var(--font);
}

/* ---------- reusable section title responsive ----------
   ใช้เป็น media ของ component กลางที่ถูกเรียกในหลาย section
   จึงวางไว้ช่วงต้นไฟล์แทนการกระจายไว้ท้ายไฟล์ */
@media (max-width:991px) {
    section[aria-labelledby] h2.bt-section-title {
        --bt-section-title-size: var(--font-size-40);
        font-size: var(--bt-section-title-size);
    }
}

@media (max-width:767px) {
    section[aria-labelledby] h2.bt-section-title {
        --bt-section-title-size: var(--font-size-32);
        font-size: var(--bt-section-title-size);
    }
}

@media (max-width:575px) {
    section[aria-labelledby] h2.bt-section-title {
        --bt-section-title-size: var(--font-size-28);
        font-size: var(--bt-section-title-size);
    }
}

/* ---------- global header ----------
    Fixed for its whole life (not just once "sticky") so it can float over the
    pinned hero from frame one. Visibility has three phases, driven by scroll
    position in the header script below: shown while the CTA/date/venue block is
    still up, hidden once that block has faded out, shown again (sticky) only once
    the hero's scroll-pin has fully released into the next section. */
.site-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 200;
    min-height: var(--header-height);
    background: transparent;
    border: 0;
    opacity: 1;
    transform: translateY(0);
    transition: opacity 520ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 520ms cubic-bezier(0.16, 1, 0.3, 1),
        background-color 320ms ease;
}

.site-header,
.site-header a,
.site-header button {
    font-family: var(--headline);
}

.site-header.is-hidden {
    opacity: 0;
    transform: translateY(-100%);
    pointer-events: none;
}

body.menu-open .site-header,
body.menu-closing .site-header,
body.menu-open .site-header.is-sticky.site-header--on-dark,
body.menu-closing .site-header.is-sticky.site-header--on-dark {
    background: var(--bt-header-bg);
    opacity: 1;
    transform: none;
    pointer-events: auto;
    /* The header may currently be translated off-screen by the hero scroll state.
       Snap it back before Safari lays out the fixed menu; animating that transform
       temporarily makes the menu use the 80px header as its containing block. */
    transition: none;
}

/* ความกว้างเดียวกันทั้งตอนปกติและตอน sticky (ไม่ใช้ .container ตอน sticky อีกแล้ว) */
.site-header__inner {
    width: min(calc(100% - var(--space-12)), 1460px);
    min-height: var(--header-height);
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(152px, 0.7fr) auto minmax(288px, 0.7fr);
    align-items: center;
    gap: var(--space-8);
}

.site-header.is-sticky {
    background: var(--bt-header-bg);
}

/* ทับด้วยพื้นมืดตอนที่ section พื้นสีดำ (data-header-theme="dark") อยู่ใต้ header พอดี
   ใช้เฉดเดียวกับพื้นหลังของ section นั้น แถบ header จึงกลืนไปกับเนื้อหาแทนที่จะเป็น
   แถบขาวคาดทับ ตัวอักษร/โลโก้สลับเป็นเวอร์ชันพื้นมืดอยู่แล้วผ่าน .site-header--on-dark */
.site-header.is-sticky.site-header--on-dark {
    background: var(--bt-header-bg-on-dark);
}

.site-header__logo {
    width: 120px;
    position: relative;
    display: flex;
    align-items: center;
}

.site-header__logo img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
    object-position: left center;
}

.site-header__logo-image--on-dark {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 180ms ease;
}

/* ท้องฟ้าชุดสว่าง: บน hero ใช้โลโก้สีปกติ (เวอร์ชันขาวเหลือไว้เฉพาะ section พื้นมืดจริง) */
.site-header--on-dark .site-header__logo-image--on-dark {
    opacity: 1;
}

.site-header__nav {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-10);
    min-width: 0;
}

/* Marks the nav's own footprint as "dark" while the hero's sky is the visible
   backdrop (toggled in hero-v2-header.js). Tagged data-header-theme="dark" so
   setupHeaderThemeObserver's IntersectionObserver counts the hero-sky phase toward
   .site-header--on-dark. The light sky set (images/light, video/light) is a light
   backdrop, so the sensor stays hidden and the header keeps its normal dark ink there;
   re-enable the .site-header--hero-sky rule below if the dark sky ever comes back. */
.site-header__nav-sky-sensor {
    display: none;
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* .site-header--hero-sky .site-header__nav-sky-sensor {
    display: block;
} */

/* ท้องฟ้าชุดสว่าง: เมนูบน hero ใช้ตัวดำไม่มีเงา (ชุดมืดเดิมเป็นตัวขาวมีเงา) */
.site-header--hero-sky:not(.is-sticky) .site-header__nav a {
    color: var(--color-text-primary);
    text-shadow: none;
}

.site-header__nav a {
    position: relative;
    min-height: var(--space-10);
    padding: 0 var(--space-1);
    display: grid;
    place-items: center;
    color: var(--bt-header-nav-ink);
    text-decoration: none;
    font-size: var(--font-size-16);
    text-transform: uppercase;
    /* ทุกเมนูต้องอยู่บรรทัดเดียวเสมอ ห้ามตัดสองบรรทัด ถ้าแถบไม่พอให้บีบฟอนต์/ช่องไฟแทน */
    white-space: nowrap;
    transition:
        color 180ms ease,
        opacity 180ms ease,
        text-shadow 180ms ease;
}

.site-header__nav-label {
    transition: color 180ms ease;
}

.site-header--on-dark .site-header__nav a {
    color: rgba(255, 255, 255, 0.82);
}

/* เส้นบอกเมนูที่เลือกอยู่ไปเกาะขอบล่างของแถบ header ไม่ใช่ใต้ตัวอักษร
   ลิงก์ถูกจัดกึ่งกลางแนวตั้งในแถบ ช่องว่างใต้ลิงก์จึงเท่ากับ (ความสูง header - ความสูงลิงก์) / 2
   ดึงเส้นลงเท่านั้นพอดี และเขียนเป็น token ไว้ ความสูง header เปลี่ยนตาม breakpoint ก็ยังตรง */
.site-header__nav a::after {
    content: '';
    position: absolute;
    left: var(--space-1);
    right: var(--space-1);
    bottom: calc((var(--header-height) - var(--space-10)) / -2);
    height: 3px;
    background: var(--spectrum);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
}

.site-header__nav a:hover {
    opacity: 0.64;
}

.site-header__nav a:focus-visible {
    color: var(--bt-header-nav-ink-hover);
}

.site-header--on-dark .site-header__nav a:focus-visible {
    color: var(--bt-header-nav-ink-on-dark-hover);
}

.site-header__nav a:hover::after,
.site-header__nav a:focus-visible::after,
.site-header__nav a[aria-current='page']::after {
    transform: scaleX(1);
}

.site-header__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
}

.site-header__primary-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ปุ่มใน header ใช้สเกลเล็กกว่า --xl ปกติ เพราะต้องแชร์แถวเดียวกับโลโก้และ nav
   ทั้งแถบ ถ้าคงไว้ที่ 16px ป้าย "ซื้อบัตร Early Bird" จะดันจนตัวหนังสือของ
   INVESTOR DNA ขาด (js/hero-v2-cta.js mount ปุ่ม liquid metal ด้วยสเกลเดียวกัน) */
.site-header .bt-action-button--header {
    padding-inline: var(--space-4);
    font-size: var(--font-size-14);
}

.site-header .bt-action-button--primary {
    --bt-action-fill: var(--color-text-primary);

    border-color: transparent;
    color: var(--color-surface-soft);
    background:
        linear-gradient(var(--bt-action-fill), var(--bt-action-fill)) padding-box,
        var(--gradient-accent-spectrum) border-box;

    &:hover,
    &:focus-visible {
        --bt-action-fill: var(--color-text-secondary);

        color: var(--color-neutral-0);
        background:
            linear-gradient(var(--bt-action-fill), var(--bt-action-fill)) padding-box,
            var(--gradient-accent-spectrum) border-box;
    }
}

.site-header__toggle {
    width: var(--bt-menu-toggle-size);
    height: var(--bt-menu-toggle-size);
    padding: 0;
    display: none;
    place-items: center;
    border: 0;
    border-radius: 0;
    color: var(--bt-menu-ink);
    background: transparent;
    cursor: pointer;
    appearance: none;
    box-shadow: none;
    transition: color var(--bt-duration-fast) ease;
}

.site-header--on-dark .site-header__toggle {
    color: var(--bt-menu-toggle-ink-on-dark);
}

.site-header__toggle-lines {
    position: relative;
    width: var(--bt-menu-toggle-lines-width);
    height: var(--bt-menu-toggle-lines-height);
}

.site-header__toggle-lines span {
    position: absolute;
    left: 0;
    width: var(--bt-menu-toggle-lines-width);
    height: var(--bt-menu-toggle-line-height);
    background: currentColor;
    transition:
        transform var(--bt-duration-base) var(--bt-ease-standard),
        top var(--bt-duration-base) ease,
        opacity var(--bt-duration-fast) ease;
}

.site-header__toggle-lines span:nth-child(1) {
    top: 0;
}

.site-header__toggle-lines span:nth-child(2) {
    top: var(--bt-menu-toggle-line-middle);
}

.site-header__toggle-lines span:nth-child(3) {
    top: var(--bt-menu-toggle-line-bottom);
}

.site-header__toggle[aria-expanded='true'] .site-header__toggle-lines span:nth-child(1) {
    top: var(--bt-menu-toggle-line-middle);
    transform: rotate(45deg);
}

.site-header__toggle[aria-expanded='true'] .site-header__toggle-lines span:nth-child(2) {
    opacity: 0;
}

.site-header__toggle[aria-expanded='true'] .site-header__toggle-lines span:nth-child(3) {
    top: var(--bt-menu-toggle-line-middle);
    transform: rotate(-45deg);
}

.site-header__mobile {
    position: fixed;
    inset: 0;
    z-index: 196;
    padding-top: var(--header-height);
    background: var(--bt-menu-bg);
    font-family: var(--headline);
    visibility: hidden;
    pointer-events: none;
    clip-path: inset(0 0 100% 0);
    transition:
        clip-path var(--bt-menu-transition-duration) var(--bt-menu-transition-ease),
        visibility 0s linear var(--bt-menu-visibility-delay);
    will-change: clip-path;
}

.site-header__mobile a {
    font-family: var(--headline);
}

.site-header__mobile-scroll {
    width: min(100%, var(--bt-menu-panel-max-width));
    height: calc(100vh - var(--header-height));
    height: calc(100dvh - var(--header-height));
    margin: 0 auto;
    padding: var(--bt-menu-scroll-padding-y) var(--bt-menu-scroll-padding-x) max(var(--bt-menu-scroll-padding-bottom), env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    opacity: 0;
    transition: opacity var(--bt-menu-content-fade-duration) ease;
}

.site-header__mobile-scroll::-webkit-scrollbar {
    display: none;
}

.site-header__mobile-eyebrow,
.site-header__mobile-label {
    margin: 0;
    color: var(--bt-menu-muted);
    font-size: var(--bt-menu-label-size);
    font-weight: var(--bt-menu-label-weight);
    line-height: 1;
    text-transform: uppercase;
}

.site-header__mobile-eyebrow {
    padding-bottom: var(--bt-menu-sponsor-padding-top);
}

.site-header__mobile-nav {
    padding-bottom: var(--space-6);
}

.site-header__mobile-nav a {
    min-height: var(--bt-menu-nav-link-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: var(--bt-menu-ink);
    text-decoration: none;
    font-size: var(--bt-menu-nav-font-size-sm);
    font-weight: var(--bt-font-weight-regular);
    line-height: var(--bt-menu-nav-line-height);
    letter-spacing: var(--bt-menu-nav-tracking);
    text-transform: uppercase;
    transition:
        color var(--bt-menu-link-transition-duration) ease,
        padding-left var(--bt-menu-link-indent-duration) var(--bt-ease-standard);
}

.site-header__mobile-nav a:hover,
.site-header__mobile-nav a:focus-visible {
    color: var(--bt-menu-ink-hover);
    padding-left: var(--bt-menu-nav-hover-indent);
}

.site-header__mobile-nav-index {
    align-self: flex-start;
    margin-top: var(--bt-menu-index-offset-y);
    color: var(--bt-menu-index);
    font-size: var(--bt-menu-index-size);
    font-weight: var(--bt-menu-label-weight);
    line-height: 1;
    letter-spacing: var(--bt-menu-index-tracking);
}

.site-header__mobile-actions {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--bt-menu-actions-gap);
    padding: var(--bt-menu-actions-padding-y) 0;
}

.site-header__mobile-footer {
    padding-top: var(--bt-menu-footer-padding-top);
    display: flex;
    flex-wrap: wrap;
    gap: var(--bt-menu-footer-gap);
    border-top: var(--bt-border-width-1) solid var(--bt-menu-line);
}

.site-header__mobile-contact {
    min-width: calc(50% - var(--bt-menu-footer-gap));
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--bt-menu-contact-gap);
}

.site-header__mobile-contact--primary {
    width: 100%;
}

.site-header__mobile-contact-grid {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    column-gap: var(--space-4);
    row-gap: var(--space-3);
}

.site-header__mobile-contact a {
    max-width: 100%;
    color: var(--bt-menu-ink);
    font-size: var(--bt-menu-contact-font-size);
    line-height: var(--bt-menu-contact-line-height);
    text-decoration: underline;
    text-decoration-color: var(--bt-menu-link-underline);
    text-underline-offset: var(--bt-menu-contact-underline-offset);
    overflow-wrap: anywhere;
}

.site-header__mobile-contact-grid a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    text-decoration: none;
}

.site-header__mobile-contact-grid .bt-icon {
    flex: 0 0 auto;
    width: var(--bt-icon-size);
    height: var(--bt-icon-size);
    color: var(--bt-menu-index);
    stroke-width: 1.8;
}

.site-header__mobile-contact-grid span {
    min-width: 0;
    overflow-wrap: anywhere;
}

.site-header__mobile-contact--sponsor {
    width: 100%;
    grid-column: 1 / -1;
    padding-top: var(--bt-menu-sponsor-padding-top);
    border-top: var(--bt-border-width-1) solid var(--bt-menu-line-soft);
}

.site-header__mobile-sponsor-list {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    column-gap: var(--space-4);
    row-gap: var(--space-3);
}

.site-header__mobile-sponsor {
    display: grid;
    gap: var(--space-2);
}

.site-header__mobile-sponsor-name {
    margin: 0 0 var(--space-1);
    color: var(--bt-menu-ink);
    font-size: var(--bt-menu-contact-font-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--bt-menu-contact-line-height);
}

.site-header__mobile-sponsor-name span {
    color: var(--bt-menu-muted);
}

.site-header__mobile-sponsor a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    text-decoration: none;
}

.site-header__mobile-sponsor .bt-icon {
    flex: 0 0 auto;
    width: var(--bt-icon-size);
    height: var(--bt-icon-size);
    color: var(--bt-menu-index);
    stroke-width: 1.8;
}

.site-header__mobile-sponsor a span {
    min-width: 0;
    overflow-wrap: anywhere;
}

.site-header__backdrop {
    position: fixed;
    inset: 0;
    z-index: 190;
    display: none;
    border: 0;
    background: var(--bt-menu-line);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--bt-menu-content-fade-duration) ease;
}

body.menu-open .site-header__mobile {
    padding-bottom: var(--space-1);
    visibility: visible;
    pointer-events: auto;
    clip-path: inset(0);
    transition:
        clip-path var(--bt-menu-transition-duration) var(--bt-menu-transition-ease),
        visibility 0s;
}

body.menu-closing .site-header__mobile {
    visibility: visible;
    transition-delay: var(--bt-menu-closing-delay), 0s;
}

body.menu-open .site-header__mobile-scroll {
    opacity: 1;
    transition-delay: var(--bt-menu-content-open-delay);
}

body.menu-closing .site-header__mobile-scroll {
    opacity: 0;
    transition-delay: 0s;
}

body.menu-open .site-header__inner,
body.menu-closing .site-header__inner {
    border-bottom-color: var(--bt-menu-line);
}

body.menu-open .site-header__logo img,
body.menu-closing .site-header__logo img,
body.menu-closing .site-header--on-dark .site-header__logo img,
body.menu-open .site-header--on-dark .site-header__logo img {
    filter: none;
}

body.menu-open .site-header__logo-image--on-dark,
body.menu-closing .site-header__logo-image--on-dark,
/* .site-header--hero-sky:not(.is-sticky) ... มี specificity (0,3,0) สูงกว่า
   body.menu-open ... (0,2,1) เฉย ๆ ต้องเติมตัวคู่แข่งเข้ามาตรง ๆ ไม่งั้นโลโก้เวอร์ชัน
   บนพื้นมืด (ขาว) จะค้างโชว์ทับเมนูพื้นขาวจนมองไม่เห็น (เจอตอนเปิดเมนูค้างอยู่ที่หัวเฮโร่) */
body.menu-open .site-header--hero-sky:not(.is-sticky) .site-header__logo-image--on-dark,
body.menu-closing .site-header--hero-sky:not(.is-sticky) .site-header__logo-image--on-dark {
    opacity: 0;
}

body.menu-open .site-header__toggle,
body.menu-closing .site-header__toggle,
body.menu-open .site-header--hero-sky:not(.is-sticky) .site-header__toggle,
body.menu-closing .site-header--hero-sky:not(.is-sticky) .site-header__toggle {
    color: var(--bt-menu-ink);
    background: transparent;
    border: 0;
    box-shadow: none;
}

body.menu-open .site-header__backdrop {
    opacity: 1;
    pointer-events: auto;
}

@media (max-width:1399px) {
    .site-header__inner {
        grid-template-columns: minmax(120px, 0.6fr) auto minmax(max-content, 0.6fr);
    }

    .site-header__nav {
        gap: var(--space-8);
    }

    /* เมนูต้องอยู่บรรทัดเดียวเสมอ (ห้ามตัดสองบรรทัด) ชื่อ "Personalized Playbook" ยาว
       จึงย่อฟอนต์เมนูลงหนึ่งขั้นตั้งแต่ช่วงนี้ ไม่งั้นตอน sticky เมนูจะชิดปุ่มเหลือไม่กี่ px */
    .site-header__nav a {
        font-size: var(--font-size-14);
    }
}

@media (min-width:992px) and (max-width: 1199px) {
    .site-header__logo {
        width: 100px;
    }

    /* ช่วงนี้แถบแคบที่สุดที่ยังโชว์ nav เต็ม คอลัมน์โลโก้จึงลดเหลือเท่าความกว้างโลโก้จริง
       คอลัมน์ปุ่มกว้างเท่าปุ่มจริง (ปุ่มซื้อบัตรย่อเหลือ 80% ในช่วงนี้) แทนขั้นต่ำ 288px
       และบีบช่องไฟของกริดกับเมนูลง เพื่อให้เมนู "Personalized Playbook" อยู่บรรทัดเดียวได้ */
    .site-header__inner {
        grid-template-columns: minmax(100px, 0.35fr) auto minmax(max-content, 0.5fr);
        gap: var(--space-6);
    }

    .site-header__nav {
        justify-content: space-between;
        gap: var(--space-4);
    }
}

@media (max-width:991px) {

    /* ตั้งแต่ 991px ลงไป แถบ header กว้างเท่า .container ของ Bootstrap (รวมค่าที่ main.css ปรับไว้)
       ขอบโลโก้/ปุ่มเมนูจึงตรงกับขอบเนื้อหาของ section ด้านล่าง ช่วง ≤767px ใช้ gutter 32px ตาม main.css */
    .site-header__inner {
        --bs-gutter-x: 1.5rem;

        width: 100%;
        max-width: 720px;
        padding-inline: calc(var(--bs-gutter-x) * 0.5);
        min-height: var(--header-height);
        display: flex;
        justify-content: space-between;
        gap: var(--space-0);
        position: relative;
        z-index: 1;
        border-bottom: 1px solid transparent;
        transition: border-color 220ms ease;
    }

    .site-header__logo {
        width: 144px;
        height: var(--space-12);
    }

    .site-header__nav,
    .site-header__actions {
        display: none;
    }

    .site-header__toggle {
        display: grid;
    }

    .site-header__backdrop {
        display: block;
        z-index: 195;
        background: var(--bt-menu-backdrop-bg);
        visibility: hidden;
        opacity: 1;
        clip-path: inset(0 0 100% 0);
        transition:
            clip-path var(--bt-menu-transition-duration) var(--bt-menu-transition-ease),
            visibility 0s linear var(--bt-menu-visibility-delay);
        will-change: clip-path;
    }

    body.menu-open .site-header__backdrop {
        visibility: visible;
        opacity: 1;
        clip-path: inset(0);
        transition:
            clip-path var(--bt-menu-transition-duration) var(--bt-menu-transition-ease),
            visibility 0s;
    }

    body.menu-closing .site-header__backdrop {
        visibility: visible;
        transition-delay: var(--bt-menu-closing-delay), 0s;
    }
}

@media (max-width:767px) {
    .site-header__inner {
        --bs-gutter-x: 32px;
    }
}

@media (max-width:575px) {
    .site-header__inner {
        max-width: none;
    }
}

/* จอ 576-991px: โชว์ site-header__actions กลับมาบน header อีกครั้ง (ตอนปกติถูกซ่อนไว้
   ทั้งช่วง <=991px ไปแล้วข้างบน) วางไว้ข้างหน้า site-header__toggle เลย เพราะใน HTML
   .site-header__actions อยู่ก่อน .site-header__toggle อยู่แล้ว (ไม่ต้องสั่ง order ใหม่)
   margin-left:auto ดันกลุ่ม actions+toggle ไปชิดขวา ส่วนโลโก้ยังอยู่ชิดซ้ายตามเดิม
   ไม่ใช้ที่จอ <=575px เพราะจอนั้นมี .mobile-cta-bar ลอยชิดขอบล่างทำหน้าที่นี้แทนแล้ว */
@media (min-width:576px) and (max-width:991px) {
    .site-header__actions {
        display: flex;
        margin-left: auto;
        margin-right: var(--space-4);
    }
}

@media (max-width:575px) {
    /* .site-header {
        background: rgba(255, 255, 255, 0.21);
        backdrop-filter: blur(4px);
    } */

    .site-header__logo {
        width: 120px;
        height: var(--space-10);
    }

    .site-header__mobile-scroll {
        padding-left: var(--bt-menu-scroll-padding-x-sm);
        padding-right: var(--bt-menu-scroll-padding-x-sm);
    }

    .site-header__mobile-nav a {
        min-height: var(--space-10);
        font-size: var(--font-size-20);
    }

    .site-header__mobile-contact-grid {
        grid-template-columns: 1fr;
    }

    .site-header__mobile-sponsor-list {
        grid-template-columns: 1fr;
        gap: var(--space-6);
    }

    .site-header__mobile-sponsor {
        gap: var(--space-1);
    }

    .site-header__mobile-sponsor-name {
        margin: 0 0 var(--space-0);
    }
}

/* ---------- opening loader ---------- */
#loader {
    position: fixed;
    inset: 0;
    z-index: 300;
    overflow: hidden;
    pointer-events: auto;
}

.loader-surface {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    /* โทนสว่าง (ค่าเดียวกับ loader ของ heor-light) — เป็นสีรองรับก่อน WebGL วาดหมอกทับ */
    background: #f3f4f6;
    will-change: opacity;
}

.loader-icon {
    position: absolute;
    left: 50%;
    top: 50%;
    width: auto;
    height: auto;
    max-width: 120px;
    max-height: 120px;
    display: block;
    background: transparent;
    opacity: 0;
    filter: none;
    will-change: transform, opacity;
}

.loader-progress {
    position: absolute;
    left: 50%;
    bottom: 64px;
    width: min(320px, calc(100% - 48px));
    transform: translateX(-50%);
    color: #111318;
    font-family: var(--headline);
}

.loader-progress__meta {
    min-height: 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-14);
    line-height: 1;
}

.loader-progress__track {
    height: 2px;
    overflow: hidden;
    background: rgba(17, 19, 24, 0.16);
}

.loader-progress__fill {
    width: 100%;
    height: 100%;
    display: block;
    background: var(--spectrum);
    transform: scaleX(0);
    transform-origin: 0 50%;
    will-change: transform;
}

@media (max-width:575px) {
    .loader-icon {
        max-width: 88px;
        max-height: 88px;
    }

    .loader-progress {
        bottom: var(--space-8);
    }
}

/* ---------- Hero ----------
   Wireframe รอบแรก (ยังไม่มี motion): ซ้าย title + คำโปรย + ปุ่ม, ขวาภาพวิทยากร
   ที่มีตัวเลขงานวางทับมุมล่าง และวันเวลาสถานที่อยู่ใต้ภาพ
   พื้นหลังเป็นวิดีโอท้องฟ้าชุดสว่างเดิม (js/hero-loader.js เล่น/หยุดตามการมองเห็น) */
.hero {
    position: relative;
    min-height: 100vh;
    display: flex;
    align-items: center;
    padding: calc(var(--header-height) + var(--space-10)) var(--space-0) var(--space-16);
    overflow: hidden;
    background: #fafafb;
}

.hero__sky {
    position: absolute;
    inset: 0;
    background: #fafafb url('../images/light/background-light.webp?v=light-2') 50% top / cover no-repeat;
    pointer-events: none;
}

.hero__sky-video {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: 50% top;
    opacity: 0;
    filter: saturate(1.08) contrast(1.025) brightness(1.015);
    transition: opacity 480ms ease;
}

.hero.is-sky-ready .hero__sky-video {
    opacity: 1;
}

/* ไอคอนสินทรัพย์: ค่าจาก POSTER ใน hero-v2-scroll-motion.js เดิม (ตำแหน่ง % ของจอ, ความกว้าง % ของจอ
   บีบด้วย min/max px, มุมเอียง) ไอคอนเลื่อนลงจาก cy อีก 9vh (≤991 = 5vh) เหมือน posterIconShiftY เดิม
   อยู่ layer ใต้ .hero__inner (z-index 1) จึงไม่ทับข้อความ ปุ่ม และภาพวิทยากร */
.hero__assets {
    --bt-hero-asset-shift: 9;

    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.hero-asset {
    position: absolute;
    left: calc(var(--cx) * 1vw);
    top: calc((var(--cy) + var(--bt-hero-asset-shift)) * 1vh);
    /* --bt-hero-asset-scale ย่อทั้งชุด (min/ค่าตามจอ/max) ด้วยอัตราเดียว สัดส่วนเล็ก-ใหญ่ระหว่างไอคอนจึงคงเดิม */
    --bt-hero-asset-width: calc(clamp(var(--min), var(--w) * 1vw, var(--max)) * var(--bt-hero-asset-scale, 1) * var(--bt-hero-asset-boost, 1));

    width: var(--bt-hero-asset-width);
    transform: translate(-50%, -50%) rotate(var(--rot));
}

.hero-asset__float {
    will-change: transform;
}

/* ซ่อนไว้จนกว่า loader จะกระจายไอคอนออกมา (js/hero-loader.js) */
.hero-asset__inner {
    opacity: 0;
    will-change: transform, opacity;

    /* filter อยู่ที่ภาพข้างในเลเยอร์ที่เคลื่อนที่ (เดิมอยู่ที่ .hero-asset ตัวนอก ทำให้ต้องวาดใหม่ทุกเฟรมตอนไอคอนขยับ) */
    img {
        width: 100%;
        height: auto;
        display: block;
        filter: saturate(1.3);
    }
}

.hero-asset[data-hero-asset="triangle"] {
    --cx: 8.5;
    --cy: 10.5;
    --w: 10;
    --rot: -10deg;
    --min: 58px;
    --max: 230px;
}

.hero-asset[data-hero-asset="gold"] {
    --cx: 91.5;
    --cy: 12.8;
    --w: 5.5;
    --rot: 16deg;
    --min: 48px;
    --max: 130px;
}

.hero-asset[data-hero-asset="card"] {
    --cx: 86.5;
    --cy: 46;
    --w: 6.5;
    --rot: 12deg;
    --min: 52px;
    --max: 180px;
}

.hero-asset[data-hero-asset="stock"] {
    --cx: 4.4;
    --cy: 71;
    --w: 4.2;
    --rot: -24deg;
    --min: 22px;
    --max: 68px;
}

.hero-asset[data-hero-asset="bitcoin"] {
    --cx: 26.8;
    --cy: 66.5;
    --w: 6;
    --rot: -8deg;
    --min: 32px;
    --max: 120px;
}

.hero-asset[data-hero-asset="heart"] {
    --cx: 92.5;
    --cy: 74;
    --w: 12;
    --rot: -5deg;
    --min: 56px;
    --max: 240px;
}

/* bitcoin ย้ายมาอยู่ข้างคนริมซ้ายแถวล่างสุดของภาพวิทยากร ตำแหน่งเป็น % ของกรอบ .hero__visual
   (≥992 กรอบเท่าภาพ 4:5 ทั้งแผ่น จุดนี้ = 4% / 72% ของภาพ) ขนาดและมุมเท่าเดิม
   อยู่หลังภาพวิทยากร (z-index 0 ต่ำกว่า .hero__speakers) ส่วนที่ติดคนจึงถูกภาพบัง */
.hero__visual {
    position: relative;
}

.hero__visual>.hero-asset[data-hero-asset="bitcoin"] {
    --bx: 4;
    --by: 68;
    --w: 4;

    z-index: 0;
    left: calc(var(--bx) * 1%);
    top: calc(var(--by) * 1%);
}

/* ไอคอนใหญ่สี่ตัวย่อลง 25% เท่ากันทุกตัว (heart ยังใหญ่กว่า card, triangle ยังใหญ่กว่า gold ฯลฯ) */
.hero-asset:is([data-hero-asset="triangle"], [data-hero-asset="gold"], [data-hero-asset="heart"], [data-hero-asset="card"]) {
    --bt-hero-asset-scale: 0.75;
}

@media (max-width:991px), (max-aspect-ratio: 1199/1000) {

    /* กำแพง wall-*-1280 (4:5 จาก <picture>) รูปทรงเฉียงอยู่ในไฟล์แล้ว วางตามสัดส่วนจริง ไม่ยืด
       ขอบล่างชนขอบล่างภาพวิทยากร มุมล่างด้านในของไฟล์ (36.3% / 62.2% ของความกว้างไฟล์)
       ชนขอบในของกำแพงที่ 36% / 63% ของกรอบภาพ
       ขนาด: สูงตั้งแต่ขอบบนของ hero (ขอบบนจอ) ถึงขอบล่างภาพ และกว้างพอให้ขอบนอกถึงขอบจอทั้งสองฝั่ง */
    .hero__wall {
        --bt-hero-wall-bottom: calc(var(--bt-hero-wall-top, 0px) + var(--bt-hero-wall-height, 0px));
        --bt-hero-wall-left-edge: 0.36;
        --bt-hero-wall-right-edge: 0.63;
        /* ขอบในห่างจากกึ่งกลางภาพอย่างน้อยเท่านี้ ช่องฟ้าจึงกว้างกว่าข้อความเสมอ (hero-loader.js อ่านค่านี้ตอนปิดกำแพงด้วย) */
        --bt-hero-wall-half-gap: 0px;
        --bt-hero-wall-mid: calc(var(--bt-hero-wall-left, 0px) + var(--bt-hero-wall-width, 0px) / 2);
        --bt-hero-wall-inner-l: min(calc(var(--bt-hero-wall-left, 0px) + var(--bt-hero-wall-width, 0px) * var(--bt-hero-wall-left-edge)),
                calc(var(--bt-hero-wall-mid) - var(--bt-hero-wall-half-gap)));
        --bt-hero-wall-inner-r: max(calc(var(--bt-hero-wall-left, 0px) + var(--bt-hero-wall-width, 0px) * var(--bt-hero-wall-right-edge)),
                calc(var(--bt-hero-wall-mid) + var(--bt-hero-wall-half-gap)));
        --bt-hero-wall-file-width: max(var(--bt-hero-wall-bottom) * 0.8,
                var(--bt-hero-wall-inner-l) / 0.363,
                (var(--bt-hero-width, 100vw) - var(--bt-hero-wall-inner-r)) / 0.378);

        display: block;
        position: absolute;
        top: calc(var(--bt-hero-wall-bottom) - var(--bt-hero-wall-file-width) * 1.25);
        width: var(--bt-hero-wall-file-width);
        max-width: none;
        height: calc(var(--bt-hero-wall-file-width) * 1.25);
        pointer-events: none;
    }

    .hero__wall--left {
        left: calc(var(--bt-hero-wall-inner-l) - var(--bt-hero-wall-file-width) * 0.363);
    }

    /* 576px ขึ้นไป (ข้อความอยู่เหนือภาพ ช่องฟ้าอยู่หลังข้อความ): เปิดช่องให้กว้างกว่าบรรทัดยาวสุด */
    @media (min-width:576px) {
        .hero__wall {
            --bt-hero-wall-half-gap: 176px;
        }
    }

    .hero__wall--right {
        left: calc(var(--bt-hero-wall-inner-r) - var(--bt-hero-wall-file-width) * 0.622);
    }

    /* ไล่สีพื้นหน้า (--color-surface-page) จากขอบล่าง hero ขึ้นไป กลบสีฟ้าที่ติดมากับกำแพงช่วงล่าง
       z-index 0 และเป็น ::after (มาหลังสุดใน DOM) จึงอยู่บนกำแพง แต่อยู่ใต้ .hero__inner (1) ที่มีภาพวิทยากร */
    /* ไอคอนอยู่เหนือแถบไล่สีขาวด้านล่าง (::after z-index 0) แต่ยังอยู่หลังเนื้อหา (.hero__inner z 1 มาทีหลังใน DOM) */
    .hero__assets {
        z-index: 1;
    }

    .hero::after {
        content: '';
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 0;
        height: 35%;
        background: linear-gradient(to top, var(--color-surface-page) 25%, transparent);
        pointer-events: none;
    }

    /* hero สูงกว่ากว้าง วิดีโอ 16:9 แบบ cover เหลือแค่แถบกลาง ~1/3 ของความกว้าง (ฟ้าเปล่าเป็นส่วนใหญ่)
       เลื่อนไปทางซ้ายให้เห็นก้อนเมฆมุมซ้ายบนช่วงบน และก้อนใหญ่ด้านล่างเข้ามาในกรอบ */
    .hero__sky,
    .hero__sky-video {
        background-position: 30% top;
        object-position: 30% top;
    }

    /* ผังบน-ล่าง: ไอคอนอยู่ในช่วงเนื้อหาด้านบน (ขอบบน title ถึงขอบบนภาพวิทยากร) ริมจอซ้าย-ขวา
       เรียงแบบเดียวกับ desktop (ฝั่ง/ลำดับบน-ล่าง/มุมเอียงเดียวกัน)
       ซ้าย: triangle > bitcoin > stock · ขวา: gold > card > heart
       --ix = จุดกึ่งกลางเป็น vw, --iy = % ของช่วงเนื้อหาด้านบน, --iw = กว้างเป็น % ของกว้างภาพ
       ลำดับขนาดเท่า desktop (ที่ 1470px: heart 132 > triangle 110 > card 72 > stock 62 ≈ gold 61 ≈ bitcoin 59)
       อยู่หลังข้อความ (.hero__assets z 1 มาก่อน .hero__inner ใน DOM) ตัวอักษรจึงไม่ถูกบัง
       จุดอ้างอิง (px เทียบกับ hero) มาจาก js/hero-loader.js */
    /* --bt-hero-icon-k ขยายไอคอนทั้งชุดด้วยอัตราเดียว (สัดส่วนเล็ก-ใหญ่ระหว่างไอคอนคงเดิม) */
    .hero-asset {
        --bt-hero-icon-k: 1.65;
        --bt-hero-asset-y: calc(var(--bt-hero-top-y, 0px) + (var(--bt-hero-img-top, 80vh) - var(--bt-hero-top-y, 0px)) * var(--iy) / 100);
    }

    .hero__assets>.hero-asset {
        left: calc(var(--ix) * 1vw);
        top: var(--bt-hero-asset-y);
        width: calc(var(--bt-hero-img-w, 100vw) * var(--iw) / 100 * var(--bt-hero-icon-k));
    }

    /* bitcoin อยู่ใน .hero__visual: แปลงพิกัดจาก hero เป็นพิกัดของ .hero__visual
       (ภาพถูกดึงขึ้น 13cqw จากขอบบน .hero__visual, ขอบซ้ายภาพห่างจาก .hero__visual ครึ่ง gutter)
       z-index -1 อยู่หลังข้อความใน .hero__inner */
    .hero__visual>.hero-asset[data-hero-asset="bitcoin"] {
        --ix: 6;
        --iy: 45;
        --iw: 5;

        z-index: -1;
        left: calc(var(--ix) * 1vw - var(--bt-hero-img-l, 0px) + var(--bs-gutter-x) * 0.5);
        top: calc(var(--bt-hero-asset-y) - var(--bt-hero-img-top, 80vh) - 13cqw);
        width: calc(var(--iw) * 1cqw * var(--bt-hero-icon-k));
    }

    .hero-asset[data-hero-asset="heart"] {
        --ix: 93;
        --iy: 90;
        --iw: 11.3;
    }

    .hero-asset[data-hero-asset="stock"] {
        --ix: 6;
        --iy: 80;
        --iw: 5.3;
    }

    .hero-asset[data-hero-asset="gold"] {
        --ix: 93;
        --iy: 8;
        --iw: 5.2;
    }

    .hero-asset[data-hero-asset="triangle"] {
        --ix: 7;
        --iy: 8;
        --iw: 9.4;
    }

    .hero-asset[data-hero-asset="card"] {
        --ix: 92;
        --iy: 50;
        --iw: 6.2;
    }
}

.hero__inner {
    position: relative;
    z-index: 1;
}

.hero__row {
    align-items: center;
    row-gap: var(--space-12);
}

.hero__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.hero__title {
    width: 100%;
    max-width: 352px;
    height: auto;
    display: block;
}

.hero__headline {
    margin: var(--space-8) var(--space-0) var(--space-0);
    color: var(--color-text-primary);
    font-family: var(--headline);
    font-size: var(--font-size-32);
    font-weight: var(--font-weight-medium);
    line-height: 1.3;
}

/* Thai has no spaces, so without this the browser breaks inside words ("ชั้น|นำ").
   Each phrase stays whole; when the column is too narrow "จากวิทยากรชั้นนำ" drops to a third line. */
.hero__headline-phrase {
    display: inline-block;
}

.hero__description {
    margin: var(--space-4) var(--space-0) var(--space-0);
    color: var(--color-text-secondary);
    font-size: var(--section-body-size);
    line-height: var(--line-height-normal);
}

/* Stat styling follows #expectation (.expectation__stat), one size step smaller: ink numbers with a blue "+", a light muted
   label underneath, and the rotated line-star image as the divider between items. */
.hero__stats {
    --bt-hero-stat-size: var(--font-size-28);
    --bt-hero-stat-rule-length: 64px;

    display: flex;
    margin: var(--space-8) var(--space-0) var(--space-0);

    @media (max-width: 991px) {
        --bt-hero-stat-size: var(--font-size-24);
        --bt-hero-stat-rule-length: 56px;
    }

    @media (max-width: 767px) {
        --bt-hero-stat-size: var(--font-size-20);
        --bt-hero-stat-rule-length: 48px;
    }
}

.hero__stat {
    position: relative;
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    padding: var(--space-0) var(--space-8);
    text-align: center;

    &:first-child {
        padding-left: var(--space-0);
    }

    &+&::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 0;
        width: var(--bt-hero-stat-rule-length);
        height: calc(var(--bt-hero-stat-rule-length) / 9.13);
        background: url('../images/line-star.webp') center / contain no-repeat;
        transform: translate(-50%, -50%) rotate(90deg);
    }

    dt {
        margin-top: var(--space-2);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    dd {
        margin: var(--space-0);
        color: var(--color-text-primary);
        font-size: var(--bt-hero-stat-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--section-title-line-height);
        letter-spacing: 0;
    }

    .hero__stat-suffix {
        color: var(--color-blue-600);
    }
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--space-8);
    margin-top: var(--space-8);
}

/* ค่าเดียวกับ #ui .venue / #ui .venue-link ของ hero เดิม (ลิงก์ Samyan Mitrtown Hall) */
.hero__dna-link {
    align-items: center;
    gap: var(--space-3);
    color: var(--color-text-primary);
    font-size: var(--font-size-20);
    font-weight: var(--font-weight-regular);
    line-height: 1.25;

    &::after {
        background: var(--spectrum);
    }

    .bt-icon {
        width: var(--bt-icon-size);
        height: var(--bt-icon-size);
        stroke-width: 2;
    }

    &:hover .bt-icon,
    &:focus-visible .bt-icon {
        stroke: #00d4fe;
        stroke: url("#hero-dna-arrow-spectrum");
    }
}

/* ข้อความราคาพิเศษข้างปุ่มซื้อบัตร เป็นข้อความธรรมดาสองบรรทัดเรียงชิดซ้าย
   บรรทัดแรกน้ำหนักกลาง บรรทัดสองเป็นเงื่อนไขเวลาสีรองที่อ่อนกว่า */
.hero__offer {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: var(--space-0);
    font-size: var(--font-size-12);
    line-height: var(--section-small-line-height);
    text-align: left;
}

/* "ราคาพิเศษ" สีดำ เว้นหนึ่งวรรคแล้วตามด้วย "ลด 30%" สีแดงตัวเอียง */
/* บรรทัดแรกใหญ่กว่าบรรทัดเงื่อนไขหนึ่งขั้น (16 / 14px) */
.hero__offer-highlight {
    color: var(--color-text-primary);
    /* font-size: var(--section-body-size); */
    font-weight: var(--font-weight-medium);
    line-height: var(--section-small-line-height);
}

.hero__offer-discount {
    color: var(--color-danger-600);
    font-weight: var(--font-weight-bold);
    font-style: italic;
    padding-right: var(--space-1);
}

.hero__offer-note {
    color: var(--color-neutral-600);
}

.hero__visual {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* ภาพ placeholder เป็นโปสเตอร์ 4:5 ที่มี title อยู่บนและวันที่อยู่ล่าง
   กรอบ 6:5 เห็นความสูงภาพ 2/3 เลื่อนลง 66% ให้เหลือเฉพาะช่วงวิทยากร (~22–88% ของภาพ) */
.hero__speakers {
    position: relative;
    margin: var(--space-0);
    overflow: hidden;
    border-radius: var(--card-radius);
    aspect-ratio: 6 / 5;

    img {
        width: 100%;
        height: 100%;
        display: block;
        object-fit: cover;
        object-position: 50% 66%;
    }
}

/* ≥992 hero กว้างเท่าแถบใน header (.site-header__inner) ภาพวิทยากรชิดขวา ข้อความชิดซ้าย
   ภาพต้องเห็นเต็มแผ่นเสมอ (ห้ามครอป คนริมภาพจะหาย) กรอบจึงเป็น 4:5 ตามไฟล์
   กว้าง min(80vh, พื้นที่ที่เหลือจากคอลัมน์ข้อความขั้นต่ำ) = สูงไม่เกิน 100vh
   จอสูงภาพกว้างขึ้นแล้วเบียดข้อความไปซ้าย จอแคบภาพเตี้ยกว่าจอและอยู่กึ่งกลางแนวตั้ง */
@media (min-width:992px) and (min-aspect-ratio: 6/5) {

    /* ข้อความ + ภาพเรียงชิดกัน (ห่างกันแค่ --bt-hero-gap) แล้วทั้งกลุ่มวางกึ่งกลางจอ
       พื้นที่ที่เหลือไปอยู่ขอบซ้าย-ขวาเท่า ๆ กัน และมีระยะจากขอบจออย่างน้อย --bt-hero-side-min เสมอ
       ภาพสูง 100vh (กว้าง 80vh ตามสัดส่วน 4:5) คอลัมน์ข้อความกว้างตามเนื้อหา (สูงสุด 600px)
       จอแคบลงคอลัมน์ข้อความหดเอง title ย่อตาม (.hero__title width 100%) */
    /* ความกว้าง: คอลัมน์ข้อความ + ภาพ วางคู่กันกึ่งกลางจอ ห่างกัน --bt-hero-gap
       ภาพกว้าง 80vh (= สูง 100vh ตามสัดส่วน 4:5) เว้นแต่จอแคบจนคอลัมน์ข้อความเหลือไม่ถึง --bt-hero-content-min
       ภาพจึงหดลงแทน (ไม่ครอป ไม่ล้นจอ) และชิดขอบล่างของ hero
       ความสูง: hero สูง 100vh เนื้อหาอยู่กึ่งกลางช่วงใต้ header เว้นบน-ล่างเท่ากัน (--bt-hero-pad-y)
       ระยะห่าง/ขนาดตัวอักษรในคอลัมน์ข้อความย่อตามความสูงจอ จอเตี้ยเนื้อหาจึงยังอยู่ครบใน 1 หน้าจอ */
    .hero {
        --bt-hero-gap: var(--space-6);
        /* ระยะขอบขั้นต่ำเป็นสัดส่วนความกว้างจอ จอสูง (เต็มจอ) จะไม่เบียดขอบจนเหลือแค่ 32px */
        --bt-hero-side-min: max(var(--space-8), 5vw);
        --bt-hero-content-min: calc(480 * var(--bt-hero-u));
        --bt-hero-content-max: calc(500 * var(--bt-hero-u));
        --bt-hero-pad-y: clamp(var(--space-4), 3vh, var(--space-10));
        --bt-hero-visual-w: min(80vh, 100vw - 2 * var(--bt-hero-side-min) - var(--bt-hero-gap) - var(--bt-hero-content-min));

        min-height: 100vh;
        padding-block: var(--space-0);
    }

    .hero__inner {
        display: flex;
        align-self: stretch;
        width: 100%;
        max-width: none;
        padding-inline: var(--bt-hero-side-min);
    }

    .hero__row {
        flex: 1 1 auto;
        flex-wrap: nowrap;
        justify-content: center;
        gap: var(--bt-hero-gap);
        margin: var(--space-0);
    }

    .hero__content {
        position: relative;
        z-index: 2;
        flex: 0 1 auto;
        width: auto;
        max-width: var(--bt-hero-content-max);
        min-width: 0;
        padding: calc(var(--header-height) + var(--bt-hero-pad-y)) var(--space-0) var(--bt-hero-pad-y);
    }

    .hero__visual {
        position: relative;
        z-index: 1;
        flex: 0 0 auto;
        align-self: flex-end;
        width: var(--bt-hero-visual-w);
        height: auto;
        aspect-ratio: 4 / 5;
        padding: var(--space-0);
    }

    /* ขนาดทั้งคอลัมน์ข้อความโตตามพื้นที่จริงด้วยตัวคูณเดียว --bt-hero-u (= k px, ค่าเดิมคือ k = 1)
       ทุกส่วน (title, headline, คำโปรย, ตัวเลข, ระยะห่าง) คูณ k เท่ากัน สัดส่วนที่ออกแบบไว้จึงคงเดิม
       k ถูกจำกัด 3 ทาง แล้วใช้ค่าที่น้อยที่สุด
       - ความสูง: เนื้อหาที่ k = 1 สูง 592px (ส่วนที่คูณ k 530px + ปุ่ม 62px ที่สูงคงที่)
         ต้องพอดี 100vh − header − ระยะบน-ล่าง (3vh × 2): 530k + 62 ≤ 0.94·100vh − 72
         → k = 0.1774vh − 0.2528px แล้วคูณ 0.917 ให้เหลือที่ว่างบน-ล่าง ไม่แน่นจอ (หน้าต่าง 1470×765 ได้ title ~446px)
       - ความกว้าง: เนื้อหาที่ k = 1 กว้าง 480px ต้องพอดีช่องที่เหลือจากภาพ 80vh → k = (100vw − 88px − 80vh) / 480
         ถ้าช่องแคบกว่านั้น ภาพหดแทนได้จนข้อความเหลือ k = 0.9 (--bt-hero-content-min = 480k)
       - เพดาน 1.2 และพื้น 0.8
       ปุ่มซื้อบัตร (liquid metal วาดด้วย canvas) สูงคงที่ ไม่คูณ k */
    .hero {
        --bt-hero-u: clamp(0.8px, min(0.1627vh - 0.2318px, max(0.9px, (100vw - 2 * var(--bt-hero-side-min) - var(--bt-hero-gap) - 80vh) / 480)), 1.2px);
    }

    .hero__title {
        max-width: calc(352 * var(--bt-hero-u));
    }

    .hero__headline {
        margin-top: calc(32 * var(--bt-hero-u));
        font-size: calc(32 * var(--bt-hero-u));
    }

    .hero__description {
        margin-top: calc(16 * var(--bt-hero-u));
        font-size: calc(16 * var(--bt-hero-u));
    }

    .hero__stats {
        --bt-hero-stat-size: min(28px, calc(28 * var(--bt-hero-u)));
        --bt-hero-stat-rule-length: calc(64 * var(--bt-hero-u));

        margin-top: calc(32 * var(--bt-hero-u));
    }

    .hero__stat {
        padding-inline: calc(32 * var(--bt-hero-u));

        &:first-child {
            padding-left: var(--space-0);
        }

        dt {
            margin-top: calc(2 * var(--bt-hero-u));
            font-size: calc(14 * var(--bt-hero-u));
        }
    }

    .hero__actions {
        margin-top: calc(32 * var(--bt-hero-u));
    }

    .hero__offer {
        font-size: calc(12 * var(--bt-hero-u));
    }

    .hero__speakers {
        z-index: 1;
        width: 100%;
        height: 100%;
        aspect-ratio: auto;
        border-radius: var(--space-0);

        img {
            object-position: 50% 50%;
        }
    }

    /* ไอคอนฝั่งซ้าย (triangle, stock) ห้ามทับข้อความ: ขอบซ้ายของคอลัมน์ข้อความ (--bt-hero-content-l จาก
       js/hero-loader.js) เป็นเพดานของกรอบไอคอนหลังหมุน (ความกว้างหลังหมุน = กว้าง × --bt-hero-asset-span)
       ไอคอนคงขนาดเดิมเสมอ ช่องซ้ายแคบก็เลื่อนไปทางซ้ายจนเลยขอบจอได้ (ส่วนเกินถูก .hero ตัด)
       จอกว้างที่ช่องซ้ายเหลือเฟือ ไอคอนอยู่ตำแหน่งเดิม (--cx) */
    .hero-asset:is([data-hero-asset="triangle"], [data-hero-asset="stock"]) {
        left: min(var(--cx) * 1vw, var(--bt-hero-content-l, 100vw) - var(--bt-hero-asset-width) * var(--bt-hero-asset-span) * 0.5 - var(--space-2));
    }

    /* triangle 800×769 เอียง 10° → 1.15 · stock 178×800 เอียง 24° → 2.74 */
    .hero-asset[data-hero-asset="triangle"] {
        --bt-hero-asset-span: 1.15;
    }

    .hero-asset[data-hero-asset="stock"] {
        --bt-hero-asset-span: 2.74;
    }

    /* กำแพงขวา: ไฟล์ 4:5 เท่ากรอบภาพวิทยากร js/hero-loader.js ใส่ตำแหน่ง/ขนาดของกรอบภาพ
       (เทียบกับ .hero) ให้ผ่าน --bt-hero-wall-* แล้ว scaleX จากขอบในของกำแพง (~63% ของไฟล์)
       ยื่นออกทางขวาจนถึงขอบจอ ส่วนเกินถูก .hero (overflow: hidden) ตัด
       ไม่มี z-index และมาหลัง .hero__sky ใน DOM จึงอยู่บนท้องฟ้าแต่ใต้ .hero__assets (0) และ .hero__inner (1) */
    /* กำแพงสูงเต็ม hero (ชิดขอบบน-ล่างเสมอ) แม้ภาพวิทยากรหดเตี้ยกว่าจอ (--bt-hero-height จาก js/hero-loader.js)
       ตำแหน่งแนวนอนยังยึดขอบในที่ 36% / 63% ของกรอบภาพ ขนาดไฟล์ตามความสูง hero จึงไม่ยืด */
    .hero__wall {
        display: block;
        position: absolute;
        top: 0;
        left: var(--bt-hero-wall-left, 0px);
        width: var(--bt-hero-wall-width, 0px);
        max-width: none;
        height: var(--bt-hero-height, 100vh);
        pointer-events: none;
    }

    /* กำแพงขวา (wall-right-new.webp 2880×2880 = 1:1) วางตามสัดส่วนจริง ไม่ยืด
       สูงเท่ากรอบภาพวิทยากร ขอบซ้ายของไฟล์ (ขอบในของกำแพง) อยู่ที่ 63% ของกรอบภาพ ตรงกับตำแหน่งเดิม
       กำแพงยาวต่อไปทางขวาเกินขอบจอ ส่วนเกินถูก .hero (overflow: hidden) ตัด */
    .hero__wall--right {
        /* ขอบในของกำแพงเทียบกับกรอบภาพ (ซ้าย 30% / ขวา 69%) ขยับออกจาก 36 / 63 ให้ช่องกลางกว้างขึ้น */
        --bt-hero-wall-right-edge: 0.69;

        left: calc(var(--bt-hero-wall-left, 0px) + var(--bt-hero-wall-width, 0px) * var(--bt-hero-wall-right-edge));
        width: var(--bt-hero-height, 100vh);
    }

    /* กำแพงซ้าย (wall-left-new.webp 3840×2880 = 4:3) วางตามสัดส่วนจริง ไม่ยืด
       สูงเท่ากรอบภาพวิทยากร ขอบขวาของไฟล์ (ขอบในของกำแพง) อยู่ที่ 36% ของกรอบภาพ ตรงกับตำแหน่งเดิม
       กำแพงยาวต่อไปทางซ้ายเกินขอบจอ ส่วนเกินถูก .hero (overflow: hidden) ตัด */
    .hero__wall--left {
        --bt-hero-wall-left-edge: 0.30;
        --bt-hero-wall-left-width: calc(var(--bt-hero-height, 100vh) * 4 / 3);

        left: calc(var(--bt-hero-wall-left, 0px) + var(--bt-hero-wall-width, 0px) * var(--bt-hero-wall-left-edge) - var(--bt-hero-wall-left-width));
        width: var(--bt-hero-wall-left-width);
    }

    /* ท้องฟ้าบน desktop เห็นแค่ช่องรูปตัว V ระหว่างกำแพง (กึ่งกลางช่อง ~62–67% ของความกว้าง, ช่วงบน ~0–25%)
       ตรงนั้นในวิดีโอเป็นฟ้าเปล่า ขยายวิดีโอเป็น 165% ของความสูง hero แล้วยกขึ้น (ชิดขอบล่าง)
       ก้อนเมฆใหญ่ด้านล่างของวิดีโอจึงขึ้นมาอยู่ในช่องนั้น ภาพ poster ก่อนวิดีโอพร้อมใช้กรอบเดียวกัน */
    .hero__sky {
        overflow: hidden;
        background-size: auto 165%;
        background-position: 50% 100%;
    }

    .hero__sky-video {
        position: absolute;
        left: 0;
        top: -65%;
        height: 165%;
        object-position: 50% 50%;
    }
}

@media (max-width:991px), (max-aspect-ratio: 1199/1000) {
    .hero {
        min-height: 0;
        padding-bottom: var(--space-20);
    }

    .hero__content {
        align-items: center;
        text-align: center;
    }

    .hero__actions {
        justify-content: center;
        flex-direction: column;
        gap: var(--space-6);
    }

    .hero__offer {
        flex-direction: row;
        gap: var(--space-1);
    }

    /* แถว stat: ทุกช่องกว้างเท่าช่องที่กว้างที่สุด (grid 1fr) เส้นคั่นจึงห่างเท่ากัน
       ช่องแรกมี padding ซ้ายเท่าช่องอื่น แถวที่จัดกึ่งกลางจึงสมดุลซ้าย-ขวา */
    .hero__stats {
        display: grid;
        grid-auto-columns: 1fr;
        grid-auto-flow: column;
    }

    .hero__stat:first-child {
        padding-left: var(--space-8);
    }

    /* จอ ≥992 แนวตั้ง (เช่น iPad Pro ตั้ง) ใช้ผังบน-ล่างนี้ด้วย แต่ Bootstrap ให้ col-lg-* กว้าง 50%
       บังคับเต็มแถว และภาพกว้างไม่เกิน 720px (เท่าจอ 768–991) ไม่ให้ภาพสูงเกินจอ */
    .hero__content,
    .hero__visual {
        width: 100%;
    }

    .hero__visual {
        max-width: 720px;
        margin-inline: auto;
    }

    /* ภาพวิทยากรสูงตามสัดส่วนไฟล์จริง (4:5) เห็นเต็มแผ่น ไม่ครอปเป็นกรอบ 6:5
       ไฟล์มีพื้นใส 10.4% บนสุด (ก่อนถึงหัวคนแถวแรก) ดึงภาพขึ้นเท่านั้นด้วย margin ติดลบ
       100cqw = ความกว้างภาพ (container คือ .hero__visual) สูงภาพ = 125cqw → 10.4% = 13cqw
       ส่วนใสที่ขึ้นไปซ้อนใต้ปุ่มไม่รับการคลิก ปุ่มซื้อบัตรจึงกดได้ตามปกติ */
    .hero__visual {
        container-type: inline-size;
    }

    .hero__speakers {
        --bt-hero-speakers-pull: 13cqw;

        aspect-ratio: auto;
        margin-top: calc(var(--bt-hero-speakers-pull) * -1);
        pointer-events: none;

        img {
            height: auto;
        }
    }
}

@media (max-width:575px) {
    .hero {
        padding: var(--section-padding-y-sm) var(--space-0);
    }
    
    .hero__headline {
        font-size: var(--font-size-28);
        line-height: 1.2;
    }

    .hero__description {
        font-size: var(--section-small-size);
    }

    .hero__stat {
        padding-inline: var(--space-5);

        &:first-child {
            padding-left: var(--space-5);
        }

        dt {
            font-size: var(--font-size-12);
        }
    }

    /* ≤575: ไม่แสดงปุ่มซื้อบัตร/ราคาพิเศษใน hero (มีแถบปุ่มลอยด้านล่างจออยู่แล้ว)
       และย้ายภาพวิทยากรขึ้นมาไว้ใต้คำโปรย ก่อนแถวตัวเลข stat
       .hero__content เป็น display: contents ลูก ๆ จึงเรียงรวมกับ .hero__visual ในแถวเดียว แล้วจัดลำดับด้วย order */
    .hero__actions {
        display: none;
    }

    .hero__row {
        flex-direction: column;
        align-items: center;
        row-gap: var(--space-0);
    }

    .hero__content {
        display: contents;
    }

    .hero__title,
    .hero__headline,
    .hero__description {
        order: 1;
    }

    /* ลูกของ .hero__content หลุดออกมาอยู่ใน .row โดยตรง (ไม่มี padding ของคอลัมน์) ใส่ gutter คืนให้ */
    .hero__title,
    .hero__headline,
    .hero__description,
    .hero__stats {
        padding-inline: calc(var(--bs-gutter-x) * 0.5);
    }

    /* โลโก้ title ไม่กว้างเต็มจอ (กว้างสุด ~3/4 ของจอ) และเว้นระยะจาก header */
    .hero__title {
        box-sizing: content-box;
        max-width: min(264px, 66vw);
        margin-top: var(--space-8);
    }

    .hero__visual {
        order: 2;
        margin-top: var(--space-10);
    }

    .hero__stats {
        order: 3;
        margin-block: var(--space-6) var(--space-0);
    }

    /* แถว stat อยู่ใต้ภาพ: ไล่สีพื้นหน้าเริ่มจาก 70% ของความสูงภาพ ทึบเต็มที่ตรงขอบล่างภาพ
       ขอบล่างภาพจึงกลืนไปกับพื้น ไม่เห็นรอยต่อกับท้องฟ้าด้านหลัง (กรอบภาพจาก js/hero-loader.js) */
    .hero::after {
        --bt-hero-fade-start: calc(var(--bt-hero-img-top, 0px) + var(--bt-hero-img-h, 0px) * 0.7);

        top: var(--bt-hero-fade-start);
        height: auto;
        background: linear-gradient(to bottom, transparent 0, var(--color-surface-page) calc(var(--bt-hero-img-h, 0px) * 0.3));
    }

    /* ไอคอนใหญ่ขึ้นทั้งชุด (ลำดับขนาดเท่า desktop คงเดิม) และกระจายลงมาถึงภาพวิทยากร:
       ช่วงวางไอคอน = ขอบบน title ถึง 80% ของความสูงภาพ
       ชิดขอบจอ (ล้นออกนอกจอได้บางส่วน) อยู่หลังข้อความและภาพวิทยากร */
    .hero-asset {
        --bt-hero-icon-k: 2.2;
        --bt-hero-asset-end: calc(var(--bt-hero-img-top, 80vh) + var(--bt-hero-img-h, 0px) * 0.8);
        --bt-hero-asset-y: calc(var(--bt-hero-top-y, 0px) + (var(--bt-hero-asset-end) - var(--bt-hero-top-y, 0px)) * var(--iy) / 100);
    }

    .hero-asset:is([data-hero-asset="triangle"], [data-hero-asset="stock"]),
    .hero__visual>.hero-asset[data-hero-asset="bitcoin"] {
        --ix: 1.5;
    }

    .hero-asset:is([data-hero-asset="gold"], [data-hero-asset="card"], [data-hero-asset="heart"]) {
        --ix: 98.5;
    }

    /* ซ้าย: triangle (ข้าง title) > bitcoin (ข้างบรรทัดหัวข้อที่สั้น) > stock (ข้างภาพ) */
    .hero-asset[data-hero-asset="triangle"] {
        --iy: 4;
    }

    /* bitcoin / gold ตัวเล็ก ขยับเข้ามาในจอเล็กน้อยให้เห็นมากกว่าครึ่งตัว */
    .hero__visual>.hero-asset[data-hero-asset="bitcoin"] {
        --ix: 8;
        --iy: 38;
    }

    .hero-asset[data-hero-asset="stock"] {
        --iy: 98;
    }

    /* ขวา: gold (ข้าง title) > card (ข้างแถวบนของภาพ) > heart (ข้างภาพช่วงล่าง) */
    .hero-asset[data-hero-asset="gold"] {
        --ix: 98;
        --iy: 14;
    }

    .hero-asset[data-hero-asset="card"] {
        --iy: 54;
    }

    .hero-asset[data-hero-asset="heart"] {
        --iy: 100;
    }
}

/* Motion เลื่อนจาก hero ไป ticket (js/hero-scroll-motion.js, desktop เท่านั้น)
   ไอคอนบินพ้นขอบล่างของ hero ลงไปหาไอคอนบัตร: ตัดแค่แนวนอน (กำแพงยาวเลยขอบจอ) แนวตั้งปล่อยล้น
   hero เป็น stacking context z-index 1 เท่ากับ .ticket__plans ซึ่งมาทีหลังใน DOM
   ไอคอนจึงลอยทับพื้นของ ticket ได้ แต่มุดลงไปอยู่หลังการ์ดบัตรตอนถึงหัวบัตร Ultimate
   ระหว่างบิน (.is-icons-flying) ไอคอนขึ้นมาอยู่หน้าเนื้อหา/ภาพ */
.hero.is-scroll-motion {
    z-index: 1;
    overflow-x: clip;
    overflow-y: visible;
}

.hero.is-icons-flying .hero__assets {
    z-index: 2;
}

/* ทุกชิ้นที่ขยับตาม scroll แยกเป็นเลเยอร์ของตัวเอง ให้ GPU เลื่อนภาพเดิมแทนการวาดใหม่ทุกเฟรม
   (กำแพงมี mask และไอคอนมี filter ถ้าไม่แยกเลเยอร์ เบราว์เซอร์ต้องวาดใหม่ทุกเฟรมจนไอคอนตามไม่ทัน) */
.hero.is-scroll-motion :is(.hero__content, .hero__speakers img, .hero__wall, .hero-asset__inner) {
    will-change: transform, opacity;
}

/* ---------- next section ---------- */
#concept {
    --bt-concept-description-size: var(--section-topic-size);
    --bt-concept-description-line-height: var(--section-topic-line-height);
    --bt-concept-bg-opacity: 0.4;
    --bt-concept-bg-reveal-delay: 520ms;
    --bt-concept-bg-reveal-duration: 980ms;

    position: relative;
    /* min-height: 180vh; */
    overflow: clip;
    isolation: isolate;
    background: var(--color-surface-page);
    color: var(--color-text-primary);
    display: block;
    padding: var(--section-padding-y) 0;
    font-family: var(--font-family-base);
    text-align: center;
}

/* ไม่มีภาพพื้นหลังแล้ว ไม่ต้องมีเงาไล่มืดทับด้านบน (#agenda ใช้คลาส .ticket ร่วมกัน จึงปิดเฉพาะ #ticket) */
#ticket::before {
    content: none;
}

/* การ์ด Explorer / Master Class ใช้พื้นสีเดียวกับหน้า เดิมตัดกับภาพพื้นหลังมืดจึงเห็นขอบการ์ด
   พอไม่มีภาพแล้วขอบหายไปกับพื้น ใส่เส้นขอบบางสีเดียวกับเส้นคั่นในการ์ดแทน
   (outline ไม่ดันขนาดการ์ด และวาดตามมุมโค้ง; Ultimate มีกรอบ spectrum ของตัวเองอยู่แล้ว) */
/* #ticket .ticket__plan:not(.ticket__plan--ultimate) {
    outline: var(--rule-width-subtle) solid var(--color-border-editorial);
    outline-offset: calc(var(--rule-width-subtle) * -1);
} */

/* กรอบรวมผืนเดียวรอบแถวการ์ด (≥992 ที่การ์ดเรียงแถวเดียว): ขอบตรงกับใบ Explorer/Master Class
   ใบ Ultimate ทับกรอบและยื่นพ้นขอบบน-ล่างออกไปเท่ากัน
   ทั้ง 3 ใบยืดสูงเต็มแถวด้วย align-self: stretch ใบข้างเว้น margin-bottom เท่ากับ margin-top
   ส่วนใบ Ultimate ยืดถึงขอบล่างแถว จึงยื่นพ้นกรอบลงล่างเท่าที่ยื่นขึ้นบนเสมอ ไม่ว่าใบไหนเนื้อหายาวกว่า
   (พื้นใบข้างสีเดียวกับหน้า ส่วนที่ยืดจึงมองไม่เห็น) */
@media (min-width: 992px) {
    #ticket .ticket__plan {
        align-self: stretch;
    }

    #ticket .ticket__plan--explorer,
    #ticket .ticket__plan--master {
        margin-bottom: calc(var(--space-16) - var(--space-2));
    }

    /* top = padding-top ของแถว + margin-top ของใบข้าง / bottom = margin-bottom ของใบข้าง
       z-index 1 เพื่อให้อยู่เหนือพื้นใบข้าง (ขอบกรอบทับขอบการ์ดพอดี) แต่ใบ Ultimate
       (z-index 1 เหมือนกันแต่มาทีหลังใน DOM) ยังทับกรอบอยู่ */
    #ticket .ticket__plans::before {
        content: '';
        position: absolute;
        inset: calc(var(--space-6) + var(--space-16) - var(--space-2)) 0 calc(var(--space-16) - var(--space-2));
        z-index: 1;
        border: var(--rule-width-subtle) solid var(--color-border-faint);
        border-radius: var(--card-radius);
        pointer-events: none;
    }
}

#concept::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background: url("../images/concept-room-bg.webp") center top / cover no-repeat;
    opacity: var(--bt-concept-bg-opacity);
    pointer-events: none;
    transition: opacity var(--bt-concept-bg-reveal-duration) var(--ease-standard);
    /* Ramp is longer and slow-start (eased) rather than a straight 2-stop linear fade so a
       higher --bt-concept-bg-opacity still reads as a gradual reveal instead of a visible
       edge where it crosses the hero's white into #concept. */
    -webkit-mask-image: linear-gradient(180deg,
            transparent 0px,
            transparent 120px,
            rgba(0, 0, 0, 0.12) 220px,
            rgba(0, 0, 0, 0.45) 320px,
            #000 460px);
    mask-image: linear-gradient(180deg,
            transparent 0px,
            transparent 120px,
            rgba(0, 0, 0, 0.12) 220px,
            rgba(0, 0, 0, 0.45) 320px,
            #000 460px);
}

.concept__aurora {
    --concept-aurora-stripes: repeating-linear-gradient(100deg,
            #fff 0%,
            #fff 7%,
            transparent 10%,
            transparent 12%,
            #fff 16%);
    --concept-aurora-rainbow: repeating-linear-gradient(100deg,
            #60a5fa 10%,
            #e879f9 15%,
            #60a5fa 20%,
            #5eead4 25%,
            #60a5fa 30%);

    position: absolute;
    top: -10px;
    right: -10px;
    left: -10px;
    z-index: 0;
    height: min(360px, 26%);
    pointer-events: none;
    opacity: 0.22;
    background-image: var(--concept-aurora-stripes), var(--concept-aurora-rainbow);
    background-position: 50% 50%, 50% 50%;
    background-size: 300%, 200%;
    filter: blur(10px) invert(100%);
    -webkit-mask-image: radial-gradient(ellipse at 100% 0%, #000 40%, transparent 70%);
    mask-image: radial-gradient(ellipse at 100% 0%, #000 40%, transparent 70%);
}

.concept__aurora::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--concept-aurora-stripes), var(--concept-aurora-rainbow);
    background-size: 200%, 100%;
    background-attachment: fixed;
    mix-blend-mode: difference;
    animation: concept-aurora-drift 60s linear infinite;
}

@keyframes concept-aurora-drift {
    from {
        background-position: 50% 50%, 50% 50%;
    }

    to {
        background-position: 350% 50%, 350% 50%;
    }
}

.concept__inner {
    position: relative;
    z-index: 1;
    display: grid;
    align-content: center;
    justify-items: center;
    gap: var(--space-6);
    opacity: 1;
    transform: translateY(0);
    will-change: transform, opacity;
}

.concept__description {
    margin: 0;
    font-size: var(--bt-concept-description-size);
    font-weight: var(--font-weight-light);
    line-height: var(--bt-concept-description-line-height);
    letter-spacing: var(--section-heading-tracking);
    text-wrap-style: balance;
}

.concept__video-scroll {
    min-height: unset;
    margin-top: var(--space-12);
    position: relative;
    z-index: 1;
    opacity: 1;
    transform: translateY(0);
    will-change: transform, opacity;
}

@media (max-width:1199px) {
    .concept__description {
        text-wrap: unset;
    }
}

@media (max-width:991px) {
    .concept__description {
        --bt-concept-description-size: var(--section-topic-size-sm);
        --bt-concept-description-line-height: var(--section-topic-line-height-sm);
        font-size: var(--bt-concept-description-size);
        line-height: var(--bt-concept-description-line-height);
    }
}

.concept__video-perspective {
    /* min-height: calc(100vh - var(--header-height)); */
    position: sticky;
    top: var(--header-height);
    display: grid;
    place-items: start center;
    perspective: 1400px;
    perspective-origin: 50% 35%;
}

.concept__video-frame {
    position: relative;
    width: min(100%, calc((100vh - var(--header-height) - var(--space-24)) * 16 / 9));
    aspect-ratio: 16 / 9;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: var(--card-radius);
    background: transparent;
    /* box-shadow: var(--shadow-low), var(--shadow-deep); */
    transform-origin: 50% 100%;
    will-change: transform;
}

.concept__video-frame-art {
    position: absolute;
    z-index: 3;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
    pointer-events: none;
    user-select: none;
}

.concept__video-media {
    position: relative;
    width: 93.5%;
    height: auto;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: var(--radius-1);
    background: var(--color-surface-inverse);
}

.concept__video-poster {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    overflow: hidden;
    color: var(--color-text-primary);
    background: var(--color-surface-inverse);
    border: 0;
    cursor: pointer;
    transition: opacity var(--duration-fast) var(--ease-standard);
}

.concept__video-poster img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
}

.concept__video-play {
    --bt-concept-video-play-ring-color: color-mix(in srgb, var(--color-surface-page) 72%, transparent);

    position: absolute;
    top: 50%;
    left: 50%;
    width: clamp(var(--space-12), 7vw, calc(var(--space-24) - var(--space-1)));
    aspect-ratio: 1;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    filter: brightness(1);
    isolation: isolate;
    transition:
        filter var(--duration-fast) var(--ease-standard),
        transform var(--duration-fast) var(--ease-standard);
}

.concept__video-play::before,
.concept__video-play::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: var(--bt-concept-video-play-ring-color);
    pointer-events: none;
    animation: concept-video-play-pulse 1.8s ease-out infinite;
}

.concept__video-play::after {
    animation-delay: 0.9s;
}

.concept__video-play-surface {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: grid;
    place-items: center;
    border-radius: inherit;
    background: linear-gradient(180deg, #9b9b9b 0%, #191a1d 100%);
    box-shadow:
        0 0 0 var(--space-1) var(--bt-concept-video-play-ring-color),
        inset 0 var(--border-width-1) color-mix(in srgb, var(--color-neutral-0) 26%, transparent),
        0 14px 28px color-mix(in srgb, var(--color-neutral-900) 34%, transparent);
}

@keyframes concept-video-play-pulse {
    0% {
        opacity: 0.7;
        transform: scale(1);
    }

    75%,
    100% {
        opacity: 0;
        transform: scale(1.45);
    }
}

.concept__video-play .bt-icon {
    --bt-icon-size: clamp(var(--space-6), 3.2vw, var(--space-10));

    position: relative;
    z-index: 1;
    margin-left: var(--space-1);
    color: var(--color-neutral-0);
    fill: currentColor;
    stroke: currentColor;
    stroke-width: 1.8;
}

.concept__video-poster:hover .concept__video-play,
.concept__video-poster:focus-visible .concept__video-play {
    filter: brightness(1.08);
    transform: translate(-50%, -50%) scale(1.03);
}

.concept__video-poster:focus-visible {
    outline: var(--border-width-2) solid var(--color-focus-ring);
    outline-offset: calc(var(--space-1) * -1);
}

.concept__video-media.is-video-playing .concept__video-poster {
    opacity: 0;
    pointer-events: none;
}

.concept__video-media iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

@media (max-width: 991px) {
    #concept {
        padding: var(--section-padding-y-sm) 0;
    }

    #concept::before {
        -webkit-mask-image: none;
        mask-image: none;
    }
}

@media (max-width: 767px) {
    #concept {
        --bt-concept-bg-opacity: 0.55;
    }

    .concept__video-scroll {
        margin-top: var(--space-8);
    }

    .concept__video-frame {
        width: 100%;
    }
}

@media (max-width:575px) {
    .concept__description {
        --bt-concept-description-size: var(--section-topic-size-xs);
        --bt-concept-description-line-height: var(--section-topic-line-height-xs);
        font-size: var(--bt-concept-description-size);
        line-height: var(--bt-concept-description-line-height);
    }

    .concept__video-scroll {
        min-height: unset;
        margin-top: var(--space-6);
    }

    .concept__video-perspective {
        min-height: unset;
    }
}

@media (max-width:1536px),
(max-height:900px),
(hover:none) and (pointer:coarse) {
    .concept__video-scroll {
        min-height: auto;
    }

    .concept__video-perspective {
        min-height: unset;
        position: relative;
        top: auto;
    }
}

@media (max-width: 575px) {
    .concept__inner {
        gap: var(--space-3);
    }
}

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

    .concept__video-play::before,
    .concept__video-play::after {
        animation: none;
    }
}

/* @media (min-width: 768px) and (max-width: 1199px) {
    #concept {
        padding: var(--section-padding-y-sm) 0;
    }
} */

/* ---------- Featured topics ---------- */
.topics-showcase {
    --bt-topics-title-size: var(--section-title-size);

    position: relative;
    z-index: 1;
    /* min-height: 100vh; */
    padding: var(--section-padding-y) 0;
    overflow: hidden;
    color: var(--bt-topics-ink);
    background: var(--bt-topics-bg);
    font-family: var(--font-family-base);
}

.topics-showcase__inner {
    display: grid;
}

.topics-showcase__header {
    width: min(100%, 1040px);
    margin: 0 auto;
    text-align: center;
}

.topics-showcase__header h2 {
    margin: 0;
    font-size: var(--bt-topics-title-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-title-line-height);
    letter-spacing: var(--section-title-tracking);
    text-wrap-style: balance;
}

.topics-showcase__header p {
    margin: var(--space-8) 0 0;
    color: var(--bt-topics-ink-muted);
    font-size: var(--section-topic-size);
    font-weight: var(--font-weight-light);
    line-height: var(--section-topic-line-height);
    letter-spacing: var(--section-heading-tracking);
    text-wrap-style: balance;
}

.topics-showcase__content {
    --topics-asset-left: 10%;
    --topics-asset-right: 90%;

    position: relative;
    margin-top: var(--bt-topics-content-margin-top);
    display: block;
}

.topics-showcase .concept__topics {
    position: relative;
    z-index: 2;
    width: min(calc(100% - 280px), 1200px);
    margin: var(--space-0);
    margin-inline: auto;
    padding: var(--space-0);
    display: flex;
    flex-wrap: wrap;
    column-gap: var(--space-8);
    list-style: none;
}

.topics-showcase .concept__topic {
    /* Each topic reveals when it scrolls in, so timing comes from scroll position rather
       than a fixed sequence. topics-reveal.js sets --topic-delay only on topics that cross
       the line in the same batch (a whole screenful arriving at once), so those fan out
       instead of popping together. The underline always trails its own text. */
    --topic-delay: 0ms;
    --topic-line-delay: calc(var(--topic-delay) + 80ms);
    --topic-star-size: var(--bt-topics-star-size);
    --topic-star-gap: var(--space-6);

    position: relative;
    flex: 0 0 calc(50% - var(--space-4));
    min-height: calc(var(--space-16) + var(--space-2));
    margin: var(--space-0);
    padding: var(--space-6) var(--space-0) var(--space-6) calc(var(--topic-star-size) + var(--topic-star-gap));
    display: grid;
    align-content: center;
    color: var(--bt-topics-ink);
    letter-spacing: 0;
}

/* ดาวผูกกับหัวข้อ (title) ไม่ใช่กึ่งกลางทั้งรายการ ไม่งั้นคำอธิบายที่ยาว 2 บรรทัดจะดันดาวให้ต่ำกว่าหัวข้อ
   เลื่อนออกไปทางซ้ายเท่ากับช่องที่ padding-left ของ .concept__topic เว้นไว้ (ขนาดดาว + ระยะห่าง) */
.topics-showcase .concept__topic-title::before {
    content: "";
    position: absolute;
    top: 50%;
    left: calc((var(--topic-star-size) + var(--topic-star-gap)) * -1);
    width: var(--topic-star-size);
    height: var(--topic-star-size);
    background: url("../images/star.webp") center / contain no-repeat;
    transform: translateY(-50%);
}

.topics-showcase .concept__topic::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background: var(--bt-topics-rule);
    transform-origin: left center;
}

.topics-showcase .concept__topic-label,
.topics-showcase .concept__topic-title,
.topics-showcase .concept__topic-description {
    display: block;
}

.topics-showcase .concept__topic-label {
    color: var(--bt-topics-ink-muted);
    font-size: var(--font-size-14);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-small-line-height);
    letter-spacing: var(--section-heading-tracking);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.topics-showcase .concept__topic-title {
    position: relative;
    margin-top: var(--space-1);
    color: var(--bt-topics-ink);
    font-size: var(--font-size-24);
    font-weight: var(--font-weight-medium);
    line-height: var(--section-topic-line-height);
}

.topics-showcase .concept__topic-description {
    margin-top: var(--space-1);
    color: var(--bt-topics-ink-muted);
    font-size: var(--font-size-16);
    font-weight: var(--font-weight-light);
    line-height: var(--section-body-line-height);
}

.topics-showcase__assets {
    position: absolute;
    inset-block: 0;
    left: calc(50% - 50vw);
    right: calc(50% - 50vw);
    z-index: 1;
    width: auto;
    min-height: 0;
    isolation: isolate;
    pointer-events: none;
}

.topics-showcase__assets::before {
    display: none;
}

.topics-showcase__asset {
    position: absolute;
    left: var(--asset-x);
    top: var(--asset-y);
    z-index: var(--asset-z, 1);
    width: var(--asset-size);
    max-width: var(--asset-max, 240px);
    margin: 0;
    translate: -50% -50%;
    scale: 0.8;
}

.topics-showcase__asset-motion {
    width: 100%;
    will-change: transform, opacity;
}

.topics-showcase__asset-float {
    width: 100%;
    will-change: transform;
}

.topics-showcase__asset img {
    display: block;
    width: 100%;
    height: auto;
    transform: rotate(var(--asset-rotation, 0deg));
    filter: saturate(1.5);
    /* filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.34)); */
}

.topics-showcase__asset--triangle {
    --asset-x: calc(var(--topics-asset-left) - 2%);
    --asset-y: -6%;
    --asset-size: 33%;
    --asset-max: 230px;
    --asset-rotation: 10deg;
    --asset-z: 3;
}

.topics-showcase__asset--bitcoin {
    --asset-x: calc(var(--topics-asset-left) + 3%);
    --asset-y: 48%;
    --asset-size: 29%;
    --asset-max: 205px;
    --asset-rotation: -10deg;
    --asset-z: 2;
}

.topics-showcase__asset--gold {
    --asset-x: calc(var(--topics-asset-right) + 1%);
    --asset-y: 6%;
    --asset-size: 15%;
    --asset-max: 108px;
    --asset-rotation: 12deg;
    --asset-z: 2;
}

.topics-showcase__asset--stock {
    --asset-x: var(--topics-asset-left);
    --asset-y: 94%;
    --asset-size: 9%;
    --asset-max: 64px;
    --asset-rotation: -12deg;
    --asset-z: 1;
}

.topics-showcase__asset--card {
    --asset-x: calc(var(--topics-asset-right) - 3%);
    --asset-y: 46%;
    --asset-size: 26%;
    --asset-max: 184px;
    --asset-rotation: 16deg;
    --asset-z: 1;
}

.topics-showcase__asset--heart {
    --asset-x: calc(var(--topics-asset-right) + 2%);
    --asset-y: 80%;
    --asset-size: 37%;
    --asset-max: 258px;
    --asset-rotation: -4deg;
    --asset-z: 3;
}

@media (max-width: 1499px) {
    .topics-showcase__asset {
        scale: 0.6;
    }

    .topics-showcase__asset--bitcoin {
        --asset-x: calc(var(--topics-asset-left) + 2%);
    }
}

@media (max-width: 1399px) {
    .topics-showcase__asset {
        scale: 0.54;
    }

    .topics-showcase .concept__topics {
        width: min(calc(100% - 320px), 1200px);
    }
}

.topics-showcase.is-reveal-ready .concept__topic {
    opacity: 0;
    transform: translateX(calc(var(--space-8) * -1));
}

.topics-showcase.is-reveal-ready .concept__topic::after {
    opacity: 0;
    transform: translateX(calc(var(--space-8) * -1)) scaleX(0);
}

.topics-showcase.is-reveal-ready .concept__topic.is-topic-visible {
    opacity: 1;
    transform: translateX(0);
    transition:
        opacity 560ms ease var(--topic-delay),
        transform 700ms var(--ease-standard) var(--topic-delay);
}

.topics-showcase.is-reveal-ready .concept__topic.is-topic-visible::after {
    opacity: 1;
    transform: translateX(0) scaleX(1);
    transition:
        opacity 520ms ease var(--topic-line-delay),
        transform 900ms var(--ease-standard) var(--topic-line-delay);
}

@media (max-width:991px) {
    .topics-showcase {
        min-height: auto;
        padding: var(--section-padding-y-sm) 0;
    }

    .topics-showcase__header p {
        font-size: var(--section-topic-size-sm);
        line-height: var(--section-topic-line-height-sm);
    }

    .topics-showcase__content {
        --topics-asset-left: 12%;
        --topics-asset-right: 88%;

        position: relative;
        margin-top: var(--bt-topics-content-margin-top-md);
        display: block;
    }

    .topics-showcase .concept__topics {
        width: min(calc(100% - 180px), 560px);
    }

    .topics-showcase .concept__topic {
        flex-basis: 100%;
    }

    .topics-showcase__assets {
        isolation: isolate;
    }

    .topics-showcase__asset {
        /* scale: 1; */
    }

    .topics-showcase__asset--triangle {
        --asset-y: 6%;
        /* --asset-size: clamp(72px, 15vw, 142px); */
        --asset-rotation: -10deg;
        --asset-z: 3;
    }

    .topics-showcase__asset--bitcoin {
        --asset-y: 64%;
        /* --asset-size: clamp(58px, 10vw, 104px); */
        --asset-rotation: -8deg;
        --asset-z: 2;
    }

    .topics-showcase__asset--gold {
        --asset-y: 18%;
        /* --asset-size: clamp(36px, 6vw, 58px); */
        --asset-rotation: 8deg;
        --asset-z: 1;
    }

    .topics-showcase__asset--stock {
        --asset-y: 94%;
        /* --asset-size: clamp(32px, 5vw, 48px); */
        --asset-rotation: -14deg;
        --asset-z: 1;
    }

    .topics-showcase__asset--card {
        --asset-y: 42%;
        /* --asset-size: clamp(54px, 9vw, 88px); */
        --asset-rotation: 12deg;
        --asset-z: 2;
    }

    .topics-showcase__asset--heart {
        --asset-y: 79%;
        /* --asset-size: clamp(82px, 16vw, 156px); */
        --asset-rotation: -5deg;
        --asset-z: 3;
    }
}

@media (max-width: 767px) {
    .topics-showcase {
        --bt-topics-title-size: var(--section-heading-size);

        min-height: auto;
        padding: var(--section-padding-y-sm) 0;
    }

    .topics-showcase__header p br {
        display: none;
    }

    .topics-showcase__content {
        margin-top: var(--bt-topics-content-margin-top-sm);
    }

    /* .topics-showcase .concept__topics {
        width: min(calc(100% - 72px), 480px);
    } */

    .topics-showcase .concept__topic {
        --topic-star-size: var(--bt-topics-star-size-sm);
        --topic-star-gap: var(--space-3);

        min-height: calc(var(--space-16) + var(--space-2));
        padding: var(--space-4) var(--space-0);
        padding-left: calc(var(--topic-star-size) + var(--topic-star-gap));
    }

    .topics-showcase .concept__topic-title {
        font-size: var(--font-size-20);
        line-height: var(--line-height-normal);
    }

    /* .topics-showcase .concept__topic-description {
        font-size: var(--font-size-14);
    } */

    .topics-showcase__assets {
        min-height: 0;
    }

}

@media (max-width:575px) {
    .topics-showcase__header p {
        font-size: var(--section-topic-size-xs);
        line-height: var(--section-topic-line-height-xs);
    }

    .topics-showcase__content {
        --topics-asset-left: 14%;
        --topics-asset-right: 86%;
    }

    .topics-showcase .concept__topics {
        width: calc(100% - 80px);
    }

    .topics-showcase__asset {
        scale: 0.72;
    }

    .topics-showcase__asset--triangle {
        --asset-x: 6%;
        --asset-y: -2%;
    }

    .topics-showcase__asset--gold {
        --asset-x: 94%;
        --asset-y: 6%;
    }

    .topics-showcase__asset--card {
        --asset-x: 98%;
        --asset-y: 42%;
    }

    .topics-showcase__asset--bitcoin {
        --asset-x: 2%;
        --asset-y: 64%;
    }

    .topics-showcase__asset--heart {
        --asset-x: 98%;
        --asset-y: 82%;
    }

    .topics-showcase__asset--stock {
        --asset-x: 10%;
        --asset-y: 98%;
    }

    .topics-showcase__asset-motion,
    .topics-showcase__asset-float {
        transform: none !important;
        animation: none !important;
    }

    .topics-showcase .concept__topic-label {
        font-size: var(--font-size-12);
    }

    .topics-showcase .concept__topic-title {
        font-size: var(--font-size-18);
    }

    .topics-showcase .concept__topic-description {
        font-size: var(--font-size-14);
        line-height: var(--section-small-line-height);
    }
}

@media (min-width: 992px) and (max-width: 1199px) {
    /* .topics-showcase {
        padding: var(--section-padding-y-sm) 0;
    } */

    .topics-showcase__assets {
        width: 100%;
        left: 50%;
        right: unset;
        transform: translateX(-50%);
    }

    .topics-showcase__asset {
        scale: 0.52;
    }

    .topics-showcase__content {
        --topics-asset-left: 3%;
        --topics-asset-right: 97%;

        margin-top: var(--bt-topics-content-margin-top-md);
    }

    .topics-showcase .concept__topics {
        width: min(calc(100% - 120px), 1000px);
    }

    .topics-showcase__asset--triangle {
        --asset-y: -4%;
    }

    .topics-showcase__asset--bitcoin {
        --asset-y: 46%;
    }

    .topics-showcase__asset--gold {
        --asset-y: 8%;
    }

    .topics-showcase__asset--stock {
        --asset-y: 91%;
    }

    .topics-showcase__asset--card {
        --asset-y: 43%;
    }

    .topics-showcase__asset--heart {
        --asset-y: 82%;
    }

    .topics-showcase .concept__topic {
        --topic-star-size: var(--bt-topics-star-size-md);
    }

}

@media (prefers-reduced-motion: reduce) {

    .topics-showcase__asset-motion,
    .topics-showcase__asset-float {
        will-change: auto;
    }
}

/* ---------- Ticket ---------- Comparison layout แบบ editorial ใช้พื้นที่ว่างและเส้นบางแทนกรอบ card */
.ticket {
    --bt-ticket-title-size: var(--section-title-size);
    --bt-ticket-plan-title-size: var(--font-size-32);
    --bt-ticket-plan-title-line-height: var(--section-heading-line-height);
    --bt-ticket-price-size: var(--section-heading-size);
    --bt-ticket-price-line-height: var(--section-heading-line-height);
    --bt-ticket-backdrop-height: 600px;
    --bt-ticket-backdrop-parallax-bleed: calc(var(--bt-ticket-backdrop-height) * 0.15);
    --bt-ticket-plans-width: 1400px;

    position: relative;
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .ticket__backdrop-clip {
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        z-index: 0;
        height: var(--bt-ticket-backdrop-height);
        overflow: hidden;
        pointer-events: none;
    }

    .ticket__backdrop {
        position: absolute;
        top: calc(var(--bt-ticket-backdrop-parallax-bleed) * -1);
        left: 0;
        width: 100%;
        height: calc(100% + var(--bt-ticket-backdrop-parallax-bleed) * 2);
        object-fit: cover;
        object-position: center;
        will-change: transform;
    }

    @media (max-width: 767px) {
        .ticket__backdrop {
            object-position: 72% center;
        }
    }

    &::before {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        z-index: 0;
        height: var(--bt-ticket-backdrop-height);
        background: linear-gradient(90deg, rgba(17, 19, 24, 0.9) 0%, rgba(17, 19, 24, 0.25) 60%, rgba(17, 19, 24, 0) 80%);
        pointer-events: none;
    }

    .ticket__inner {
        position: relative;
        z-index: 1;
    }

    /* พื้นขาวย้ายไปอยู่ที่ .ticket__plan แต่ละใบแทน (การ์ดมีช่องว่างคั่นแล้ว
       ไม่ได้ต่อกันสนิทเหมือนก่อน จึงไม่ต้องมีแผ่นทึบแสงผืนเดียวคลุมทั้งแถว) */
    .ticket__plans {
        position: relative;
        z-index: 1;
        width: min(calc(100% - var(--space-12)), var(--bt-ticket-plans-width));
        margin-right: auto;
        margin-left: auto;
        /* จุดลงจอดของเมนู Ticket (data-scroll-to ใน index.html) การ์ดบนสุดอยู่ใต้ header พอดี */
        scroll-margin-top: calc(var(--header-height) + var(--space-24));
    }

    /* ไม่มีภาพพื้นหลังมืดด้านบนแล้ว หัว section ใช้สีหมึกปกติเหมือน section อื่น */
    .ticket__heading h2 {
        color: var(--color-text-primary);
    }

    .ticket__header {
        --bs-gutter-y: var(--space-6);

        align-items: end;
        margin-bottom: var(--section-padding-y-sm);
    }

    .ticket__plan-index {
        margin: 0 0 var(--space-2);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        text-transform: uppercase;
    }

    .ticket__heading h2 {
        margin: 0;
        font-size: var(--bt-ticket-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-title-line-height);
        letter-spacing: var(--section-title-tracking);
        text-wrap-style: balance;
    }

    .ticket__intro {
        margin: 0;
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    /* ≥992 การ์ดเรียงชิดกันไม่มี gap (อยู่ในกรอบรวมผืนเดียว ดู #ticket .ticket__plans::before)
       ส่วน ≤991 ที่ซ้อนเป็นคอลัมน์ ใช้ gap แนวตั้งของตัวเองใน media query ด้านล่าง */
    .ticket__plans {
        padding: var(--space-6) 0 0;
        align-items: flex-start;
        justify-content: center;
        border-radius: var(--bt-ticket-benefit-radius);
    }

    /* 3 ใบเท่ากันพอดีแถว (ไม่มี gap แนวนอนแล้ว) */
    @media (min-width: 992px) {
        .ticket__plan {
            width: calc(100% / 3);
        }
    }

    /* แต่ละใบยืนเป็นการ์ดของตัวเอง (กรอบรอบ + มุมโค้ง + พื้นหลัง) แทนที่จะอาศัยเส้นคาด
       คั่นระหว่างใบที่ชนกันแบบเดิม เพราะตอนนี้มีช่องว่างจริงคั่นอยู่แล้ว */
    .ticket__plan {
        position: relative;
        min-width: 0;
        padding: var(--space-12) var(--space-8);
        display: flex;
        flex-direction: column;
        border-top: var(--border-width-6) solid transparent;
        border-radius: var(--card-radius);
        background: var(--color-surface-page);
        transition: background-color var(--duration-standard) var(--ease-standard);
    }

    /* พื้นผิว grain: noise แบบ feTurbulence เบลนด์ overlay ทับการ์ดราคาทั้ง 3 ใบแบบบาง ๆ
       ความทึบต่ำจงใจ ให้แค่รู้สึกถึงพื้นผิวโดยไม่รบกวนการอ่านตัวเลข/ราคา */
    .ticket__plan::after {
        content: '';
        position: absolute;
        inset: 0;
        z-index: 2;
        background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
        opacity: 0.05;
        mix-blend-mode: overlay;
        pointer-events: none;
    }

    /* ใบข้าง ๆ (Master Class/Explorer) เตี้ยกว่าใบ Ultimate ที่มีแถบริบบอนแนะนำเพิ่มขึ้น
       มา ดัน margin-top ลงมาให้ขอบบนของใบข้างอยู่ต่ำกว่าใบ Ultimate แทนที่จะเสมอกัน
       ตอกย้ำว่า Ultimate เป็นใบเด่น */
    .ticket__plan--master,
    .ticket__plan--explorer {
        margin-top: calc(var(--space-16) - var(--space-2));
    }

    .ticket__plan--explorer {
        order: 1;
    }

    .ticket__plan--ultimate {
        order: 2;

        .ticket__plan-header {
            margin-top: calc(var(--space-10) + 2px);
        }
    }

    .ticket__plan--master {
        order: 3;
    }

    .ticket__plan--ultimate {
        padding-top: var(--space-8);
        z-index: 1;
        /* ต้องระบุ border-style เองเพราะ .ticket__plan ฐานตั้ง border เป็น none ไว้
           overflow: hidden ใช้ตัดมุม ribbon และ glow ให้โค้งตามการ์ดพอดี */
        border: var(--border-width-2) solid #19274A;
        border-top: none;
        overflow: hidden;
        /* ทินต์เดิมเคยทึบ 100% (mix กับสีทึบ ไม่ใช่ transparent) พอจะใส่รูป ultimate-bg.webp
           เป็นพื้นหลังด้วย ต้องลดความทึบของทินต์ลง (mix กับ transparent แทน) ให้รูปโปร่งผ่านออกมาเห็นได้ */
        background:
            linear-gradient(color-mix(in srgb, #ffffff 72%, transparent), color-mix(in srgb, var(--color-surface-page) 64%, transparent)),
            url('../images/ultimate-bg.webp') center / cover no-repeat;
        transition: all var(--duration-standard) var(--ease-standard);
        /* box-shadow:
            0 18px 48px rgba(17, 19, 24, 0.10),
            0 0 0 1px var(--alpha-ink-06); */

        &::before {
            content: '';
            position: absolute;
            inset: 0;
            z-index: -1;
            background:
                radial-gradient(circle at 18% 0%, color-mix(in srgb, var(--color-kv-spectrum-1) 12%, transparent) 0%, transparent 34%),
                radial-gradient(circle at 88% 10%, color-mix(in srgb, var(--color-kv-spectrum-5) 10%, transparent) 0%, transparent 30%);
            opacity: 0.64;
            pointer-events: none;
        }

        &:hover {
            background:
                linear-gradient(color-mix(in srgb, #ffffff 64%, transparent), color-mix(in srgb, var(--color-surface-page) 56%, transparent)),
                url('../images/ultimate-bg.webp') center / cover no-repeat;
        }
    }

    /* แถบริบบอนบนสุดของใบ Ultimate เท่านั้น ดึงชิดขอบทั้ง 3 ด้าน (บน-ซ้าย-ขวา) ด้วย
       margin ลบเท่ากับ padding ของ .ticket__plan (var(--space-8)) ให้ทับเนื้อในเดิม
       จนสุดขอบด้านในของกรอบสเปกตรัมพอดี มุมบนโค้งเท่ากับ card-radius หักความหนาของ
       border ออก (มุมด้านในของกรอบย่อมโค้งน้อยกว่ามุมด้านนอกเสมอ) */
    .ticket__plan-ribbon {
        position: absolute;
        inset: 0 -1px auto 0;
        width: auto;
        height: max-content;
        isolation: isolate;
        overflow: hidden;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        /* margin: calc(var(--space-8) * -1) calc(var(--space-8) * -1) var(--space-6); */
        padding: var(--space-3) var(--space-4);
        background: linear-gradient(180deg, #19274A 0%, #020B1E 100%);
        color: var(--color-text-inverse);
        font-size: var(--font-size-18);
        font-weight: var(--font-weight-regular);
        letter-spacing: 0.02em;

        span {
            position: relative;
            z-index: 1;
            display: inline-block;
            color: transparent;
            background: linear-gradient(105deg,
                    #c9d1df 0%,
                    #f7f9ff 26%,
                    #ffffff 38%,
                    #b7c0cf 46%,
                    #ffffff 54%,
                    #f7f9ff 66%,
                    #c9d1df 100%);
            background-size: 280% 100%;
            -webkit-background-clip: text;
            background-clip: text;
            text-shadow:
                0 0 0.03em rgba(255, 255, 255, 0.18);
            animation: ticket-ribbon-text-glow 4.6s ease-in-out infinite;
        }

        span::after {
            content: none;
        }

        &::before,
        &::after {
            content: "";
            position: absolute;
            pointer-events: none;
        }

        &::before {
            inset: calc(var(--space-4) * -1) var(--space-8) auto;
            z-index: -1;
            height: calc(100% + var(--space-8));
            background:
                radial-gradient(ellipse at 50% 0%, rgba(244, 221, 178, 0.3) 0%, rgba(214, 171, 104, 0.16) 36%, transparent 74%);
            filter: blur(10px);
            opacity: 0.94;
        }

        &::after {
            top: 0;
            left: 50%;
            z-index: -1;
            width: min(72%, 280px);
            height: var(--border-width-1);
            background: linear-gradient(90deg,
                    transparent 0%,
                    rgba(244, 221, 178, 0.18) 14%,
                    rgba(231, 201, 151, 0.82) 50%,
                    rgba(214, 171, 104, 0.22) 86%,
                    transparent 100%);
            box-shadow:
                0 0 14px rgba(231, 201, 151, 0.34),
                0 0 24px rgba(214, 171, 104, 0.16);
            opacity: 0.86;
            transform: translateX(-50%);
        }
    }

    @media (prefers-reduced-motion: reduce) {
        .ticket__plan-ribbon span {
            animation: none;
        }
    }

    .ticket__plan-header {
        margin-bottom: calc(var(--space-6) + var(--space-1));
    }

    /* ไอคอนประจำแพ็กเกจ: รูปมงกุฎ/เพชร/เข็มทิศ (ultimate/master/explorer)
       ทั้ง 3 ใบ มีแสง/เงาในตัวรูปอยู่แล้ว ไม่ต้องเติม filter engrave แบบไอคอนเส้นเดิม */
    .ticket__plan-icon {
        width: 44px;
        height: 44px;
        margin-bottom: var(--space-4);
        object-fit: contain;
        filter: saturate(1.5);
    }

    .ticket__plan-icon--ultimate {
        width: 80px;
        height: 80px;
    }

    .ticket__plan-header h3 {
        margin: 0;
        font-family: 'Baskervville', var(--font-family-base);
        font-size: var(--bt-ticket-plan-title-size);
        font-weight: var(--font-weight-regular);
        /* line-height: var(--bt-ticket-plan-title-line-height); */
        letter-spacing: var(--section-heading-tracking);
        text-transform: uppercase;
    }

    .ticket__plan-note {
        margin: var(--space-3) var(--space-0) var(--space-0);
        color: var(--color-text-muted);
        font-size: var(--section-topic-size-xs);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    .ticket__prices {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-auto-rows: var(--bt-ticket-price-equal-height, auto);
        border-top: var(--rule-width-subtle) solid var(--color-border-editorial);
        border-bottom: var(--rule-width-subtle) solid var(--color-border-editorial);
    }

    .ticket__price {
        appearance: none;
        width: 100%;
        min-height: var(--bt-ticket-price-equal-height, auto);
        min-width: 0;
        padding: var(--space-6);
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        justify-content: flex-start;
        border: 0;
        border-radius: 0;
        color: inherit;
        background: transparent;
        font: inherit;
        text-align: left;
        cursor: pointer;
        transition:
            background-color var(--duration-standard) var(--ease-standard),
            box-shadow var(--duration-standard) var(--ease-standard);

        &:hover {
            background: color-mix(in srgb, var(--color-blue-100) 55%, transparent);
        }

        &:disabled {
            cursor: not-allowed;

            strong {
                color: var(--color-text-muted);
            }
        }

        &:disabled:hover {
            background: transparent;
        }

        &:focus-visible {
            position: relative;
            z-index: 1;
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: calc(var(--border-width-2) * -1);
        }

        &.is-active {
            position: relative;
            z-index: 1;
            background: color-mix(in srgb, var(--color-blue-100) 72%, transparent);
            box-shadow: inset 0 0 0 var(--border-width-1) var(--color-blue-400);

            strong {
                color: var(--color-blue-600);
                font-weight: var(--font-weight-medium);
            }
        }

        &:not(:first-child) {
            border-left: var(--rule-width-subtle) solid var(--color-border-editorial);
        }

        .ticket__price-day {
            display: inline-flex;
            align-items: center;
            gap: var(--space-2);
            color: var(--color-text-muted);
            font-size: var(--font-size-14);
            font-weight: var(--font-weight-medium);
            line-height: var(--section-small-line-height);
        }

        &:not(:disabled) .ticket__price-day {
            width: 100%;
        }

        &:not(:disabled) .ticket__price-day::after {
            content: "";
            width: var(--space-4);
            height: var(--space-4);
            margin-left: auto;
            flex: 0 0 auto;
            border: var(--border-width-1) solid var(--color-border-default);
            border-radius: var(--radius-round);
            background: var(--color-neutral-0);
            box-shadow: inset 0 0 0 var(--border-width-2) var(--color-neutral-0);
        }

        &.is-active:not(:disabled) .ticket__price-day::after {
            background: var(--color-blue-600);
            box-shadow:
                inset 0 0 0 var(--border-width-2) var(--color-neutral-0),
                0 0 0 var(--border-width-1) var(--color-blue-600);
        }

        small {
            display: inline-flex;
            align-items: center;
            gap: var(--space-2);
            color: var(--color-text-muted);
            font-size: var(--font-size-14);
            font-weight: var(--font-weight-medium);
            line-height: var(--section-small-line-height);
        }

        /* ราคาเดิม + ป้าย SAVE วางแถวเดียวกัน ระยะด้านบนย้ายมาอยู่ที่แถวนี้แทนราคาเดิม
           ช่องราคาแคบ (เช่นมือถือที่วางสองช่องคู่กัน) ให้ป้ายตกลงบรรทัดถัดไป แทนการบีบราคาเดิมให้หักบรรทัด */
        /* แถวกว้างเต็มช่อง แล้วดันป้ายไปชิดขวา ตรงแนวเดียวกับปุ่มเลือก (วงกลม) ของ .ticket__price-day */
        .ticket__price-compare {
            width: 100%;
            margin-top: var(--space-3);
            display: inline-flex;
            flex-wrap: nowrap;
            align-items: center;
            gap: var(--space-1);
        }

        .ticket__price-save {
            margin-left: auto;
        }

        .ticket__price-original {
            color: var(--color-text-inverse-muted);
            white-space: nowrap;
            font-size: var(--font-size-14);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-small-line-height);
            text-decoration-thickness: var(--border-width-1);
        }

        strong {
            margin-top: var(--space-2);
            font-size: var(--bt-ticket-price-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--bt-ticket-price-line-height);
            letter-spacing: 0;
            white-space: nowrap;
        }

        .ticket__price-compare+strong {
            margin-top: var(--space-0);
        }

        .ticket__price-note {
            min-height: calc(var(--section-small-line-height) * 1em);
            margin-top: var(--space-2);
            text-align: left;
            font-weight: var(--font-weight-regular);
        }

        &.ticket__price--unavailable strong {
            font-size: var(--font-size-28);
        }
    }

    .ticket__access {
        margin: var(--space-6) 0 0;

        >div {
            min-height: var(--space-16);
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: var(--space-4);
            padding: var(--space-3) var(--space-0);
            border-top: var(--rule-width-subtle) solid var(--color-border-editorial);

            &:first-child {
                border-top: 0;
            }

        }

        dt,
        dd {
            margin: 0;
            font-size: var(--section-small-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-body-line-height);
        }
    }

    /* ไอคอนขนาดเล็กช่วยเชื่อมชื่อในตารางกับรายละเอียดแต่ละรูปแบบด้านล่าง */
    .ticket__access-label {
        min-width: 0;
        flex: 1 1 auto;
        display: flex;
        align-items: flex-start;
        gap: var(--space-2);

        >.bt-icon {
            flex: 0 0 auto;
            width: var(--bt-ticket-access-icon-size);
            height: var(--bt-ticket-access-icon-size);
            display: grid;
            place-items: center;
            padding: var(--space-1);
            color: var(--color-blue-600);
            border-radius: var(--radius-1);
            /* background: var(--color-blue-100);
            border: 1px solid var(--color-blue-200); */
            stroke-width: 1.75;
        }

        .ticket__access-copy {
            min-width: 0;
            display: flex;
            flex-direction: column;
            gap: var(--space-1);
        }

        .ticket__access-title {
            color: var(--color-text-primary);
            font-weight: var(--font-weight-medium);

            small {
                color: var(--color-text-muted);
                font-size: inherit;
                font-weight: var(--font-weight-medium);
            }
        }

        .ticket__access-description {
            color: var(--color-text-muted);
            font-size: var(--font-size-12);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-small-line-height);
        }
    }

    .ticket__status {
        min-width: var(--space-8);
        display: inline-flex;
        align-items: center;
        justify-content: flex-end;
        gap: var(--space-1);
        color: var(--color-text-muted);
        text-align: right;

        .bt-icon {
            font-size: var(--bt-icon-size);
            stroke-width: 2.25;
        }

        &.ticket__status--badge {
            flex: 0 0 auto;
            min-width: var(--space-12);
            min-height: var(--space-5);
            padding: var(--space-0) var(--space-2);
            border-radius: var(--pill-radius);
            border: var(--rule-width-subtle) solid var(--color-blue-200);
            background: var(--color-blue-100);
            color: var(--color-blue-400);
            font-size: var(--section-tag-size-sm);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-body-line-height);
        }
    }

    .ticket__action {
        width: 100%;
        margin: var(--space-6) 0 0;

        /* ปุ่ม Ultimate ใช้สีดำล้วน ไม่มีขอบ spectrum */
        &.bt-action-button--primary {
            border-color: var(--bt-action-fill);
            background: var(--bt-action-fill);
        }
    }

    .ticket__action-lock {
        display: block;
        margin: var(--space-6) 0 0;
        cursor: not-allowed;

        .ticket__action {
            margin: 0;
            pointer-events: none;
            cursor: not-allowed;
        }
    }

    .ticket__benefits {
        --bt-ticket-benefit-list-gap-x: var(--space-0);
        --bt-ticket-benefit-list-gap-y: var(--space-0);

        margin-top: var(--section-padding-y-sm);
        padding: var(--bt-ticket-benefit-block-padding-y) var(--bt-ticket-benefit-block-padding-x);
        border-radius: var(--bt-ticket-benefit-radius);
        background: var(--bt-ticket-benefit-bg);
        --bs-gutter-x: 0;

        h3 {
            margin: 0;
            font-size: var(--section-topic-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-topic-line-height);
            letter-spacing: 0;
            text-align: center;
        }

        ul {
            margin: 0;
            padding: 0;
            list-style: none;
            row-gap: var(--bt-ticket-benefit-list-gap-y);
            column-gap: var(--bt-ticket-benefit-list-gap-x);
        }

        li {
            position: relative;
            flex: 0 0 25%;
            max-width: 25%;
            min-width: 0;
            padding: 0 var(--bt-ticket-benefit-padding-x);
            display: grid;
            align-content: start;
            justify-items: center;
            gap: var(--space-4);
            color: var(--color-text-muted);
            font-size: var(--bt-ticket-benefit-text-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-body-line-height);
            text-align: center;

            &::before {
                content: '';
                position: absolute;
                top: 50%;
                left: 0;
                width: var(--bt-ticket-benefit-rule-length);
                height: calc(var(--bt-ticket-benefit-rule-length) / 9.13);
                background: url('../images/line-star.webp') center / contain no-repeat;
                transform: translate(-50%, -50%) rotate(90deg);
            }

            &:first-child::before {
                display: none;
            }

            .ticket__benefit-icon {
                width: var(--bt-ticket-benefit-icon-size);
                height: var(--bt-ticket-benefit-icon-size);
                display: block;
                filter: var(--bt-ticket-benefit-icon-shadow);
                object-fit: contain;
                filter: saturate(1.5);
            }

            span {
                color: var(--bt-ticket-benefit-text-color);
                font-size: var(--bt-ticket-benefit-text-size);
                font-weight: var(--bt-ticket-benefit-text-weight);
                text-wrap-style: balance;
            }
        }
    }

    @media (max-width:1399px) {
        --bt-ticket-plan-title-size: var(--font-size-28);
        --bt-ticket-price-size: var(--font-size-32);

        .ticket__plan {
            padding: var(--space-10) var(--space-6);
        }

        .ticket__plan--ultimate {
            padding: var(--space-6);
        }

        .ticket__price {
            strong {
                margin-top: var(--space-1);
            }

            /* ช่องราคาแคบลง ให้ป้าย SAVE ลงบรรทัดใต้ราคาเดิม ชิดซ้ายแนวเดียวกัน */
            .ticket__price-compare {
                flex-wrap: wrap;
                gap: var(--space-2);
            }

            .ticket__price-save {
                margin-left: 0;
            }
        }
    }

    @media (max-width:1199px) {
        --bt-ticket-backdrop-height: 540px;
        --bt-ticket-price-size: var(--font-size-36);

        .ticket__plan-header h3 {
            display: flex;
            flex-direction: column;
            gap: var(--space-2);
        }

        .ticket__prices {
            grid-template-columns: 1fr;
        }

        .ticket__price {
            /* justify-content: space-between; */

            &:not(:first-child) {
                border-left: none;
                border-top: var(--rule-width-subtle) solid var(--color-border-editorial);
            }

            span,
            small {
                font-size: var(--font-size-16);
            }
        }

        .ticket__access {
            >div {
                gap: var(--space-3);
                flex-direction: column;
                align-items: flex-start;
            }
        }

        .ticket__status {
            &.ticket__status--badge {
                margin-left: 32px;
            }
        }

        .ticket__benefits {
            --bt-ticket-benefit-list-gap-x: var(--space-6);
            --bt-ticket-benefit-list-gap-y: var(--space-10);

            h3 {
                margin-bottom: var(--space-8);
                text-align: start;
            }

            ul {
                row-gap: var(--bt-ticket-benefit-list-gap-y);
            }

            li {
                flex: 0 0 calc((100% - var(--bt-ticket-benefit-list-gap-x)) / 2);
                max-width: calc((100% - var(--bt-ticket-benefit-list-gap-x)) / 2);
                padding: 0 var(--bt-ticket-benefit-padding-x-md);
                display: flex;
                align-items: center;
                justify-content: flex-start;
                gap: var(--space-4);
                text-align: start;

                &::before {
                    left: calc(var(--bt-ticket-benefit-list-gap-x) / -2);
                    width: var(--bt-ticket-benefit-rule-length-sm);
                    height: calc(var(--bt-ticket-benefit-rule-length-sm) / 9.13);
                }

                &:nth-child(odd)::before {
                    display: none;
                }

                &:nth-child(even)::before {
                    display: block;
                }

                .ticket__benefit-icon {
                    width: var(--bt-ticket-benefit-icon-size-sm);
                    height: var(--bt-ticket-benefit-icon-size-sm);
                    flex: 0 0 auto;
                }

                span {
                    min-width: 0;
                    text-align: start;
                }
            }
        }
    }

    @media (max-width:991px) {
        --bt-ticket-backdrop-height: 440px;
        --bt-ticket-plan-title-size: var(--font-size-32);
        --bt-ticket-price-size: var(--font-size-40);

        padding: var(--section-padding-y-sm) 0;

        &::before {
            background: linear-gradient(180deg,
                    rgba(17, 19, 24, 0.50) 0%,
                    rgba(17, 19, 24, 0.34) 60%,
                    rgba(17, 19, 24, 0.12) 100%);
        }

        .ticket__header {
            margin-bottom: var(--space-12);
        }

        .ticket__plan-header h3 {
            display: block;
            gap: var(--space-0);
            font-size: var(--bt-ticket-plan-title-size);
        }

        .ticket__prices {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }

        .ticket__price {
            &:not(:first-child) {
                border-left: var(--rule-width-subtle) solid var(--color-border-editorial);
                border-top: none;
            }


            strong {
                margin-top: var(--space-2);
            }

            span,
            small {
                flex-direction: row;
                align-items: center;
                gap: var(--space-3);
                font-size: var(--font-size-16);
            }
        }

        .ticket__access {
            >div {
                gap: var(--space-4);
                flex-direction: row;
                align-items: center;
            }
        }

        .ticket__status {
            &.ticket__status--badge {
                margin-left: 0;
            }
        }

        /* จอนี้ลงไปการ์ดเรียงเป็นคอลัมน์เดียว ใช้ gap แนวตั้งคั่นให้อ่านง่าย
           ส่วน Ultimate ยังคงกรอบ spectrum ครบทั้ง 4 ด้าน
           ความกว้างเลิกกินเกือบเต็มจอ ใช้เท่าเนื้อหาใน .container ของ Bootstrap (รวม gutter ที่ main.css ปรับ)
           การ์ดจึงตรงแนวกับหัว section (.ticket__inner.container) */
        .ticket__plans {
            --bs-gutter-x: 1.5rem;

            gap: var(--space-6);
            padding: var(--space-0);
            width: min(calc(100% - var(--bs-gutter-x)), calc(720px - var(--bs-gutter-x)));
        }

        .ticket__plan {
            padding: var(--space-12) var(--space-8);
            border-radius: var(--radius-0);
            /* border-right: 0;
            border-bottom: 0;
            border-left: 0; */

            &:not(:first-child) {
                border-top: var(--rule-width-subtle) solid var(--color-border-faint);
            }
        }

        .ticket__plan--master {
            margin-top: var(--space-0);
        }

        .ticket__plan--explorer {
            margin-top: var(--space-0);
        }


        .ticket__plan--ultimate {
            order: 1;
            padding: var(--space-8);
            border-radius: var(--radius-1);
            /* border: var(--border-width-6) solid transparent; */
            border-top: none !important;
        }

        .ticket__plan--master {
            order: 3;
            border-top: var(--rule-width-subtle) solid var(--color-border-faint);
            margin-top: var(--space-0);
            padding-bottom: var(--space-0);
        }

        .ticket__plan--explorer {
            order: 2;
        }

        .ticket__plan-header {
            margin-bottom: var(--space-8);
        }

        .ticket__benefits {
            padding: var(--bt-ticket-benefit-block-padding-y) var(--bt-ticket-benefit-block-padding-x);

            h3 {
                margin-bottom: var(--space-8);
            }

            li {
                gap: var(--space-6);

                &:nth-child(odd) {
                    padding-left: var(--space-0);
                }

                &:nth-child(even) {
                    padding-right: var(--space-0);
                }
            }
        }

    }

    /* main.css ตั้ง gutter ของ .container เป็น 32px ตั้งแต่ 767px ลงมา ตามให้ตรงกัน */
    @media (max-width:767px) {
        .ticket__plans {
            --bs-gutter-x: 32px;
        }
    }

    @media (max-width:575px) {
        --bt-ticket-backdrop-height: 360px;
        --bt-ticket-title-size: var(--section-topic-size);
        --bt-ticket-plan-title-size: var(--font-size-28);
        --bt-ticket-plan-title-line-height: var(--section-topic-line-height);
        --bt-ticket-price-size: var(--font-size-32);
        --bt-ticket-benefit-text-size: var(--font-size-14);



        .ticket__plan-header {
            margin-bottom: var(--space-6);
        }

        .ticket__plan-header h3 {
            font-size: var(--bt-ticket-plan-title-size);
        }

        .ticket__plan-index {
            margin: 0 0 var(--space-1);
            font-size: var(--section-small-size);
        }

        .ticket__price {
            padding: var(--space-4);
        }

        .ticket__price strong {
            margin-top: var(--space-0);
            font-size: var(--bt-ticket-price-size);
        }

        .ticket__plan--master .ticket__prices {
            grid-auto-rows: auto;
        }

        /* บัตร Ultimate/Explorer ไม่ต้องสูงเท่ากันข้ามการ์ดแล้ว (ค่า --bt-ticket-price-equal-height จาก js/ticket-price-selector.js)
           แต่ละการ์ดสูงตามเนื้อหาของตัวเอง ส่วน Master Class (รอประกาศ) ใช้กฎของตัวเองด้านบน */
        .ticket__plan--ultimate .ticket__prices,
        .ticket__plan--explorer .ticket__prices {
            grid-auto-rows: auto;
        }

        .ticket__plan--ultimate .ticket__price,
        .ticket__plan--explorer .ticket__price {
            min-height: auto;
        }

        .ticket__plan--master .ticket__price--unavailable {
            min-height: auto;
            padding: var(--space-4);

            strong {
                margin-top: var(--space-3);
                font-size: var(--font-size-24);
                line-height: 1.15;
            }
        }

        .ticket__plan {
            padding: var(--space-8) var(--space-5);
        }

        .ticket__plan--master {
            padding-bottom: var(--space-0);
        }

        /* .ticket__plan--master {
            margin-top: var(--space-8);
        } */

        .ticket__price {

            span,
            small {
                font-size: var(--font-size-14);
                flex-wrap: wrap;
                gap: var(--space-2);
            }
        }

        .ticket__access {
            margin: var(--space-4) var(--space-0) var(--space-0);

            /* >div {
                min-height: var(--space-10);
            } */
        }

        .ticket__status .bt-icon {
            font-size: var(--font-size-16);
        }

        .ticket__benefits {
            --bt-ticket-benefit-list-gap-y: var(--space-8);

            padding: var(--bt-ticket-benefit-block-padding-y-sm) var(--bt-ticket-benefit-block-padding-x-sm);

            h3 {
                font-size: var(--section-topic-size-sm);
                margin-bottom: var(--space-6);
            }

            ul {
                row-gap: var(--bt-ticket-benefit-list-gap-y);
            }

            li {
                flex-direction: column;
                align-items: flex-start;
                align-content: start;
                padding: 0 var(--bt-ticket-benefit-padding-x-sm);
                gap: var(--space-3);

                span {
                    text-align: start;
                    min-width: 0;
                }

                &:nth-child(even) {
                    padding-left: var(--space-6);
                }

                .ticket__benefit-icon {
                    width: var(--bt-ticket-benefit-icon-size-xs);
                    height: var(--bt-ticket-benefit-icon-size-xs);
                    flex: 0 0 auto;
                }
            }
        }

    }

    @media (max-width:425px) {
        .ticket__price {

            /* ช่องราคาแคบลง ให้ป้าย SAVE ลงบรรทัดใต้ราคาเดิม ชิดซ้ายแนวเดียวกัน */
            .ticket__price-compare {
                margin-bottom: var(--space-1);
            }
        }
    }

    @media (max-width:390px) {
        .ticket__price .ticket__price-day {
            flex-wrap: nowrap;
            gap: 2px;
        }
    }
}

/* ---------- Agenda ----------
   ตารางกำหนดการแบบ editorial เน้นลำดับเวลา พื้นที่ว่าง และเส้นบาง */
.agenda {
    position: relative;
    scroll-margin-top: calc(var(--header-height) - var(--space-2));
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
    --agenda-day-label-size: var(--font-size-24);
    --agenda-day-label-line-height: 56px;
    --agenda-day-label-weight: var(--font-weight-regular);
    --agenda-day-label-color: var(--color-text-inverse-muted);
    --agenda-day-label-active-size: var(--font-size-48);
    --agenda-day-label-active-line-height: var(--section-topic-line-height);
    --agenda-day-label-active-weight: var(--font-weight-regular);
    --agenda-day-label-active-color: var(--color-text-primary);
    --agenda-day-details-size: var(--section-body-size);
    --agenda-day-details-line-height: var(--section-body-line-height);
    --agenda-day-details-weight: var(--font-weight-regular);
    --agenda-day-details-color: var(--color-text-muted);
    --agenda-day-details-active-size: var(--agenda-day-details-size);
    --agenda-day-details-active-line-height: var(--agenda-day-details-line-height);
    --agenda-day-details-active-weight: var(--agenda-day-details-weight);
    --agenda-day-details-active-color: var(--agenda-day-details-color);
    --agenda-day-switch-details-gap: var(--space-3);
    --agenda-sticky-gap: var(--space-6);
    --agenda-sticky-top: calc(var(--header-height) + var(--agenda-sticky-gap));
    --agenda-stage-tabs-height: var(--touch-target-md);
    --agenda-day-sticky-header-height: var(--agenda-day-panel-header-height);
    --agenda-day-panel-header-height: calc(var(--space-12) + var(--space-6));

    &.ticket::before {
        content: none;
    }

    /* margin-bottom ต้องไม่แคบกว่าฉากขาว ::before ของ .agenda__tabs (บรรทัดล่าง)
       ที่ยื่นขึ้นมาปิดพื้นที่เหนือแถบ sticky สูง calc(header-height + space-6)
       เท่ากันเป๊ะ — ถ้าช่องว่างตรงนี้แคบกว่านั้น ฉากขาวจะยื่นทับหัวข้อด้านบน */
    .agenda__section-header {
        margin-bottom: calc(var(--header-height) + var(--space-6));
    }

    .agenda__section-header h2 {
        max-width: 920px;
        margin: 0;
        font-size: var(--section-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-title-line-height);
        letter-spacing: 0;
    }

    /* align-items: start สำคัญ — ถ้าคอลัมน์ sidebar ถูกยืดเต็มความสูงแถว
       กล่องของมันจะสูงเท่าตาราง ทำให้ sticky ไม่มีระยะให้เลื่อน */
    .agenda__layout {
        align-items: start;
    }

    .agenda__inner {
        scroll-margin-top: calc(var(--header-height) + var(--space-6));
    }

    /* Day 1/Day 2 มีแถบแท็บ Stage sticky ของตัวเอง จึงต้องเผื่อระยะเท่ากับที่
       .agenda__panel ใช้ ไม่ใช่แค่ใต้ header เฉย ๆ ไม่งั้นคลิกสลับวันแล้วหัวตาราง
       จะโผล่ไปโดนแถบแท็บบัง */
    .agenda__day-panel {
        scroll-margin-top: calc(var(--agenda-sticky-top) + var(--agenda-day-panel-header-height) + var(--touch-target-md) + var(--rule-width-subtle));
        padding-left: var(--space-12);
        border-radius: var(--radius-1);
    }

    .agenda__day-panel-header {
        position: sticky;
        top: var(--agenda-sticky-top);
        z-index: 3;
        height: var(--agenda-day-panel-header-height);
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: var(--space-2) var(--space-4);
        padding: var(--space-3) var(--space-0) var(--space-8);
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        line-height: var(--section-body-line-height);
        background: var(--color-surface-page);
    }

    /* ปิดช่องว่างระหว่าง site header กับหัววันที่ ไม่ให้ข้อมูลตารางที่เลื่อนผ่าน
       มองเห็นลอดขึ้นมา โดยยังคง breathing room เดิมของ layout ไว้ */
    .agenda__day-panel-header::before {
        content: '';
        position: absolute;
        right: 0;
        bottom: 100%;
        left: 0;
        height: var(--agenda-sticky-gap);
        background: var(--color-surface-page);
        pointer-events: none;
    }

    .agenda__day-panel-date,
    .agenda__day-panel-time {
        margin: 0;
        color: var(--color-text-primary);
        font-size: var(--font-size-24);
        font-weight: var(--font-weight-medium);
    }

    /* Day 1 กับ Day 2 อยู่ในตารางต่อกันตรง ๆ ไม่งั้นดูเหมือนตารางเดียวยาวต่อเนื่อง
       เว้นระยะ + ขีดคั่นเข้าไปให้เห็นชัดว่าขึ้นวันใหม่แล้ว (ตัวสลับวันด้านข้างบอก
       อยู่แล้วว่าเป็นวันไหน แต่คนละองค์ประกอบกัน ตรงนี้ต้องอ่านออกในตัวมันเองด้วย)
       :not([hidden]) ทั้งสองฝั่งกันไว้ไม่ให้กระทบจอ ≤991px ที่โชว์ทีละวัน — วันที่
       ถูกซ่อนอยู่ตัดคู่ sibling ที่ตรงเงื่อนไขไปเลย วันที่เหลือโชว์อยู่คนเดียวเลย
       ไม่มีระยะ/ขีดคั่นเผื่อไว้ด้านบนแบบผิดที่ */
    .agenda__day-panel:not([hidden])+.agenda__day-panel:not([hidden]) {
        margin-top: var(--space-32);
        /* padding-top: var(--space-16);
        border-top: var(--rule-width-subtle) solid var(--color-border-editorial); */
    }

    .agenda__days {
        min-width: 0;
    }

    .agenda__eyebrow {
        margin: 0 0 var(--space-2);
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        text-transform: uppercase;
    }

    /* sidebar เป็นคอลัมน์จริงในแถว จึงมีความสูงจริงให้ browser ใช้คำนวณจุดปล่อย
       (เดิมเป็น overlay height:0 ทำให้ค้างเลยขอบ section ไปทับ section ถัดไป) */
    .agenda__day-switcher {
        position: sticky;
        top: calc(var(--header-height) + var(--space-6));
        z-index: 2;
        align-self: start;
        min-width: 0;
    }

    /* แถวสูงตามเนื้อหาจริง ไม่ล็อกค่าคงที่ ไม่งั้นวันที่ไม่ได้เลือก (เหลือแค่บรรทัดเดียว)
       จะทิ้งช่องว่างค้างไว้ ความสูงรวมยังเท่าเดิมทั้งสองสถานะ เพราะส่วนที่ขยาย
       ย้ายจากวันหนึ่งไปอีกวันหนึ่งพอดี จึงไม่เกิดการกระตุก */
    .agenda__day-switcher-inner {
        display: grid;
        justify-items: start;
        gap: var(--space-6);
    }

    .agenda__day-switch {
        position: relative;
        z-index: 1;
        display: block;
        align-self: start;
        width: fit-content;
        min-width: 0;
        padding: 0;
        color: var(--agenda-day-label-color);
        font-size: var(--agenda-day-label-size);
        font-weight: var(--agenda-day-label-weight);
        line-height: var(--agenda-day-label-line-height);
        letter-spacing: 0;
        text-decoration: none;
        text-transform: uppercase;
        transition:
            color var(--duration-base) var(--ease-standard),
            opacity var(--duration-base) var(--ease-standard);

        &:hover,
        &:focus-visible {
            color: var(--agenda-day-label-active-color);
        }

        &[aria-current='true'] {
            color: var(--agenda-day-label-active-color);
        }

        &:focus-visible {
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: var(--space-2);
        }
    }

    .agenda__day-switch-label {
        display: block;
        font-size: var(--agenda-day-label-size);
        line-height: var(--line-height-normal);
        transition:
            font-size var(--duration-base) var(--ease-standard),
            line-height var(--duration-base) var(--ease-standard),
            color var(--duration-base) var(--ease-standard);
    }

    /* ใช้ 0fr → 1fr แทน max-height เพราะ max-height ต้องกำหนดค่าปลายทางเผื่อไว้
       (เดิม 72px ขณะที่เนื้อหาจริง 56px) ค่าที่เกินมาทำให้กล่องกางเสร็จตั้งแต่ 26%
       ของเวลา แล้วเหลืออีก 178ms ที่ค่าวิ่งต่อโดยตาไม่เห็นอะไรเปลี่ยน
       ส่วน 1fr วิ่งตามความสูงจริงเสมอ จังหวะจึงตรงกับ opacity ที่วิ่งคู่กัน */
    .agenda__day-switch-details {
        display: grid;
        grid-template-rows: 0fr;
        margin-top: 0;
        color: var(--agenda-day-details-color);
        font-size: var(--agenda-day-details-size);
        font-weight: var(--agenda-day-details-weight);
        line-height: var(--agenda-day-details-line-height);
        text-transform: none;
        opacity: 0;
        transform: translateY(calc(var(--space-2) * -1));
        transition:
            grid-template-rows var(--duration-base) var(--ease-standard),
            margin-top var(--duration-base) var(--ease-standard),
            opacity var(--duration-base) var(--ease-standard),
            transform var(--duration-base) var(--ease-standard);
    }

    /* ต้องมีชั้นนี้เพื่อให้ 0fr บีบได้จริง — min-height: 0 ปลดขนาดขั้นต่ำของ grid item
       และ overflow: hidden เป็นตัวตัดเนื้อหาส่วนเกินระหว่างย่อ */
    .agenda__day-switch-details-inner {
        display: grid;
        gap: var(--space-1);
        min-height: 0;
        overflow: hidden;
    }

    .agenda__day-switch[aria-current='true'] .agenda__day-switch-label {
        font-size: var(--agenda-day-label-active-size);
        font-weight: var(--agenda-day-label-active-weight);
        line-height: var(--agenda-day-label-active-line-height);
    }

    .agenda__day-switch:not([aria-current='true']) .agenda__day-switch-details {
        grid-template-rows: 1fr;
        margin-top: var(--agenda-day-switch-details-gap);
        color: var(--agenda-day-label-color);
        font-size: var(--agenda-day-details-active-size);
        font-weight: var(--agenda-day-details-active-weight);
        line-height: var(--agenda-day-details-active-line-height);
        opacity: 1;
        transform: translateY(0);
    }

    /* เส้นนำสายตาเป็น grid item แถวกลาง (อยู่ระหว่างสอง <a> ใน DOM อยู่แล้ว)
       จึงขยับตามความสูงจริงของแต่ละวันเอง ไม่ต้องผูกกับตำแหน่ง absolute คงที่ */
    .agenda__day-switch-rail {
        position: relative;
        overflow: hidden;
        width: var(--rule-width-subtle);
        height: var(--space-28);
        background: var(--color-border-editorial);
        pointer-events: none;
    }

    .agenda__day-switch-prompt {
        display: none;
    }

    /* ช่วงสเปกตรัมครึ่งเส้น เลื่อนไปเกาะฝั่งของวันที่เลือก — ล้อกับตัวชี้ใต้ Stage tabs
       ที่เลื่อนแนวนอน ใช้ translateY ล้วนจึงไม่แตะ layout เลย */
    .agenda__day-switch-rail::after {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        height: 50%;
        background: var(--spectrum-vertical);
        transform: translateY(0);
        transition: transform var(--duration-base) var(--ease-standard);
    }

    .agenda__day-switcher-inner[data-active-day='day-two'] .agenda__day-switch-rail::after {
        transform: translateY(100%);
    }

    .agenda__content {
        min-width: 0;
        background: var(--color-neutral-50);
        border-radius: var(--radius-1);
    }

    .agenda__tabs-viewport {
        display: contents;
    }

    .agenda__tabs {
        --agenda-tab-indicator-x: 0px;
        --agenda-tab-indicator-y: 0px;
        --agenda-tab-indicator-width: 0px;

        position: sticky;
        top: calc(var(--agenda-sticky-top) + var(--agenda-day-panel-header-height));
        z-index: 2;
        min-height: var(--touch-target-md);
        display: flex;
        flex-direction: row;
        align-items: flex-end;
        /* border-bottom: var(--rule-width-emphasis) solid var(--color-border-editorial); */
        background: var(--color-surface-page);
        overflow: visible;
        scrollbar-width: none;

        &::-webkit-scrollbar {
            display: none;
        }

        /* ฉากใต้ Header ปิดเนื้อหาตารางที่เลื่อนผ่านด้านบนของแถบ sticky */
        &::before {
            content: '';
            position: absolute;
            right: 0;
            bottom: 100%;
            left: 0;
            z-index: 0;
            height: calc(var(--header-height) + var(--space-6));
            background: var(--color-surface-page);
            pointer-events: none;
        }

        /* border-bottom อยู่ที่ .agenda__tab (flex: 0 0 auto) เส้นจึงยาวแค่ความกว้าง
           ของปุ่มแท็บรวมกัน ไม่ยาวสุดแถว — ตัวเติมนี้ยืด (flex: 1 1 auto) กินพื้นที่
           ที่เหลือ พร้อมเส้นเดียวกัน ให้ดูเป็นเส้นเดียวยาวต่อกันสุดแถว */
        &::after {
            content: '';
            flex: 1 1 auto;
            border-bottom: var(--rule-width-emphasis) solid var(--color-border-faint);
        }
    }

    .agenda__tab {
        position: relative;
        z-index: 1;
        flex: 0 0 auto;
        width: auto;
        min-height: var(--touch-target-md);
        padding: 0 var(--space-6);
        border: 0;
        color: var(--color-text-muted);
        background: transparent;
        font: inherit;
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        white-space: nowrap;
        cursor: pointer;
        border-bottom: var(--rule-width-emphasis) solid var(--color-border-faint);
        transition:
            color var(--duration-fast) var(--ease-standard),
            background-color var(--duration-fast) var(--ease-standard);

        /* วงเล็บไทยแพตเทิร์นเดียวกับ .ticket__access-title small: ขนาดเท่าป้าย (ทับ .875em ของ Bootstrap)
           ยังไม่เลือกใช้สีรอง */
        small {
            color: var(--color-text-muted);
            font-size: inherit;
            font-weight: inherit;
        }

        &:hover {
            color: var(--color-text-primary);
            /* background: var(--color-surface-paper); */
        }

        &:focus-visible {
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: calc(var(--border-width-2) * -1);
        }

        &[aria-selected="true"] {
            color: var(--color-text-primary);
            font-weight: var(--font-weight-medium);

            /* แท็บที่เลือกแล้ว วงเล็บไทยใช้สีเดียวกับป้าย */
            small {
                color: inherit;
            }
        }
    }

    .agenda__tab-indicator {
        position: absolute;
        bottom: 0;
        left: 0;
        z-index: 2;
        width: var(--agenda-tab-indicator-width);
        height: var(--rule-width-emphasis);
        background: var(--gradient-table-active-spectrum);
        pointer-events: none;
        transform: translateX(var(--agenda-tab-indicator-x));
        will-change: width, transform;
    }

    .agenda__tabs[data-indicator-ready="true"] .agenda__tab-indicator {
        transition:
            width var(--duration-base) linear,
            transform var(--duration-base) linear;
    }

    .agenda__panel {
        padding: var(--space-0) var(--space-6) var(--space-6);
        min-width: 0;
        /* สลับแท็บ Stage แล้วเลื่อนมาจอดใต้แถบแท็บที่ sticky อยู่พอดี ไม่ใช่ใต้ header
           เฉย ๆ (นั่นจะทำให้แถบแท็บมาบังหัวตาราง) เผื่อความสูงแถบแท็บ+เส้นคาดเพิ่ม
           จากออฟเซตที่ .agenda__day-panel ใช้ */
        scroll-margin-top: calc(var(--header-height) + var(--space-6) + var(--touch-target-md) + var(--rule-width-subtle));

        &[hidden] {
            display: none;
        }

        &.agenda__panel--empty {
            min-height: var(--section-padding-y-sm);
        }
    }

    .agenda__empty-state {
        display: grid;
        align-content: center;
        min-height: 320px;
        padding: var(--space-12) var(--space-8);
        text-align: center;
    }

    .agenda__empty-kicker {
        margin: 0 0 var(--space-3);
        color: var(--color-text-muted);
        font-family: var(--font-family-heading);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-semibold);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    .agenda__empty-state h3 {
        margin: 0 0 var(--space-3);
        color: var(--color-text-strong);
        font-family: var(--font-family-heading);
        font-size: var(--font-size-40);
        font-weight: var(--font-weight-bold);
        line-height: 1;
        letter-spacing: 0;
    }

    .agenda__empty-state p:not(.agenda__empty-kicker) {
        max-width: 360px;
        margin: 0 auto;
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    .agenda__table {
        width: 100%;
        border-collapse: collapse;
        table-layout: fixed;
    }

    .agenda__time-column {
        width: var(--bt-agenda-time-width);
    }

    .agenda__tags-column {
        width: var(--bt-agenda-tags-column-width);
    }

    .agenda__speaker-column {
        width: var(--bt-agenda-speaker-column-width);
    }

    .agenda__table tr {
        border-bottom: var(--rule-width-subtle) solid var(--color-border-faint);
    }

    .agenda__table th,
    .agenda__table td {
        padding: var(--space-4) 0;
        vertical-align: top;
    }

    .agenda__table th {
        padding-right: var(--space-4);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        text-align: left;
        white-space: nowrap;
    }

    .agenda__table th time {
        font-size: var(--bt-agenda-time-size);
    }

    .agenda__table td {
        border-left: var(--rule-width-subtle) solid var(--color-border-faint);
        padding-left: var(--space-4);
        height: 100%;
    }

    /* Session ที่มีเพียงชื่อ เช่น Lucky Draw ให้อยู่กึ่งกลางความสูงของแถว */
    .agenda__table td:has(> .agenda__session-title--simple) {
        vertical-align: middle;
    }

    /* กรอบรูปวิทยากรอยู่ขวาสุดของแต่ละ Session แถวละไม่เกิน 2 คน */
    .agenda__table td.agenda__speakers {
        padding-top: var(--space-0);
        padding-left: var(--space-0);
        padding-right: var(--space-0);
        border-left: 0;
        vertical-align: middle;
    }

    .agenda__speakers {
        display: grid;
        grid-template-columns: repeat(2, var(--bt-agenda-speaker-width));
        justify-content: end;
        gap: var(--space-2);
        font-size: 0;
        text-align: right;
        white-space: normal;
    }

    .agenda__speakers>.agenda__speaker-frame:last-child:nth-child(odd) {
        grid-column: 2;
    }

    .agenda__speaker-frame {
        --agenda-glow-a-duration: 13s;
        --agenda-glow-b-duration: 19s;
        --agenda-glow-a-delay: -2.4s;
        --agenda-glow-b-delay: -8.1s;
        --agenda-glow-a-direction: normal;
        --agenda-glow-b-direction: reverse;

        position: relative;
        width: var(--bt-agenda-speaker-width);
        height: var(--bt-agenda-speaker-height);
        display: inline-grid;
        place-items: center;
        isolation: isolate;
        overflow: visible;
        border: var(--rule-width-subtle) solid var(--color-border-faint);
        border-radius: var(--radius-1);
        background: var(--color-surface-paper);
        overflow: hidden;

        &+.agenda__speaker-frame {
            margin-left: 0;
        }

    }

    .agenda__speaker-photo {
        position: absolute;
        inset: 0;
        z-index: 1;
        display: block;
        overflow: hidden;
    }

    .agenda__speaker-photo>img {
        width: 100%;
        height: 100%;
        display: block;
        object-fit: cover;
        object-position: center top;
        border-radius: var(--radius-1);
        filter: saturate(1.1);
        /* ซูมหน้าวิทยากรให้ใกล้ขึ้น โดยยึดขอบบนไว้ ส่วนที่ล้นด้านข้าง/ล่างถูก frame (overflow: hidden) ตัดออก */
        transform: scale(1.2);
        transform-origin: center top;
    }

    .agenda__speaker-frame::before,
    .agenda__speaker-frame::after {
        content: '';
        position: absolute;
        inset: 10%;
        z-index: 0;
        border-radius: 20%;
        filter: blur(4px) saturate(1.5);
        pointer-events: none;
    }

    .agenda__speaker-frame::before {
        opacity: 0.52;
        background:
            radial-gradient(circle at 28% 30%, var(--color-cyan-400) 0%, transparent 52%),
            radial-gradient(circle at 72% 66%, var(--color-violet-400) 0%, transparent 52%);
        animation: speaker-aurora-a var(--agenda-glow-a-duration) linear var(--agenda-glow-a-delay) infinite var(--agenda-glow-a-direction);
    }

    .agenda__speaker-frame::after {
        opacity: 0.42;
        background:
            radial-gradient(circle at 70% 26%, var(--color-pink-400) 0%, transparent 50%),
            radial-gradient(circle at 30% 74%, var(--color-yellow-500) 0%, transparent 54%);
        animation: speaker-aurora-b var(--agenda-glow-b-duration) linear var(--agenda-glow-b-delay) infinite var(--agenda-glow-b-direction);
    }

    /* แต่ละ session ใช้ความเร็ว จุดเริ่ม และทิศทางต่างกัน จึงไม่เกิดภาพ glow
       หมุนพร้อมกันเป็นแพตเทิร์นเดียว แม้ทุก avatar จะใช้ keyframes ชุดเดียวกัน */
    .agenda__table tr:nth-child(4n + 2) .agenda__speaker-frame {
        --agenda-glow-a-duration: 16.5s;
        --agenda-glow-b-duration: 22s;
        --agenda-glow-a-delay: -9.2s;
        --agenda-glow-b-delay: -3.7s;
        --agenda-glow-a-direction: reverse;
        --agenda-glow-b-direction: normal;
    }

    .agenda__table tr:nth-child(4n + 3) .agenda__speaker-frame {
        --agenda-glow-a-duration: 11.5s;
        --agenda-glow-b-duration: 18.5s;
        --agenda-glow-a-delay: -5.8s;
        --agenda-glow-b-delay: -12.4s;
    }

    .agenda__table tr:nth-child(4n) .agenda__speaker-frame {
        --agenda-glow-a-duration: 19s;
        --agenda-glow-b-duration: 14.5s;
        --agenda-glow-a-delay: -14.1s;
        --agenda-glow-b-delay: -6.3s;
        --agenda-glow-a-direction: reverse;
    }

    .agenda__speaker-frame:nth-child(2) {
        --agenda-glow-a-duration: 17.25s;
        --agenda-glow-b-duration: 12.75s;
        --agenda-glow-a-delay: -11.6s;
        --agenda-glow-b-delay: -4.4s;
        --agenda-glow-a-direction: reverse;
        --agenda-glow-b-direction: normal;
    }

    .agenda__speaker-frame:nth-child(3) {
        --agenda-glow-a-duration: 14.25s;
        --agenda-glow-b-duration: 23.5s;
        --agenda-glow-a-delay: -7.3s;
        --agenda-glow-b-delay: -16.8s;
        --agenda-glow-a-direction: normal;
        --agenda-glow-b-direction: reverse;
    }

    .agenda__table tr:nth-child(1) .agenda__speaker-frame {
        --agenda-glow-a-delay: -1.1s;
        --agenda-glow-b-delay: -10.3s;
    }

    .agenda__table tr:nth-child(2) .agenda__speaker-frame {
        --agenda-glow-a-delay: -9.2s;
        --agenda-glow-b-delay: -3.7s;
    }

    .agenda__table tr:nth-child(3) .agenda__speaker-frame {
        --agenda-glow-a-delay: -5.8s;
        --agenda-glow-b-delay: -12.4s;
    }

    .agenda__table tr:nth-child(4) .agenda__speaker-frame {
        --agenda-glow-a-delay: -14.1s;
        --agenda-glow-b-delay: -6.3s;
    }

    .agenda__table tr:nth-child(5) .agenda__speaker-frame {
        --agenda-glow-a-delay: -3.6s;
        --agenda-glow-b-delay: -15.7s;
    }

    .agenda__table tr:nth-child(6) .agenda__speaker-frame {
        --agenda-glow-a-delay: -11.8s;
        --agenda-glow-b-delay: -1.9s;
    }

    .agenda__table tr:nth-child(7) .agenda__speaker-frame {
        --agenda-glow-a-delay: -7.4s;
        --agenda-glow-b-delay: -17.2s;
    }

    .agenda__table tr:nth-child(8) .agenda__speaker-frame {
        --agenda-glow-a-delay: -16.3s;
        --agenda-glow-b-delay: -8.6s;
    }

    .agenda__table tr:nth-child(9) .agenda__speaker-frame {
        --agenda-glow-a-delay: -2.7s;
        --agenda-glow-b-delay: -13.8s;
    }

    .agenda__table tr:nth-child(10) .agenda__speaker-frame {
        --agenda-glow-a-delay: -12.9s;
        --agenda-glow-b-delay: -5.1s;
    }

    .agenda__table tr:nth-child(11) .agenda__speaker-frame {
        --agenda-glow-a-delay: -6.6s;
        --agenda-glow-b-delay: -18.4s;
    }

    .agenda__table tr:nth-child(12) .agenda__speaker-frame {
        --agenda-glow-a-delay: -17.5s;
        --agenda-glow-b-delay: -9.7s;
    }

    .agenda__table tr:nth-child(13) .agenda__speaker-frame {
        --agenda-glow-a-delay: -4.5s;
        --agenda-glow-b-delay: -14.9s;
    }

    .agenda__table tr:nth-child(14) .agenda__speaker-frame {
        --agenda-glow-a-delay: -13.7s;
        --agenda-glow-b-delay: -2.8s;
    }

    .agenda__table tr:nth-child(15) .agenda__speaker-frame {
        --agenda-glow-a-delay: -8.3s;
        --agenda-glow-b-delay: -16.1s;
    }

    .agenda__session-title,
    .agenda__session-summary {
        display: inline;
        margin: 0;
        letter-spacing: 0;
    }

    .agenda__session-title {
        color: var(--color-blue-600);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--section-small-line-height);
        text-transform: uppercase;
        margin-bottom: var(--space-1);

        &.agenda__session-title--simple {
            color: var(--color-text-primary);
            margin-bottom: 0;
        }

        &:has(+ .agenda__session-summary)::after {
            content: ' ';
        }
    }

    .agenda__session-summary {
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
    }

    .agenda__session-speaker {
        margin: var(--space-2) var(--space-0) var(--space-0);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
    }

    .agenda__note {
        margin: var(--space-6) 0 0;
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
    }

    @media (max-width:1199px) {
        --agenda-day-panel-header-height: calc(var(--space-10) + var(--space-6));

        .agenda__day-panel {
            padding-left: var(--space-0);
        }

        .agenda__day-panel-header {
            padding: var(--space-1) var(--space-0) var(--space-6);
        }
    }

    @media (max-width:991px) {
        --agenda-day-label-size: var(--font-size-24);
        --agenda-day-label-active-size: var(--font-size-40);
        --agenda-sticky-gap: var(--space-0);
        --agenda-day-panel-header-height: calc(var(--space-12) + var(--space-8) + var(--space-1));

        padding: var(--section-padding-y-sm) 0;

        .agenda__day-panel-header {
            padding: var(--space-8) var(--space-0) var(--space-6);
        }

        .agenda__section-header {
            margin-bottom: var(--space-12);
        }

        .agenda__day-switch-rail {
            height: var(--space-12);
        }

        .agenda__tabs {
            top: calc(var(--agenda-sticky-top) + var(--agenda-day-panel-header-height));
        }

        .agenda__day-switch,
        .agenda__day-switch-label {
            font-size: var(--agenda-day-label-size);
        }

        .agenda__day-switch[aria-current='true'] .agenda__day-switch-label {
            font-size: var(--agenda-day-label-active-size);
        }

        .agenda__day-panel-date,
        .agenda__day-panel-time {
            font-size: var(--font-size-20);
        }

        .agenda__speakers {
            justify-content: start;
        }

        .agenda__speakers>.agenda__speaker-frame:last-child:nth-child(odd) {
            grid-column: 1;
        }
    }

    /* แถบ Stage รวมใช้เฉพาะจอ ≥992px ค่าตั้งต้นจึงซ่อนทั้งกล่อง แถบแท็บข้างในเลยไม่โดนกฎ .agenda__tabs ของมือถือ */
    .agenda__stage-tabs {
        display: none;
    }

    /* ---------- จอ ≥992px: Day 1 | Day 2 วางคู่กันสองคอลัมน์ ----------
       เห็นทั้งสองวันทันทีไม่ต้องเลื่อนหรือกดสลับวัน ตัวสลับวันกับแถบ Stage รายวันจึงซ่อน
       ใช้แถบ Stage รวมแถบเดียวคุมทั้งสองคอลัมน์แทน
       ทุกกฎอยู่ใน min-width:992px เท่านั้น เพราะจอ ≤991px ใช้ระบบเลือกวันทีละวัน */
    @media (min-width:992px) {
        /* การ์ดครึ่งจอแคบกว่าตารางเดิม ใช้กรอบรูปขนาดเดียวกับมือถือ เหลือที่ให้ข้อความ */
        --bt-agenda-speaker-width: var(--bt-agenda-speaker-width-mobile);
        --bt-agenda-speaker-height: var(--bt-agenda-speaker-height-mobile);

        .agenda__section-header {
            margin-bottom: var(--space-12);
        }

        /* ค้างใต้ Header ตอนเลื่อนดูการ์ด สลับ Stage ได้ตลอดไม่ต้องเลื่อนกลับขึ้นไป
           ฉากทึบ ::before ปิดเนื้อหาตารางที่เลื่อนผ่านช่องว่างเหนือแถบ ความสูงต้องไม่เกินช่องว่างนั้น
           (space-6 เท่าระยะ sticky) ไม่งั้นตอนแถบยังไม่ติดขอบบน ฉากจะยื่นขึ้นไปทับหัวข้อ section */
        .agenda__stage-tabs {
            position: sticky;
            top: calc(var(--header-height) + var(--space-6));
            z-index: 4;
            display: block;
            /* ระยะเดียวกับ top: keepStageTabsInView() ใน js/agenda-tabs.js เรียก scrollIntoView ตัวนี้
               ตอนแผงที่สั้นลงดันแถบหลุดขึ้นไปเหนือจอ จะได้กลับมาจอดตรงตำแหน่งที่ค้างไว้พอดี */
            scroll-margin-top: calc(var(--header-height) + var(--space-6));
            margin-bottom: var(--agenda-day-sticky-header-height);

            &::before {
                content: '';
                position: absolute;
                right: 0;
                bottom: 100%;
                left: 0;
                height: var(--space-6);
                background: var(--color-surface-page);
                pointer-events: none;
            }
        }

        /* แถบรวมอยู่ในหัว section ไม่ได้อยู่ใต้หัวการ์ด จึงไม่ sticky และตัดฉากทึบ ::before ที่ยื่นขึ้นไปทับหัวข้อ section
           ยังต้อง position: relative เป็นกรอบให้เส้นสีรุ้ง (.agenda__tab-indicator) */
        .agenda__stage-tabs .agenda__tabs {
            position: relative;
            top: auto;

            &::before {
                content: none;
            }
        }

        /* Windows High Contrast ตัด gradient เส้นสีรุ้งและบังคับสีข้อความทุกแท็บเท่ากัน จึงวาดเส้นแท็บที่เลือกด้วยสีระบบ Highlight */
        @media (forced-colors: active) {
            .agenda__stage-tabs .agenda__tab-indicator {
                forced-color-adjust: none;
                background: Highlight;
            }

            .agenda__stage-tabs .agenda__tab[aria-selected="true"] {
                border-bottom-color: Highlight;
            }
        }

        .agenda__day-switcher,
        .agenda__tabs-viewport {
            display: none;
        }

        /* ระยะมองเห็นระหว่างแถบ Stage กับหัววันยังคง 32px เหมือนเดิม แต่ใช้
           margin ของ Stage เท่าความสูงหัววัน เพื่อให้ทั้งสองชั้นปล่อย sticky
           พร้อมกันที่ท้าย Agenda โดยไม่เลื่อนทับกัน */
        .agenda__layout {
            margin-top: calc(var(--space-8) - var(--agenda-day-sticky-header-height));
            scroll-margin-top: calc(var(--header-height) + var(--space-6) + var(--agenda-stage-tabs-height));
            overflow-anchor: none;
        }

        /* width ทับ col-md-9/col-xl-10 ของ Bootstrap (0,1,0) — คง class ไว้ใน HTML เพราะไม่มีผลกับจอ ≤991px */
        .agenda__days {
            width: 100%;
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            column-gap: var(--space-6);
        }

        /* subgrid ให้หัวการ์ดสองวันสูงเท่ากันเสมอ แม้หัวของวันหนึ่งตัดบรรทัด แถวแรกของตารางจึงเริ่มระดับเดียวกัน
           พื้นเทาไม่ใส่ที่ตัว panel ไม่งั้นการ์ด Day 2 (สั้นกว่า) จะถูกยืดเท่า Day 1 เหลือพื้นเทาว่างยาวใต้หมายเหตุ */
        .agenda__day-panel {
            display: grid;
            grid-row: span 2;
            grid-template-columns: minmax(0, 1fr);
            grid-template-rows: subgrid;
            padding-left: var(--space-0);
            /* เผื่อความสูงแถบ Stage ที่ค้างอยู่ (สูงสุด ~66px ตอนป้ายสองบรรทัดที่ 768–991px) ไม่งั้นลิงก์ #agenda-day-two จะไปจอดใต้แถบ */
            scroll-margin-top: calc(var(--header-height) + var(--space-6) + var(--space-16) + var(--space-2));
        }

        .agenda__day-panel:not([hidden])+.agenda__day-panel:not([hidden]) {
            margin-top: var(--space-0);
        }

        .agenda__day-panel-header {
            position: sticky;
            top: calc(var(--header-height) + var(--space-6) + var(--agenda-stage-tabs-height));
            z-index: 3;
            align-self: start;
            height: auto;
            justify-content: space-between;
            gap: var(--space-1) var(--space-3);
            padding: var(--space-4) var(--space-6);
            border-bottom: var(--rule-width-emphasis) solid var(--color-border-faint);
            border-radius: var(--radius-1) var(--radius-1) 0 0;
            background: var(--color-neutral-50);

            &::before {
                content: none;
            }
        }

        .agenda__day-panel-date {
            font-size: var(--font-size-18);
            text-transform: uppercase;
        }

        .agenda__day-panel-time {
            /* color: var(--color-text-muted); */
            font-size: var(--section-body-size);
            font-weight: var(--font-weight-medium);
        }

        /* การ์ดจบตามเนื้อหาของวันนั้นเอง (พื้นเทามาจากค่าฐานของ .agenda__content อยู่แล้ว) */
        .agenda__content {
            align-self: start;
            border-radius: 0 0 var(--radius-1) var(--radius-1);
        }

        .agenda__table,
        .agenda__table tbody {
            display: block;
        }

        .agenda__table colgroup {
            display: none;
        }

        /* เวลาใน layout สองคอลัมน์: เวลาเริ่ม ขีดคั่น และเวลาจบแยกเป็น 3 บรรทัดคงที่ */
        .agenda__table th time {
            display: block;
            width: 4.6ch;
            font-variant-numeric: tabular-nums;
            text-align: center;
            white-space: normal;
        }

        .agenda__table tr {
            display: grid;
            grid-template-columns: var(--space-20) minmax(0, 1fr);
        }

        .agenda__table th[scope="row"] {
            grid-column: 1;
            grid-row: 1;
            white-space: normal;
        }

        /* td แรก (ช่องหมวดหมู่เดิม) ว่างทุกแถวแล้ว ซ่อนไม่ให้กินช่องกริด แต่ต้องคง td ไว้ใน HTML
           เพราะกฎจอ ≤991px เลือกช่องตามลำดับด้วย :first-of-type */
        .agenda__table td:first-of-type {
            display: none;
        }

        .agenda__table td:first-of-type+td {
            grid-column: 2;
            grid-row: 1;
        }

        /* การ์ดสองคอลัมน์ช่วง 992–1199px ยังแคบ รูปวิทยากรลงไปอยู่ใต้ข้อความก่อน
           แล้วกฎ ≥992px ด้านล่างจะจัดตำแหน่งรูปตามพื้นที่ของ layout ใหม่ */
        .agenda__table td.agenda__speakers {
            grid-column: 2;
            grid-row: 2;
            justify-content: start;
            padding: var(--space-0) var(--space-0) var(--space-4) var(--space-4);
            border-left: var(--rule-width-subtle) solid var(--color-border-faint);

            &:empty {
                display: none;
            }
        }

        .agenda__speakers>.agenda__speaker-frame:last-child:nth-child(odd) {
            grid-column: 1;
        }

        .agenda__session-title,
        .agenda__session-summary {
            display: block;
        }
    }

    /* ≥992px รูปวิทยากรอยู่ขวาข้อความตามแบบ คอลัมน์ auto กว้างเท่ากริดรูป
       แถวที่ไม่มีรูป (ช่องถูกซ่อน) คอลัมน์นี้เป็น 0 ข้อความได้ความกว้างเต็ม */
    @media (min-width:992px) {
        .agenda__table tr {
            grid-template-columns: var(--space-20) minmax(0, 1fr) auto;
        }

        .agenda__table td.agenda__speakers {
            grid-column: 3;
            grid-row: 1;
            align-self: center;
            height: auto;
            justify-content: end;
            padding: var(--space-4) var(--space-0) var(--space-4) var(--space-3);
            border-left: 0;
        }

        /* ใน layout สองคอลัมน์ td ถูกเปลี่ยนเป็น grid item และสูงเต็มแถว
           จึงต้องจัดข้อความภายในเซลล์ด้วย flex แทน vertical-align */
        .agenda__table td:has(> .agenda__session-title--simple) {
            display: flex;
            align-items: center;
        }
    }

    /* 992–1199px การ์ดกว้าง ~416px ถ้ารูปวางคู่กัน (136px) ข้อความเหลือแค่ ~127px
       จึงเรียงรูปซ้อนเป็นคอลัมน์เดียวแบบจอ ≤575px ข้อความได้ ~195px */
    @media (min-width:992px) and (max-width:1199px) {

        /* 4 ป้ายของแถบรวมกับ padding ปกติ 24px กว้าง ~883px เกินคอนเทนเนอร์ 856px ที่จอ 992px */
        .agenda__stage-tabs .agenda__tab {
            padding: var(--space-0) var(--space-4);
        }

        .agenda__table td.agenda__speakers {
            grid-template-columns: var(--bt-agenda-speaker-width);
        }
    }

    /* ≥1200px การ์ดกว้างพอวางรูปคู่กันแบบกริด 2 ช่องของค่าฐาน รูปเดียวชิดขวา
       Session ที่มีวิทยากรคนเดียว ใช้กริดช่องเดียว ไม่เว้นช่องว่างไว้ซ้ายรูป ข้อความจึงได้พื้นที่เพิ่ม */
    @media (min-width:1200px) {
        .agenda__day-panel-date {
            font-size: var(--font-size-20);
        }

        .agenda__speakers>.agenda__speaker-frame:last-child:nth-child(odd) {
            grid-column: 2;
        }

        /* specificity ต้องชนะ .agenda__table td.agenda__speakers และกฎ :last-child:nth-child(odd) ด้านบน */
        .agenda__table td.agenda__speakers:has(> .agenda__speaker-frame:only-child) {
            grid-template-columns: var(--bt-agenda-speaker-width);
        }

        .agenda__speakers>.agenda__speaker-frame:last-child:only-child {
            grid-column: 1;
        }
    }

    /* Mobile agenda: ย้ายข้อมูลวิทยากรลงใต้ชื่อ Session เพื่อให้อ่านเป็นลำดับเดียว */
    @media (max-width:991px) {
        --agenda-day-label-size: var(--font-size-32);
        --agenda-day-label-line-height: var(--section-topic-line-height);
        --agenda-day-label-weight: var(--font-weight-regular);
        --agenda-day-label-active-size: var(--font-size-32);
        --agenda-day-label-active-line-height: var(--agenda-day-label-line-height);
        --agenda-day-label-active-weight: var(--font-weight-bold);

        .agenda__layout {
            margin-right: 0;
            margin-left: 0;
        }

        .agenda__day-panel-header {
            display: none;
        }

        .agenda__day-switcher {
            position: static;
            width: 100%;
            margin-bottom: var(--space-0);
            padding: 0;
            background: var(--color-surface-paper);
            scroll-margin-top: calc(var(--header-height) + var(--space-4));
            display: flex;
            justify-content: center;
        }

        .agenda__day-switcher,
        .agenda__days {
            flex: 0 0 100%;
            width: 100%;
            max-width: 100%;
            padding-right: 0;
            padding-left: 0;
        }

        .agenda__day-switcher-inner {
            --day-switcher-padding-y: var(--space-8);
            --day-switcher-details-space: var(--space-8);
            --day-switcher-rail-width: 44%;
            --day-switcher-label-shift: 0px;

            position: relative;
            width: min(100%, 360px);
            grid-template-columns: max-content var(--day-switcher-rail-width) max-content;
            justify-content: center;
            justify-items: center;
            align-items: end;
            column-gap: var(--space-2);
            padding-top: var(--day-switcher-padding-y);
            padding-bottom: calc(var(--day-switcher-padding-y) + var(--day-switcher-details-space));
        }

        .agenda__day-switch {
            position: static;
            width: auto;
            min-height: var(--touch-target-md);
            padding: 0 0 var(--space-3);
            display: flex;
            align-items: flex-end;
            background: transparent;
            text-align: left;

            &:first-of-type {
                grid-column: 1;
                padding-left: var(--day-switcher-label-shift);
            }

            &:last-of-type {
                grid-column: 3;
                padding-right: var(--day-switcher-label-shift);
                justify-content: flex-end;
                text-align: right;
            }

            &[aria-current='true'] {
                color: var(--agenda-day-label-active-color);
            }
        }

        .agenda__day-switch-label {
            font-size: var(--agenda-day-label-size);
            font-weight: var(--agenda-day-label-weight);
            line-height: var(--agenda-day-label-line-height);
        }

        .agenda__day-switch[aria-current='true'] .agenda__day-switch-label {
            font-size: var(--agenda-day-label-active-size);
            font-weight: var(--agenda-day-label-active-weight);
            line-height: var(--agenda-day-label-active-line-height);
        }

        .agenda__day-switch-details,
        .agenda__day-switch:not([aria-current='true']) .agenda__day-switch-details {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + var(--touch-target-md) + var(--agenda-day-switch-details-gap));
            left: 0;
            width: 100%;
            margin-top: 0;
            opacity: 0;
            visibility: hidden;
            transform: none;
            transition: opacity var(--duration-fast) var(--ease-standard);
        }

        .agenda__day-switch:last-of-type .agenda__day-switch-details {
            transform: none;
        }

        .agenda__day-switch:not([aria-current='true']) .agenda__day-switch-details {
            opacity: 1;
            visibility: visible;
        }

        .agenda__day-switch-details-inner {
            display: flex;
            flex-wrap: nowrap;
            justify-content: center;
            align-items: center;
            gap: var(--space-1) var(--space-4);
            overflow: visible;
            text-align: left;
            white-space: nowrap;
        }

        .agenda__day-switch-details-inner span+span::before {
            content: none;
        }

        .agenda__day-switch-rail {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + (var(--touch-target-md) / 2));
            left: 50%;
            display: block;
            width: var(--day-switcher-rail-width);
            height: var(--rule-width-subtle);
            background: var(--color-border-editorial);
            transform: translate(-50%, -50%);
        }

        .agenda__day-switch-prompt {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + (var(--touch-target-md) / 2));
            left: 50%;
            display: block;
            color: var(--color-text-muted);
            font-size: var(--section-small-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--section-small-line-height);
            transform: translate(-50%, calc(-100% + var(--space-2)));
            white-space: nowrap;
            background: var(--color-surface-paper);
            padding: var(--space-0) var(--space-2);
            z-index: 2;
        }

        .agenda__day-switch-rail::after {
            top: auto;
            right: auto;
            bottom: 0;
            left: 0;
            width: 50%;
            height: var(--rule-width-emphasis);
            background: var(--spectrum);
            transform: translateX(0);
        }

        .agenda__day-switcher-inner[data-active-day='day-two'] .agenda__day-switch-rail::after {
            transform: translateX(100%);
        }

        .agenda__tabs-viewport {
            --agenda-tabs-gap: var(--space-8);

            position: sticky;
            top: var(--header-height);
            z-index: 2;
            display: block;
            margin-top: var(--agenda-tabs-gap);
            background: var(--color-surface-page);

            /* ปิดเนื้อหาตารางที่เลื่อนผ่านใต้ Header โดยไม่ถูก overflow แนวนอน clip
               ความสูงต้องเท่ากับช่องว่างเหนือแถบแท็บ (--agenda-tabs-gap) เป๊ะ ๆ ห้ามสูงกว่านี้:
               แถบนี้ sticky แต่ ::before ขยับตามแถบเสมอ ตอนที่แถบยังไม่ติดขอบบน (เช่นเพิ่งเลื่อน
               เข้ามาถึง Agenda) ฉากทึบนี้จะยื่นขึ้นไปทับ .agenda__day-switcher ที่อยู่เหนือมัน
               จนวันที่/เวลาใต้ปุ่ม Day หายไปทั้งแถบ (เคยสูง header+24 = 96px ทับกินเข้าไป 64px)
               ส่วนตอนที่แถบติดขอบบนแล้ว พื้นที่เหนือมันคือใต้ Header ซึ่ง Header ทึบคลุมอยู่แล้ว
               จึงไม่ต้องใช้ฉากสูงไปกว่าช่องว่างนี้ */
            &::before {
                content: '';
                position: absolute;
                right: 0;
                bottom: 100%;
                left: 0;
                height: var(--agenda-tabs-gap);
                background: var(--color-surface-page);
                pointer-events: none;
            }
        }

        .agenda__tabs {
            position: relative;
            top: auto;
            z-index: 1;
            overflow-x: auto;
            overflow-y: hidden;

            &::before {
                display: none;
            }
        }

        .agenda__table,
        .agenda__table tbody {
            display: block;
        }

        .agenda__table colgroup {
            display: none;
        }

        .agenda__table tr {
            display: grid;
            grid-template-columns: var(--bt-agenda-time-width) minmax(0, 1fr);
        }

        .agenda__table th,
        .agenda__table td {
            display: block;
        }

        .agenda__table th {
            grid-column: 1;
            grid-row: 1 / span 3;
            padding-right: var(--space-4);
        }

        .agenda__table td:first-of-type {
            grid-column: 2;
            grid-row: 1;
            padding-bottom: var(--space-0);

            /* &:empty {
                display: none;
            } */
        }

        .agenda__table td:first-of-type+td {
            grid-column: 2;
            grid-row: 2;
            padding-top: var(--space-0);
        }

        .agenda__table td.agenda__speakers {
            grid-column: 2;
            grid-row: 3;
            padding: var(--space-2) var(--space-0) var(--space-6) var(--space-6);
            display: grid;
            justify-content: start;
            border-left: var(--rule-width-subtle) solid var(--color-border-faint);
            font-size: var(--section-small-size);
            text-align: left;
            white-space: normal;

            &:empty {
                display: none;
            }

        }

        .agenda__speaker-frame {
            vertical-align: top;
        }
    }

    @media (max-width:575px) {
        --agenda-day-label-size: var(--font-size-20);
        --agenda-day-label-active-size: var(--font-size-20);
        --bt-agenda-speaker-column-width-mobile: var(--bt-agenda-speaker-width-mobile);

        .agenda__day-panel-date,
        .agenda__day-panel-time {
            font-size: var(--font-size-18);
        }

        .agenda__panel {
            padding: var(--space-0) var(--space-4) var(--space-4);
        }

        .agenda__day-switcher-inner {
            --day-switcher-rail-width: 36%;

            width: min(100%, 320px);
        }

        .agenda__day-switch,
        .agenda__day-switch-label {
            font-size: var(--agenda-day-label-size);
        }

        .agenda__day-switch[aria-current='true'] .agenda__day-switch-label {
            font-size: var(--agenda-day-label-active-size);
        }

        .agenda__time-column {
            width: var(--space-20);
        }

        .agenda__tabs-viewport {
            --agenda-tabs-gap: var(--space-3);
        }

        .agenda__tab {
            padding: 0 var(--space-4);
        }

        .agenda__empty-state {
            min-height: 240px;
            padding: var(--space-8) var(--space-4);
        }

        .agenda__empty-state h3 {
            font-size: var(--font-size-32);
        }

        .agenda__table th,
        .agenda__table td {
            padding-top: var(--space-4);
            padding-bottom: var(--space-5);
        }

        .agenda__table th {
            grid-column: 1 / -1;
            grid-row: 1;
            padding-right: var(--space-0);
            padding-bottom: var(--space-3);
            white-space: normal;
        }

        .agenda__table th time {
            white-space: nowrap;
        }

        .agenda__table tr {
            grid-template-columns: minmax(0, 1fr) var(--bt-agenda-speaker-column-width-mobile);
            column-gap: var(--space-5);
        }

        .agenda__table td {
            padding-left: 0;
            border-left: 0;
        }

        .agenda__table td:first-of-type {
            grid-column: 1 / -1;
            grid-row: 2;
            padding-top: var(--space-0);

            &:empty {
                display: none;
            }
        }

        .agenda__table td:first-of-type+td {
            grid-column: 1;
            grid-row: 3;
            padding-top: var(--space-0);
            padding-bottom: var(--space-4);
        }

        /* Session ที่ไม่มีภาพวิทยากรให้รายละเอียดใช้พื้นที่เต็มแถว */
        .agenda__table tr:has(td.agenda__speakers:empty) td:first-of-type+td {
            grid-column: 1 / -1;
        }

        .agenda__speaker-column {
            width: var(--bt-agenda-speaker-column-width-mobile);
        }

        .agenda__table td.agenda__speakers {
            grid-column: 2;
            grid-row: 3;
            width: var(--bt-agenda-speaker-column-width-mobile);
            display: grid;
            grid-template-columns: var(--bt-agenda-speaker-width-mobile);
            align-content: flex-end;
            justify-content: end;
            gap: var(--space-2);
            padding: 0 0 var(--space-6);
            border-left: 0;
            text-align: right;
        }

        .agenda__speakers>.agenda__speaker-frame:last-child:nth-child(odd) {
            grid-column: 1;
        }

        .agenda__speaker-frame {
            width: var(--bt-agenda-speaker-width-mobile);
            height: var(--bt-agenda-speaker-height-mobile);

            &+.agenda__speaker-frame {
                margin-left: 0;
            }

        }

        .agenda__speaker-frame>.bt-icon {
            font-size: var(--bt-icon-size);
        }

        .agenda__session-title {
            font-size: var(--font-size-14);
        }

        .agenda__session-summary {
            display: block;
            font-size: var(--section-small-size);
        }

        .agenda__session-speaker {
            margin: var(--space-2) var(--space-0) var(--space-0);
            font-size: var(--section-small-size);
        }
    }
}

@media (prefers-reduced-motion: reduce) {

    /* เดิมครอบแค่ตารางฝั่งขวา ตัวสลับวันยังมอร์ฟป้าย 24→48px เต็ม 240ms อยู่ */
    .agenda .agenda__day-switch,
    .agenda .agenda__day-switch-label,
    .agenda .agenda__day-switch-details,
    .agenda .agenda__day-switch-rail::after {
        transition-duration: var(--duration-reduced);
    }

    /* ยังเห็นออร่าตอน hover ได้ แต่ไม่ต้องลอยหมุน */
    .speaker-card__portrait::before,
    .speaker-card__portrait::after {
        transition-duration: var(--duration-reduced);
    }

    .speaker-card:hover .speaker-card__portrait::before,
    .speaker-card:hover .speaker-card__portrait::after {
        animation: none;
    }

    .agenda__speaker-frame::before,
    .agenda__speaker-frame::after {
        animation: none;
    }
}

/* ---------- Speakers ---------- */
.speaker {
    position: relative;
    scroll-margin-top: var(--header-height);
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
    --speaker-day-label-size: var(--font-size-24);
    --speaker-day-label-line-height: 56px;
    --speaker-day-label-weight: var(--font-weight-regular);
    --speaker-day-label-color: var(--color-text-inverse-muted);
    --speaker-day-label-active-size: var(--font-size-48);
    --speaker-day-label-active-line-height: var(--section-topic-line-height);
    --speaker-day-label-active-weight: var(--font-weight-regular);
    --speaker-day-label-active-color: var(--color-text-primary);
    --speaker-day-switch-details-gap: var(--space-3);
    --speaker-sticky-gap: var(--space-6);
    --speaker-sticky-top: calc(var(--header-height) + var(--speaker-sticky-gap));
    --speaker-day-panel-header-height: calc(var(--space-12) + var(--space-6));

    .speaker__section-header {
        margin-bottom: var(--space-20);
    }

    .speaker__section-header h2 {
        max-width: 920px;
        margin: 0;
        font-size: var(--section-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-title-line-height);
        letter-spacing: 0;
    }

    .speaker__layout {
        align-items: start;
    }


    /* ---- ตัวสลับวัน: ก๊อปแพตเทิร์นจาก .agenda__day-switcher ทั้งชุด ---- */
    .speaker__day-switcher {
        position: sticky;
        top: var(--speaker-sticky-top);
        z-index: 2;
        align-self: start;
        min-width: 0;
    }

    .speaker__days {
        min-width: 0;
    }

    .speaker__day-panel {
        scroll-margin-top: var(--speaker-sticky-top);
        padding-left: var(--space-12);
    }

    .speaker__day-panel-header {
        position: sticky;
        top: var(--speaker-sticky-top);
        z-index: 3;
        height: var(--speaker-day-panel-header-height);
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: var(--space-2) var(--space-4);
        padding: var(--space-3) var(--space-0) var(--space-8);
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        line-height: var(--section-body-line-height);
        background: var(--color-surface-page);
    }

    /* ปิดช่องว่างใต้ site header ไม่ให้การ์ดวิทยากรที่เลื่อนผ่านมองเห็นลอดขึ้นมา */
    .speaker__day-panel-header::before {
        content: '';
        position: absolute;
        right: 0;
        bottom: 100%;
        left: 0;
        height: var(--speaker-sticky-gap);
        background: var(--color-surface-page);
        pointer-events: none;
    }

    .speaker__day-panel-date,
    .speaker__day-panel-time {
        margin: 0;
        color: var(--color-text-primary);
        font-size: var(--font-size-24);
        font-weight: var(--font-weight-medium);
    }

    /* Day 1 กับ Day 2 ต่อกันในพื้นที่เลื่อนเดียว เว้นระยะ + ขีดคั่นให้เห็นว่าขึ้นวันใหม่
       :not([hidden]) ทั้งสองฝั่งกันไว้ไม่ให้กระทบจอ ≤991px ที่โชว์ทีละวัน — วันที่ถูกซ่อน
       ตัดคู่ sibling ที่ตรงเงื่อนไขไปเลย วันที่เหลือจึงไม่มีระยะ/ขีดคั่นค้างไว้ด้านบน */
    .speaker__day-panel:not([hidden])+.speaker__day-panel:not([hidden]) {
        margin-top: var(--space-32);
        /* padding-top: var(--space-16);
        border-top: var(--rule-width-subtle) solid var(--color-border-editorial); */
    }

    .speaker__day-panel[hidden] {
        display: none;
    }

    .speaker__day-switcher-inner {
        display: grid;
        justify-items: start;
        gap: var(--space-6);
    }

    .speaker__day-switch {
        position: relative;
        z-index: 1;
        display: block;
        align-self: start;
        width: fit-content;
        min-width: 0;
        padding: 0;
        color: var(--speaker-day-label-color);
        font-size: var(--speaker-day-label-size);
        font-weight: var(--speaker-day-label-weight);
        line-height: var(--speaker-day-label-line-height);
        letter-spacing: 0;
        text-decoration: none;
        text-transform: uppercase;
        transition:
            color var(--duration-base) var(--ease-standard),
            opacity var(--duration-base) var(--ease-standard);

        &:hover,
        &:focus-visible {
            color: var(--speaker-day-label-active-color);
        }

        &[aria-current='true'] {
            color: var(--speaker-day-label-active-color);
        }

        &:focus-visible {
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: var(--space-2);
        }
    }

    .speaker__day-switch-label {
        display: block;
        font-size: var(--speaker-day-label-size);
        line-height: var(--line-height-normal);
        transition:
            font-size var(--duration-base) var(--ease-standard),
            line-height var(--duration-base) var(--ease-standard),
            color var(--duration-base) var(--ease-standard);
    }

    /* 0fr → 1fr วิ่งตามความสูงจริง ไม่ต้องเดาเพดานแบบ max-height */
    .speaker__day-switch-details {
        display: grid;
        grid-template-rows: 0fr;
        margin-top: 0;
        color: var(--speaker-day-label-color);
        font-size: var(--section-body-size);
        line-height: var(--section-body-line-height);
        text-transform: none;
        opacity: 0;
        transform: translateY(calc(var(--space-2) * -1));
        transition:
            grid-template-rows var(--duration-base) var(--ease-standard),
            margin-top var(--duration-base) var(--ease-standard),
            opacity var(--duration-base) var(--ease-standard),
            transform var(--duration-base) var(--ease-standard);
    }

    .speaker__day-switch-details-inner {
        display: grid;
        gap: var(--space-1);
        min-height: 0;
        overflow: hidden;
    }

    .speaker__day-switch[aria-current='true'] .speaker__day-switch-label {
        font-size: var(--speaker-day-label-active-size);
        font-weight: var(--speaker-day-label-active-weight);
        line-height: var(--speaker-day-label-active-line-height);
    }

    .speaker__day-switch:not([aria-current='true']) .speaker__day-switch-details {
        grid-template-rows: 1fr;
        margin-top: var(--speaker-day-switch-details-gap);
        color: var(--speaker-day-label-color);
        opacity: 1;
        transform: translateY(0);
    }

    .speaker__day-switch-rail {
        position: relative;
        overflow: hidden;
        width: var(--rule-width-subtle);
        height: var(--space-28);
        background: var(--color-border-editorial);
        pointer-events: none;
    }

    .speaker__day-switch-prompt {
        display: none;
    }

    .speaker__day-switch-rail::after {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        height: 50%;
        background: var(--spectrum-vertical);
        transform: translateY(0);
        transition: transform var(--duration-base) var(--ease-standard);
    }

    .speaker__day-switcher-inner[data-active-day='day-two'] .speaker__day-switch-rail::after {
        transform: translateY(100%);
    }

    /* หัวข้อกับแถบวันค้างอยู่ระหว่างเลื่อนดูการ์ด ใช้แพตเทิร์นเดียวกับ .agenda__tabs
       สติกกี้ถูกจำกัดด้วยกล่องของ .speaker__inner จึงหลุดเองเมื่อจบ section */
    .speaker__eyebrow {
        margin: 0 0 var(--space-2);
        color: var(--color-text-muted);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        text-transform: uppercase;
    }

    /* แถบวันใช้ดีไซน์เดียวกับแถบเวทีของ Agenda: ปุ่มข้อความเรียงแถว
       เส้นคาดล่างของกล่อง และตัวชี้สเปกตรัมที่เลื่อนตามปุ่มที่เลือก */
    /* กติกาของกริด (คอลัมน์/ระยะห่าง) ย้ายไปเขียนรวมกับ .moderator__grid ที่ระดับบนสุด
       เพื่อให้สอง section เปลี่ยนพร้อมกันเสมอ ที่เหลือไว้ตรงนี้คือเรื่องเฉพาะแท็บวัน */
    .speaker__panel[hidden] {
        display: none;
    }

    /* วันที่ยังไม่ประกาศรายชื่อ กันไม่ให้ section ยุบจนดูเหมือนหน้าพัง
       (แนวเดียวกับ .agenda__panel--empty) */
    .speaker__panel--empty {
        min-height: var(--section-padding-y-sm);
    }

    @media (max-width: 1199px) {
        --speaker-day-panel-header-height: calc(var(--space-10) + var(--space-6));

        .speaker__day-panel {
            padding-left: var(--space-0);
        }

        .speaker__day-panel-header {
            padding: var(--space-1) var(--space-0) var(--space-8);
        }
    }

    @media (max-width: 991px) {
        --speaker-day-label-size: var(--font-size-24);
        --speaker-day-label-active-size: var(--font-size-40);
        --speaker-sticky-gap: var(--space-0);

        padding: var(--section-padding-y-sm) 0;


        .speaker__day-panel-header {
            padding: var(--space-2) var(--space-0) var(--space-8);
        }

        .speaker__section-header {
            margin-bottom: var(--space-12);
        }

        .speaker__day-switch-rail {
            height: var(--space-12);
        }

        .speaker__day-panel-date,
        .speaker__day-panel-time {
            font-size: var(--font-size-20);
        }
    }

    @media (max-width: 991px) {
        --speaker-day-label-size: var(--font-size-32);
        --speaker-day-label-line-height: var(--section-topic-line-height);
        --speaker-day-label-weight: var(--font-weight-regular);
        --speaker-day-label-active-size: var(--font-size-32);
        --speaker-day-label-active-line-height: var(--speaker-day-label-line-height);
        --speaker-day-label-active-weight: var(--font-weight-bold);

        .speaker__layout {
            margin-right: 0;
            margin-left: 0;
        }

        .speaker__day-panel-header {
            display: none;
        }

        .speaker__day-switcher {
            position: static;
            width: 100%;
            margin-bottom: var(--space-0);
            padding: 0;
            background: var(--color-surface-paper);
            scroll-margin-top: calc(var(--header-height) + var(--space-4));
            display: flex;
            justify-content: center;
        }

        .speaker__day-switcher,
        .speaker__days {
            flex: 0 0 100%;
            width: 100%;
            max-width: 100%;
            padding-right: 0;
            padding-left: 0;
        }

        .speaker__day-switcher-inner {
            --day-switcher-padding-y: var(--space-8);
            --day-switcher-details-space: var(--space-8);
            --day-switcher-rail-width: 44%;
            --day-switcher-label-shift: 0px;

            position: relative;
            width: min(100%, 360px);
            grid-template-columns: max-content var(--day-switcher-rail-width) max-content;
            justify-content: center;
            justify-items: center;
            align-items: end;
            column-gap: var(--space-2);
            padding-top: var(--day-switcher-padding-y);
            padding-bottom: calc(var(--day-switcher-padding-y) + var(--day-switcher-details-space));
        }

        .speaker__day-switch {
            position: static;
            width: auto;
            min-height: var(--touch-target-md);
            padding: 0 0 var(--space-3);
            display: flex;
            align-items: flex-end;
            font-size: var(--speaker-day-label-size);
            line-height: var(--speaker-day-label-line-height);
            background: transparent;
            text-align: left;

            &:first-of-type {
                grid-column: 1;
                padding-left: var(--day-switcher-label-shift);
            }

            &:last-of-type {
                grid-column: 3;
                padding-right: var(--day-switcher-label-shift);
                justify-content: flex-end;
                text-align: right;
            }
        }

        .speaker__day-switch-label {
            font-size: var(--speaker-day-label-size);
            line-height: var(--speaker-day-label-line-height);
        }

        .speaker__day-switch[aria-current='true'] .speaker__day-switch-label {
            font-size: var(--speaker-day-label-active-size);
            font-weight: var(--speaker-day-label-active-weight);
            line-height: var(--speaker-day-label-active-line-height);
        }

        .speaker__day-switch-details,
        .speaker__day-switch:not([aria-current='true']) .speaker__day-switch-details {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + var(--touch-target-md) + var(--speaker-day-switch-details-gap));
            left: 0;
            width: 100%;
            margin-top: 0;
            opacity: 0;
            visibility: hidden;
            transform: none;
            transition: opacity var(--duration-fast) var(--ease-standard);
        }

        .speaker__day-switch:last-of-type .speaker__day-switch-details {
            transform: none;
        }

        .speaker__day-switch:not([aria-current='true']) .speaker__day-switch-details {
            opacity: 1;
            visibility: visible;
        }

        .speaker__day-switch-details-inner {
            display: flex;
            flex-wrap: nowrap;
            justify-content: center;
            align-items: center;
            gap: var(--space-1) var(--space-4);
            overflow: visible;
            text-align: left;
            white-space: nowrap;
        }

        .speaker__day-switch-details-inner span+span::before {
            content: none;
        }

        .speaker__day-switch-rail {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + (var(--touch-target-md) / 2));
            left: 50%;
            display: block;
            width: var(--day-switcher-rail-width);
            height: var(--rule-width-subtle);
            background: var(--color-border-editorial);
            transform: translate(-50%, -50%);
        }

        .speaker__day-switch-prompt {
            position: absolute;
            top: calc(var(--day-switcher-padding-y) + (var(--touch-target-md) / 2));
            left: 50%;
            display: block;
            color: var(--color-text-muted);
            font-size: var(--section-small-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--section-small-line-height);
            transform: translate(-50%, calc(-100% + var(--space-2)));
            white-space: nowrap;
            background: var(--color-surface-paper);
            padding: var(--space-0) var(--space-2);
            z-index: 2;
        }

        .speaker__day-switch-rail::after {
            top: auto;
            right: auto;
            bottom: 0;
            left: 0;
            width: 50%;
            height: var(--rule-width-emphasis);
            background: var(--spectrum);
            transform: translateX(0);
        }

        .speaker__day-switcher-inner[data-active-day='day-two'] .speaker__day-switch-rail::after {
            transform: translateX(100%);
        }
    }

    @media (max-width: 575px) {
        --speaker-day-label-size: var(--font-size-20);
        --speaker-day-label-active-size: var(--font-size-20);

        .speaker__day-panel-date,
        .speaker__day-panel-time {
            font-size: var(--font-size-18);
        }

        .speaker__day-switcher-inner {
            --day-switcher-label-shift: 0px;

            width: min(100%, 320px);
        }
    }

    @media (max-width: 395px) {
        .speaker__section-header {
            .bt-title-highlight {
                &.has-ps {
                    padding-left: var(--space-0);
                }
            }
        }
    }
}


/* Mobile day switcher pattern shared by Agenda and Speaker */
#agenda .agenda__day-switch-date-short,
#speaker .speaker__day-switch-date-short {
    display: none;
}

/* ขยายรูปแบบตัวเลือกวันของ Agenda และ Speaker จากมือถือให้ครอบคลุม tablet ถึง 991px */
@media (min-width: 768px) and (max-width: 991px) {
    #agenda .agenda__day-switcher {
        background: transparent;
    }

    #agenda .agenda__day-switcher-inner {
        position: relative;
        width: 100%;
        display: grid;
        grid-template-columns: repeat(2, 96px);
        align-items: center;
        justify-content: center;
        justify-items: center;
        column-gap: var(--space-8);
        overflow: hidden;
        padding: var(--space-6) var(--space-6) var(--space-16);
        background: var(--color-surface-paper);
    }

    #agenda .agenda__day-switcher-inner::before {
        content: "/";
        position: absolute;
        top: calc(var(--space-6) + (var(--section-topic-line-height) / 2));
        left: 50%;
        z-index: 1;
        color: var(--color-text-inverse-muted);
        font-size: var(--font-size-24);
        font-weight: var(--font-weight-light);
        line-height: 1;
        transform: translate(-50%, -50%);
        pointer-events: none;
    }

    #agenda .agenda__day-switch {
        position: static;
        width: 100%;
        min-height: auto;
        padding: var(--space-0);
        display: grid;
        justify-items: center;
        align-items: center;
        text-align: center;
    }

    #agenda .agenda__day-switch-label {
        white-space: nowrap;
    }

    #agenda .agenda__day-switch:first-of-type {
        grid-column: 1;
    }

    #agenda .agenda__day-switch:last-of-type {
        grid-column: 2;
        justify-content: center;
        text-align: center;
    }

    #agenda .agenda__day-switch-details {
        position: absolute;
        top: unset;
        right: 0;
        bottom: 28px;
        left: 0;
        width: 100%;
        display: block;
        margin-top: var(--space-0);
        opacity: 0;
        visibility: hidden;
        transform: none;
        text-align: center;
        pointer-events: none;
    }

    #agenda .agenda__day-switch[aria-current='true'] .agenda__day-switch-details {
        color: var(--agenda-day-label-color);
        opacity: 1;
        visibility: visible;
    }

    #agenda .agenda__day-switch-details-inner {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        min-height: fit-content;
        overflow: visible;
        text-align: center;
        white-space: nowrap;
    }

    #agenda .agenda__day-switch-date-full {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }

    #agenda .agenda__day-switch-date-short {
        display: inline;
    }

    #agenda .agenda__day-switch-prompt,
    #agenda .agenda__day-switch-rail {
        display: none;
    }

    #speaker .speaker__day-switcher {
        background: transparent;
    }

    #speaker .speaker__day-switcher-inner {
        position: relative;
        width: 100%;
        display: grid;
        grid-template-columns: repeat(2, 96px);
        align-items: center;
        justify-content: center;
        justify-items: center;
        column-gap: var(--space-8);
        overflow: hidden;
        padding: var(--space-6) var(--space-6) var(--space-16);
        background: var(--color-surface-paper);
    }

    #speaker .speaker__day-switcher-inner::before {
        content: "/";
        position: absolute;
        top: calc(var(--space-6) + (var(--section-topic-line-height) / 2));
        left: 50%;
        z-index: 1;
        color: var(--color-text-inverse-muted);
        font-size: var(--font-size-24);
        font-weight: var(--font-weight-light);
        line-height: 1;
        transform: translate(-50%, -50%);
        pointer-events: none;
    }

    #speaker .speaker__day-switch {
        position: static;
        width: 100%;
        min-height: auto;
        padding: var(--space-0);
        display: grid;
        justify-items: center;
        align-items: center;
        text-align: center;
    }

    #speaker .speaker__day-switch-label {
        white-space: nowrap;
    }

    #speaker .speaker__day-switch:first-of-type {
        grid-column: 1;
    }

    #speaker .speaker__day-switch:last-of-type {
        grid-column: 2;
        justify-content: center;
        text-align: center;
    }

    #speaker .speaker__day-switch-details {
        position: absolute;
        top: unset;
        right: 0;
        bottom: 28px;
        left: 0;
        width: 100%;
        display: block;
        margin-top: var(--space-0);
        opacity: 0;
        visibility: hidden;
        transform: none;
        text-align: center;
        pointer-events: none;
    }

    #speaker .speaker__day-switch[aria-current='true'] .speaker__day-switch-details {
        color: var(--speaker-day-label-active-color);
        opacity: 1;
        visibility: visible;
    }

    #speaker .speaker__day-switch-details-inner {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        min-height: fit-content;
        overflow: visible;
        text-align: center;
        white-space: nowrap;
    }

    #speaker .speaker__day-switch-date-full {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }

    #speaker .speaker__day-switch-date-short {
        display: inline;
    }

    #speaker .speaker__day-switch-prompt,
    #speaker .speaker__day-switch-rail {
        display: none;
    }

    #speaker .speaker__panel {
        margin-top: var(--space-8);
        padding: var(--space-8) var(--space-8) var(--space-12);
    }
}

@media (max-width: 767px) {

    #agenda .agenda__day-switcher,
    #speaker .speaker__day-switcher {
        background: transparent;
    }

    #agenda .agenda__day-switcher-inner,
    #speaker .speaker__day-switcher-inner {
        position: relative;
        width: 100%;
        display: grid;
        grid-template-columns: repeat(2, 96px);
        align-items: center;
        justify-content: center;
        justify-items: center;
        column-gap: var(--space-8);
        overflow: hidden;
        padding: var(--space-6) var(--space-6) var(--space-16);
        background: var(--color-surface-paper);
    }

    #agenda .agenda__day-switcher-inner::before,
    #speaker .speaker__day-switcher-inner::before {
        content: "/";
        position: absolute;
        top: calc(var(--space-6) + (var(--section-topic-line-height) / 2));
        left: 50%;
        z-index: 1;
        color: var(--color-text-inverse-muted);
        font-size: var(--font-size-24);
        font-weight: var(--font-weight-light);
        line-height: 1;
        transform: translate(-50%, -50%);
        pointer-events: none;
    }

    #agenda .agenda__day-switch,
    #speaker .speaker__day-switch {
        position: static;
        width: 100%;
        min-height: auto;
        padding: var(--space-0);
        display: grid;
        justify-items: center;
        align-items: center;
        text-align: center;
    }

    #agenda .agenda__day-switch-label,
    #speaker .speaker__day-switch-label {
        white-space: nowrap;
    }

    #agenda .agenda__day-switch:first-of-type,
    #speaker .speaker__day-switch:first-of-type {
        grid-column: 1;
    }

    #agenda .agenda__day-switch:last-of-type,
    #speaker .speaker__day-switch:last-of-type {
        grid-column: 2;
        justify-content: center;
        text-align: center;
    }

    #agenda .agenda__day-switch-details,
    #speaker .speaker__day-switch-details {
        position: absolute;
        top: unset;
        right: 0;
        bottom: 28px;
        left: 0;
        width: 100%;
        display: block;
        margin-top: var(--space-0);
        opacity: 0;
        visibility: hidden;
        transform: none;
        text-align: center;
        pointer-events: none;
    }

    #agenda .agenda__day-switch[aria-current='true'] .agenda__day-switch-details {
        color: var(--agenda-day-details-color);
        opacity: 1;
        visibility: visible;
    }

    #speaker .speaker__day-switch[aria-current='true'] .speaker__day-switch-details {
        color: var(--speaker-day-label-active-color);
        opacity: 1;
        visibility: visible;
    }

    #agenda .agenda__day-switch-details-inner,
    #speaker .speaker__day-switch-details-inner {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        min-height: fit-content;
        overflow: visible;
        text-align: center;
        white-space: nowrap;
    }

    #agenda .agenda__day-switch-date-full,
    #speaker .speaker__day-switch-date-full {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }

    #agenda .agenda__day-switch-date-short,
    #speaker .speaker__day-switch-date-short {
        display: inline;
    }

    #agenda .agenda__day-switch-prompt,
    #speaker .speaker__day-switch-prompt,
    #agenda .agenda__day-switch-rail,
    #speaker .speaker__day-switch-rail {
        display: none;
    }
}

@media (max-width: 575px) {

    #agenda .agenda__day-switcher-inner,
    #speaker .speaker__day-switcher-inner {
        grid-template-columns: repeat(2, 72px);
        padding: var(--space-3) var(--space-3) var(--space-10);
        column-gap: var(--space-6);
    }

    #agenda .agenda__day-switcher-inner::before,
    #speaker .speaker__day-switcher-inner::before {
        top: calc(var(--space-3) + (var(--section-topic-line-height) / 2));
        font-size: var(--font-size-14);
    }

    #agenda .agenda__day-switch-details,
    #speaker .speaker__day-switch-details {
        bottom: 18px;
        font-size: var(--font-size-14);
        line-height: var(--section-small-line-height);
    }
}


/* ---------- กริดของการ์ดคน (ใช้ร่วมกัน) ----------
   Speaker กับ Moderators & MC ต้องได้แทร็กกว้างเท่ากันเป๊ะ การ์ดถึงจะขนาดเดียวกัน
   เขียนรวมเป็นกฎเดียวแบบนี้เพื่อไม่ให้ค่าใดค่าหนึ่งถูกแก้ทีหลังแล้วสองฝั่งหลุดจากกัน */
.speaker__panel,
.moderator__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
    grid-auto-rows: auto;
    gap: var(--space-8) var(--space-12);
    margin-top: 0;
}

.speaker__panel {
    padding: var(--space-8) var(--space-8) var(--space-12);
    background: var(--color-neutral-50);
    border-radius: var(--radius-1);
}

/* Moderator เต็ม 12 คอลัมน์ (ไม่เยื้องแบบเดิมแล้ว) แบ่ง 4 การ์ด/แถว แทนที่ 3 ของ Speaker
   9÷3 = 12÷4 = 3 หน่วยคอลัมน์ต่อการ์ดเท่ากัน บวกกับ padding/gap ที่เท่ากันทุกค่า
   การ์ดสองฝั่งจึงกว้างเท่ากันพอดี แม้พื้นที่กริดรวมกว้างไม่เท่ากันก็ตาม */
.moderator__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    padding: var(--space-8);
    background: var(--color-neutral-50);
    border-radius: var(--radius-1);
}

@media (max-width: 1199px) {

    .speaker__panel,
    .moderator__grid {
        gap: var(--space-12) var(--space-8);
    }

    .speaker__panel {
        padding: var(--space-8) var(--space-6) var(--space-12);
    }

    .speaker-card h3 {
        text-wrap: nowrap;
    }
}

@media (max-width: 991px) {

    .speaker__panel,
    .moderator__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-12) var(--space-6);
    }
}

@media (max-width: 767px) {

    .speaker__panel,
    .moderator__grid {
        margin-top: var(--space-8);
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-12) var(--space-6);
    }

    .speaker__panel {
        padding: var(--space-8) var(--space-8) var(--space-12);
    }
}

@media (max-width: 575px) {

    .speaker__panel {
        margin-top: var(--space-6);
        padding: var(--space-4) var(--space-4) var(--space-8);
        gap: var(--space-8) var(--space-4);
    }

    .moderator__grid {
        margin-top: var(--space-3);
        padding: var(--space-4);
        gap: var(--space-12) var(--space-4);
    }
}

@media (max-width: 393px) {
    .moderator__section-header {
        .bt-title-highlight {
            &.has-ps {
                padding-left: var(--space-0);
            }
        }
    }
}


/* ---------- การ์ดคนหนึ่งใบ (คอมโพเนนต์ร่วม) ----------
   ใช้ทั้งใน Speaker และ Moderators & MC จึงอยู่นอกบล็อกของ section ไหนทั้งสิ้น
   ความกว้างมาจากแทร็กของกริดที่ครอบอยู่ ความสูงมาจาก aspect-ratio ของกรอบรูป
   บวกความสูงคงที่ของ meta — สอง section จึงได้การ์ดขนาดเท่ากันเองโดยไม่ต้องล็อก px */
.speaker-card {
    justify-self: center;
    width: 100%;
    min-width: 0;
    margin-top: 0;
    /* padding: var(--space-4); */
    /* border: var(--rule-width-subtle) solid var(--color-border-editorial); */
}

/* ออร่าสเปกตรัมหลังรูปวิทยากร (รูปเป็น WebP พื้นโปร่ง แสงจึงลอดออกมารอบตัวคน)
   ตั้งใจไม่ครอบด้วย overflow: hidden อีกต่อไป (เอาออกที่ .speaker-card__portrait
   ด้านล่าง) เพื่อให้แสงฟุ้งล้นออกไปนอกกรอบรูปได้จริงตามที่ต้องการ
   เพื่อไม่ให้ไปทับการ์ดใบข้างเคียง ต้องคุมด้วย "ขนาด" แทนการ "ตัดขอบ":
   ย่อกล่องเข้ามาจากขอบกรอบรูปด้วย inset (แทนที่จะเต็มกรอบแบบเดิม) และลด blur ลง
   ระยะที่เหลือ (inset 24% + blur 10px ≈ เผื่อไว้ราว 20px จากขอบกรอบรูป) ยังน้อยกว่า
   ช่องว่างระหว่างการ์ดที่แคบที่สุด (16px ตอนจอมือถือ ≤767px, ดู .speaker__panel) ไม่พอ
   ชนกับการ์ดข้างเคียงแน่ แต่เผื่อขอบเพิ่มไว้อีกชั้นเพราะขนาดจริงยังขึ้นกับสีของรูปด้วย */
.speaker-card__portrait::before,
.speaker-card__portrait::after {
    content: '';
    position: absolute;
    inset: 14%;
    z-index: -1;
    border-radius: 50%;
    filter: blur(8px) saturate(1.5);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-slow) var(--ease-standard);
}

/* แยกสองชั้น คนละคู่สี คนละจังหวะ/ทิศหมุน เวลาเหลื่อมกันจึงผสมกันเป็นทิศทาง
   อิสระแบบสุ่ม ไม่ใช่วิ่งตามแกน x หรือ y อย่างเดียว */
.speaker-card__portrait::before {
    background:
        radial-gradient(circle at 30% 32%, var(--color-category-cyan) 0%, transparent 52%),
        radial-gradient(circle at 70% 64%, var(--color-category-violet) 0%, transparent 52%);
}

.speaker-card__portrait::after {
    background:
        radial-gradient(circle at 68% 28%, var(--color-category-pink) 0%, transparent 50%),
        radial-gradient(circle at 32% 72%, var(--color-category-yellow) 0%, transparent 54%);
}

.speaker-card:hover .speaker-card__portrait::before {
    opacity: 0.8;
    animation: speaker-aurora-a 16s linear infinite;
}

.speaker-card:hover .speaker-card__portrait::after {
    opacity: 0.65;
    animation: speaker-aurora-b 22s linear infinite;
}

.speaker-card__portrait {
    position: relative;
    aspect-ratio: 4 / 5;
    /* isolation: isolate ยังต้องอยู่ — ไม่ใช่แค่ของเก่าที่ค้างมากับ overflow ที่เพิ่งเอาออก
       ทำให้กรอบรูปเป็น stacking context ของตัวเอง z-index: -1 ของออร่าจึงยังถูกวาด
       "หลังกรอบรูปนี้" เท่านั้น (แสงยังล้นออกไปได้ปกติ เพราะ isolation คุมแค่ลำดับการวาด
       ไม่ใช่ขอบเขตการแสดงผลแบบ overflow) ถ้าลบออกด้วย z-index จะทะลุไปอยู่หลังทุกอย่าง
       บนหน้าเว็บเหมือนบั๊กที่เจอตอนทำ section Expectation */
    isolation: isolate;
    background: linear-gradient(0deg, var(--color-surface-page) 10%, transparent 80%);
}

/* กรอบตัดภาพแยกจาก .speaker-card__portrait โดยตั้งใจ — ต้องมี overflow: hidden
   เพื่อกันรูปที่ scale(1.03) ตอน hover ไม่ให้ล้นลงไปทับข้อความชื่อ/ตำแหน่งด้านล่าง
   (พิสูจน์แล้วว่าไม่ใช่แค่ทฤษฎี: สุ่มสีพิกเซลแถวล่างสุดของรูปจริงออกมาเป็นสีเข้ม
   เกือบดำของสูท ถ้าปล่อยให้ล้นจะเห็นเป็นรอยเปื้อนสีเข้มในช่องว่างเหนือชื่อชัดเจน)
   วางเป็นชั้นแยกจากตัว .speaker-card__portrait เอง เพราะ portrait ต้องเป็น
   overflow: visible ไว้ให้ออร่าสเปกตรัมด้านบนฟุ้งออกนอกกรอบได้ตามที่ต้องการ
   ถ้าใส่ overflow: hidden ไว้ที่ portrait เหมือนเดิม ออร่าจะโดนตัดไปด้วย */
.speaker-card__frame {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* ลายคริสตัล (speaker-bg-overlay.webp) เป็นพื้นหลังหลังรูปคน ใช้ทั้งการ์ด Speaker และ Moderators & MC
   รูปคนเป็น WebP พื้นโปร่งจึงเห็นลายรอบตัว ภาพต้นฉบับเป็นขาวดำ ใช้ multiply ทับพื้นสีหน้าเว็บ
   ให้กลืนกับโทนการ์ด และจางลงด้านล่างตาม gradient ของ .speaker-card__portrait ให้ต่อกับชื่อได้เนียน */
/* .speaker-card__frame::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('../images/speaker-bg-overlay2.webp') center / cover no-repeat;
    opacity: var(--speaker-card-overlay-opacity, 0.5);
    mix-blend-mode: multiply;
    -webkit-mask-image: linear-gradient(0deg, transparent 10%, #000 80%);
    mask-image: linear-gradient(0deg, transparent 10%, #000 80%);
    pointer-events: none;
} */

.speaker-card__portrait img {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* --speaker-portrait-y คือค่าจัดหัวให้เสมอกันของแต่ละรูป (speaker-directory.js ตั้ง
       ให้ฝั่ง Speaker ส่วน Moderators & MC เขียนไว้ที่ style ของการ์ดใน HTML)
       ส่วน --speaker-portrait-drift เป็นตัวที่ ScrollTrigger ขยับเท่านั้น แยกกันไว้
       เพื่อให้ revert ของ gsap ล้าง drift ได้โดยค่าจัดหัวยังอยู่ครบ */
    object-position: center;
    filter: saturate(1.1);
    transform: scale(var(--speaker-portrait-scale, 1));
    transform-origin: center;
    transition:
        filter var(--duration-slow) var(--ease-standard),
        transform var(--duration-slow) var(--ease-standard);
}

.speaker-card:hover .speaker-card__portrait img {
    filter: saturate(1) contrast(1);
    transform: scale(calc(var(--speaker-portrait-scale, 1) + 0.03));
}

.speaker-card__meta {
    /* position + z-index จำเป็นคู่กับ background-color ด้านล่าง ไม่ใช่แค่ของประดับ:
       .speaker-card__portrait เป็น positioned element จึงถูกวาดในขั้นหลังกว่า
       พื้นหลังของ block ธรรมดาอย่าง meta ออร่าที่ฟุ้งเลยขอบรูปลงมาจึงทับพื้นขาว
       ตรงนี้ได้ ต้องดัน meta ขึ้นมาเป็น positioned ด้วย ถึงจะวาดทีหลัง (อยู่หลัง
       ใน DOM) แล้วปิดออร่าส่วนที่ล้ำลงมาได้จริง */
    position: relative;
    z-index: 1;
    min-width: 0;
    padding: var(--space-6) var(--space-0) var(--space-0);
    /* border-top: var(--rule-width-subtle) solid var(--color-border-editorial); */
}

.speaker-card h3 {
    margin: var(--space-0);
    font-size: var(--section-body-size);
    font-weight: var(--font-weight-medium);
    line-height: var(--section-body-line-height);
    letter-spacing: 0;
}

.speaker-card p {
    margin: var(--space-1) var(--space-0) var(--space-0);
    color: var(--color-text-muted);
    font-size: var(--section-small-size);
    font-weight: var(--font-weight-light);
}

/* ต่ำกว่า 1200px การ์ดไหลตามกริดปกติ เพดาน 260px กันไม่ให้ใบเดียวยืดจนเสียสัดส่วน */
@media (max-width: 1199px) {
    .speaker-card {
        width: min(100%, 260px);
    }
}

@media (max-width: 991px) {
    .speaker-card {
        width: min(100%, 320px);
    }
}

@media (max-width: 767px) {

    /* การ์ด 2 คอลัมน์บนจอเล็กแคบเกินกว่าชื่อไทยจะพอดีบรรทัดเดียว
       เผื่อไว้ 2 บรรทัดเท่ากันทุกใบ ชื่อจึงไม่โดนตัดและการ์ดยังสูงเท่ากัน
       ระยะบรรทัด 28px เผื่อที่ให้วรรณยุกต์/สระบนของไทยไม่ชนกัน */
    .speaker-card__meta {
        padding: var(--space-5) var(--space-0) var(--space-0);
    }

    .speaker-card h3 {
        text-wrap: auto;
    }

    .speaker-card p {
        text-wrap: balance;
    }
}

@media (max-width: 575px) {
    .speaker-card h3 {
        font-size: var(--font-size-14);
        line-height: var(--section-small-line-height);
    }

    .speaker-card h3 {
        text-wrap: pretty;
    }

    .speaker-card p {
        font-size: var(--font-size-12);
        line-height: var(--section-small-line-height);
    }

    .speaker-card__meta {
        padding: var(--space-4) var(--space-0) var(--space-0);
    }
}

/* จอสัมผัสไม่มี hover ให้เห็น โชว์ออร่าจาง ๆ ค้างไว้แทน (ไม่ต้องขยับ) */
@media (hover: none) {
    .speaker-card__portrait::before {
        opacity: 0;
    }

    .speaker-card__portrait::after {
        opacity: 0;
    }
}


/* ---------- Moderators & MC ----------
   โครงเดียวกับ Speaker ทุกอย่าง ต่างแค่ไม่มีตัวสลับวันและมีการ์ดชุดเดียว
   กริดจึงต้องอยู่ในคอลัมน์ 9 ช่องที่เยื้อง 3 ช่องเท่ากับ .speaker__days
   เพื่อให้แทร็กกว้างเท่ากัน การ์ดสองฝั่งจึงมีขนาดตรงกันเป๊ะโดยไม่ต้องล็อกค่าใด */
.moderator {
    /* ข้อมูลและการ์ดพร้อมใช้งานแล้ว แต่ซ่อน section ไว้จนกว่าจะประกาศเปิดตัว */
    display: none;
    position: relative;
    scroll-margin-top: var(--header-height);
    /* เว้นบน-ล่างเต็มเท่า section อื่นทุกอัน ระยะระหว่าง Speaker กับ section นี้
       จึงเป็น 128+128 เท่ากับคู่ section อื่นในหน้า ไม่ใช่ 128 อย่างที่ตัดบนออก */
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .moderator__section-header {
        margin-bottom: var(--space-20);
    }

    .moderator__section-header h2 {
        max-width: 920px;
        margin: 0;
        font-size: var(--section-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-title-line-height);
        letter-spacing: 0;
    }

    /* ใช้กริด 3 คอลัมน์ชุดเดียวกับฝั่ง Speaker (นิยามอยู่ในบล็อกกริดร่วมด้านบน) */

    @media (max-width: 991px) {
        padding: var(--section-padding-y-sm) 0;

        .moderator__section-header {
            margin-bottom: var(--space-12);
        }
    }
}

/* ---------- Past Event ----------
   Editorial archive: asymmetric films above a continuously moving photo reel. */
.past-event {
    position: relative;
    overflow: hidden;
    scroll-margin-top: var(--header-height);
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
}

.past-event__inner {
    display: grid;
    gap: var(--space-16);
}

.past-event__header {
    display: block;
}

.past-event__heading {
    min-width: 0;
}

.past-event__header h2 {
    max-width: 1000px;
    margin: 0;
    font-size: var(--section-title-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-title-line-height);
    letter-spacing: 0;
}

.past-event__films {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    grid-template-rows: repeat(2, minmax(0, 1fr));
    gap: var(--space-6);
}

.past-event__film {
    min-width: 0;
    min-height: 0;
}

.past-event__film--featured {
    grid-row: 1 / span 2;
}

.past-event__film--second {
    grid-column: 2;
    grid-row: 1;
}

.past-event__film--third {
    grid-column: 2;
    grid-row: 2;
}

.past-event__video-frame {
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: var(--color-surface-inverse);
    border-radius: var(--radius-1);
}

.past-event__film:not(.past-event__film--featured) .past-event__video-frame {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
}

.past-event__video-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.past-event__marquee {
    --marquee-fade: clamp(24px, 5vw, 80px);

    width: 100%;
    margin-top: var(--space-6);
    overflow: hidden;
    outline: none;
    /* -webkit-mask-image: linear-gradient(90deg,
            transparent 0,
            #000 var(--marquee-fade),
            #000 calc(100% - var(--marquee-fade)),
            transparent 100%);
    mask-image: linear-gradient(90deg,
            transparent 0,
            #000 var(--marquee-fade),
            #000 calc(100% - var(--marquee-fade)),
            transparent 100%); */
}

.past-event__marquee-track {
    align-items: stretch;
    transition-timing-function: linear;
}

.past-event__marquee:focus-visible {
    outline: var(--rule-width-subtle) solid var(--color-text-primary);
    outline-offset: var(--space-2);
}

.past-event__slide {
    width: clamp(220px, 22vw, 352px);
    height: auto;
    margin: 0;
}

.past-event__slide-frame {
    display: grid;
    width: 100%;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    color: var(--color-text-primary);
    background: var(--color-surface-paper);
    border-radius: var(--radius-1);
}

.past-event__slide-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 991px) {
    .past-event {
        padding: var(--section-padding-y-sm) 0;
    }

    .past-event__inner {
        gap: var(--space-12);
    }

    .past-event__header {
        display: block;
    }

    /* วิดีโอที่ 2-3 จับคู่กันในแถวเดียวกัน วิดีโอแรกยังใหญ่สุดเต็มความกว้างแถวบน
       (จอ ≤575px จะกลับไปเรียงคอลัมน์เดียวทั้งหมด ดู block ด้านล่าง) */
    .past-event__films {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: auto auto;
    }

    .past-event__film--featured {
        grid-column: 1 / -1;
        grid-row: 1;
    }

    .past-event__film--second {
        grid-column: 1;
        grid-row: 2;
    }

    .past-event__film--third {
        grid-column: 2;
        grid-row: 2;
    }

    .past-event__film:not(.past-event__film--featured) .past-event__video-frame {
        height: auto;
        aspect-ratio: 16 / 9;
    }

}

@media (max-width: 767px) {
    .past-event__films {
        gap: var(--space-4);
    }

}

@media (max-width: 575px) {
    .past-event__films {
        grid-template-columns: 1fr;
        grid-template-rows: auto;
    }

    .past-event__film--featured,
    .past-event__film--second,
    .past-event__film--third {
        grid-column: 1;
        grid-row: auto;
    }

    .past-event__slide {
        width: 240px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .past-event__marquee {
        overflow-x: auto;
        scrollbar-width: none;
    }

    .past-event__marquee::-webkit-scrollbar {
        display: none;
    }

}

/* ---------- FAQ ---------- */
.faq {
    /* สีลิงก์ในคำตอบ FAQ ใช้น้ำเงินหลักของเว็บ (ชุดเดียวกับตัวเน้นสีน้ำเงินใน section อื่น)
       เดิมเป็นทอง #f2c15a */
    --bt-faq-link-ink: var(--color-accent-primary);

    --faq-question-font-size: var(--font-size-16);
    --faq-question-font-weight: var(--font-weight-medium);
    --faq-answer-font-size: var(--font-size-16);
    --faq-answer-font-weight: var(--font-weight-regular);
    --faq-sticky-gap: var(--space-12);

    position: relative;
    scroll-margin-top: var(--header-height);
    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    /* background:
        radial-gradient(circle at 12% 0%, rgba(78, 92, 255, 0.08), transparent 34%),
        radial-gradient(circle at 88% 100%, rgba(255, 95, 173, 0.08), transparent 30%),
        var(--color-surface-page); */
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
}

.faq__inner {
    position: relative;
}

.faq__header-col {
    /* Bootstrap's align-items-start keeps this column at its content height, which
       leaves the sticky header with no vertical travel. Stretch only the left column
       to the FAQ row height so it can remain pinned beside the sticky tabs. */
    align-self: stretch;
}

.faq__header {
    position: sticky;
    top: calc(var(--header-height) + var(--faq-sticky-gap));
    align-self: start;
}

.faq__header h2 {
    margin: 0;
    font-size: var(--section-title-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-title-line-height);
}

.faq__content {
    min-width: 0;
}

.faq__content-col {
    min-width: 0;
}

/* ---- แท็บหมวดคำถาม: ทำสไตล์ตามแนวเดียวกับ .agenda__tabs (แถบปุ่ม + เส้น
   indicator ไล่สีที่เลื่อนตามตำแหน่งจริงของปุ่มที่เลือก) แต่เป็น class และ
   ตัวแปรของ FAQ เองทั้งหมด ไม่ได้ดึง CSS ของ agenda มาใช้ */
.faq__tabs-viewport {
    position: sticky;
    top: calc(var(--header-height) + var(--faq-sticky-gap));
    z-index: 20;
    margin-bottom: var(--space-0);
    padding: var(--space-4) var(--space-0) var(--space-0);
    background: var(--color-surface-page);
}

.faq__tabs-viewport.is-sticky::before {
    content: '';
    position: absolute;
    right: 0;
    bottom: 100%;
    left: 0;
    height: var(--faq-sticky-gap);
    background: var(--color-surface-page);
    pointer-events: none;
}

.faq__tabs {
    --faq-tab-indicator-x: 0px;
    --faq-tab-indicator-width: 0px;

    position: relative;
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    min-height: var(--touch-target-md);
    margin: 0;
    overflow: visible;
    scrollbar-width: none;

    &::-webkit-scrollbar {
        display: none;
    }

    /* เส้นใต้แถบแท็บยาวสุดแถวเสมอ ไม่ใช่แค่ความกว้างของปุ่มรวมกัน */
    &::after {
        content: '';
        flex: 1 1 auto;
        border-bottom: var(--rule-width-emphasis) solid var(--color-border-faint);
    }
}

.faq__tab {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    min-height: var(--touch-target-md);
    padding: 0 var(--space-6);
    border: 0;
    border-bottom: var(--rule-width-emphasis) solid var(--color-border-faint);
    color: var(--color-text-muted);
    background: transparent;
    font: inherit;
    font-size: var(--section-body-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-body-line-height);
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-standard);

    &:hover {
        color: var(--color-text-primary);
    }

    &:focus-visible {
        outline: var(--border-width-2) solid var(--color-focus-ring);
        outline-offset: calc(var(--border-width-2) * -1);
    }

    &[aria-selected="true"] {
        color: var(--color-text-primary);
        font-weight: var(--font-weight-medium);
    }
}

.faq__tab-indicator {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 2;
    width: var(--faq-tab-indicator-width);
    height: var(--rule-width-emphasis);
    background: var(--gradient-table-active-spectrum);
    pointer-events: none;
    transform: translateX(var(--faq-tab-indicator-x));
    will-change: width, transform;
}

.faq__tabs[data-indicator-ready="true"] .faq__tab-indicator {
    transition:
        width var(--duration-base) linear,
        transform var(--duration-base) linear;
}

.faq__panel[hidden] {
    display: none;
}

.faq__accordion {
    border-top: 0;
    --bs-accordion-bg: transparent;
    --bs-accordion-border-width: 0;
    --bs-accordion-border-color: transparent;
    --bs-accordion-border-radius: 0;
    --bs-accordion-inner-border-radius: 0;
    --bs-accordion-active-bg: transparent;
    --bs-accordion-active-color: var(--color-text-primary);
    --bs-accordion-btn-bg: transparent;
    --bs-accordion-btn-color: var(--color-text-primary);
    --bs-accordion-btn-focus-border-color: transparent;
    --bs-accordion-btn-focus-box-shadow: none;
}

.faq__item {
    background: transparent;
    border-bottom: var(--rule-width-subtle) solid var(--color-border-faint);
    /* border-bottom: var(--rule-width-subtle) solid var(--color-border-editorial); */
}

.faq__question-heading {
    margin: 0;
}

.faq__question {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--space-10);
    gap: var(--space-6);
    align-items: center;
    padding: var(--space-5) var(--space-6);
    color: var(--color-text-primary);
    font-size: var(--faq-question-font-size);
    font-weight: var(--faq-question-font-weight);
    line-height: 1.45;
    cursor: pointer;
    list-style: none;
    box-shadow: none;
}

.faq__question::after {
    display: none;
}

.faq__question:not(.collapsed) {
    padding-top: var(--space-10);
    padding-bottom: var(--space-4);
}

.faq__question:focus-visible {
    outline: 2px solid #315efb;
    outline-offset: var(--space-1);
}

.faq__icon {
    position: relative;
    /* width: var(--space-10);
    height: var(--space-10);
    border-radius: 50%; */
}

.faq__icon::before,
.faq__icon::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 1.5px;
    border-radius: 999px;
    background: currentColor;
    transform: translate(-50%, -50%);
    transition:
        opacity var(--duration-base) var(--ease-standard),
        transform var(--duration-base) var(--ease-standard);
}

.faq__icon::after {
    transform: translate(-50%, -50%) rotate(90deg);
}

.faq__question:not(.collapsed) .faq__icon::after {
    opacity: 0;
    transform: translate(-50%, -50%) rotate(90deg) scaleX(0.2);
}

.faq__answer {
    box-sizing: border-box;
    color: var(--color-text-muted);
    font-size: var(--faq-answer-font-size);
    font-weight: var(--faq-answer-font-weight);
    line-height: var(--section-body-line-height);
}

.faq__answer-body {
    box-sizing: border-box;
    padding: var(--space-0) var(--space-6) var(--space-10);
    color: var(--color-text-muted);
    font-size: var(--faq-answer-font-size);
    font-weight: var(--faq-answer-font-weight);
    line-height: var(--section-body-line-height);
}

.faq__answer-body p {
    margin: 0;
}

.faq__answer-body p+ul,
.faq__answer-body ul+p {
    margin-top: var(--space-2);
}

.faq__answer-body ul {
    margin-bottom: 0;
    padding-left: 0;
    list-style: none;
}

.faq__answer-body li {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
}

.faq__answer-body li::before {
    content: "";
    flex: 0 0 var(--space-3);
    width: var(--space-3);
    height: var(--space-3);
    margin-top: calc((var(--section-body-line-height) - var(--space-3)) / 2);
    background: url("../images/star.webp") center / contain no-repeat;
}

.faq__answer-body li+li {
    margin-top: var(--space-1);
}

/* คำตอบที่เป็นขั้นตอน (เช่น 3 ขั้นตอนของ PERSONALIZED PLAYBOOK) ใช้ตัวเลขกำกับลำดับ
   จึงต้องคืน display: list-item และปิดจุดดาวที่กฎรวมของ li ใส่ไว้ให้ ul */
.faq__answer-body ol {
    margin-bottom: 0;
    padding-left: var(--space-5);
    list-style: decimal;
}

.faq__answer-body p+ol,
.faq__answer-body ol+p {
    margin-top: var(--space-2);
}

.faq__answer-body ol li {
    display: list-item;
    gap: var(--space-0);
}

.faq__answer-body ol li::before {
    content: none;
}

.faq__answer-body ol li+li {
    margin-top: var(--space-1);
}

.faq__answer-body a {
    color: var(--bt-faq-link-ink);
    font-weight: var(--font-weight-medium);
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

@media (max-width: 991px) {
    .faq {
        padding: var(--section-padding-y-sm) 0;
    }

    .faq__header {
        position: static;
        margin-bottom: var(--space-12);
    }

    .faq__tabs-viewport {
        padding: var(--space-0);
    }

}

@media (max-width: 767px) {
    .faq {
        --faq-sticky-gap: var(--space-4);
    }
}

/* ป้ายแท็บ 4 อันรวมกันกว้างเกินพื้นที่คอลัมน์ขวาในบาง breakpoint (เหมือนปัญหา
   เดียวกับ .agenda__tabs) จึงเปลี่ยนเป็นเลื่อนแนวนอนได้แทนการหด/ตัดคำ เพื่อให้
   อ่านป้ายแท็บครบทุกคำ โดยไม่ดันหน้าเว็บล้นออกด้านขวา */
@media (max-width: 1399px) {
    .faq__tabs {
        overflow-x: auto;
        overflow-y: hidden;
        padding-right: var(--space-4);
        scroll-padding-inline: var(--space-4);
    }
}

@media (max-width: 1399px) and (min-width: 992px) {
    .faq .bt-title-highlight.has-px {
        padding-left: var(--space-0);
    }
}

@media (max-width: 575px) {
    .faq {
        --faq-question-font-size: var(--font-size-14);
        --faq-answer-font-size: var(--font-size-14);
    }

    .faq__tab {
        padding: 0 var(--space-4);
    }

    .faq__question {
        grid-template-columns: minmax(0, 1fr) var(--space-8);
        gap: var(--space-4);
        padding: var(--space-4) var(--space-3);
    }

    .faq__question:not(.collapsed) {
        padding-top: var(--space-8);
        padding-bottom: var(--space-2);
    }

    .faq__icon {
        width: var(--space-8);
        height: var(--space-8);
    }

    .faq__answer-body {
        padding: var(--space-0) var(--space-0) var(--space-8) var(--space-3);
        line-height: var(--section-small-line-height);
    }

    .faq__answer-body p+ul,
    .faq__answer-body ul+p {
        margin-top: var(--space-1);
    }
}

/* ---------- CTA ---------- */
.cta {
    position: relative;
    padding: var(--section-padding-y-sm) var(--space-0) var(--space-0);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
}

.cta__inner {
    position: relative;
}

.cta__panel {
    /* scroll-driven expand ขาเข้าอย่างเดียว ชุดเดียวกับ .playbook-cta__panel ในหน้า
       personalized-playbook.html: แผงอยู่ใน .container จึงย่อแค่ 0.94 และมุมคงที่ตลอดทาง */
    --bt-cta-expand-min: 0.94;
    --bt-scroll-expand: 1;

    position: relative;
    overflow: hidden;
    padding: var(--space-16) var(--space-12) var(--space-20);
    border-radius: var(--card-radius);
    scale: calc(var(--bt-cta-expand-min) + (1 - var(--bt-cta-expand-min)) * var(--bt-scroll-expand));
    transform-origin: center top;
    background:
        radial-gradient(circle at 18% 0%, color-mix(in srgb, var(--color-blue-100) 72%, transparent) 0%, transparent 34%),
        radial-gradient(circle at 92% 100%, color-mix(in srgb, var(--color-kv-spectrum-4) 12%, transparent) 0%, transparent 34%),
        var(--color-neutral-50);
    text-align: center;
}

/* .cta__panel::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: var(--rule-width-subtle) solid var(--color-border-faint);
    pointer-events: none;
} */

/* ---------- ของประกอบฉากในแผง CTA ----------
   ใช้ภาพ ขนาด ฟิลเตอร์ และการลอยขยับชุดเดียวกับ .playbook__asset
   ตำแหน่งกำหนดเป็น % ของแผงจึงเลื่อนตามขนาดจอเอง และถูกตัดขอบด้วย overflow ของ .cta__panel */
.cta__assets {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

/* เนื้อหาต้องอยู่เหนือของประกอบฉากเสมอ เพราะเลเยอร์ด้านบนเป็น element ที่ positioned */
.cta__panel> :not(.cta__assets) {
    position: relative;
    z-index: 1;
}

.cta__asset {
    position: absolute;
    top: var(--bt-cta-asset-y);
    left: var(--bt-cta-asset-x);
    width: var(--bt-cta-asset-size);
    display: block;
    transform: translate(-50%, -50%);
    filter: saturate(1.3);
}

.cta__asset-float {
    display: block;
    will-change: transform;
}

/* saturate เท่ากับของ playbook แต่ไม่ใส่เงา (พื้นแผง CTA สว่าง เงาจะเด่นเกินไป) */
.cta__asset img {
    width: 100%;
    height: auto;
    display: block;
    filter: saturate(1.3);
    transform: rotate(var(--bt-cta-asset-rotation));
}

/* องศาเดียวกับ --bt-playbook-stock-rotation */
.cta__asset--stock {
    --bt-cta-asset-x: 16%;
    --bt-cta-asset-y: 56%;
    --bt-cta-asset-size: calc(var(--space-16) + var(--space-1));
    --bt-cta-asset-rotation: -34deg;
}

.cta__asset--triangle {
    --bt-cta-asset-x: 83%;
    --bt-cta-asset-y: 27%;
    --bt-cta-asset-size: var(--space-28);
    --bt-cta-asset-rotation: -8deg;
}

.cta__title {
    max-width: 900px;
    margin: 0 auto;
    font-size: var(--section-title-size);
    font-weight: var(--font-weight-regular);
    line-height: var(--section-title-line-height);
    letter-spacing: var(--section-title-tracking);
    text-wrap-style: balance;
}

.cta__meta,
.cta__offer {
    margin: var(--space-6) auto var(--space-0);
    color: var(--color-text-muted);
    font-size: var(--font-size-20);
    font-weight: var(--font-weight-regular);
    line-height: var(--line-height-relaxed);
    letter-spacing: 0;
    text-wrap-style: balance;
}

.cta__offer {
    margin-top: var(--space-2);
    color: var(--color-text-muted);
    font-weight: var(--font-weight-regular);
}

.cta__action {
    margin-top: var(--space-8);
    display: grid;
    place-items: center;
}

/* ---------- CTA responsive ----------
   ขนาด title ไม่ต้องกำหนดที่นี่ เพราะ h2 ใส่คลาส .bt-section-title แล้ว
   จึงย่อตามบันไดกลางของทุก section (48 → 40 → 32 → 28)
   ของประกอบฉากย่อลงและถอยเข้ามุมทุกขั้น เพื่อไม่ให้ทับคอลัมน์ข้อความที่จัดกลาง */
@media (max-width: 1199px) {
    .cta__panel {
        padding: var(--space-12) var(--space-10) var(--space-16);
    }

    .cta__asset--stock {
        --bt-cta-asset-x: 12%;
        --bt-cta-asset-y: 72%;
    }

    .cta__asset--triangle {
        --bt-cta-asset-x: 88%;
        --bt-cta-asset-y: 22%;
    }
}

@media (max-width: 991px) {
    .cta__panel {
        padding: var(--space-12) var(--space-8);
    }

    .cta__asset--stock {
        --bt-cta-asset-size: calc(var(--space-16) - var(--space-2));
    }

    .cta__asset--triangle {
        --bt-cta-asset-size: var(--space-24);
    }
}

@media (max-width: 767px) {
    .cta__panel {
        padding: var(--space-10) var(--space-6);
    }

    .cta__meta,
    .cta__offer {
        font-size: var(--section-body-size);
    }

    .cta__asset--stock {
        --bt-cta-asset-size: calc(var(--space-16) - var(--space-3));
    }

    .cta__asset--triangle {
        --bt-cta-asset-x: 90%;
        --bt-cta-asset-y: 20%;
        --bt-cta-asset-size: calc(var(--space-24) - var(--space-2));
    }
}

@media (max-width: 575px) {
    .cta {
        padding: var(--space-0);
    }

    .cta__panel {
        padding: var(--space-16) var(--space-5);
        text-align: center;
    }

    .cta__meta,
    .cta__offer {
        line-height: var(--section-body-line-height);
    }

    .cta__action {
        justify-items: center;
    }

    .cta__asset--stock {
        --bt-cta-asset-x: 20%;
        --bt-cta-asset-y: 76%;
        --bt-cta-asset-size: var(--space-10);
    }

    .cta__asset--triangle {
        --bt-cta-asset-x: 90%;
        --bt-cta-asset-y: 42%;
        --bt-cta-asset-size: var(--space-20);
    }
}

/* หมุนรอบจุดกึ่งกลางพร้อมเลื่อน/ย่อขยายเล็กน้อยไปด้วย ทำให้ blob ลอยเป็นวงอิสระ
   ไม่ตรงตามแกนใดแกนหนึ่ง — สองชุดหมุนคนละทิศและคนละความเร็ว เพื่อไม่ให้จับจังหวะซ้ำได้ */
@keyframes speaker-aurora-a {
    0% {
        transform: rotate(0deg) translate(0, 0) scale(1);
    }

    25% {
        transform: rotate(90deg) translate(6%, -5%) scale(1.08);
    }

    50% {
        transform: rotate(180deg) translate(-5%, 6%) scale(0.95);
    }

    75% {
        transform: rotate(270deg) translate(-6%, -4%) scale(1.06);
    }

    100% {
        transform: rotate(360deg) translate(0, 0) scale(1);
    }
}

@keyframes speaker-aurora-b {
    0% {
        transform: rotate(0deg) translate(0, 0) scale(1.04);
    }

    25% {
        transform: rotate(-90deg) translate(-7%, 4%) scale(0.96);
    }

    50% {
        transform: rotate(-180deg) translate(5%, -6%) scale(1.1);
    }

    75% {
        transform: rotate(-270deg) translate(4%, 6%) scale(0.98);
    }

    100% {
        transform: rotate(-360deg) translate(0, 0) scale(1.04);
    }
}


/* ---------- Expectation ----------
   สรุปขนาดของงานแบบนิตยสาร: พื้นที่ขาว ตัวเลขเด่น และใช้เส้นบางแบ่งจังหวะแทนกรอบการ์ด */
.expectation {
    --bt-expectation-title-size: var(--section-title-size);
    --bt-expectation-stat-size: var(--section-title-size);
    --bt-expectation-stat-line-height: var(--section-title-line-height);
    --bt-expectation-bg: var(--color-neutral-50);

    /* ความยาวของเส้นคั่นระหว่างช่อง (ดู .expectation__stat::before)
       เพดานอยู่ที่ ~150px เพราะเนื้อหาสูง 103px และช่องไฟระหว่างสองแถวมี 48px
       ถ้าเส้นยาวกว่านั้นส่วนที่ยื่นเกินของแถวบน-ล่างจะไล่มาชนกันจนดูรก */
    --expectation-rule-length: 80px;

    /* scroll-driven expand ขาออกอย่างเดียว (data-scroll-expand-exit="only", js/scroll-expand.js)
       ปกติเต็มจอ พอขอบล่างเลื่อนขึ้นจากขอบล่างจอไปถึงกลางจอ ค่อย ๆ หดเป็นแผงขอบมน
       ค่าชุดเดียวกับ .playbook (0.898 เท่า มุม 32px) ยึดขอบล่างไว้ให้ติดกับ section ถัดไป */
    --bt-expectation-expand-min: 0.898;
    --bt-expectation-expand-radius: var(--space-8);
    --bt-scroll-expand: 1;
    --bt-expectation-expand-scale: calc(var(--bt-expectation-expand-min) + (1 - var(--bt-expectation-expand-min)) * var(--bt-scroll-expand));

    padding: var(--section-padding-y) 0;
    border-radius: calc((1 - var(--bt-scroll-expand)) * var(--bt-expectation-expand-radius) / var(--bt-expectation-expand-scale));
    color: var(--color-text-primary);
    background: var(--bt-expectation-bg);
    font-family: var(--font-family-base);
    scale: var(--bt-expectation-expand-scale);
    transform-origin: center bottom;

    .expectation__header {
        text-align: center;

        h2 {
            margin: 0;
            font-size: var(--bt-expectation-title-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-title-line-height);
            letter-spacing: var(--section-title-tracking);
        }
    }

    /* ใช้ Bootstrap row/column เป็นโครงหลัก เส้นตั้งวางที่ขอบ column จึงคงแนวตรงกันทุกขนาด */
    .expectation__stats {
        margin-top: var(--space-16);
        row-gap: var(--space-12);
    }

    .expectation__stat {
        position: relative;
        display: flex;
        min-width: 0;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        text-align: center;

        /* เส้นคั่นเป็นภาพเส้น-ดาวที่วาดมาเป็นแนวนอน จึงต้องหมุน 90° เอา
           กล่องเลยกว้าง = ความยาวเส้น และสูง = ความยาวหารอัตราส่วนภาพ (1023:112 ≈ 9.13)
           ต่างจากเส้น 1px เดิมตรงที่ยืดตามความสูงเนื้อหาเองไม่ได้แล้ว ต้องกำหนดความยาว
           ตายตัวผ่าน --expectation-rule-length แล้วปรับเป็นช่วง ๆ ตามขนาดจอ */
        &::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 0;
            width: var(--expectation-rule-length);
            height: calc(var(--expectation-rule-length) / 9.13);
            background: url('../images/line-star.webp') center / contain no-repeat;
            transform: translate(-50%, -50%) rotate(90deg);
        }

        &:first-child::before {
            display: none;
        }

        /* Desktop แถวที่สองเริ่มจากรายการที่ 4 */
        &:nth-child(4)::before {
            display: none;
        }

        strong {
            font-size: var(--bt-expectation-stat-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--bt-expectation-stat-line-height);
            letter-spacing: 0;
        }

        span {
            color: var(--color-text-muted);
            margin-top: var(--space-3);
            font-size: var(--section-body-size);
            font-weight: var(--font-weight-light);
            line-height: var(--section-body-line-height);
            letter-spacing: 0;
        }

        /* ลำดับการอ่านในแต่ละช่อง: ตัวเลข → ป้ายไทย → ป้ายอังกฤษ
           ป้ายไทยเป็นบรรทัดหลักจึงใช้สีหมึกเต็มและน้ำหนักปกติ ส่วนอังกฤษยังเป็นบรรทัดรอง
           (สีจาง น้ำหนักบาง) ตามค่าเดิม — ขนาดตัวอักษรใช้สเกลเดิมทุกเบรกพอยต์ ไม่แตะดีไซน์ */
        span.expectation__stat-label-th {
            color: var(--color-text-primary);
            font-weight: var(--font-weight-regular);
        }

        span.expectation__stat-label-th+span {
            margin-top: 2px;
        }

        /* เครื่องหมาย + ท้ายตัวเลข: รับขนาด/น้ำหนักจากตัวเลข ไม่รับค่าของป้ายข้อความ (span) ด้านบน เปลี่ยนแค่สี */
        strong .expectation__stat-suffix {
            margin-top: 0;
            color: var(--color-blue-600);
            font: inherit;
            letter-spacing: inherit;
        }
    }

    @media (max-width: 991px) {
        --bt-expectation-stat-size: var(--section-heading-size);

        /* ตัวเลขเล็กลงตามกฎด้านล่าง เนื้อหาจึงเตี้ยลงเหลือ ~92px
           ถ้าคงเส้นไว้ที่ 135px ส่วนที่ยื่นเกินจะเหลือช่องไฟระหว่างแถวแค่ 5px */
        --expectation-rule-length: 72px;

        padding: var(--section-padding-y-sm) 0;

        .expectation__stats {
            margin-top: var(--space-12);
            row-gap: var(--space-8);
            justify-content: center;
        }

        /* ที่ต่ำกว่า desktop รายการที่ 7 เริ่มแถวสุดท้าย */
        .expectation__stat:nth-child(7)::before {
            display: none;
        }
    }

    @media (max-width: 767px) {
        --bt-expectation-title-size: var(--section-heading-size);
        --bt-expectation-stat-size: var(--font-size-32);
        --expectation-rule-length: 64px;

        .expectation__stat {
            span {
                font-size: var(--section-body-size);
                line-height: var(--section-body-line-height);
            }
        }

    }

    @media (max-width: 575px) {
        .expectation__stats {
            row-gap: var(--space-6);
        }

        .expectation__stat {
            flex: 0 0 auto;
            width: 50%;
        }

        .expectation__stat:nth-child(odd)::before {
            display: none;
        }

        .expectation__stat:nth-child(even)::before {
            display: block;
        }

        .expectation__stat span {
            font-size: var(--section-small-size);
        }
    }
}


/* ---------- Floor Plan ----------
   แสดงหัวข้อและภาพแผนผังบูทเต็มความกว้างของ Bootstrap container */
.floor-plan {
    --bt-floor-plan-title-size: var(--section-title-size);
    --bt-floor-plan-zone-label-size: var(--font-size-36);
    --bt-floor-plan-line-width: var(--border-width-2);
    --bt-floor-plan-image-offset: var(--space-6);
    --bt-floor-plan-callout-offset: var(--space-2);
    --bt-floor-plan-image-duration: calc(var(--duration-slow) + var(--duration-standard) + var(--duration-fast));
    --bt-floor-plan-callout-duration: calc(var(--duration-slow) + var(--duration-base));
    --bt-floor-plan-callout-start-delay: var(--bt-floor-plan-callout-duration);
    --bt-floor-plan-callout-step-delay: calc(var(--duration-base) + var(--duration-fast));

    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    /* หัวข้อเป็นสองบรรทัดเหมือน section อื่น จึงใช้ title-line-height (140%)
       ไม่ใช่ display-line-height (88px) ที่ตั้งไว้ตอนยังเป็นบรรทัดเดียว ไม่งั้นสองบรรทัดจะห่างเกิน */
    .floor-plan__title {
        margin: 0;
        font-size: var(--bt-floor-plan-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-title-line-height);
        letter-spacing: 0;
    }

    .floor-plan__figure {
        position: relative;
        margin: var(--space-12) 0 0;
    }

    /* ภาพฐานและ callout ใช้ viewBox เดียวกัน จึงย่อขยายพร้อมกันโดยตำแหน่งไม่คลาด */
    .floor-plan__visual {
        position: relative;
        width: 90%;
        margin-inline: auto;
    }

    .floor-plan__image {
        display: block;
        width: 100%;
        height: auto;
    }

    .floor-plan__callouts {
        position: absolute;
        inset: 0;
        display: block;
        width: 100%;
        height: 100%;
        overflow: visible;
        pointer-events: none;
    }

    .floor-plan__callout-line {
        fill: none;
        stroke: var(--color-neutral-400);
        stroke-width: var(--bt-floor-plan-line-width);
        vector-effect: non-scaling-stroke;
    }

    .floor-plan__callout-label {
        fill: var(--color-blue-600);
        font-family: var(--font-family-heading);
        font-size: var(--bt-floor-plan-zone-label-size);
        font-weight: var(--font-weight-medium);
        letter-spacing: 0;
    }

    /* ซ่อนเฉพาะเมื่อ JavaScript พร้อมทำ reveal เพื่อให้เนื้อหายังแสดงหาก JS ไม่ทำงาน */
    &.is-reveal-ready {
        .floor-plan__image {
            opacity: 0;
            transform: translateY(var(--bt-floor-plan-image-offset));
        }

        .floor-plan__callout-line {
            stroke-dasharray: var(--floor-plan-line-length);
            stroke-dashoffset: var(--floor-plan-line-length);
        }

        .floor-plan__callout-mark,
        .floor-plan__callout-label {
            opacity: 0;
        }

        .floor-plan__callout-mark {
            transform-box: fill-box;
            transform-origin: center;
            transform: scale(0.72);
        }

        .floor-plan__callout-label {
            transform: translateY(var(--bt-floor-plan-callout-offset));
        }
    }

    &.is-reveal-ready.is-visible {
        .floor-plan__image {
            opacity: 1;
            transform: translateY(0);
            transition:
                opacity var(--bt-floor-plan-image-duration) var(--ease-standard),
                transform var(--bt-floor-plan-image-duration) var(--ease-standard);
        }

        .floor-plan__callout-line {
            stroke-dashoffset: 0;
            transition: stroke-dashoffset var(--bt-floor-plan-callout-duration) var(--ease-standard);
        }

        .floor-plan__callout-mark {
            opacity: 1;
            transform: scale(1);
            transition:
                opacity var(--bt-floor-plan-callout-duration) var(--ease-standard),
                transform var(--bt-floor-plan-callout-duration) var(--ease-standard);
        }

        .floor-plan__callout-label {
            opacity: 1;
            transform: translateY(0);
            transition:
                opacity var(--bt-floor-plan-callout-duration) var(--ease-standard),
                transform var(--bt-floor-plan-callout-duration) var(--ease-standard);
        }

        /* Callouts reveal by layer: every line, then every star, then every label. */
        .floor-plan__callout-line {
            transition-delay: var(--bt-floor-plan-callout-start-delay);
        }

        .floor-plan__callout-mark {
            transition-delay: calc(var(--bt-floor-plan-callout-start-delay) + var(--bt-floor-plan-callout-step-delay));
        }

        .floor-plan__callout-label {
            transition-delay: calc(var(--bt-floor-plan-callout-start-delay) + var(--bt-floor-plan-callout-step-delay) + var(--bt-floor-plan-callout-step-delay));
        }
    }

    @media (max-width:991px) {
        padding: var(--section-padding-y-sm) 0;

        /* จอเล็กคืนความกว้างเต็ม ย่ออีก 20% แล้วชื่อโซนในแผนผังจะอ่านไม่ออก */
        .floor-plan__visual {
            width: 100%;
        }
    }

    /* ลดหัวข้อลงเท่า Expectation/Concept ที่ทำไว้แล้ว ถ้าคง 48px ไว้บนจอ 375px
       จะเหลือที่ราว 16 ตัวอักษรต่อบรรทัด หัวข้อจึงตัดคำจนมีคำห้อยท้ายบรรทัดเดียวโดด ๆ */
    @media (max-width: 767px) {
        --bt-floor-plan-title-size: var(--section-heading-size);
        --bt-floor-plan-zone-label-size: var(--font-size-48);
    }

    @media (prefers-reduced-motion: reduce) {

        .floor-plan__image,
        .floor-plan__callout-line,
        .floor-plan__callout-mark,
        .floor-plan__callout-label {
            opacity: 1;
            transform: none;
            transition: none;
        }
    }
}


/* ---------- Sponsor & Partners ----------
   กรอบเปล่ารอใส่โลโก้จริงภายหลัง ขนาดตามดีไซน์คุมด้วยแทร็กของกริด (minmax) กรอบจึงหด
   ตามจอแคบได้เองโดยยังคงสัดส่วนเดิมไว้ด้วย aspect-ratio ไม่ต้องล็อกความสูงเป็น px */
.sponsor {
    --bt-sponsor-lead-width: 258px;
    --bt-sponsor-lead-ratio: 258 / 120;
    --bt-sponsor-md-width: 192px;
    --bt-sponsor-md-ratio: 192 / 90;
    --bt-sponsor-sm-width: 90px;
    --bt-sponsor-sm-ratio: 90 / 62;
    --bt-sponsor-sm-columns: 6;
    --bt-sponsor-frame-bg: #eaeaea;

    padding: var(--section-padding-y) 0;
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .sponsor__group:not([hidden])~.sponsor__group:not([hidden]) {
        margin-top: var(--space-20);
    }

    /* หน้าตาตัวอักษรมาจาก .bt-section-title ทั้งหมด (ฟอนต์/ขนาด/น้ำหนัก/line-height/tracking)
       ให้เหมือนหัวข้อของ section อื่น ที่นี่เหลือแค่ระยะห่างกับการจัดกึ่งกลางตามเลย์เอาต์ของ section นี้ */
    .sponsor__group-title {
        margin: 0 0 var(--space-8);
        text-align: center;
        text-transform: uppercase;
    }

    .sponsor__image {
        width: 100%;
        max-width: 610px;
        height: auto;
        margin: 0 auto;
        display: block;
        filter: drop-shadow(0 clamp(0.5px, 0.16vw, 1px) clamp(1.5px, 0.5vw, 3px) rgba(7, 16, 28, 0.04));
    }

    .sponsor__logos {
        margin: 0;
        padding: 0;
        display: grid;
        justify-content: center;
        gap: var(--space-3);
        list-style: none;
    }

    /* Sponsors มีสองแถว (3 ช่องใหญ่ + 12 ช่องเล็ก) อยู่คนละ <ul> จึงต้องคั่นระยะเอง */
    .sponsor__logos+.sponsor__logos {
        margin-top: var(--space-3);
    }

    .sponsor__logos--lead {
        grid-template-columns: minmax(0, var(--bt-sponsor-lead-width));
    }

    .sponsor__logos--md {
        grid-template-columns: repeat(3, minmax(0, var(--bt-sponsor-md-width)));
    }

    .sponsor__logos--sm {
        grid-template-columns: repeat(var(--bt-sponsor-sm-columns), minmax(0, var(--bt-sponsor-sm-width)));
        gap: var(--space-3);
    }

    /* กรอบเปล่า: วาง <img> เข้าไปทีหลังได้เลย รูปจะ contain อยู่ในกรอบเองไม่ล้นและไม่ยืดเสียสัดส่วน */
    .sponsor__logo {
        width: 100%;
        display: grid;
        place-items: center;
        overflow: hidden;
        padding: var(--space-2);
        border-radius: var(--card-radius);
        background: var(--bt-sponsor-frame-bg);
    }

    .sponsor__logo--lead {
        aspect-ratio: var(--bt-sponsor-lead-ratio);
    }

    .sponsor__logo--md {
        aspect-ratio: var(--bt-sponsor-md-ratio);
    }

    .sponsor__logo--sm {
        aspect-ratio: var(--bt-sponsor-sm-ratio);
    }

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

    /* กฎย่อขนาดหัวข้อของส่วนกลางเจาะจงไว้ที่ h2.bt-section-title เท่านั้น หัวข้อกลุ่มที่นี่
       เป็น h3 (ลำดับหัวข้อถูกต้องเพราะซ้อนอยู่ใต้ h2 ของ section) จึงต้องไล่ขนาดเองให้ตรงกัน
       ไม่งั้นจอเล็กจะค้างที่ 48px ขณะที่หัวข้อ section อื่นย่อลงไปแล้ว */
    @media (max-width: 991px) {
        .sponsor__group-title {
            --bt-section-title-size: var(--font-size-40);
        }
    }

    /* ช่องเล็กเรียง 6 ต่อแถวตามดีไซน์ ลดจำนวนคอลัมน์ลงตามจอแทนที่จะปล่อยให้บีบจนโลโก้เล็กเกินอ่าน */
    @media (max-width: 767px) {

        padding: var(--section-padding-y-sm) 0;

        .sponsor__group:not([hidden])~.sponsor__group:not([hidden]) {
            margin-top: var(--space-12);
        }

        .sponsor__group-title {
            --bt-section-title-size: var(--font-size-32);

            margin-bottom: var(--space-6);
        }
    }

    @media (max-width: 575px) {

        /* ต่ำกว่านี้ช่องขนาดกลาง/เล็กถูกแทร็กของกริดบีบให้เล็กลงตามความกว้างจอ (ราว 0.62 เท่า)
           แต่ Title Sponsor มีคอลัมน์เดียวจึงยังกางเต็ม 258px อยู่ เลยดูใหญ่เกินสัดส่วนช่องอื่น
           ผูกความกว้างไว้กับแทร็กจริงของช่องขนาดกลาง แล้วคูณอัตราส่วนเดิมของดีไซน์กลับเข้าไป
           ทุกช่องจึงย่อลงพร้อมกันด้วยอัตราเดียวกัน ความสูงตามมาเองจาก aspect-ratio
           min() ทำให้ตอนจอยังกว้างพอ (ใกล้ 575px) ได้ 258px เท่าเดิม ไม่กระโดดตรงรอยต่อ
           เลข 258/188 คือค่าของ --bt-sponsor-lead-width กับ --bt-sponsor-md-width ด้านบน
           (calc หารความยาวด้วยความยาวเป็นตัวเลขไม่ได้ จึงต้องเขียนซ้ำ) ถ้าแก้สองค่านั้นต้องแก้ตรงนี้ด้วย */
        --bt-sponsor-lead-width:
            calc(min(var(--bt-sponsor-md-width), (100% - var(--space-1) * 2) / 3) * 258 / 188);

        .sponsor__group-title {
            --bt-section-title-size: var(--font-size-28);
        }

        .sponsor__logos+.sponsor__logos {
            margin-top: var(--space-1);
        }

        .sponsor__logos {
            gap: var(--space-1);
        }

        .sponsor__logos--sm {
            gap: var(--space-1);
        }
    }
}


/* ---------- Footer ----------
   ส่วนปิดท้ายแบบ contact module สำหรับงาน event แสดงเฉพาะช่องทางติดต่อและผู้สนับสนุน */
.site-footer {
    padding: var(--section-padding-y-sm) 0 0;
    color: var(--bt-footer-ink);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .site-footer__inner {
        padding-right: calc(var(--bs-gutter-x) * 0.5 + var(--space-10));
        padding-left: calc(var(--bs-gutter-x) * 0.5 + var(--space-10));
    }

    .site-footer__panel {
        position: relative;
        isolation: isolate;
        overflow: hidden;
        /* ด้านล่างแคบกว่าด้านบน เพื่อให้บรรทัดสรุปงานอยู่ชิดขอบล่างของแผง */
        padding: var(--space-16) 0 var(--space-4);
        border-radius: var(--radius-1);
        background:
            radial-gradient(35% 80% at 30% 0%, rgba(115, 130, 170, 0.28), transparent),
            linear-gradient(180deg, #19274A 0%, #020B1E 100%);

        &::before,
        &::after {
            content: "";
            position: absolute;
            pointer-events: none;
        }

        &::before {
            top: calc(var(--space-10) * -1);
            left: 50%;
            z-index: 0;
            width: min(78%, 900px);
            height: min(76%, 280px);
            background:
                radial-gradient(ellipse at 50% 0%, rgba(244, 221, 178, 0.3) 0%, rgba(214, 171, 104, 0.16) 30%, rgba(115, 130, 170, 0.1) 56%, transparent 78%);
            filter: blur(20px);
            opacity: 0.94;
            transform: translateX(-50%);
        }

        &::after {
            top: var(--space-0);
            left: 50%;
            z-index: 0;
            width: min(58%, 680px);
            height: var(--border-width-2);
            background: linear-gradient(90deg,
                    transparent 0%,
                    rgba(244, 221, 178, 0.16) 14%,
                    rgba(231, 201, 151, 0.88) 50%,
                    rgba(214, 171, 104, 0.2) 86%,
                    transparent 100%);
            box-shadow:
                0 0 16px rgba(231, 201, 151, 0.42),
                0 0 34px rgba(214, 171, 104, 0.2);
            opacity: 0.9;
            transform: translateX(-50%);
        }
    }

    .site-footer__content {
        position: relative;
        z-index: 1;
        align-items: stretch;
        /* gutter เดิมของ Bootstrap (1.5rem รวม = 12px ต่อฝั่ง) แคบเกินไปสำหรับ
           border-left ที่ทำหน้าที่เป็นเส้นแบ่ง section — โลโก้ (แคบ) กับหัวข้อ
           "Booths & Sponsors" (เกือบเต็มคอลัมน์) กว้างต่างกันมาก พอเจอ gutter แคบ
           เส้นเลยดูเหมือนแปะติดฝั่งขวาตลอด ไม่ใช่เส้นแบ่งกลางที่เป็นกลาง */
        --bs-gutter-x: var(--space-16);
    }

    .site-footer__logo {
        display: block;
        margin-bottom: var(--space-6);
        width: min(100%, var(--bt-footer-logo-width));
        height: auto;
    }

    .site-footer__column {
        min-width: 0;
        margin: var(--space-0);
        border-left: var(--rule-width-subtle) solid var(--bt-footer-line);
    }

    /* The contact column is first now that the logo lives inside it instead of its own
       column, so it no longer needs a leading rule at any width. */
    .site-footer__column:first-of-type {
        border-left: 0;
    }

    .site-footer__eyebrow {
        margin: var(--space-0);
        font-size: var(--section-body-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-body-line-height);
        letter-spacing: 0;
        text-transform: uppercase;
    }

    /* บรรทัดสรุปงานปิดท้าย footer อยู่ล่างสุดและจัดกึ่งกลาง
       ต้องมี z-index เพราะฉากเรืองแสงของแผง (::before/::after) เป็น element ที่ positioned */
    .site-footer__summary {
        position: relative;
        z-index: 1;
        margin: var(--space-12) var(--space-0) var(--space-0);
        padding-top: var(--space-4);
        border-top: var(--rule-width-subtle) solid var(--bt-footer-line);
        color: var(--bt-footer-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-small-line-height);
        text-align: center;
    }

    h3 {
        margin: 0;
        color: var(--bt-footer-ink);
        font-size: var(--section-subheading-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-topic-line-height);
        letter-spacing: 0;
    }

    .site-footer__contact-list,
    .site-footer__person {
        font-style: normal;
    }

    .site-footer__contact-list {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-6);
        margin: var(--space-0);
        padding-top: var(--space-4);
        /* border-top: var(--rule-width-subtle) solid var(--bt-footer-line); */

        a {
            display: inline-flex;
            gap: var(--space-3);
            align-items: center;
            color: var(--bt-footer-ink);
            text-decoration: none;
            transition:
                color var(--duration-base) var(--ease-standard),
                opacity var(--duration-base) var(--ease-standard);

            &:hover {
                opacity: 0.64;
            }

            &:focus-visible {
                color: var(--color-category-cyan);
                outline: var(--border-width-2) solid var(--color-category-cyan);
                outline-offset: var(--space-1);
            }
        }

        .site-footer__contact-icon {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            color: var(--bt-footer-muted);

            .bt-icon {
                width: var(--bt-icon-size);
                height: var(--bt-icon-size);
            }
        }

        strong {
            min-width: 0;
            white-space: nowrap;
            font-size: var(--section-body-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--section-body-line-height);
        }

    }

    .site-footer__people {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-8);
        margin: var(--space-0);
        padding-top: var(--space-4);
        /* border-top: var(--rule-width-subtle) solid var(--bt-footer-line); */
    }

    .site-footer__person {
        display: grid;
        gap: var(--space-1);
        margin: 0;
        padding-top: var(--space-4);

        p,
        a {
            margin: 0;
            font-size: var(--section-body-size);
            line-height: var(--section-body-line-height);
        }

        p {
            color: var(--bt-footer-ink);
            font-weight: var(--font-weight-regular);
        }

        p span {
            color: var(--bt-footer-muted);
            font-weight: var(--font-weight-light);
        }

        a {
            display: inline-flex;
            align-items: center;
            gap: var(--space-3);
            width: fit-content;
            color: var(--bt-footer-ink);
            font-weight: var(--font-weight-light);
            white-space: nowrap;
            text-decoration: none;
            transition:
                color var(--duration-base) var(--ease-standard),
                opacity var(--duration-base) var(--ease-standard);

            &:hover {
                opacity: 0.64;
            }

            &:focus-visible {
                color: var(--color-category-cyan);
                outline: var(--border-width-2) solid var(--color-category-cyan);
                outline-offset: var(--space-1);
            }
        }

        .site-footer__contact-icon {
            display: inline-flex;
            flex: none;
            align-items: center;
            justify-content: center;
            color: var(--bt-footer-muted);

            .bt-icon {
                width: var(--bt-icon-size);
                height: var(--bt-icon-size);
            }
        }
    }

    @media (max-width: 1350px) {

        .site-footer__contact-list strong,
        .site-footer__person a {
            font-size: var(--font-size-14);
        }
    }

    @media (max-width: 1199px) {
        .site-footer__people {
            grid-template-columns: 1fr;
            gap: var(--space-4);
        }

        .site-footer__contact-list {
            grid-template-columns: 1fr;
            gap: var(--space-4);
        }

        .site-footer__contact-list strong,
        .site-footer__person a {
            font-size: var(--font-size-16);
        }
    }

    @media (max-width: 991px) {
        .site-footer__panel {
            padding: var(--space-6) 0;
            background:
                radial-gradient(circle at 30% 0%, rgba(115, 130, 170, 0.28), transparent 48%),
                linear-gradient(180deg, #19274A 0%, #020B1E 100%);
        }

        .site-footer__inner {
            padding-right: calc(var(--bs-gutter-x) * 0.5 + var(--space-8));
            padding-left: calc(var(--bs-gutter-x) * 0.5 + var(--space-8));
        }

        .site-footer__column {
            flex: 0 0 100%;
            max-width: 100%;
            padding-top: var(--space-8);
            padding-bottom: var(--space-8);
            border-top: var(--rule-width-subtle) solid var(--bt-footer-line);
            border-left: 0;
        }

        .site-footer__column:first-of-type {
            border-top: none;
        }

        .site-footer__people {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }

        .site-footer__contact-list {
            grid-template-columns: repeat(2, 1fr);
        }

        .site-footer__person {
            padding-top: 0;
        }
    }

    @media (max-width: 767px) {
        .site-footer__people {
            grid-template-columns: 1fr;
            gap: var(--space-6);
            padding-top: var(--space-10);
        }

        .site-footer__person {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: var(--space-2) var(--space-10);

            p {
                grid-column: span 2;
            }
        }

        .site-footer__contact-list {
            gap: var(--space-4) var(--space-10);
        }
    }

    @media (max-width: 575px) {
        .site-footer__inner {
            padding-right: calc(var(--bs-gutter-x) * 0.5 + var(--space-3));
            padding-left: calc(var(--bs-gutter-x) * 0.5 + var(--space-3));
        }

        .site-footer__summary {
            margin: var(--space-0);
        }

        .site-footer__panel {
            padding-bottom: calc(var(--space-20) + max(var(--space-3), env(safe-area-inset-bottom)));
        }

        .site-footer__contact-list {
            grid-template-columns: 1fr;
        }

        .site-footer__people {
            padding-top: var(--space-6);
        }

        .site-footer__person {
            grid-template-columns: 1fr;

            p {
                grid-column: auto;
            }
        }
    }
}

@media (prefers-reduced-motion:reduce) {

    .site-header__mobile,
    .site-header__mobile-scroll,
    .site-header__backdrop,
    .site-header__toggle-lines span,
    .bt-action-button,
    .site-header__nav a::after {
        transition-duration: 0.01ms;
    }

    .site-header {
        transition-duration: 0.01ms;
    }

    .agenda__tab-indicator {
        transition-duration: var(--duration-reduced) !important;
    }

    .faq__tab-indicator {
        transition-duration: var(--duration-reduced) !important;
    }
}


/* Keep the Ticket subtext intact in Safari, where an anonymous flex text item
   can otherwise wrap before the decorative rule has yielded its available width. */
#ticket .bt-section-subtext {
    flex-wrap: nowrap;
    white-space: nowrap;
}

#ticket .bt-section-subtext::after {
    flex: 0 1 var(--bt-subtext-rule-length);
    min-width: var(--space-8);
}

/* Journey indicator: a passive route map from Concept to Past Event. */
.journey-indicator {
    --journey-progress: 0%;
    --journey-edge-gap: var(--space-28);
    --journey-title-length: 160px;
    --journey-track-color: rgba(17, 19, 24, 0.20);
    --journey-track-background: var(--journey-track-color);
    --journey-title-background: var(--color-neutral-900);
    --journey-label-color: var(--color-neutral-900);
    --journey-label-background: var(--bt-journey-label-bg);
    --journey-label-offset: var(--space-3);
    --journey-marker-size: var(--bt-journey-label-star-size);

    position: fixed;
    top: max(var(--journey-edge-gap), env(safe-area-inset-top));
    right: auto;
    bottom: max(var(--journey-edge-gap), env(safe-area-inset-bottom));
    left: max(var(--space-2), env(safe-area-inset-left));
    z-index: 230;
    display: block;
    opacity: 0;
    pointer-events: none;
    transform: translate3d(-12px, 0, 0);
    transition:
        opacity var(--duration-standard) var(--ease-standard),
        transform var(--duration-standard) var(--ease-standard);
}

.journey-indicator.is-visible {
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

.journey-indicator.is-marker-on-dark {
    --journey-label-color: var(--color-neutral-0);
    --journey-label-background: var(--bt-journey-label-bg-dark);
}


.journey-indicator__title {
    position: absolute;
    /* กล่องนี้ยังไม่ได้หมุน วางเลื่อนลงมาตามความยาวของคำ (--journey-title-length) แล้วค่อย
       หมุน -90deg รอบจุด left center ด้านล่างเพื่อให้กลายเป็นตัวหนังสือแนวตั้งพาดขึ้นด้านบน
       ค่าคงที่ 24px เดิมทำให้ปลายบนของตัวหนังสือหลังหมุนย้อนขึ้นไปทับ header sticky (สูง 80px)
       อยู่ประมาณ 18px เปลี่ยนเป็นค่าบวกเพื่อดันกล่องลงมาก่อนหมุน ให้ปลายบนเคลียร์ header
       พร้อมเว้นช่องว่างอีก 8px (ตัวเลขนี้ผูกกับความสูง header ปัจจุบันเท่านั้น ถ้า header
       สูงเปลี่ยนไปมากต้องคำนวณค่านี้ใหม่) */
    top: calc(var(--journey-title-length) + -8px);
    left: 16px;
    color: transparent;
    background: var(--journey-title-background);
    -webkit-background-clip: text;
    background-clip: text;
    font-size: var(--font-size-12);
    font-weight: var(--font-weight-regular);
    line-height: 1;
    letter-spacing: 0.1em;
    white-space: nowrap;
    transform: rotate(-90deg);
    transform-origin: left center;
    -webkit-text-fill-color: transparent;
}

.journey-indicator__rail {
    position: absolute;
    top: calc(var(--journey-title-length) + var(--space-3));
    bottom: 0;
    left: 0;
    width: 32px;
}

.journey-indicator__rail::after {
    content: '';
    position: absolute;
    top: var(--journey-progress);
    left: 50%;
    z-index: 2;
    width: var(--journey-marker-size);
    height: var(--journey-marker-size);
    background: url('../images/star.webp') center / contain no-repeat;
    filter: drop-shadow(0 2px 6px rgba(17, 19, 24, 0.20));
    opacity: 0;
    transform: translate(-50%, -50%);
    transition: opacity var(--duration-fast) var(--ease-standard);
    pointer-events: none;
    will-change: top;
}

.journey-indicator.is-marker-visible .journey-indicator__rail::after {
    opacity: 1;
}

.journey-indicator.is-marker-changing .journey-indicator__rail::after {
    animation: journey-marker-in var(--duration-standard) var(--ease-standard);
}

.journey-indicator__track,
.journey-indicator__progress {
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: 100%;
    border-radius: var(--radius-round);
    transform: translateX(-50%);
}

.journey-indicator__track {
    background: var(--journey-track-background);
    transition: background-color var(--duration-fast) var(--ease-standard);
}

.journey-indicator__progress {
    background: var(--gradient-spectrum-vertical);
    clip-path: inset(0 0 calc(100% - var(--journey-progress)) 0 round var(--radius-round));
}

.journey-indicator__label {
    position: absolute;
    top: var(--journey-progress);
    left: calc(50% + var(--journey-label-offset));
    color: var(--journey-label-color);
    font-size: var(--font-size-14);
    font-weight: var(--font-weight-regular);
    line-height: 1;
    letter-spacing: 0.02em;
    padding: var(--bt-journey-label-padding-y) var(--bt-journey-label-padding-x);
    border-radius: var(--bt-journey-label-radius);
    background: var(--journey-label-background);
    box-shadow: var(--bt-journey-label-shadow);
    white-space: nowrap;
    opacity: 0;
    transform: translateY(-50%);
    transition:
        color var(--duration-fast) var(--ease-standard),
        background-color var(--duration-fast) var(--ease-standard),
        opacity var(--duration-fast) var(--ease-standard);
}

.journey-indicator__label::before {
    content: none;
}

.journey-indicator__label.is-visible {
    opacity: 1;
}

.journey-indicator__label.is-changing {
    animation: journey-label-in var(--duration-standard) var(--ease-standard);
}

@keyframes journey-label-in {
    from {
        opacity: 0;
        transform: translate(-8px, -50%);
    }
}

@keyframes journey-marker-in {
    from {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.72);
    }
}

@media (max-width: 991px) {
    .journey-indicator {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .journey-indicator {
        transition-duration: var(--duration-reduced);
    }

    .journey-indicator__label.is-changing {
        animation: none;
    }

    .journey-indicator.is-marker-changing .journey-indicator__rail::after {
        animation: none;
    }
}

/* ---------- Playbook ---------- grid-layered artwork with responsive content flow */
.playbook {
    --bt-playbook-content-top-space: calc(var(--space-32) - var(--space-3));
    --bt-playbook-content-bottom-space: calc(var(--space-32) - var(--space-3));
    --bt-playbook-content-middle-space: var(--space-0);
    --bt-playbook-content-scale: 1;
    --bt-playbook-header-scale: var(--bt-playbook-content-scale);
    --bt-playbook-steps-scale: var(--bt-playbook-content-scale);
    --bt-playbook-artboard-width: 100%;
    --bt-playbook-artboard-fixed-width: calc(var(--space-32) * 7 + var(--space-24) - var(--border-width-1));
    --bt-playbook-artboard-aspect-ratio: 2490 / 1720;
    --bt-playbook-title-overlap-base: var(--space-3);
    --bt-playbook-title-base-size: var(--font-size-80);
    --bt-playbook-subtitle-space-base: var(--space-6);
    --bt-playbook-subtitle-base-size: var(--font-size-24);
    --bt-playbook-title-art-base-width: calc(var(--space-32) * 6.5 - var(--space-2));
    --bt-playbook-title-overlap: calc(var(--bt-playbook-title-overlap-base) * var(--bt-playbook-header-scale));
    --bt-playbook-title-size: max(var(--font-size-32), calc(var(--bt-playbook-title-base-size) * var(--bt-playbook-header-scale)));
    --bt-playbook-title-color: inherit;
    --bt-playbook-title-shine: linear-gradient(120deg,
            rgba(255, 255, 255, 0) 40%,
            rgba(255, 255, 255, 0.8) 50%,
            rgba(255, 255, 255, 0) 60%);
    --bt-playbook-subtitle-space: calc(var(--bt-playbook-subtitle-space-base) * var(--bt-playbook-header-scale));
    --bt-playbook-subtitle-size: max(var(--font-size-16), calc(var(--bt-playbook-subtitle-base-size) * var(--bt-playbook-header-scale)));
    --bt-playbook-subtitle-line-height: var(--line-height-normal);
    --bt-playbook-steps-grid: repeat(3, minmax(var(--space-0), 1fr));
    --bt-playbook-steps-gap: var(--space-0);
    --bt-playbook-footer-gap-base: var(--space-8);
    --bt-playbook-step-padding-inline-base: var(--space-8);
    --bt-playbook-step-padding-bottom-base: var(--space-0);
    --bt-playbook-step-number-base-size: var(--font-size-32);
    --bt-playbook-step-title-base-size: var(--font-size-24);
    --bt-playbook-step-copy-base-size: var(--font-size-16);
    --bt-playbook-footer-gap: max(var(--space-6), calc(var(--bt-playbook-footer-gap-base) * var(--bt-playbook-steps-scale)));
    --bt-playbook-steps-container: 1140px;
    --bt-playbook-steps-width: auto;
    --bt-playbook-step-padding-inline: max(var(--space-3), calc(var(--bt-playbook-step-padding-inline-base) * var(--bt-playbook-steps-scale)));
    --bt-playbook-step-padding-bottom: calc(var(--bt-playbook-step-padding-bottom-base) * var(--bt-playbook-steps-scale));
    --bt-playbook-step-number-size: max(var(--font-size-20), calc(var(--bt-playbook-step-number-base-size) * var(--bt-playbook-steps-scale)));
    --bt-playbook-step-title-size: max(var(--font-size-16), calc(var(--bt-playbook-step-title-base-size) * var(--bt-playbook-steps-scale)));
    --bt-playbook-step-copy-size: max(var(--font-size-14), calc(var(--bt-playbook-step-copy-base-size) * var(--bt-playbook-steps-scale)));
    --bt-playbook-step-copy-margin: calc(var(--space-2) + var(--border-width-1)) var(--space-0) var(--space-0);
    --bt-playbook-step-copy-line-height: normal;
    --bt-playbook-divider-top: 50%;
    --bt-playbook-divider-right: var(--space-0);
    --bt-playbook-divider-bottom: auto;
    --bt-playbook-divider-left: auto;
    --bt-playbook-divider-length-base: var(--space-24);
    --bt-playbook-divider-length: max(var(--space-12), calc(var(--bt-playbook-divider-length-base) * var(--bt-playbook-steps-scale)));
    --bt-playbook-divider-aspect-ratio: 9.13;
    --bt-playbook-divider-transform: translate(50%, -50%) rotate(90deg);
    --bt-playbook-divider-filter: invert(1);
    --bt-playbook-bitcoin-x: 19%;
    --bt-playbook-bitcoin-y: 23%;
    --bt-playbook-bitcoin-size: calc(var(--space-32) + var(--space-4));
    --bt-playbook-bitcoin-rotation: -4deg;
    --bt-playbook-gold-x: 79%;
    --bt-playbook-gold-y: 26%;
    --bt-playbook-gold-size: var(--space-28);
    --bt-playbook-gold-rotation: 18deg;
    --bt-playbook-triangle-x: 88%;
    --bt-playbook-triangle-y: 48%;
    --bt-playbook-triangle-size: var(--space-28);
    --bt-playbook-triangle-rotation: -8deg;
    --bt-playbook-heart-x: 84%;
    --bt-playbook-heart-y: 73%;
    --bt-playbook-heart-size: calc(var(--space-32) + var(--space-12));
    --bt-playbook-heart-rotation: 8deg;
    --bt-playbook-stock-x: 11%;
    --bt-playbook-stock-y: 73%;
    --bt-playbook-stock-size: var(--space-20);
    --bt-playbook-stock-rotation: -34deg;
    --bt-playbook-arrow-up-x: 11%;
    --bt-playbook-arrow-up-y: 48%;
    --bt-playbook-arrow-up-size: var(--space-32);
    --bt-playbook-arrow-up-rotation: 0deg;
    --bt-playbook-asset-image-filter: saturate(1.3) drop-shadow(0 var(--space-2) var(--space-3) var(--alpha-ink-34));
    --bt-playbook-title-art-width: calc(var(--bt-playbook-title-art-base-width) * var(--bt-playbook-header-scale));
    --bt-playbook-title-art-max-width: 100%;
    --bt-playbook-title-art-margin-left: auto;
    --bt-playbook-title-art-transform: none;
    --bt-playbook-overlay-background: linear-gradient(180deg, var(--alpha-ink-08) 52%, color-mix(in srgb, var(--color-neutral-900) 58%, transparent) 100%);
    --bt-playbook-ink-soft: color-mix(in srgb, var(--color-neutral-0) 92%, transparent);
    --bt-playbook-ink-dim: color-mix(in srgb, var(--color-neutral-0) 86%, transparent);
    --bt-playbook-step-1-color: #ff5d43;
    --bt-playbook-step-2-color: #ff168d;
    --bt-playbook-step-3-color: #a91cff;
    --bt-playbook-shadow-soft: 0 var(--border-width-2) calc(var(--space-4) + var(--border-width-2)) var(--alpha-ink-34);
    --bt-playbook-shadow-strong: 0 var(--border-width-2) calc(var(--space-3) + var(--border-width-2)) color-mix(in srgb, var(--color-neutral-900) 58%, transparent);
    --bt-playbook-glow-breathe-duration: var(--duration-ambient);
    --bt-playbook-glow-ease: var(--ease-ambient);
    --bt-playbook-glow-base-opacity-low: 0.5;
    --bt-playbook-glow-base-opacity-high: 1;
    --bt-playbook-glow-base-brightness-low: 1.08;
    --bt-playbook-glow-base-brightness-high: 2;
    /* ---------- scroll-driven expand ----------
       แบบเดียวกับ section identity-cards ในหน้า personalized-playbook.html (ดูคำอธิบายเต็มที่นั่น)
       แผงขอบมนกว้าง 0.898 เท่าของจอ ค่อย ๆ ขยายจนเต็มจอตามระยะที่เลื่อน ค่า 0-1 มาจาก
       js/scroll-expand.js ส่วน radius หาร scale กลับไว้ ค่าที่เห็นจริงจึงเท่ากับ px ที่เขียน */
    --bt-playbook-expand-min: 0.898;
    --bt-playbook-expand-radius: var(--space-8);
    --bt-scroll-expand: 1;
    --bt-playbook-expand-scale: calc(var(--bt-playbook-expand-min) + (1 - var(--bt-playbook-expand-min)) * var(--bt-scroll-expand));

    position: relative;
    display: grid;
    /* clip ไม่ใช่ visible: ต้องตัดพื้นหลังและ overlay ให้โค้งตามมุมระหว่างที่ยังไม่ขยายเต็ม */
    overflow: clip;
    isolation: isolate;
    border-radius: calc((1 - var(--bt-scroll-expand)) * var(--bt-playbook-expand-radius) / var(--bt-playbook-expand-scale));
    color: var(--color-neutral-0);
    background: var(--color-neutral-900);
    font-family: var(--font-family-base);
    scale: var(--bt-playbook-expand-scale);
    transform-origin: center top;

    &::after {
        content: '';
        position: absolute;
        inset: var(--space-0);
        z-index: 1;
        background: var(--bt-playbook-overlay-background);
        pointer-events: none;
    }

    .playbook__background,
    .playbook__assets,
    .playbook__scene,
    .playbook__content {
        grid-area: 1 / 1;
    }

    .playbook__background {
        z-index: 0;
        width: 100%;
        max-width: none;
        justify-self: stretch;
        overflow: hidden;
        pointer-events: none;
    }

    .playbook__background picture,
    .playbook__scene picture {
        width: var(--bt-playbook-artboard-width);
        max-width: none;
        display: block;
        margin-inline: auto;
    }

    .playbook__background-image {
        width: var(--bt-playbook-artboard-width);
        max-width: none;
        height: auto;
        display: block;
        margin-inline: auto;
    }

    .playbook__assets {
        position: absolute;
        inset: var(--space-0);
        z-index: 2;
        overflow: hidden;
        pointer-events: none;
    }

    .playbook__assets-artboard {
        position: relative;
        width: var(--bt-playbook-artboard-width);
        max-width: none;
        aspect-ratio: var(--bt-playbook-artboard-aspect-ratio);
        margin-inline: auto;
    }

    .playbook__asset {
        position: absolute;
        top: var(--bt-playbook-asset-y);
        left: var(--bt-playbook-asset-x);
        width: var(--bt-playbook-asset-size);
        display: block;
        transform: translate(-50%, -50%);
    }

    .playbook__asset-motion,
    .playbook__asset-float {
        display: block;
        will-change: transform;
    }

    .playbook__asset-motion {
        will-change: transform, opacity;
    }

    .playbook__asset img {
        width: 100%;
        height: auto;
        display: block;
        filter: var(--bt-playbook-asset-image-filter);
        transform: rotate(var(--bt-playbook-asset-rotation));
    }

    .playbook__asset--bitcoin {
        --bt-playbook-asset-x: var(--bt-playbook-bitcoin-x);
        --bt-playbook-asset-y: var(--bt-playbook-bitcoin-y);
        --bt-playbook-asset-size: var(--bt-playbook-bitcoin-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-bitcoin-rotation);
    }

    .playbook__asset--gold {
        --bt-playbook-asset-x: var(--bt-playbook-gold-x);
        --bt-playbook-asset-y: var(--bt-playbook-gold-y);
        --bt-playbook-asset-size: var(--bt-playbook-gold-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-gold-rotation);
    }

    .playbook__asset--triangle {
        --bt-playbook-asset-x: var(--bt-playbook-triangle-x);
        --bt-playbook-asset-y: var(--bt-playbook-triangle-y);
        --bt-playbook-asset-size: var(--bt-playbook-triangle-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-triangle-rotation);
    }

    .playbook__asset--heart {
        --bt-playbook-asset-x: var(--bt-playbook-heart-x);
        --bt-playbook-asset-y: var(--bt-playbook-heart-y);
        --bt-playbook-asset-size: var(--bt-playbook-heart-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-heart-rotation);
    }

    .playbook__asset--stock {
        --bt-playbook-asset-x: var(--bt-playbook-stock-x);
        --bt-playbook-asset-y: var(--bt-playbook-stock-y);
        --bt-playbook-asset-size: var(--bt-playbook-stock-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-stock-rotation);
    }

    .playbook__asset--arrow-up {
        --bt-playbook-asset-x: var(--bt-playbook-arrow-up-x);
        --bt-playbook-asset-y: var(--bt-playbook-arrow-up-y);
        --bt-playbook-asset-size: var(--bt-playbook-arrow-up-size);
        --bt-playbook-asset-rotation: var(--bt-playbook-arrow-up-rotation);
    }

    .playbook__scene {
        position: relative;
        z-index: 3;
        align-self: start;
        width: 100%;
        max-width: none;
        justify-self: stretch;
        overflow: hidden;
        pointer-events: none;
    }

    .playbook__glow {
        position: absolute;
        top: var(--space-0);
        left: 50%;
        z-index: 0;
        height: 100%;
        opacity: 0;
        transform: translateX(-50%);
        mix-blend-mode: screen;
        pointer-events: none;
    }

    .playbook__glow-image {
        width: var(--bt-playbook-artboard-width);
        max-width: none;
        height: auto;
        display: block;
        margin-inline: auto;
        will-change: opacity, filter;
    }

    .playbook__glow--base .playbook__glow-image {
        animation: playbook-glow-breathe var(--bt-playbook-glow-breathe-duration) var(--bt-playbook-glow-ease) infinite;
        animation-play-state: paused;
    }

    .playbook__glow--base {
        opacity: 1;
    }

    &.playbook--glow-running {
        .playbook__glow--base .playbook__glow-image {
            animation-play-state: running;
        }
    }

    .playbook__book {
        position: relative;
        z-index: 1;
        width: var(--bt-playbook-artboard-width);
        max-width: none;
        height: auto;
        display: block;
        margin-inline: auto;
    }

    .playbook__content {
        z-index: 4;
        align-self: stretch;
        width: 100%;
        height: 100%;
        display: grid;
        grid-template-rows:
            var(--bt-playbook-content-top-space) auto minmax(var(--bt-playbook-content-middle-space), 1fr) auto var(--bt-playbook-content-bottom-space);
    }

    .playbook__header {
        grid-row: 2;
        margin: var(--space-0) auto;
        text-align: center;
        text-shadow: var(--bt-playbook-shadow-soft);

        h2 {
            position: relative;
            margin: var(--bt-playbook-title-overlap) var(--space-0) var(--space-0);
            color: var(--bt-playbook-title-color);
            font-size: var(--bt-playbook-title-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--line-height-1);
            letter-spacing: var(--letter-spacing-0);
        }

        h2::after {
            content: attr(data-shiny-text);
            position: absolute;
            inset: 0;
            color: transparent;
            background: var(--bt-playbook-title-shine);
            background-size: 200% 100%;
            background-position: 100% 50%;
            -webkit-background-clip: text;
            background-clip: text;
            animation: playbook-title-shine 5s linear infinite;
            filter:
                drop-shadow(0 0 0.06em rgba(255, 255, 255, 0.72)) drop-shadow(0 0 0.14em rgba(255, 255, 255, 0.34));
            -webkit-text-fill-color: transparent;
            pointer-events: none;
        }

        p {
            margin: var(--bt-playbook-subtitle-space) var(--space-0) var(--space-0);
            color: var(--alpha-white-96);
            font-size: var(--bt-playbook-subtitle-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--bt-playbook-subtitle-line-height);
        }
    }

    .playbook__title-art {
        max-width: var(--bt-playbook-title-art-max-width);
        width: var(--bt-playbook-title-art-width);
        height: auto;
        display: block;
        margin: var(--space-0) auto;
        margin-left: var(--bt-playbook-title-art-margin-left);
        transform: var(--bt-playbook-title-art-transform);
    }

    .playbook__footer {
        grid-row: 4;
        display: grid;
        gap: var(--bt-playbook-footer-gap);
    }

    .playbook__steps {
        width: var(--bt-playbook-steps-width);
        margin: var(--space-0) auto;
        padding: var(--space-0);
        max-width: var(--bt-playbook-steps-container);
        display: grid;
        grid-template-columns: var(--bt-playbook-steps-grid);
        gap: var(--bt-playbook-steps-gap);
        list-style: none;
    }

    .playbook__step {
        position: relative;
        min-width: var(--space-0);
        padding: var(--space-0) var(--bt-playbook-step-padding-inline) var(--bt-playbook-step-padding-bottom);
        text-align: center;
        text-shadow: var(--bt-playbook-shadow-strong);

        &:not(:last-child)::after {
            content: '';
            position: absolute;
            top: var(--bt-playbook-divider-top);
            right: var(--bt-playbook-divider-right);
            bottom: var(--bt-playbook-divider-bottom);
            left: var(--bt-playbook-divider-left);
            width: var(--bt-playbook-divider-length);
            height: calc(var(--bt-playbook-divider-length) / var(--bt-playbook-divider-aspect-ratio));
            background: url('../images/line-star.webp') center / contain no-repeat;
            filter: var(--bt-playbook-divider-filter);
            transform: var(--bt-playbook-divider-transform);
        }

        strong {
            display: block;
            color: var(--bt-playbook-step-1-color);
            font-size: var(--bt-playbook-step-number-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--line-height-1);
        }

        &:nth-child(2) strong {
            color: var(--bt-playbook-step-2-color);
        }

        &:nth-child(3) strong {
            color: var(--bt-playbook-step-3-color);
        }

        h3 {
            margin: var(--space-2) var(--space-0) var(--space-0);
            color: inherit;
            font-size: var(--bt-playbook-step-title-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--line-height-1);
        }

        p {
            margin: var(--bt-playbook-step-copy-margin);
            color: var(--bt-playbook-ink-soft);
            font-size: var(--bt-playbook-step-copy-size);
            font-weight: var(--font-weight-regular);
            line-height: var(--bt-playbook-step-copy-line-height);
        }
    }

    /* ปุ่ม liquid metal (mount โดย js/hero-v2-cta.js) กับปุ่มดำวางคู่กันในแถวเดียว
       จอแคบตกลงมาเรียงกันเองด้วย flex-wrap */
    .playbook__action {
        /* ความสูงปุ่ม liquid metal ตั้งไว้ใน js/hero-v2-cta.js (height: 56 ปกติ, 46 ที่จอ ≤767px
           และจอนอนเตี้ย) ปุ่มดำข้าง ๆ จึงอ้างค่าเดียวกันไว้ที่นี่ เพื่อให้สูงเท่ากันทั้งสองปุ่ม */
        --bt-playbook-cta-height: 56px;

        display: flex;
        /* row-reverse: ปุ่มขาว (liquid metal) ซึ่งอยู่ก่อนใน HTML จึงไปอยู่ขวาของปุ่มดำ
           และตอนจอแคบจนตกบรรทัด ปุ่มขาวยังได้อยู่บรรทัดบน ปุ่มดำอยู่ล่าง */
        flex-direction: row-reverse;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        gap: var(--space-4);

        /* ช่องของปุ่ม liquid metal เป็น block ที่มี .lmb แบบ inline-block อยู่ข้างใน
           ถ้าไม่ทำเป็น flex จะมีที่ว่างใต้บรรทัดติดมา ทำให้สองปุ่มไม่อยู่กึ่งกลางแนวเดียวกัน */
        >#playbook-cta-slot {
            display: flex;
            align-items: center;
        }

        .lmb button:focus-visible {
            outline-color: var(--color-neutral-0);
        }

        /* ปุ่มดำล้วน ไม่มีขอบ spectrum ชุดค่าเดียวกับปุ่มซื้อบัตรใน section Ticket (.ticket__action) */
        .playbook__action-link.bt-action-button--primary {
            border-color: var(--bt-action-fill);
            background: var(--bt-action-fill);
        }

        .playbook__action-link {
            min-height: var(--bt-playbook-cta-height);
        }

        @media (max-width: 767px),
        (max-width: 1199px) and (max-height: 575px) and (orientation: landscape) {
            --bt-playbook-cta-height: 46px;
        }
    }

    @media (max-width: 1699px) {
        --bt-playbook-header-scale: 0.9;
    }

    @media (max-width: 1599px) {
        /* --bt-playbook-content-scale: 0.8; */
        --bt-playbook-header-scale: 0.8;
    }

    @media (max-width: 1499px) {
        --bt-playbook-content-top-space: var(--space-24);
        --bt-playbook-content-bottom-space: var(--space-24);
        --bt-playbook-steps-container: 920px;
        /* --bt-playbook-content-scale: 0.7; */
        --bt-playbook-bitcoin-size: calc(var(--space-28) + var(--space-2));
        --bt-playbook-gold-size: var(--space-24);
        --bt-playbook-triangle-size: var(--space-24);
        --bt-playbook-heart-x: 88%;
        --bt-playbook-heart-size: calc(var(--space-32) + var(--space-4));
        --bt-playbook-stock-size: calc(var(--space-16) + var(--space-2));
        --bt-playbook-arrow-up-size: var(--space-28);
    }

    @media (max-width: 1399px) {
        --bt-playbook-header-scale: 0.7;
        --bt-playbook-content-scale: 0.8;
    }

    @media (max-width: 1299px) {
        --bt-playbook-content-top-space: var(--space-20);
        --bt-playbook-content-bottom-space: var(--space-20);
        --bt-playbook-steps-container: 720px;
    }

    @media (max-width: 1199px) {
        --bt-playbook-content-top-space: var(--space-24);
        --bt-playbook-content-bottom-space: var(--space-24);
        --bt-playbook-content-middle-space: calc(var(--space-32) * 3 + var(--space-16));
        --bt-playbook-content-scale: 1;
        --bt-playbook-header-scale: 0.85;
        --bt-playbook-steps-scale: 0.95;
        --bt-playbook-steps-container: 960px;
        --bt-playbook-step-padding-inline-base: var(--space-6);
        --bt-playbook-bitcoin-x: 12%;
        --bt-playbook-bitcoin-y: 22%;
        --bt-playbook-bitcoin-size: var(--space-28);
        --bt-playbook-gold-x: 86%;
        --bt-playbook-gold-y: 24%;
        --bt-playbook-gold-size: var(--space-20);
        --bt-playbook-triangle-x: 81%;
        --bt-playbook-triangle-y: 42%;
        --bt-playbook-triangle-size: var(--space-20);
        --bt-playbook-heart-x: 88%;
        --bt-playbook-heart-y: 60%;
        --bt-playbook-heart-size: var(--space-32);
        --bt-playbook-stock-x: 12%;
        --bt-playbook-stock-y: 54%;
        --bt-playbook-stock-size: calc(var(--space-16) - var(--space-2));
        --bt-playbook-arrow-up-x: 24%;
        --bt-playbook-arrow-up-y: 40%;
        --bt-playbook-arrow-up-size: var(--space-24);


        .playbook__background,
        .playbook__scene {
            display: flex;
            justify-content: center;
            height: 100%;
        }

        .playbook__background-image {
            object-fit: cover;
            height: 100%;
        }

        .playbook__book {
            object-fit: cover;
            height: 100%;
        }

        .playbook__glow-image {
            object-fit: cover;
            height: 100%;
        }

        .playbook__assets-artboard {
            height: 100%;
        }
    }

    @media (max-width: 991px) {
        --bt-playbook-header-scale: 0.7;
        --bt-playbook-steps-scale: 0.85;
        --bt-playbook-content-top-space: var(--space-20);
        --bt-playbook-content-bottom-space: var(--space-20);
        --bt-playbook-content-middle-space: calc(var(--space-32) * 2 + var(--space-16));
        --bt-playbook-footer-gap: var(--space-6);
        --bt-playbook-bitcoin-y: 24%;
        --bt-playbook-bitcoin-size: calc(var(--space-28) - var(--space-2));
        --bt-playbook-gold-x: 88%;
        --bt-playbook-gold-y: 28%;
        --bt-playbook-gold-size: calc(var(--space-16) - var(--space-1));
        --bt-playbook-triangle-y: 44%;
        --bt-playbook-overlay-background:
            linear-gradient(180deg,
                color-mix(in srgb, var(--color-neutral-900) 2%, transparent) 28%,
                color-mix(in srgb, var(--color-neutral-900) 58%, transparent) 55%,
                color-mix(in srgb, var(--color-neutral-900) 88%, transparent) 100%);

    }

    @media (max-width: 767px) {
        --bt-playbook-content-top-space: var(--space-24);
        --bt-playbook-content-bottom-space: var(--space-24);
        --bt-playbook-header-scale: 0.65;
        --bt-playbook-steps-scale: 0.6;
        --bt-playbook-subtitle-line-height: 1.2;
        --bt-playbook-title-art-margin-left: auto;
        --bt-playbook-title-art-transform: none;
        --bt-playbook-content-middle-space: calc(var(--space-32) * 3 + var(--space-16));
        --bt-playbook-footer-gap: var(--space-8);
        --bt-playbook-steps-grid: repeat(3, minmax(var(--space-0), 1fr));
        --bt-playbook-steps-gap: var(--space-0);
        --bt-playbook-step-padding-inline: var(--space-3);
        --bt-playbook-step-padding-bottom: var(--space-0);
        --bt-playbook-divider-top: 50%;
        --bt-playbook-divider-right: var(--space-0);
        --bt-playbook-divider-bottom: auto;
        --bt-playbook-divider-left: auto;
        --bt-playbook-divider-length: var(--space-16);
        --bt-playbook-divider-transform: translate(50%, -50%) rotate(90deg);
        --bt-playbook-bitcoin-x: 12%;
        --bt-playbook-bitcoin-y: 26%;
        --bt-playbook-bitcoin-size: var(--space-20);
        --bt-playbook-gold-x: 86%;
        --bt-playbook-gold-y: 28%;
        --bt-playbook-gold-size: var(--space-16);
        --bt-playbook-triangle-size: var(--space-16);
        --bt-playbook-heart-x: 88%;
        --bt-playbook-heart-y: 62%;
        --bt-playbook-heart-size: var(--space-20);
        --bt-playbook-stock-x: 12%;
        --bt-playbook-stock-y: 58%;
        --bt-playbook-stock-size: var(--space-12);
        --bt-playbook-arrow-up-x: 16%;
        --bt-playbook-arrow-up-y: 40%;
        --bt-playbook-arrow-up-size: var(--space-20);
    }

    @media (max-width: 575px) {
        /* ระยะบน-ล่างเท่ากับ padding ของ section อื่นที่จอนี้ (--section-padding-y-sm) */
        --bt-playbook-content-top-space: var(--section-padding-y-sm);
        --bt-playbook-content-bottom-space: var(--section-padding-y-sm);
        --bt-playbook-content-middle-space: calc(var(--space-32) * 2 + var(--space-16));
        --bt-playbook-header-scale: 1;
        --bt-playbook-steps-scale: 1;
        --bt-playbook-title-art-max-width: var(--size-320);
        --bt-playbook-title-size: var(--font-size-36);
        --bt-playbook-subtitle-size: var(--font-size-14);
        --bt-playbook-subtitle-space: var(--space-4);
        --bt-playbook-step-number-size: var(--font-size-24);
        --bt-playbook-step-title-size: var(--font-size-20);
        --bt-playbook-step-copy-margin: var(--space-2) var(--space-0) var(--space-0);
        --bt-playbook-step-copy-size: var(--font-size-14);
        --bt-playbook-step-copy-line-height: var(--line-height-normal);
        --bt-playbook-artboard-aspect-ratio: 2490 / 2100;
        --bt-playbook-bitcoin-size: var(--space-16);
        --bt-playbook-gold-size: var(--space-12);
        --bt-playbook-triangle-size: var(--space-12);
        --bt-playbook-heart-size: var(--space-16);
        --bt-playbook-stock-size: var(--space-10);
        --bt-playbook-arrow-up-size: var(--space-16);
        --bt-playbook-steps-width: 100%;
        --bt-playbook-steps-grid: 1fr;
        --bt-playbook-steps-gap: calc(var(--space-6) + var(--space-1));
        --bt-playbook-step-padding-inline: var(--space-0);
        --bt-playbook-step-padding-bottom: var(--space-8);
        --bt-playbook-divider-top: auto;
        --bt-playbook-divider-right: auto;
        --bt-playbook-divider-bottom: var(--space-0);
        --bt-playbook-divider-left: 50%;
        --bt-playbook-divider-length: var(--space-32);
        --bt-playbook-divider-transform: translate(-50%, 50%);
        --bt-playbook-footer-gap: var(--space-3);
    }

    @media (prefers-reduced-motion: reduce) {

        .playbook__asset-motion,
        .playbook__asset-float {
            transform: none !important;
        }

        .playbook__header h2::after {
            animation: none;
            background-position: 100% 50%;
        }

        .playbook__glow--base .playbook__glow-image {
            animation: none;
            opacity: var(--bt-playbook-glow-base-opacity-low);
            filter: brightness(var(--bt-playbook-glow-base-brightness-low));
        }

    }
}

@keyframes playbook-glow-breathe {

    0%,
    100% {
        opacity: var(--bt-playbook-glow-base-opacity-low);
        filter: brightness(var(--bt-playbook-glow-base-brightness-low));
    }

    50% {
        opacity: var(--bt-playbook-glow-base-opacity-high);
        filter: brightness(var(--bt-playbook-glow-base-brightness-high));
    }
}

@keyframes playbook-title-shine {
    0% {
        background-position: 100% 50%;
    }

    100% {
        background-position: -100% 50%;
    }
}

@keyframes ticket-ribbon-text-glow {

    0%,
    100% {
        background-position: 0% 50%;
        text-shadow:
            0 0 6px rgba(255, 255, 255, 0.18),
            0 0 16px rgba(115, 130, 170, 0.14);
    }

    48% {
        background-position: 100% 50%;
        text-shadow:
            0 0 10px rgba(255, 255, 255, 0.34),
            0 0 24px rgba(173, 190, 226, 0.22);
    }
}

@keyframes ticket-ribbon-text-sweep {
    0% {
        background-position: 150% 50%;
        opacity: 0;
    }

    18%,
    62% {
        opacity: 0.72;
    }

    76% {
        background-position: -70% 50%;
        opacity: 0;
    }

    100% {
        background-position: -70% 50%;
        opacity: 0;
    }
}


/* ---------- Cookie Banner ---------- */
.cookie-banner {
    position: fixed;
    right: 0;
    left: 0;
    bottom: var(--space-4);
    z-index: 290;
    width: calc(100% - var(--space-8));
    max-width: 1120px;
    margin-inline: auto;
    padding: var(--space-3) var(--space-4);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    /* border: var(--border-width-1) solid var(--color-border-default); */
    border-radius: var(--radius-1);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    box-shadow:
        0 1px 3px rgba(0, 0, 0, 0.06),
        0 6px 18px rgba(0, 0, 0, 0.10);
    opacity: 0;
    transform: translateY(calc(100% + var(--space-8)));
    transition:
        opacity var(--duration-standard) var(--ease-standard),
        transform var(--duration-slow) var(--ease-standard);
}

.cookie-banner.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.cookie-banner__content {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.cookie-banner__icon {
    flex: 0 0 auto;
    width: var(--space-8);
    height: var(--space-8);
    color: var(--color-accent-primary);
    stroke-width: 1.8;
}

.cookie-banner__message {
    min-width: 0;
    margin: var(--space-0);
    color: var(--color-text-secondary);
    font-size: var(--font-size-14);
    font-weight: var(--font-weight-regular);
}

.cookie-banner__message a {
    margin-left: var(--space-1);
    color: var(--color-accent-primary);
    font-weight: var(--font-weight-medium);
    text-underline-offset: var(--space-1);
    transition: opacity var(--duration-fast) var(--ease-standard);
}

.cookie-banner__message a:hover {
    opacity: 0.64;
}

.cookie-banner__message a:focus-visible {
    outline: var(--border-width-2) solid var(--color-focus-ring);
    outline-offset: var(--space-1);
}

.cookie-banner__actions {
    display: flex;
    flex: 0 0 auto;
    gap: var(--space-2);
}

.cookie-banner__button {
    min-width: 104px;
}

.cookie-banner__dismiss {
    width: var(--space-10);
    height: var(--space-10);
    padding: 0;
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    border: 0;
    border-radius: var(--radius-round);
    color: var(--color-text-secondary);
    background: transparent;
    cursor: pointer;
    transition:
        color var(--duration-fast) var(--ease-standard),
        background-color var(--duration-fast) var(--ease-standard);
}

.cookie-banner__dismiss .bt-icon {
    width: var(--space-5);
    height: var(--space-5);
}

.cookie-banner__dismiss:hover {
    color: var(--color-text-primary);
    background: var(--alpha-ink-06);
}

.cookie-banner__dismiss:focus-visible {
    outline: var(--border-width-2) solid var(--color-focus-ring);
    outline-offset: var(--space-1);
}

/* Match the solid primary treatment used by the Ultimate ticket action. */
.cookie-banner__button.bt-action-button--primary {
    border-color: var(--bt-action-fill);
    background: var(--bt-action-fill);
}

@media (max-width: 767px) {
    .cookie-banner {
        padding: var(--space-4);
        align-items: stretch;
        flex-direction: column;
        gap: var(--space-3);
    }

    .cookie-banner__content {
        padding-right: var(--space-12);
    }

    .cookie-banner__actions {
        align-items: center;
        justify-content: flex-end;
    }

    .cookie-banner__dismiss {
        position: absolute;
        top: var(--space-3);
        right: var(--space-3);
    }
}

@media (max-width: 575px) {
    .cookie-banner {
        right: 0;
        bottom: var(--space-3);
        left: 0;
        width: calc(100% - var(--space-6));
        padding: var(--space-4);
    }

    .cookie-banner__message {
        font-size: var(--font-size-14);
    }

    .cookie-banner__content {
        flex-direction: column;
        align-items: flex-start;
        padding-right: var(--space-0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .cookie-banner {
        transition-duration: var(--duration-reduced);
    }
}

/* ==========================================================================
   Playbook Scene — ฉากห้องที่เป็นพื้นหลังร่วมของ hero + intro (personalized-playbook.html)
   สอง section วางซ้อนอยู่บนภาพผืนเดียวกัน ไม่ได้มีพื้นหลังเป็นของตัวเอง
   เหตุผล: ถ้าแยกกรอบกัน ม่านไล่สีของแต่ละฝั่งจะมาชนกันที่รอยต่อจนเห็นเป็นเส้นตรงพาดขวางจอ
   ภาพตรึงกับ viewport (fixed) ฉากจึงอยู่นิ่งสนิทตลอดการเลื่อนผ่านทั้งสอง section
   ========================================================================== */
.playbook-scene {
    --bt-playbook-scene-image: url('../images/playbook-bg.webp');
    --bt-playbook-scene-veil: linear-gradient(90deg,
            color-mix(in srgb, var(--color-neutral-950) 92%, transparent) 0%,
            color-mix(in srgb, var(--color-neutral-950) 78%, transparent) 42%,
            color-mix(in srgb, var(--color-neutral-950) 34%, transparent) 78%,
            transparent 100%);
    /* ม่านชุดของ intro: ทึบเท่ากันทั้งผืนและทึบกว่าของ hero (ที่จางสุดถึง 34% ทางขวา)
       เขียนเป็น linear-gradient สองสต็อปสีเดียวกัน เพื่อให้เป็นชั้นภาพซ้อนกับม่านขอบล่างได้
       (background shorthand วางสีทึบร่วมกับ gradient หลายชั้นไม่ได้) */
    --bt-playbook-scene-veil-intro-strength: 88%;
    --bt-playbook-scene-veil-intro: linear-gradient(color-mix(in srgb, var(--color-neutral-950) var(--bt-playbook-scene-veil-intro-strength), transparent),
            color-mix(in srgb, var(--color-neutral-950) var(--bt-playbook-scene-veil-intro-strength), transparent));
    /* ไล่เข้มเฉพาะปลายล่างสุดของฉาก ส่งต่อไปยัง section พื้นขาวที่อยู่ถัดไป */
    --bt-playbook-scene-veil-edge: linear-gradient(180deg,
            transparent 88%,
            color-mix(in srgb, var(--color-neutral-950) 72%, transparent) 100%);
    --bt-playbook-scene-veil-fade: 1600ms;
    /* ระยะที่ลำแสงเลื่อนตลอดช่วงที่ฉากวิ่งผ่านจอ (JS อ่านค่านี้ไปใช้) */
    --bt-playbook-scene-light-travel: 56;
    --bt-playbook-scene-light: radial-gradient(ellipse 46% 58% at 50% 6%,
            color-mix(in srgb, var(--color-neutral-0) 12%, transparent) 0%,
            color-mix(in srgb, var(--color-neutral-0) 4%, transparent) 46%,
            transparent 72%);

    position: relative;
    isolation: isolate;
    background: var(--color-neutral-950);
}

.playbook-scene__backdrop {
    position: absolute;
    inset: var(--space-0);
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    background: var(--bt-playbook-scene-image) center / cover no-repeat fixed;

    /* ม่านสองผืนซ้อนกัน แล้วไขว้ opacity ตอนเข้า intro
       เปลี่ยน background-image ตรง ๆ ไม่ได้ เพราะ gradient ไม่ไล่ค่าให้ เปลี่ยนแล้วจะกระตุกเป็นขั้น */
    &::before,
    &::after {
        content: '';
        position: absolute;
        inset: var(--space-0);
        transition: opacity var(--bt-playbook-scene-veil-fade) var(--ease-standard);
    }

    &::after {
        background: var(--bt-playbook-scene-veil), var(--bt-playbook-scene-veil-edge);
    }

    &::before {
        background: var(--bt-playbook-scene-veil-intro), var(--bt-playbook-scene-veil-edge);
        opacity: 0;
    }
}

.playbook-scene.is-intro .playbook-scene__backdrop::after {
    opacity: 0;
}

.playbook-scene.is-intro .playbook-scene__backdrop::before {
    opacity: 1;
}

/* เนื้อหาของ hero จางหายด้วยคลาสและจังหวะเดียวกับม่าน จึงหายไปพร้อมกันเสมอ
   ผูกกับคลาสไม่ใช่ตำแหน่ง scroll เพราะถ้าคำนวณจากระยะ ค่าจะแตะ "เกือบศูนย์"
   ตั้งแต่ม่านยังไม่มา ตาคนอ่านว่าหายไปแล้วทั้งที่เลขยังไม่ถึง 0
   กฎอยู่ที่ฝั่ง scene เพราะ scene เป็นผู้ส่งไม้ระหว่าง hero กับ intro */
.playbook-scene.is-intro .playbook-hero__inner {
    opacity: 0;
    pointer-events: none;
}

/* ≤991 เนื้อหา hero ไม่จางหาย แสดงปกติตลอด (ม่านของฉากยังไขว้เป็นชุด intro เหมือนเดิม)
   ผังจอแคบเรียงข้อความกับวงแหวนลงล่าง ตอนเลื่อนเข้า intro ส่วนท้ายของ hero ยังอยู่ในจอ
   ให้จางหายตรงนั้นจะเห็นเป็นเนื้อหาหายไปกลางจอ ไม่ใช่การส่งไม้ระหว่างสอง section */
@media (max-width: 991px) {
    .playbook-scene.is-intro .playbook-hero__inner {
        opacity: 1;
        pointer-events: auto;
    }
}

/* ลำแสงแยกชั้นเพื่อให้เลื่อนได้เอง ฉากหลักยังตรึงนิ่งอยู่ข้างหลัง
   สูงเกินกรอบไว้ทั้งบนและล่าง จะได้ไม่เห็นขอบชั้นตอนมันเลื่อน */
.playbook-scene__light {
    position: absolute;
    inset: -6% var(--space-0);
    z-index: 0;
    pointer-events: none;
    background: var(--bt-playbook-scene-light);
    will-change: transform;
}

@media (prefers-reduced-motion: reduce) {

    .playbook-scene__backdrop::before,
    .playbook-scene__backdrop::after {
        transition: none;
    }
}

/* สอง section ต้องลอยอยู่เหนือชั้นฉาก ไม่งั้นเนื้อหาจะถูกภาพทับ */
.playbook-scene>section {
    position: relative;
    z-index: 1;
}

@media (max-width: 991px) {
    .playbook-scene {
        /* จอแคบภาพแคบลงมาก ม่านแนวนอนจะเหลือแต่ด้านมืด เลยสลับเป็นไล่แนวตั้งแทน */
        --bt-playbook-scene-veil: linear-gradient(180deg,
                color-mix(in srgb, var(--color-neutral-950) 88%, transparent) 0%,
                color-mix(in srgb, var(--color-neutral-950) 68%, transparent) 55%,
                color-mix(in srgb, var(--color-neutral-950) 82%, transparent) 100%);
    }

    /* iOS Safari ไม่รองรับ fixed จริง ภาพจะกระตุกหรือยืดผิดสัดส่วน จึงกลับไปเลื่อนตามหน้า */
    .playbook-scene__backdrop {
        background-attachment: scroll;
    }
}

/* ชั้นภาพติดจอ ใช้เฉพาะ ≤991 จอที่กว้างกว่าซ่อนไว้ ภาพยังวาดที่ตัว backdrop ด้วย fixed ตามเดิม */
.playbook-scene__image {
    display: none;
}

/* ---------- ≤991: ภาพฉากเต็มจอและอยู่นิ่งเหมือน desktop ----------
   ช่วงนี้ปิด background-attachment: fixed ไว้ (บล็อก ≤991 ด้านบน เพราะ iOS Safari ไม่รองรับ)
   ภาพที่เลื่อนตามหน้าต้อง cover ทั้งฉาก hero + intro ซึ่งสูงราว 2 เท่าของจอ
   ภาพ 2490x1720 จึงถูกขยายตามความสูงฉากจนเหลือแค่กลางห้อง ประตูสองข้างหลุดกรอบไปหมด
   หน้าตาไม่เหมือน desktop ที่ภาพ cover แค่หนึ่งจอ

   แทนที่ด้วยชั้นภาพที่สูงหนึ่งจอแล้วติดขอบบนจอไว้ด้วย sticky
   ภาพจึงเต็มจอพอดีและนิ่งอยู่กับที่ตลอดช่วงที่ฉากวิ่งผ่าน ได้ผลเท่า fixed ของ desktop
   และ sticky ทำงานบน iOS Safari ปกติ
   - backdrop ต้องเปลี่ยน overflow จาก hidden เป็น clip: hidden ทำให้กล่องกลายเป็น
     scroll container แล้ว sticky จะไปติดกับกล่องที่ไม่เคยเลื่อนแทนหน้าจอ
   - z-index: -1 ให้ภาพอยู่ใต้ม่านไล่สีทั้งสองผืน (::before / ::after ของ backdrop)
   - 100lvh = ความสูงจอตอนแถบเบราว์เซอร์มือถือหุบ ภาพจึงไม่ขาดตอนแถบหุบ (เบราว์เซอร์เก่าใช้ 100vh)
   - จอ ≤575 ใช้ชั้นเดียวกัน แค่สลับไฟล์เป็นภาพแนวตั้ง (token ในบล็อก ≤575 ถัดไป) */
@media (max-width: 991px) {
    .playbook-scene__backdrop {
        overflow: clip;
        background: none;
    }

    .playbook-scene__image {
        position: sticky;
        top: var(--space-0);
        z-index: -1;
        height: 100vh;
        height: 100lvh;
        display: block;
        background: var(--bt-playbook-scene-image) center / cover no-repeat;
    }
}

@media (max-width: 575px) {
    .playbook-scene {
        --bt-playbook-scene-image: url('../images/playbook-bg-mobile.webp');
    }
}


/* ==========================================================================
   Section: Playbook Hero (personalized-playbook.html)
   ใช้ฉากเดียวกับ section playbook ของหน้าแรก (ประตูตัวตนนักลงทุน + หนังสือ + แสง)
   เพื่อให้คนที่กดปุ่มมาจากหน้าแรกเห็นของชิ้นเดิมต่อเนื่องกัน ไม่รู้สึกว่าหลุดไปอีกเว็บ
   ========================================================================== */
.playbook-hero {
    /* บน-ล่างเท่ากัน เนื้อหาจึงอยู่กึ่งกลางกรอบ hero จริง ไม่ใช่กลางเฉพาะพื้นที่ใต้ header
       (ตั้งแต่ lg ขึ้นไปภาพอยู่ข้างข้อความ แถวจึงสูงกว่าข้อความอยู่แล้ว บรรทัดแรกไม่ชนแถบเมนู)
       กล่องข้อความบรรทัดแรกมีช่องไฟเหนือตัวอักษรตามค่า line-height แต่บรรทัดสุดท้ายจบที่เส้นใต้พอดี
       ถ้าแบ่ง padding เท่ากันเป๊ะ ตาจะเห็นด้านบนโล่งกว่า จึงหักช่องไฟส่วนนั้นออกจากระยะบน
       เพื่อให้ "ขอบตัวอักษรจริง" ห่างจากขอบ section เท่ากันทั้งสองด้าน */
    --bt-playbook-hero-optical-shift: 6px;
    --bt-playbook-hero-copy-action-space: var(--space-3);
    --bt-playbook-hero-padding-top: calc(var(--space-20) - var(--bt-playbook-hero-optical-shift));
    --bt-playbook-hero-padding-bottom: var(--space-12);
    --bt-playbook-hero-row-gap: var(--space-12);
    --bt-playbook-hero-content-gap: var(--space-8);
    --bt-playbook-hero-eyebrow-size: var(--font-size-16);
    --bt-playbook-hero-title-size: var(--font-size-56);
    --bt-playbook-hero-title-art-size: var(--font-size-64);
    --bt-playbook-hero-title-line-height: var(--line-height-1);
    --bt-playbook-hero-title-space: var(--space-8);
    --bt-playbook-hero-lead-size: var(--section-subheading-size);
    --bt-playbook-hero-lead-line-height: var(--line-height-normal);
    --bt-playbook-hero-copy-size: var(--font-size-18);
    --bt-playbook-hero-copy-line-height: var(--line-height-relaxed);
    --bt-playbook-hero-copy-max-width: var(--layout-copy-max);
    --bt-playbook-hero-actions-gap: var(--space-4);
    --bt-playbook-hero-actions-space-top: var(--space-10);
    --bt-playbook-hero-actions-space-bottom: var(--space-3);
    --bt-playbook-hero-visual-ratio: 1 / 1;
    --bt-playbook-hero-visual-max-width: none;
    /* เกลียวการ์ดตัวตน: ค่ารูปทรงทั้งชุดอยู่ที่นี่ที่เดียว JS อ่านไปคำนวณตำแหน่งการ์ดทุกเฟรม
       ค่าที่มีหน่วย px คือระยะจริงบนจอ ส่วนค่าที่ไม่มีหน่วยคือจำนวนใบต่อรอบและตัวคูณ
       ขนาดต่อ breakpoint จึงแก้ที่ token ชุดนี้ ไม่ต้องแตะ JS */
    --bt-playbook-hero-spiral-card-width: 132px;
    --bt-playbook-hero-spiral-radius: 210px;
    /* เพดานรัศมีเป็นสัดส่วนของความกว้างกรอบ (ไม่มีหน่วย) JS ใช้ค่าที่เล็กกว่าระหว่างสองตัวนี้ */
    --bt-playbook-hero-spiral-radius-cap: 0.36;
    --bt-playbook-hero-spiral-spacing: 84px;
    --bt-playbook-hero-spiral-perspective: 1000px;
    --bt-playbook-hero-spiral-speed: 0.44;
    --bt-playbook-hero-spiral-cards-per-turn: 7;
    --bt-playbook-hero-spiral-rotation: 0;
    --bt-playbook-hero-spiral-tilt: 0;
    --bt-playbook-hero-spiral-center-scale: 1.2;
    --bt-playbook-hero-spiral-edge-fade: 0.3;
    --bt-playbook-hero-spiral-edge-blur: 6;
    /* 1 = สกรอลล์แล้วเกลียวหมุนเร็วขึ้นตามระยะที่เลื่อน 0 = หมุนเองอย่างเดียว
       (ต่ำกว่า lg ปิดไว้ ดูเหตุผลที่บล็อก ≤991) */
    --bt-playbook-hero-spiral-scroll-drive: 1;
    /* ความสูงที่เกลียวต้องการ คิดเป็น "กี่เท่าของความสูงการ์ด" JS ใช้ตัดสินว่ากรอบเตี้ยเกิน
       ต้องย่อทั้งชุดหรือไม่ เกลียวตั้ง (desktop) ไต่ขึ้นลงหลายใบจึงต้องการ 2.35 เท่า
       ส่วนวงแหวนแนวนอน (≤991) สูงแค่ใบหน้าสุดใบเดียว x1.25 x ระยะมอง = ราว 1.5 เท่า
       ถ้าปล่อยค่า desktop ไว้ วงแหวนจะถูกย่อทั้งที่กรอบมีที่พอ (ที่ 991x775 เคยเหลือ 69%) */
    --bt-playbook-hero-spiral-fit-rows: 2.35;
    /* จุดที่เลิกวนลูป: ค่า 0.8 = ขอบล่างของ section ขึ้นมาถึงระดับ 80% ของความสูงจอ
       จากจังหวะนั้นการ์ดจะไหลขึ้นไปตามเกลียวแล้วหมดไปเลย ไม่วนกลับมาโผล่ใหม่ */
    --bt-playbook-hero-spiral-unwrap-at: 0.8;
    /* ไอคอนสินทรัพย์: คุมด้วยความสูงเพราะสามชิ้นสัดส่วนต่างกันมาก
       (เหรียญเกือบจัตุรัส แท่งทองสูงแคบ แท่งกราฟยิ่งแคบกว่า) ถ้าคุมด้วยความกว้างจะสูงไม่เท่ากัน
       drift คือระยะลอยขึ้น-ลง ครึ่งหนึ่งของค่านี้ต่อทิศทาง */
    /* ขนาดอ้างอิงชุดเดียวกับ section playbook ในหน้าหลัก คือคุมที่ "ความกว้าง"
       และคิดจากสเกลระยะห่างกลางของเว็บ (--space-*) ไม่ได้หยิบ token ของ section นั้นมาใช้ตรง ๆ
       fit เป็นตัวคูณรวม ปรับขนาดทั้งชุดพร้อมกันได้จากที่เดียว */
    --bt-playbook-hero-asset-coin-size: calc(var(--space-32) + var(--space-4));
    --bt-playbook-hero-asset-bar-size: var(--space-28);
    --bt-playbook-hero-asset-chart-size: var(--space-20);
    --bt-playbook-hero-asset-arrow-size: var(--space-32);
    --bt-playbook-hero-asset-fit: 0.72;
    --bt-playbook-hero-asset-rotation: 0deg;
    --bt-playbook-hero-asset-filter: saturate(1.5);
    /* จังหวะลอยยึดตามชุดเดียวกับ hero หน้า index (ที่นั่นสุ่มค่าในช่วงนี้ตอนรันด้วย GSAP
       ส่วนที่นี่เป็น CSS จึงกระจายค่าคงที่ให้แต่ละชิ้นแทน): เลื่อนลง 9–17px
       หมุนต่อจากมุมตั้งต้น 3–8 องศา รอบละ 3–5 วินาที ไป-กลับด้วยจังหวะ sine */
    --bt-playbook-hero-asset-drift: 12px;
    --bt-playbook-hero-asset-swing: 5deg;
    --bt-playbook-hero-asset-cycle: 4s;
    --bt-playbook-hero-spiral-card-radius: var(--radius-2);
    --bt-playbook-hero-spiral-card-shadow: 0 14px 38px color-mix(in srgb, var(--color-neutral-950) 55%, transparent);
    --bt-playbook-hero-ink: var(--color-neutral-0);
    --bt-playbook-hero-ink-soft: color-mix(in srgb, var(--color-neutral-0) 88%, transparent);
    --bt-playbook-hero-ink-dim: color-mix(in srgb, var(--color-neutral-0) 72%, transparent);

    /* svh คือความสูงจอตอนแถบเบราว์เซอร์กางอยู่ ใช้แทน vh เพื่อไม่ให้ hero
       กระโดดตอนแถบที่อยู่เว็บบนมือถือย่อ-ขยาย (เบราว์เซอร์เก่าตกมาใช้ vh)
       ใช้ min-height ไม่ใช่ height เนื้อหาจึงยืดได้เองถ้าจอเตี้ยกว่าที่ข้อความต้องการ */
    --bt-playbook-hero-min-height: 100vh;

    position: relative;
    min-height: var(--bt-playbook-hero-min-height);
    display: grid;
    align-content: center;
    isolation: isolate;
    padding: var(--bt-playbook-hero-padding-top) var(--space-0) var(--bt-playbook-hero-padding-bottom);
    color: var(--bt-playbook-hero-ink);
    /* พื้นหลังเป็นของ .playbook-scene ที่ครอบอยู่ ตรงนี้ต้องโปร่งเพื่อให้ฉากทะลุขึ้นมา */
    background: transparent;
    font-family: var(--font-family-base);

    @supports (height: 100svh) {
        --bt-playbook-hero-min-height: 100svh;
    }

    /* เนื้อหาทั้งก้อนจางลงตามระยะที่เลื่อนเข้าหา intro (ค่า opacity เขียนจาก JS)
       จางที่ตัวเนื้อหาเอง ไม่เอาแผ่นทึบมาทับ ฉากหลังจึงไม่มีขอบของแผ่นให้เห็นเป็นรอยต่อ
       เขียน opacity ที่ element ตรง ๆ ไม่ผ่าน custom property เพราะถ้าใช้ตัวแปร
       เบราว์เซอร์จะคำนวณสไตล์ลูกทั้งกิ่งใหม่ทุกเฟรมที่เลื่อน */
    .playbook-hero__inner {
        position: relative;
        z-index: 1;
        /* จังหวะเดียวกับม่านของ .playbook-scene เป๊ะ ๆ (ดู .playbook-scene__backdrop::before/::after)
           เนื้อหาจึงจางหายพร้อมกับตอนที่ม่านทึบของ intro เข้ามาแทน ไม่ใช่หายไปก่อน */
        transition: opacity var(--bt-playbook-scene-veil-fade) var(--ease-standard);
    }

    .playbook-hero__inner .row {
        row-gap: var(--bt-playbook-hero-row-gap);
    }

    .playbook-hero__content {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
    }

    /* eyebrow ใช้ component เดิมของทุก section แต่หน้านี้อยู่บนพื้นมืด
       จึงกลับสีตัวอักษรและเส้น-ดาวท้ายบรรทัดให้อ่านออก */
    .playbook-hero__eyebrow {
        /* ปรับผ่าน token ของ component เอง (ไม่ทับ font-size ตรง ๆ) hero จึงเล็กกว่า eyebrow ของ section อื่น */
        --bt-section-subtext-size: var(--bt-playbook-hero-eyebrow-size);

        margin-top: var(--space-0);
        color: var(--bt-playbook-hero-ink-dim);

        &::after {
            filter: invert(1);
        }
    }

    .playbook-hero__title {
        margin-top: var(--bt-playbook-hero-title-space);
        color: var(--bt-playbook-hero-ink);
        font-size: var(--bt-playbook-hero-title-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--bt-playbook-hero-title-line-height);
        text-transform: uppercase;
    }

    /* คำว่า Playbook เป็นภาพ wordmark ไม่ใช่ตัวอักษร จึงกำหนดความกว้างจากขนาดตัวอักษรของหัวข้อ
       ขนาดภาพคุมด้วย token ของตัวเอง แยกจากขนาดตัวอักษร จึงลดขนาดคำว่า Personalized
       ได้โดยภาพไม่เล็กตาม (ตัวคูณ 7.04 คือความกว้างของคำต่อ 1 หน่วย font-size วัดจากฟอนต์จริง
       คงไว้เพื่อให้ภาพยังไล่สเกลตาม breakpoint ชุดเดิม) */
    .playbook-hero__title-art {
        margin-top: var(--space-6);
        display: block;
        width: calc(var(--bt-playbook-hero-title-art-size) * 7.04);
        max-width: 100%;
        height: auto;
    }

    .playbook-hero__lead {
        max-width: var(--bt-playbook-hero-copy-max-width);
        margin-top: var(--bt-playbook-hero-content-gap);
        color: var(--bt-playbook-hero-ink-soft);
        font-size: var(--bt-playbook-hero-lead-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--bt-playbook-hero-lead-line-height);
    }

    /* ย่อหน้านี้ย้ายมาอยู่ใต้ปุ่มแล้ว ระยะจึงเว้นเท่าระยะเหนือปุ่ม ไม่ใช่ระยะบรรทัดชิด ๆ แบบเดิม */
    .playbook-hero__copy {
        max-width: var(--bt-playbook-hero-copy-max-width);
        margin-top: var(--bt-playbook-hero-actions-space-top);
        margin-bottom: var(--bt-playbook-hero-actions-space-bottom);
        color: var(--bt-playbook-hero-ink-dim);
        font-size: var(--bt-playbook-hero-copy-size);
        font-weight: var(--font-weight-light);
        line-height: var(--bt-playbook-hero-copy-line-height);
    }

    .playbook-hero__actions {
        margin-top: var(--bt-playbook-hero-actions-space-top);
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--bt-playbook-hero-actions-gap);
    }

    /* ปุ่มรองบนพื้นมืด: ใช้ variant --text เดิม แล้วกลับสีตัวอักษรเป็นขาว
       ส่วนเส้นใต้ใช้ --spectrum ชุด KV เดียวกับเส้นใต้เมนูใน header ไม่ใช่ชุด
       --gradient-accent-spectrum (โทนพาสเทลชุดเก่า) ที่เป็นค่าเริ่มต้นของ variant */
    /* ลูกศรท้ายลิงก์ ชุดเดียวกับปุ่มสถานที่บน hero หน้าแรก: ปกติเป็นสีเดียวกับตัวอักษร
       แล้วไล่เป็นสเปกตรัมตอน hover ด้วย gradient ที่ประกาศไว้ใน svg ของตัวเอง */
    .playbook-hero__action-arrow {
        width: var(--bt-icon-size);
        height: var(--bt-icon-size);
        stroke-width: 2;
    }

    /* ลิงก์อยู่ท้ายประโยค จึงใช้ขนาดเดียวกับย่อหน้าที่มันอยู่ (18px บน desktop)
       ผูกกับ token ของย่อหน้าไว้ พอจอเล็กแล้วข้อความย่อ ลิงก์จะย่อตามไปในบรรทัดเดียวกัน */
    /* ลิงก์อยู่บรรทัดของตัวเองใต้ย่อหน้า จึงต้องเว้นระยะเอง
       ดึงกลับทางซ้ายเท่ากับระยะในของ component ตัวอักษรจะได้เริ่มตรงกับย่อหน้าด้านบนพอดี */
    .playbook-hero__copy-action {
        margin-top: var(--bt-playbook-hero-copy-action-space);
        margin-left: calc(var(--space-1) * -1);
    }

    .playbook-hero__action--ghost {
        gap: var(--space-2);
        /* ขนาดเท่าย่อหน้าที่มันอยู่ใต้ ไม่ใช่ 16px ของ component ตั้งต้น */
        font-size: var(--bt-playbook-hero-copy-size);
        color: var(--bt-playbook-hero-ink);

        &:hover .playbook-hero__action-arrow,
        &:focus-visible .playbook-hero__action-arrow {
            stroke: #00d4fe;
            stroke: url('#playbook-hero-arrow-spectrum');
        }


        &::after {
            background: var(--spectrum);
        }

        &:hover,
        &:focus-visible {
            color: var(--bt-playbook-hero-ink);
        }
    }

    /* คอลัมน์ขวาเว้นว่างไว้รอภาพ hero ชุดใหม่ สัดส่วนกันที่ไว้แล้วเพื่อให้
       ความสูงของ hero ไม่กระโดดตอนใส่ภาพเข้ามา */
    .playbook-hero__visual {
        position: relative;
        max-width: var(--bt-playbook-hero-visual-max-width);
        aspect-ratio: var(--bt-playbook-hero-visual-ratio);
    }

    /* เวทีเกลียว: JS เป็นคนเขียน transform/opacity ให้การ์ดทีละใบ CSS จึงดูแลแค่
       กรอบ ระยะมอง และสถานะของตัวชี้ ไม่มี transition ทับ ไม่งั้นจะสู้กับลูปทุกเฟรม */
    .playbook-hero__spiral {
        position: absolute;
        inset: var(--space-0);
        perspective: var(--bt-playbook-hero-spiral-perspective);
        opacity: 0;
        transition: opacity var(--duration-slow) var(--ease-standard);

        /* ถ้า JS ไม่ทำงาน การ์ดจะกองซ้อนกันกลางกรอบ จึงเริ่มที่ซ่อนไว้
           แล้วให้ JS เปิดเองหลังจัดตำแหน่งเฟรมแรกเสร็จ */
        &.is-ready {
            opacity: 1;
        }

        &.is-draggable {
            cursor: grab;
        }

        &.is-dragging {
            cursor: grabbing;
        }

        /* นิ้วปัดขึ้น-ลงบนมือถือยังเป็นการเลื่อนหน้าเสมอ การลากเกลียวสงวนไว้ให้เมาส์ */
        @media (hover: hover) and (pointer: fine) {
            &.is-draggable {
                user-select: none;
            }
        }
    }

    .playbook-hero__spiral-stage {
        position: absolute;
        inset: var(--space-0);
        transform-style: preserve-3d;
    }

    /* ความสูงมาจากสัดส่วนจริงของไฟล์ (หน้าไพ่ 554×740 หลังการ์ด 520×728 ไม่เท่ากัน)
       กล่องจึงกำหนดแค่ความกว้าง ไม่บังคับความสูง ภาพเลยไม่ถูกตัดขอบ
       แอตทริบิวต์ width/height ของ <img> เป็นตัวจองสัดส่วนไว้ก่อนภาพโหลดเสร็จ */
    .playbook-hero__spiral-card {
        position: absolute;
        top: 50%;
        left: 50%;
        width: var(--bt-playbook-hero-spiral-card-width);
        height: auto;
        opacity: 0;
        overflow: hidden;
        border-radius: var(--bt-playbook-hero-spiral-card-radius);
        box-shadow: var(--bt-playbook-hero-spiral-card-shadow);
        backface-visibility: hidden;
    }

    /* ยก layer ให้การ์ดเฉพาะตอนเกลียวหมุนอยู่จริง เลื่อนพ้น hero แล้วคืนหน่วยความจำ compositor */
    .playbook-hero__spiral.is-running .playbook-hero__spiral-card {
        will-change: transform, opacity, filter;
    }

    .playbook-hero__spiral-image {
        width: 100%;
        height: auto;
        display: block;
        user-select: none;
    }

    /* ไม่กำหนด z-index ให้ชั้นนี้ การ์ดที่ JS ยก z-index ให้ตามความลึก (สูงสุดราว 1005)
       จึงวาดทับไอคอนได้เสมอ ไอคอนอยู่หลังการ์ดทั้งหมด */
    .playbook-hero__assets {
        position: absolute;
        inset: var(--space-0);
        pointer-events: none;
    }

    /* กล่องนอกดูแลตำแหน่ง ส่วนการลอยขึ้น-ลงอยู่ที่ภาพด้านใน แยกกันไว้เผื่อปรับอย่างใดอย่างหนึ่ง */
    .playbook-hero__asset {
        position: absolute;
        width: calc(var(--bt-playbook-hero-asset-size) * var(--bt-playbook-hero-asset-fit));

        img {
            width: 100%;
            height: auto;
            display: block;
            filter: var(--bt-playbook-hero-asset-filter);
            animation: playbook-hero-asset-drift var(--bt-playbook-hero-asset-cycle) var(--ease-ambient) infinite alternate;
            animation-delay: var(--bt-playbook-hero-asset-offset, 0ms);
        }
    }

    .playbook-hero__asset--coin {
        --bt-playbook-hero-asset-size: var(--bt-playbook-hero-asset-coin-size);
        --bt-playbook-hero-asset-rotation: -4deg;
        --bt-playbook-hero-asset-drift: 15px;
        --bt-playbook-hero-asset-swing: 6deg;
        --bt-playbook-hero-asset-cycle: 3.4s;
        --bt-playbook-hero-asset-offset: -900ms;

        top: 1%;
        left: 0%;
    }

    .playbook-hero__asset--bar {
        --bt-playbook-hero-asset-size: var(--bt-playbook-hero-asset-bar-size);
        --bt-playbook-hero-asset-rotation: 18deg;
        --bt-playbook-hero-asset-drift: 11px;
        --bt-playbook-hero-asset-swing: -4deg;
        --bt-playbook-hero-asset-cycle: 4.6s;
        --bt-playbook-hero-asset-offset: -2100ms;

        top: 16%;
        right: 0%;
    }

    .playbook-hero__asset--chart {
        --bt-playbook-hero-asset-size: var(--bt-playbook-hero-asset-chart-size);
        --bt-playbook-hero-asset-rotation: -34deg;
        --bt-playbook-hero-asset-drift: 17px;
        --bt-playbook-hero-asset-swing: -3.4deg;
        --bt-playbook-hero-asset-cycle: 4s;
        --bt-playbook-hero-asset-offset: -3200ms;

        bottom: 2%;
        left: 2%;
    }

    .playbook-hero__asset--arrow {
        --bt-playbook-hero-asset-size: var(--bt-playbook-hero-asset-arrow-size);
        --bt-playbook-hero-asset-rotation: 0deg;
        --bt-playbook-hero-asset-drift: 13px;
        --bt-playbook-hero-asset-swing: 7deg;
        --bt-playbook-hero-asset-cycle: 3.2s;
        --bt-playbook-hero-asset-offset: 0ms;

        bottom: 6%;
        right: 3%;
    }

    /* index หยุด tween ของไอคอนเมื่อฉากหลุดจอ ที่นี่ทำแบบเดียวกันโดยไม่ต้องใช้ JS เพิ่ม
       อาศัยคลาส is-running ที่ตัวเกลียวติด-ถอดเองอยู่แล้วตามการมองเห็น */
    .playbook-hero__visual:has(.playbook-hero__spiral:not(.is-running)) .playbook-hero__asset img {
        animation-play-state: paused;
    }

    @media (prefers-reduced-motion: reduce) {
        .playbook-hero__asset img {
            animation: none;
            transform: rotate(var(--bt-playbook-hero-asset-rotation));
        }
    }
}

/* ลอยขึ้น-ลงพร้อมแกว่งรอบมุมเอียงตั้งต้นของตัวเอง คนละจังหวะกันทั้งสี่ชิ้น
   มุมตั้งต้นใช้ชุดเดียวกับ section playbook ส่วน tilt คือระยะแกว่งรอบมุมนั้น
   การแกว่งทำให้เห็นว่าชิ้นงานลอยอยู่จริง ชัดกว่าการเลื่อนขึ้น-ลงอย่างเดียวที่เกือบมองไม่ออก */
@keyframes playbook-hero-asset-drift {
    from {
        transform: translate3d(0, var(--space-0), 0) rotate(var(--bt-playbook-hero-asset-rotation));
    }

    to {
        transform: translate3d(0, var(--bt-playbook-hero-asset-drift), 0) rotate(calc(var(--bt-playbook-hero-asset-rotation) + var(--bt-playbook-hero-asset-swing)));
    }
}

@media (max-width: 1199px) {
    .playbook-hero {
        --bt-playbook-hero-title-size: var(--font-size-48);
        --bt-playbook-hero-title-art-size: var(--font-size-56);
        --bt-playbook-hero-lead-size: var(--font-size-20);
        /* ลดขนาดตัวรองกับระยะในคอลัมน์ข้อความลงหนึ่งขั้น ไม่แตะหัวเรื่อง
           หัวเรื่องถูกย่อไปแล้วในชุดข้างบน (56->48 / 64->56) ถ้าย่ออีกจะไปเท่ากับของจอ ≤991
           แล้ว breakpoint นี้จะกลายเป็นขั้นซ้ำที่ไม่มีความหมาย */
        --bt-playbook-hero-eyebrow-size: var(--font-size-14);
        --bt-playbook-hero-copy-size: var(--font-size-16);
        --bt-playbook-hero-title-space: var(--space-6);
        --bt-playbook-hero-content-gap: var(--space-6);
        --bt-playbook-hero-actions-space-top: var(--space-5);
        --bt-playbook-hero-actions-space-bottom: var(--space-1);
        --bt-playbook-hero-actions-gap: var(--space-3);
        /* ย่อทั้งชุดลงพร้อมกัน 13% (การ์ด/รัศมี/ระยะห่าง) สัดส่วนเกลียวจึงคงรูปเดิม
           ถ้าย่อแค่การ์ดอย่างเดียว วงจะโล่งขึ้นแต่กินที่เท่าเดิม
           ไม่ลงไปถึงค่าของจอเล็ก (100/140/56) เพราะตรงนี้ยังเป็นจอ desktop */
        --bt-playbook-hero-spiral-card-width: 104px;
        --bt-playbook-hero-spiral-radius: 156px;
        --bt-playbook-hero-spiral-spacing: 66px;
        --bt-playbook-hero-asset-coin-size: calc(var(--space-28) + var(--space-2));
        --bt-playbook-hero-asset-bar-size: var(--space-24);
        --bt-playbook-hero-asset-chart-size: calc(var(--space-16) + var(--space-2));
        --bt-playbook-hero-asset-arrow-size: var(--space-28);
        --bt-playbook-hero-padding-top: calc(var(--space-10) - var(--bt-playbook-hero-optical-shift));
        --bt-playbook-hero-padding-bottom: var(--space-10);

        /* กรอบภาพแคบลงมาก ไอคอนสองมุมนี้เลยไปกองอยู่ในวงโคจรของการ์ด
           ดันออกนอกกรอบเล็กน้อยให้พ้นทาง (ทุกชั้นเหนือขึ้นไปเป็น overflow: visible
           จึงโผล่ออกได้โดยไม่โดนตัด และไม่ทำให้เกิด scrollbar แนวนอน)
           อยู่ใน media query นี้เท่านั้น จอใหญ่กว่านี้ยังใช้ตำแหน่งเดิม */
        .playbook-hero__asset--coin {
            top: -4%;
        }

        .playbook-hero__asset--arrow {
            bottom: 1%;
            right: -2%;
        }
    }
}

/* ---------- ต่ำกว่า lg: ผังกึ่งกลางแนวตั้ง ----------
   บน lg ขึ้นไปเป็นสองคอลัมน์ ข้อความชิดซ้าย เกลียวการ์ดเป็น "เกลียวแนวตั้ง" อยู่คอลัมน์ขวา
   พอคอลัมน์ซ้อนกัน เกลียวแนวตั้งที่ย้ายลงมาอยู่ใต้ข้อความในกล่องกว้าง-เตี้ยจะกลายเป็น
   การ์ดกองซ้อนกันกลางกล่อง ทั้งกินความสูง (hero 1107px เกินจอ) และไม่มีแกนสมมาตรให้อ่าน

   จึงเปลี่ยนสองอย่างพร้อมกันให้ผังทั้งหมดมีแกนกลางร่วมกัน
   1) ข้อความจัดกึ่งกลางทั้งบล็อก (eyebrow หัวข้อ ปุ่ม ย่อหน้า ลิงก์)
   2) เกลียวกลายเป็น "วงแหวนแนวนอน": ระยะแนวตั้งต่อใบ (spacing) เป็น 0 การ์ดจึงเรียงอยู่
      ระดับเดียวกันบนวงกลมที่มองจากด้านหน้า ใบหน้าสุดใหญ่และชัด ใบด้านหลังเล็ก จาง และเบลอ
      ตาม depth เดิมของ JS ไม่ต้องแตะ JS เลย รัศมีขยายให้วงกว้างเกือบเต็มกล่อง
      วงกลมที่หมุนรอบแกนกลางของกล่องคือรูปทรงที่สมมาตรในตัวเองทุกเฟรม */
@media (max-width: 991px) {
    .playbook-hero {
        /* หัวข้อกลับไปเท่าตอน desktop (56/64) ผังกึ่งกลางมีที่ให้เต็มความกว้าง 720px
           "PERSONALIZED" ที่ 56px กว้างราว 400px และ wordmark 450px ยังเหลือข้างละ ~150px
           ให้ไอคอนสินทรัพย์ลอยขนาบได้ (ดูบล็อก 576-991 ด้านล่าง) */
        --bt-playbook-hero-title-size: var(--font-size-56);
        --bt-playbook-hero-title-art-size: var(--font-size-64);
        /* ร่องระหว่างข้อความกับวงแหวน 64px ให้สองก้อนหายใจแยกกันชัด */
        --bt-playbook-hero-row-gap: var(--space-16);
        /* วงแหวนหมุนเองอย่างเดียว ไม่เร่งตามสกรอลล์
           สูตรใน JS หารระยะสกรอลล์ด้วย spacing x 2 พอ spacing เป็น 0 (วงแหวนแนวนอน)
           ตัวหารเหลือ 1 การ์ดจึงหมุนเร็วผิดปกติทันทีที่เลื่อนหน้า ปิดทางนี้ไปเลย
           บนจอสัมผัสการหมุนตามสกรอลล์ก็ไม่ได้ช่วยอะไร (นิ้วปัดคือเลื่อนหน้า ไม่ใช่เล่นกับเกลียว) */
        --bt-playbook-hero-spiral-scroll-drive: 0;
        /* ปิดการเลิกวนลูป (0 = ปิด) ค่า 0.8 ของ desktop ออกแบบให้การ์ดไหลหมดตอนเกลียวข้างข้อความ
           กำลังพ้นจอ แต่ช่วงนี้วงแหวนอยู่ท้าย hero พอเลื่อนลงราว 20% ของจอ
           วงแหวนยังอยู่กลางจอเต็ม ๆ แล้วการ์ดไหลออกข้างเดียวจนหายหมดภายใน 2 วินาที */
        --bt-playbook-hero-spiral-unwrap-at: 0;
        /* กล่องภาพเตี้ยลงจาก 16:10 เพราะวงแหวนแนวนอนสูงแค่ราวการ์ดใบเดียว (x1.2 ตอนอยู่หน้าสุด)
           ไม่ต้องกันที่แนวตั้งไว้ให้เกลียวไต่อีก hero ทั้งชิ้นจึงกลับมาใกล้ความสูงจอ */
        /* 2.6:1 ไม่ใช่ 2.4:1 เพื่อชดเชยร่อง 64 กับระยะใต้ header ที่เพิ่มขึ้น
           ให้ 768x1024 ยังพอดีจอ (295px ยังสูงกว่า 277px ที่ใบหน้าสุดของการ์ด 132 ต้องการ) */
        --bt-playbook-hero-visual-ratio: 2.6 / 1;
        /* การ์ดเท่าตอน desktop (132px) วงแหวนกว้างขึ้นเป็น 330px
           JS ยังตัดรัศมีไม่ให้เกิน 36% ของความกว้างกรอบ กรอบที่ 768px จึงได้วง 276px เอง */
        --bt-playbook-hero-spiral-card-width: 132px;
        --bt-playbook-hero-spiral-radius: 330px;
        --bt-playbook-hero-spiral-spacing: 0px;
        --bt-playbook-hero-spiral-center-scale: 1.25;
        --bt-playbook-hero-spiral-fit-rows: 1.5;
        /* ไอคอนย่อลงอีกขั้น กล่องเตี้ยลงแล้ว ขนาดเดิมจะไปทับวงแหวน */
        --bt-playbook-hero-asset-fit: 0.6;
        /* ต่ำกว่า lg ภาพลงไปอยู่ใต้ข้อความ บรรทัดแรกขึ้นบนสุด จึงต้องเผื่อความสูง header ไว้
           แล้วเว้นอีก 48px ให้หัวข้อไม่จ่อแถบเมนู */
        --bt-playbook-hero-padding-top: calc(var(--header-height) + var(--space-12));

        /* กล่องภาพหลุดออกจาก .container (720px) ไปกว้างเท่าจอ แต่ไม่เกิน 960px
           วงแหวนจึงกางได้กว้างกว่าคอลัมน์ข้อความ ใบด้านหลังที่จางแล้วเลยออกไปถึงขอบจอ
           อ่านเป็นวงที่ "ลอยอยู่หน้าเวที" ไม่ใช่ถูกขังอยู่ในคอลัมน์
           50% ในสูตร margin คือครึ่งหนึ่งของแถว ลบครึ่งหนึ่งของความกว้างที่ต้องการ กล่องจึงอยู่กลางเสมอ
           100vw นับรวม scrollbar ด้วย จึงต้องกันด้วย overflow-x: clip ที่ section
           (clip ไม่ใช่ hidden เพื่อไม่ให้ section กลายเป็น scroll container) */
        overflow-x: clip;

        .playbook-hero__visual {
            width: min(100vw, 960px);
            max-width: none;
            margin-inline: calc(50% - min(50vw, 480px));
        }

        .playbook-hero__content {
            align-items: center;
            text-align: center;
        }

        .playbook-hero__actions {
            justify-content: center;
        }

        /* ลิงก์เคยดึงกลับซ้ายให้ตรงกับย่อหน้าตอนชิดซ้าย พอกึ่งกลางแล้วไม่มีขอบให้ตรง
           คืนค่าเป็นศูนย์ ไม่งั้นจะเยื้องซ้าย 4px จากแกนกลาง */
        .playbook-hero__copy-action {
            margin-left: var(--space-0);
        }

        /* ภาพ wordmark "Playbook" ต้องอยู่กลางเช่นกัน (เป็น block จึงไม่ตาม text-align) */
        .playbook-hero__title-art {
            margin-inline: auto;
        }

        /* ไอคอนสี่ชิ้นวางเป็นคู่กระจกซ้าย-ขวา ห่างจากแกนกลางเท่ากันเป็นคู่ ๆ
           เหรียญ/ลูกศร (ทรงกลม-จัตุรัส) อยู่บน แท่งทอง/แท่งกราฟ (ทรงสูง) อยู่ล่าง
           ให้น้ำหนักภาพสมดุลกันทั้งสี่มุมของวงแหวน */
        .playbook-hero__asset--coin {
            top: 0%;
            left: 4%;
        }

        .playbook-hero__asset--arrow {
            top: 0%;
            right: 4%;
            bottom: auto;
        }

        .playbook-hero__asset--bar {
            top: auto;
            bottom: 0%;
            right: 6%;
        }

        .playbook-hero__asset--chart {
            bottom: -4%;
            left: 6%;
        }

        .playbook-hero__eyebrow {
            &::after {
                display: none;
            }
        }
    }
}

@media (max-width: 767px) {
    .playbook-hero {
        /* ลงจาก 56/64 ของ ≤991 หนึ่งขั้น คอลัมน์แคบกว่า 720 แล้ว (540px ที่ 576-767) */
        --bt-playbook-hero-title-size: var(--font-size-48);
        --bt-playbook-hero-title-art-size: var(--font-size-56);
        --bt-playbook-hero-padding-top: calc(var(--header-height) + var(--space-8));
        --bt-playbook-hero-padding-bottom: var(--space-8);
        --bt-playbook-hero-actions-space-top: var(--space-8);
        /* กล่องกว้างเท่าจอ (576-767) รัศมีถูก JS ตัดตามความกว้างเอง (36% ของกล่อง)
           การ์ดลดหนึ่งขั้นจาก 132 ให้ใบหน้าสุด (x1.25) ยังอยู่ในกรอบ 2.4:1 ที่กว้าง 600px */
        --bt-playbook-hero-spiral-card-width: 120px;
        --bt-playbook-hero-visual-ratio: 2.6 / 1;
    }
}

@media (max-width: 575px) {
    .playbook-hero {
        /* มือถือ: "PERSONALIZED" ที่ 40px กว้างราว 300px ยังพอดีคอลัมน์ 343px ของจอ 375
           ใหญ่กว่านี้บรรทัดจะตัด ส่วน wordmark ถูก max-width: 100% ครอบไว้อยู่แล้ว */
        --bt-playbook-hero-title-size: var(--font-size-40);
        --bt-playbook-hero-title-art-size: var(--font-size-48);
        --bt-playbook-hero-lead-size: var(--font-size-18);
        --bt-playbook-hero-copy-size: var(--font-size-16);
        /* วงแหวนการ์ดย่อตามความกว้างจอทั้งวง ภาพที่จอ 575 จึงเป็นต้นแบบของทุกจอในช่วงนี้
           เดิมการ์ดคงที่ 104px ขณะที่จอแคบลง พอถึง 375 การ์ดกินที่เกือบเท่าเดิมในจอที่แคบกว่ามาก
           ภาพเลยแน่นอึดอัด ตอนนี้การ์ด 18vw (104px ที่ 575, 68px ที่ 375) เล็กสุด 64px
           รัศมีใช้เพดาน 31% ของความกว้างกรอบ (กรอบกว้างเท่าจอ) ได้ 178px ที่ 575 และ 116px ที่ 375
           ห่างกว่าวง 150px เดิม ใบข้าง ๆ ซ้อนใบหน้าสุดแค่ราว 9px ที่ 575 และแทบไม่ซ้อนที่ 375
           (perspective คงที่ 1000px ใบหน้าสุดของวงเล็กจึงขยายน้อยกว่า ระยะซ้อนเลยลดลงตามจอ)
           ใบด้านหลังที่เลยขอบจอเป็นใบที่จางแล้ว และ section ตัดด้วย overflow-x: clip */
        --bt-playbook-hero-spiral-card-width: clamp(64px, 18vw, 104px);
        --bt-playbook-hero-spiral-radius: 180px;
        --bt-playbook-hero-spiral-radius-cap: 0.31;
        --bt-playbook-hero-visual-ratio: 16 / 9;
        /* ร่องกับขอบล่างลดลงขั้นเดียว: การ์ด 104 กับกล่อง 16:9 ทำให้ hero บนจอ 375x812
           เกินไป 17px ถ้าคง 24/32 ไว้ ลดเหลือ 16/16 แล้วพอดี (805px) ส่วน 440x900 มีที่เผื่อ */
        --bt-playbook-hero-row-gap: var(--space-4);
        /* คง 0 ไว้ตามผังวงแหวนของ ≤991 (ค่า 56px เดิมเป็นของเกลียวตั้งสมัยยังเป็นสองคอลัมน์)
           ถ้าปล่อยไว้ บล็อกนี้มาทีหลังจะชนะแล้ววงแหวนกลับกลายเป็นเกลียวตั้งเฉพาะบนมือถือ */
        --bt-playbook-hero-spiral-spacing: 0px;
        /* ขนาดกับตำแหน่งไอคอนสินทรัพย์ของช่วงนี้อยู่ในบล็อก ≤575 ท้ายส่วน hero */
        --bt-playbook-hero-spiral-edge-blur: 4;
        --bt-playbook-hero-padding-top: calc(var(--header-height) + var(--space-8));
        --bt-playbook-hero-padding-bottom: var(--space-4);
        --bt-playbook-hero-actions-gap: var(--space-4);
        --bt-playbook-hero-actions-space-top: var(--space-6);
        --bt-playbook-hero-copy-action-space: var(--space-2);

        /* ปุ่มหลักเป็น liquid metal ที่คำนวณความกว้างจากตัวอักษรของตัวเอง
           จอแคบจึงเรียงลงล่างและชิดซ้ายให้ตรงแนวกับข้อความด้านบน */
        .playbook-hero__actions {
            flex-direction: column;
            align-items: flex-start;
        }
    }
}

/* ---------- ≤991: ไอคอนสินทรัพย์ลอยทั่วทั้ง hero ไม่ใช่แค่รอบกล่องภาพ ----------
   บน lg ขึ้นไปไอคอนอยู่ในคอลัมน์ภาพ (กล่อง .playbook-hero__assets เป็น absolute
   ในกรอบ .playbook-hero__visual) พอผังกึ่งกลางเรียงลงล่าง กล่องภาพเหลือแค่แถบเตี้ย ๆ
   ท้าย hero ไอคอนสี่ชิ้นเลยกองอยู่รอบวงแหวน ส่วนข้อความด้านบนโล่งทั้งสองข้าง

   ย้าย "กรอบอ้างอิง" ของไอคอนจากกล่องภาพไปเป็นทั้งแถว (.row = ข้อความ + ภาพ)
   โดยไม่แตะ markup: ให้ .row เป็น positioned แล้วปลด position ออกจากกล่องภาพ
   ไอคอนที่เป็น absolute จึงไปยึดกับแถวแทน วางขนาบหัวข้อได้
   แต่เกลียวการ์ดต้องยังยึดกับกล่องภาพเหมือนเดิม จึงเปลี่ยนเกลียวจาก absolute
   เป็นกล่องในสายน้ำที่เต็มกล่องภาพ (relative 100%) เวทีข้างในยังเป็น absolute ของเกลียว
   JS วัดขนาดจากกล่องเกลียวโดยตรง จึงได้ค่าเท่าเดิมทุกประการ

   มือถือ (≤575) ใช้ผังเดียวกันเพื่อให้ไอคอนอยู่ตำแหน่งเดียวกับจอ 767
   แต่ที่ว่างข้างข้อความแคบกว่ามาก ขนาดกับตำแหน่งจึงมีชุดของตัวเอง (ดูบล็อก ≤575 ท้ายสุด) */
@media (max-width: 991px) {
    .playbook-hero {
        /* 85% ของชุด ≤1199 (เหรียญ 102 ลูกศร 95 แท่งทอง 82 แท่งกราฟ 61)
           ใกล้เคียงขนาด desktop ผังกึ่งกลางเหลือที่ว่างข้างหัวข้อพอ ไม่ต้องย่อเท่าผังสองคอลัมน์
           ช่วง 576-767 หัวข้อกินความกว้างคอลัมน์มากกว่า ขนาดจึงไหลตามจอ (ดูบล็อกท้ายสุด) */
        --bt-playbook-hero-asset-fit: 0.85;

        .playbook-hero__inner .row {
            position: relative;
        }

        .playbook-hero__visual {
            position: static;
        }

        .playbook-hero__spiral {
            position: relative;
            inset: auto;
            width: 100%;
            height: 100%;
        }

        /* ข้อความต้องอยู่เหนือไอคอนเสมอ (ไอคอนเป็น positioned จะทับของที่ static)
           ส่วนการ์ดในเกลียวอยู่หลังไอคอนใน DOM จึงวาดทับไอคอนได้เอง */
        .playbook-hero__content {
            position: relative;
            z-index: 1;
        }

        .playbook-hero__assets {
            z-index: 0;
        }

        /* คู่บน ขนาบหัวข้อ: เหรียญซ้าย ลูกศรขวา ระดับเดียวกับบรรทัด PERSONALIZED
           คู่ล่าง ขนาบวงแหวน: แท่งกราฟซ้าย แท่งทองขวา ยึดจากขอบล่างของแถว
           ระยะจากขอบซ้าย-ขวาเท่ากันเป็นคู่ ให้แกนกลางเดียวกับข้อความและวงแหวน */
        /* ดันออกนอกขอบแถว 24px ไปอยู่ในระยะขอบจอ ไอคอนที่ใหญ่ขึ้นจึงยังห่างจาก wordmark
           (ตัวที่กว้างที่สุดในหัวข้อ) ราว 40px ทั้งที่ 991 และ 768
           ถ้าคงไว้ที่ขอบแถวพอดี ช่องว่างจะเหลือแค่ ~10px ดูเบียด
           ที่ 768 ขอบนอกของไอคอนชนขอบจอพอดี ส่วนที่แกว่งเลยออกไปโดน overflow-x: clip ตัด */
        .playbook-hero__asset--coin {
            top: -12px;
            left: 4px;
        }

        .playbook-hero__asset--arrow {
            top: 12px;
            right: 12px;
            bottom: auto;
        }

        .playbook-hero__asset--chart {
            bottom: 180px;
            left: 32px;
        }

        .playbook-hero__asset--bar {
            top: auto;
            bottom: 260px;
            right: 8px;
        }
    }
}

/* ---------- จอแนวนอนเตี้ย (กว้าง ≤991 แต่สูงไม่ถึง 1024 เช่น 991x775 ใน DevTools) ----------
   ผังกึ่งกลางของ ≤991 ต้องการความสูงราว 1010px คิดจากแท็บเล็ตแนวตั้ง (768x1024) ที่พอดีจอ
   จอที่เตี้ยกว่านั้น hero จะล้นจอ วงแหวนการ์ดหล่นไปอยู่ใต้พับ (ที่ 991x775 ล้นราว 230px)
   เกณฑ์ 1023 จึงหมายถึง "ต่ำกว่าความสูงที่ผังปกติพอดี" ไม่ใช่ตัวเลขลอย ๆ
   จำกัดความกว้างขั้นต่ำ 576 ด้วย เพราะมือถือแนวตั้งก็ "เตี้ยกว่า 1024" เหมือนกัน
   แต่ไม่ใช่เคสจอแนวนอน ถ้าปล่อยให้เข้าเงื่อนไข กล่องภาพ 4.5:1 บนจอกว้าง 375
   จะเหลือสูงแค่ 83px วงแหวนถูกย่อจนการ์ดเหลือ 52px (เคยหลุดไปแล้วครั้งหนึ่ง)
   มือถือใช้ค่าของบล็อก ≤575 ตามปกติ ส่วนมือถือแนวนอน (กว้าง 576+ เตี้ย) ยังเข้าบล็อกนี้
   ตรงนี้เลยบีบแนวตั้งทั้งชุดในคราวเดียว โดยคงลำดับและสัดส่วนเดิม:
   ช่องไฟระหว่างบล็อกลดลงหนึ่งขั้น การ์ดในวงแหวนย่อลง (108 -> 88px) และกล่องภาพ
   เปลี่ยนจาก 2:1 เป็น 3:1 เพราะวงแหวนที่การ์ดเล็กลงต้องการความสูงน้อยลงตามส่วน
   ใช้ max-height ไม่ใช่แค่ max-width เพราะแท็บเล็ตแนวตั้ง (768x1024) พอดีจออยู่แล้ว
   ไม่ควรถูกบีบตาม */
@media (min-width: 576px) and (max-width: 991px) and (max-height: 1023px) {
    .playbook-hero {
        /* วัดที่ 991x775 แล้วยังเกิน 18px จึงไล่เก็บจากขอบนอกก่อนแตะเนื้อหา:
           ระยะใต้ header 16 -> 8, ขอบล่าง 24 -> 16, ร่องระหว่างข้อความกับภาพ 16 -> 12
           และกล่องภาพ 3:1 -> 3.2:1 (225px ยังสูงกว่าวงแหวนที่การ์ด 88px ต้องการ ~155px)
           รวมแล้วเหลือ 758px ในจอ 775 มีที่เผื่อ 17px */
        /* ร่อง 64 กับระยะใต้ header 32 คงไว้ตามที่ต้องการ แม้จะทำให้ 991x775 เกินจอราว 75px
           (วงแหวนล้นใต้พับเล็กน้อย) ยอมแลกกับที่ว่างระหว่างก้อนที่อ่านง่ายกว่า
           ที่ 991x900 ยังพอดีจอ */
        --bt-playbook-hero-padding-top: calc(var(--header-height) + var(--space-8));
        --bt-playbook-hero-padding-bottom: var(--space-4);
        --bt-playbook-hero-title-space: var(--space-4);
        --bt-playbook-hero-content-gap: var(--space-8);
        --bt-playbook-hero-actions-space-top: var(--space-4);
        --bt-playbook-hero-copy-action-space: var(--space-2);
        /* กล่องกว้าง 960 (ที่ 991) จึงเตี้ยลงเป็น 4.5:1 = 213px พอดีกับใบหน้าสุดของการ์ด 100px
           (100 x 1.4 x 1.25 x ระยะมอง ≈ 210) hero รวมยังอยู่ใน 775px */
        --bt-playbook-hero-visual-ratio: 4.5 / 1;
        --bt-playbook-hero-spiral-card-width: 100px;
        --bt-playbook-hero-spiral-radius: 330px;
        /* ไม่ย่อไอคอนในบล็อกนี้ ไอคอนเป็น absolute ไม่ได้กินความสูงของ hero
           ย่อไปก็ไม่ได้ช่วยให้พอดีจอ ได้แค่ไอคอนเล็กลงเปล่า ๆ (เคยตั้งไว้ 0.5) */

        /* ระยะระหว่าง PERSONALIZED กับ wordmark ลดตามส่วนกับที่อื่น (24 -> 8) */
        .playbook-hero__title-art {
            margin-top: var(--space-2);
        }
    }
}

/* 576-767: แถวกว้างเกือบเต็มจอ (ขอบจอแค่ ~6px) แต่ wordmark ยังกว้าง 394px เท่าเดิม
   ที่ว่างข้างหัวข้อจึงแปรตามความกว้างจอมาก: ที่ 576 เหลือราว 85px ที่ 700 เหลือราว 150px
   ตัวเลขเดียวใช้ไม่ได้ทั้งช่วง (0.8 เดิมชน wordmark ที่ 576-600 ส่วน 0.6 ก็เล็กเกินที่ 700+)
   จึงให้ขนาดไหลตามความกว้างจอ: 1 หน่วย = 1px ที่ขนาดเต็ม (ราว 675px ขึ้นไป)
   ต่ำกว่านั้นลดลงเป็นเส้นตรงจนเหลือ 0.6 ที่ 576 ไอคอนทั้งสี่ย่อพร้อมกันตามสัดส่วนเดิม
   สูตรมาจาก "ครึ่งจอ - ครึ่ง wordmark (197) - ระยะเว้น (16)" = ที่ว่างที่เหรียญวางได้
   หาร 124 (เหรียญ 120 + ส่วนที่มุมเอียงเกินกล่องออกมา) ได้เป็นสัดส่วนของขนาดเต็ม

   ช่วงนี้ขอบแถวชนขอบจออยู่แล้ว จึงคืนตำแหน่งคู่บนกลับไปที่ขอบแถวพอดี
   ถ้าดันออก -24px แบบช่วง 768-991 ไอคอนจะหลุดจอไปเกือบครึ่งใบ */
@media (min-width: 576px) and (max-width: 767px) {
    .playbook-hero {
        /* ลดลงเท่ากับช่วง 768-991 (85%) สูตรไหลตามจอด้านล่างยังคุมไม่ให้ชนหัวข้อ
           ย่อแล้วยิ่งห่างหัวข้อขึ้น จึงไม่ต้องแก้สูตร */
        --bt-playbook-hero-asset-fit: 0.85;
        --bt-playbook-hero-asset-unit: clamp(0.6px, calc((50vw - 213px) / 124), 1px);
        --bt-playbook-hero-asset-coin-size: calc(var(--bt-playbook-hero-asset-unit) * 120);
        --bt-playbook-hero-asset-arrow-size: calc(var(--bt-playbook-hero-asset-unit) * 112);
        --bt-playbook-hero-asset-bar-size: calc(var(--bt-playbook-hero-asset-unit) * 96);
        --bt-playbook-hero-asset-chart-size: calc(var(--bt-playbook-hero-asset-unit) * 72);

        .playbook-hero__asset--coin {
            left: var(--space-0);
        }

        .playbook-hero__asset--arrow {
            right: var(--space-0);
        }
    }
}

/* ≤575: ไอคอนอยู่ตำแหน่งเดียวกับจอ 767 (ผังจากบล็อก ≤991 ด้านบน ไอคอนยึดกับทั้งแถว)
   เหรียญ-ลูกศรขนาบหัวข้อ แท่งทองขนาบย่อหน้าบน แท่งกราฟขนาบย่อหน้าล่าง
   ต่างกันที่ข้อความกินเกือบเต็มจอ ที่จอ 375 เหลือที่ข้างละราว 45-65px
   (ข้างหัวข้อเล็ก 65, ข้างย่อหน้าบน 51, ข้างย่อหน้าล่าง 46) และแถวปุ่มกว้างเกือบเต็มจอ

   ขนาด: หน่วยไหลตามจอต่อจากช่วง 576-767 (ซึ่งเริ่มที่ 0.6) ลงไปเหลือ 0.46 ที่ 375
   เหรียญจึงกว้าง 61px ที่ 575 และ 47px ที่ 375 พอดีช่องข้างหัวข้อเล็ก
   ตำแหน่งนับจากขอบบนของแถว เพราะความสูงของก้อนข้อความเท่ากันทุกจอในช่วงนี้
   (ส่วนกล่องวงแหวนด้านล่างสูงตามความกว้างจอ ถ้านับจากขอบล่างตำแหน่งจะเลื่อนตามจอ)
   - ลูกศรไม่เหลื่อมลงมาเหมือน 767 ไม่งั้นมุมจะเข้าไปทับท้าย "PERSONALIZED"
   - แท่งทองอยู่ระดับย่อหน้าบน (บรรทัด 183-234px) จบก่อนถึงแถวปุ่ม (266px)
   - แท่งกราฟอยู่ระดับย่อหน้าล่างกับลิงก์ นับจากขอบล่างของแถวแทน ให้ปลายล่างจบเหนือวงแหวน 4px
     ทุกจอ (กล่องวงแหวนสูง = ความกว้างจอ / สัดส่วนกล่อง) ถ้านับจากบนเหมือนชิ้นอื่น
     แท่งที่ยาวขึ้นตามจอจะยื่นลงไปทับวงแหวน 33px ที่ 575
   - ชิดขอบแถวทั้งสี่ชิ้น ระยะ 32/8px แบบ 767 จะดันแท่งกราฟเข้าไปทับตัวหนังสือ */
@media (max-width: 575px) {
    .playbook-hero {
        --bt-playbook-hero-asset-fit: 0.85;
        --bt-playbook-hero-asset-unit: clamp(0.45px, calc(0.2px + 0.07vw), 0.6px);
        --bt-playbook-hero-asset-coin-size: calc(var(--bt-playbook-hero-asset-unit) * 120);
        --bt-playbook-hero-asset-arrow-size: calc(var(--bt-playbook-hero-asset-unit) * 112);
        --bt-playbook-hero-asset-bar-size: calc(var(--bt-playbook-hero-asset-unit) * 96);
        /* 64 ไม่ใช่ 72: แท่งกราฟสูงราว 4.5 เท่าของความกว้าง ช่องระหว่างปุ่มกับวงแหวนมีแค่ ~132px
           ที่ 72 แท่งยาว 138px ที่จอ 430 ปลายบนจึงชนมุมซ้ายล่างของปุ่ม */
        --bt-playbook-hero-asset-chart-size: calc(var(--bt-playbook-hero-asset-unit) * 64);

        .playbook-hero__asset--coin {
            top: -12px;
            right: auto;
            bottom: auto;
            left: var(--space-0);
        }

        .playbook-hero__asset--arrow {
            top: var(--space-0);
            right: var(--space-0);
            bottom: auto;
            left: auto;
        }

        .playbook-hero__asset--bar {
            top: 167px;
            right: var(--space-0);
            bottom: auto;
            left: auto;
        }

        .playbook-hero__asset--chart {
            top: auto;
            right: auto;
            bottom: calc(100vw / (var(--bt-playbook-hero-visual-ratio)) + var(--space-1));
            left: var(--space-0);
        }
    }
}


/* ==========================================================================
   Section: Playbook Intro — What it is (personalized-playbook.html)
   หัวข้อใช้ component ชุดเดียวกับ section อื่นของเว็บ (.bt-section-subtext /
   .bt-section-title) แล้ว override เฉพาะสิ่งที่ต่างจริง คือจัดกึ่งกลางและ
   กลับสีให้อ่านบนพื้นมืด ต่อเนื่องจาก hero ด้านบนโดยไม่มีรอยต่อ
   ========================================================================== */
.playbook-intro {
    --bt-playbook-intro-padding-y: var(--section-padding-y);
    --bt-playbook-intro-lead-space: var(--space-12);
    --bt-playbook-intro-lead-size: var(--font-size-24);
    /* ตัวโตขึ้นแล้วระยะบรรทัดต้องแน่นลง ไม่งั้นย่อหน้ากลางจอจะอ่านเป็นบรรทัดลอย ๆ
       ไม่ลงไปต่ำกว่านี้เพราะสระบน-ล่างของไทยต้องการที่ว่างระหว่างบรรทัด */
    --bt-playbook-intro-lead-line-height: 1.5;
    --bt-playbook-intro-lead-max-width: var(--layout-narrow-max);
    --bt-playbook-intro-note-space: var(--space-8);
    --bt-playbook-intro-note-size: var(--font-size-18);
    --bt-playbook-intro-note-line-height: var(--line-height-relaxed);
    --bt-playbook-intro-note-max-width: var(--layout-narrow-max);
    /* การ์ดลอย: size คือความกว้างฐาน แต่ละใบคูณสเกลของตัวเองอีกที
       amplitude คือระยะขยับสูงสุดของใบที่ depth = 1 (JS อ่านค่านี้ไปคูณกับ depth) */
    /* ย่อตามจอทั้งสองแกน ไม่ใช่แค่ความกว้าง เพราะการ์ดชุดนี้ลอยรอบบล็อกข้อความ
       พอหน้าต่างเตี้ยลง (เช่นจอ laptop 13 นิ้วที่เปิด dock หรือหน้าต่างครึ่งจอ)
       ที่ว่างบน-ล่างหายไปก่อนที่ความกว้างจะเปลี่ยน การ์ดจะเริ่มเบียดข้อความ
       vmin = ด้านที่สั้นกว่าของจอ จึงตอบทั้งจอแคบลงและจอเตี้ยลงด้วยค่าเดียว
       ปลายบนคงไว้ที่ 150px เท่าเดิม จอปกติจึงไม่เปลี่ยนจากของเดิมเลย */
    --bt-playbook-intro-float-size: clamp(96px, 18vmin, 150px);
    --bt-playbook-intro-float-amplitude: 26px;
    --bt-playbook-intro-float-radius: var(--radius-2);
    --bt-playbook-intro-float-shadow: 0 18px 44px color-mix(in srgb, var(--color-neutral-950) 60%, transparent);
    --bt-playbook-intro-float-stagger: 180ms;
    /* การพลิกหน้า-หลังของสี่ใบมุม: duration คือความเร็วพลิกหนึ่งครั้ง
       ส่วนจังหวะเริ่มกับรอบของแต่ละใบอยู่ที่ nth-child ด้านล่าง ตั้งไม่เท่ากันโดยตั้งใจ
       เลขรอบไม่หารลงตัวกัน สี่ใบจึงไม่มีวันกลับมาพลิกพร้อมกัน */
    --bt-playbook-intro-float-flip-duration: 900ms;
    --bt-playbook-intro-float-flip-perspective: 900px;
    /* ภาพฉากไหลต่อจาก hero: ใช้ชุดค่าการแสดงผลเดียวกับพื้นหลัง hero ทุกอย่าง
       (ม่านไล่สีแนวนอนจางไปทางขวา + ไล่เข้มที่ขอบล่าง) เพื่อให้สองส่วนอ่านเป็นฉากเดียวกัน
       ประกาศเป็น token ของ section นี้เอง ไม่ได้อ้าง token ของ hero ข้ามมา
       ภาพตรึงกับจอ ไม่เลื่อนตามหน้า ฉากจึงต่อเนื่องจาก hero โดยไม่มีรอยต่อ */
    --bt-playbook-intro-ornament-length: var(--space-32);
    --bt-playbook-intro-ornament-space: var(--space-10);
    --bt-playbook-intro-ink: var(--color-neutral-0);
    --bt-playbook-intro-ink-soft: color-mix(in srgb, var(--color-neutral-0) 88%, transparent);
    --bt-playbook-intro-ink-dim: color-mix(in srgb, var(--color-neutral-0) 72%, transparent);

    /* svh คือความสูงจอตอนแถบเบราว์เซอร์กางอยู่ ใช้แทน vh เพื่อไม่ให้ section
       กระโดดตอนแถบที่อยู่เว็บบนมือถือย่อ-ขยาย (เบราว์เซอร์เก่าตกมาใช้ vh) */
    --bt-playbook-intro-min-height: 100vh;

    position: relative;
    min-height: var(--bt-playbook-intro-min-height);
    display: grid;
    align-content: center;
    isolation: isolate;
    padding: var(--bt-playbook-intro-padding-y) var(--space-0);
    color: var(--bt-playbook-intro-ink);
    /* พื้นหลังเป็นของ .playbook-scene ที่ครอบอยู่ ตรงนี้ต้องโปร่งเพื่อให้ฉากทะลุขึ้นมา */
    background: transparent;
    font-family: var(--font-family-base);

    @supports (height: 100svh) {
        --bt-playbook-intro-min-height: 100svh;
    }

    /* ชั้นการ์ดลอยอยู่หลังเนื้อหาเสมอ และไม่รับคลิก เพื่อไม่ให้บังข้อความหรือลิงก์ */
    .playbook-intro__float {
        position: absolute;
        inset: var(--space-0);
        z-index: 0;
        overflow: hidden;
        pointer-events: none;

        /* ประกาศเป็น container เพื่อให้ใช้หน่วย cqw/cqh ได้ ตอนคำนวณระยะจากตำแหน่งของ
           การ์ดแต่ละใบกลับมาที่กึ่งกลางกรอบ — เป็นวิธีเดียวที่เขียนเป็น CSS ล้วนได้
           เพราะ % ใน translate หมายถึงขนาดของตัวการ์ดเอง ไม่ใช่ขนาดกรอบ */
        container-type: size;
    }

    .playbook-intro>.container {
        position: relative;
        z-index: 1;
    }

    /* กล่องนอกเป็นของ JS (เขียน transform ทุกเฟรมตอนตามเคอร์เซอร์)
       ส่วนจังหวะโผล่ตอนเข้าจออยู่ที่ภาพด้านใน แยกเจ้าของ transform กันคนละชั้น
       ไม่งั้นสองอย่างจะเขียนทับกัน */
    .playbook-intro__float-item {
        position: absolute;
        width: calc(var(--bt-playbook-intro-float-size) * var(--bt-playbook-intro-float-item-scale, 1));
    }

    /* สามชั้นซ้อนกัน แต่ละชั้นมีเจ้าของ transform คนละคนจึงไม่เขียนทับกัน
       item = JS (ขยับตามเคอร์เซอร์) / inner = CSS (กระจายออกจากกึ่งกลางตอนเข้าจอ)
       / flip = JS (พลิกหน้า-หลัง)

       --from ของแต่ละใบคือระยะจากตำแหน่งจริงกลับมาที่กึ่งกลาง (ดูค่าที่ nth-child ด้านล่าง) */
    .playbook-intro__float-inner {
        opacity: 0;
        transform: var(--bt-playbook-intro-float-item-from, translate(0, 0)) scale(0.55);
        transition:
            opacity 720ms ease var(--bt-playbook-intro-float-item-delay, 0ms),
            transform 1100ms var(--ease-standard) var(--bt-playbook-intro-float-item-delay, 0ms);
    }

    /* ไล่ทีละใบ ให้อ่านเป็นกองการ์ดที่คลี่ออกจากจุดเดียวกลางจอ */
    .playbook-intro__float.is-revealed .playbook-intro__float-inner {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }

    /* ใส่ perspective ไว้ใน transform ของตัวเอง ไม่ต้องพึ่ง ancestor
       (ชั้นแม่มี transform ของตัวเองอยู่แล้ว perspective ที่ประกาศแยกจะไม่ส่งถึงหลานชั้นนี้) */
    .playbook-intro__float-flip {
        position: relative;
        transform: perspective(var(--bt-playbook-intro-float-flip-perspective)) rotateY(0deg);
        transform-style: preserve-3d;
        transition: transform var(--bt-playbook-intro-float-flip-duration) var(--ease-standard);
    }

    /* ใบหน้าอยู่ในสายเอกสารปกติ เป็นตัวกำหนดความสูงของกรอบ
       ส่วนใบหลังทาบทับไว้แล้วหมุนกลับด้าน 180 องศา */
    .playbook-intro__float-face {
        width: 100%;
        height: auto;
        display: block;
        border-radius: var(--bt-playbook-intro-float-radius);
        box-shadow: var(--bt-playbook-intro-float-shadow);
        backface-visibility: hidden;
    }

    .playbook-intro__float-face--back {
        position: absolute;
        inset: var(--space-0);
        height: 100%;
        transform: rotateY(180deg);
    }

    /* วางแบบสมมาตร: สี่ใบมุม ใช้ top/bottom + left/right คู่กัน ระยะขอบจึงเท่ากันเป๊ะ
       ไม่ว่าการ์ดจะกว้างเท่าไร (ถ้าใช้ left อย่างเดียว ฝั่งขวาจะเยื้องตามความกว้างการ์ด)
       อีกสองใบเกาะขอบซ้าย-ขวาที่ระดับกึ่งกลางแนวตั้งพอดี
       สี่ใบมุมตั้งขนาดต่างกันรายใบ (ดูที่ nth-child ด้านล่าง) ให้ไล่ใหญ่-เล็กสลับทแยงกัน
       ตำแหน่งยังสมมาตรเหมือนเดิมเพราะยึดจากระยะขอบ ไม่ได้ยึดจากขนาดการ์ด */

    .playbook-intro__float-item:nth-child(3),
    .playbook-intro__float-item:nth-child(4) {
        --bt-playbook-intro-float-item-scale: 0.56;

        /* หักครึ่งความสูงการ์ดออกจากกึ่งกลาง (สัดส่วนไฟล์ 520x728 ครึ่งหนึ่งคือ 0.7 เท่าของความกว้าง)
           กึ่งกลางการ์ดจึงตรงกับกึ่งกลางกรอบพอดี ระยะถอยกลับแนวตั้งของสองใบนี้เลยเป็นศูนย์ */
        top: calc(50% - var(--bt-playbook-intro-float-size) * var(--bt-playbook-intro-float-item-scale) * 0.7);
    }

    .playbook-intro__float-item:nth-child(1) {
        --bt-playbook-intro-float-item-scale: 1.08;
        --bt-playbook-intro-float-flip-delay: 1600ms;
        --bt-playbook-intro-float-flip-period: 6400ms;
        --bt-playbook-intro-float-item-from: translate(calc(34cqw - 50%), calc(40cqh - 50%));
        --bt-playbook-intro-float-item-delay: 0ms;

        top: 8%;
        left: 16%;
    }

    .playbook-intro__float-item:nth-child(2) {
        --bt-playbook-intro-float-item-scale: 0.8;
        --bt-playbook-intro-float-flip-delay: 3000ms;
        --bt-playbook-intro-float-flip-period: 7100ms;
        --bt-playbook-intro-float-item-from: translate(calc(50% - 38cqw), calc(40cqh - 50%));
        --bt-playbook-intro-float-item-delay: 0ms;

        top: 14%;
        right: 16%;
    }

    .playbook-intro__float-item:nth-child(3) {
        --bt-playbook-intro-float-item-from: translate(calc(50% - 47cqw), 0);
        --bt-playbook-intro-float-item-delay: var(--bt-playbook-intro-float-stagger);

        right: 3%;
    }

    .playbook-intro__float-item:nth-child(4) {
        --bt-playbook-intro-float-item-from: translate(calc(47cqw - 50%), 0);
        --bt-playbook-intro-float-item-delay: var(--bt-playbook-intro-float-stagger);

        left: 3%;
    }

    .playbook-intro__float-item:nth-child(5) {
        --bt-playbook-intro-float-item-scale: 0.88;
        --bt-playbook-intro-float-flip-delay: 4400ms;
        --bt-playbook-intro-float-flip-period: 5900ms;
        --bt-playbook-intro-float-item-from: translate(calc(38cqw - 50%), calc(50% - 40cqh));
        --bt-playbook-intro-float-item-delay: calc(var(--bt-playbook-intro-float-stagger) * 2);

        bottom: 14%;
        left: 12%;
    }

    .playbook-intro__float-item:nth-child(6) {
        --bt-playbook-intro-float-item-scale: 1;
        --bt-playbook-intro-float-flip-delay: 5800ms;
        --bt-playbook-intro-float-flip-period: 6700ms;
        --bt-playbook-intro-float-item-from: translate(calc(50% - 34cqw), calc(50% - 40cqh));
        --bt-playbook-intro-float-item-delay: calc(var(--bt-playbook-intro-float-stagger) * 2);

        bottom: 10%;
        right: 12%;
    }

    @media (prefers-reduced-motion: reduce) {

        .playbook-intro__float-inner,
        .playbook-intro__float-flip {
            transition: none;
        }
    }

    .playbook-intro__header {
        text-align: center;
    }

    /* component เดิมวางเส้น-ดาวต่อท้ายข้อความในแถวเดียวกัน พอ section นี้จัดกึ่งกลาง
       เส้นจะดันให้ข้อความดูเยื้องซ้าย จึงให้ ::after ขึ้นบรรทัดใหม่ด้วย flex-basis เต็มแถวแทน
       แล้วเปลี่ยนเป็น line-star.webp ที่ดาวอยู่กึ่งกลางเส้น (คนละภาพกับ line-star-trail
       ของ component ซึ่งดาวอยู่ปลายข้างเดียว เหมาะกับ section ที่ชิดซ้าย)
       กล่องกว้างเต็มแถวเพื่อให้จัดกึ่งกลางเอง ความยาวเส้นจึงคุมที่ background-size ไม่ใช่ width */
    .playbook-intro__eyebrow {
        justify-content: center;
        flex-wrap: wrap;
        color: var(--bt-playbook-intro-ink-dim);

        &::after {
            flex-basis: 100%;
            width: auto;
            /* อัตราส่วนภาพ 360:39 ใช้ตัวหารชุดเดียวกับเส้นคั่น line-star ที่อื่นในเว็บ */
            height: calc(var(--bt-playbook-intro-ornament-length) / 9.13);
            margin: var(--bt-playbook-intro-ornament-space) var(--space-0) var(--space-0);
            background:
                url('../images/line-star.webp') center / var(--bt-playbook-intro-ornament-length) auto no-repeat;
        }
    }

    /* ตั้งแต่ 1500px ขึ้นไปพื้นที่พอให้หัวข้ออยู่บรรทัดเดียว จึงซ่อนตัวขึ้นบรรทัดทิ้ง
       (เว้นวรรคก่อน <br> ไว้ใน markup แล้ว พอซ่อนสองคำจึงยังมีช่องไฟคั่น ไม่ติดกัน) */
    @media (min-width: 1600px) {
        .playbook-intro__title-break {
            display: none;
        }
    }

    .playbook-intro__title {
        color: var(--bt-playbook-intro-ink);
        font-weight: var(--font-weight-medium);
        text-transform: uppercase;
    }

    .playbook-intro__lead {
        max-width: var(--bt-playbook-intro-lead-max-width);
        margin: var(--bt-playbook-intro-lead-space) auto var(--space-0);
        color: var(--bt-playbook-intro-ink-soft);
        font-size: var(--bt-playbook-intro-lead-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--bt-playbook-intro-lead-line-height);
    }

    .playbook-intro__note {
        max-width: var(--bt-playbook-intro-note-max-width);
        margin: var(--bt-playbook-intro-note-space) auto var(--space-0);
        color: var(--bt-playbook-intro-ink-dim);
        font-size: var(--bt-playbook-intro-note-size);
        font-weight: var(--font-weight-light);
        line-height: var(--bt-playbook-intro-note-line-height);
    }
}

/* คอลัมน์ข้อความกว้างเท่าเดิม (856px) แต่จอแคบลง ขอบข้างเหลือข้างละ 172px
   การ์ดลอยที่เคยอยู่นอกแนวข้อความจึงเลื่อนเข้ามาทับตัวหนังสือ
   แก้สองทางพร้อมกัน: ย่อการ์ดให้พอดีช่องว่างที่เหลือ และดันออกไปชิดขอบมากขึ้น
   (ย่ออย่างเดียวไม่พอ เพราะใบใหญ่สุดยังกว้างเกินครึ่งของช่องว่าง
   ส่วนดันออกอย่างเดียวก็ไม่พอ ใบ 162px ต้องไปอยู่ที่ left: 0 ถึงจะพ้นข้อความ) */
@media (max-width: 1199px) {
    .playbook-intro {
        --bt-playbook-intro-float-size: clamp(88px, 14vmin, 112px);
        --bt-playbook-intro-lead-space: var(--space-8);
        --bt-playbook-intro-note-space: var(--space-6);
        /* ระยะที่การ์ดเลื่อนตามเคอร์เซอร์ คูณกับ depth ของแต่ละใบ (สูงสุด 2.2 ในใบกลาง)
           ที่ 26px ใบมุมจะแกว่งได้ถึง 42px ซึ่งกินระยะกันชนที่เผื่อไว้จนทับข้อความอีก
           ลดเหลือ 10px เพราะใบ 1 ถูกขยับเข้าหาข้อความ ระยะเผื่อเหลือ 15px
           ถ้าคงไว้ที่ 16px ใบนั้นจะแกว่งได้ 19px ซึ่งเกินระยะเผื่อไปแล้ว */
        --bt-playbook-intro-float-amplitude: 10px;

        .playbook-intro__float-item:nth-child(1) {
            left: 6%;
        }

        .playbook-intro__float-item:nth-child(2) {
            right: 7%;
        }

        .playbook-intro__float-item:nth-child(3) {
            right: 12%;
        }

        .playbook-intro__float-item:nth-child(4) {
            left: 12%;
        }

        .playbook-intro__float-item:nth-child(5) {
            left: 2%;
        }

        .playbook-intro__float-item:nth-child(6) {
            right: 2%;
        }
    }
}

@media (max-width: 991px) {
    .playbook-intro {
        /* จอแคบภาพแคบลงมาก ม่านแนวนอนจะเหลือแต่ด้านมืด เลยสลับเป็นแนวตั้งชุดเดียวกับ hero */
        --bt-playbook-intro-backdrop-veil: linear-gradient(180deg,
                color-mix(in srgb, var(--color-neutral-950) 88%, transparent) 0%,
                color-mix(in srgb, var(--color-neutral-950) 68%, transparent) 55%,
                color-mix(in srgb, var(--color-neutral-950) 82%, transparent) 100%);
        --bt-playbook-intro-padding-y: var(--section-padding-y-sm);
        --bt-playbook-intro-lead-size: var(--font-size-20);
        --bt-playbook-intro-note-size: var(--font-size-16);
        --bt-playbook-intro-note-space: var(--space-6);
        --bt-playbook-intro-float-size: clamp(80px, 15vmin, 112px);
        --bt-playbook-intro-float-amplitude: 18px;
    }
}

@media (max-width: 767px) {
    .playbook-intro {
        .playbook-intro__float-item:nth-child(3) {
            top: 40%;
            right: 12%;
        }

        .playbook-intro__float-item:nth-child(4) {
            top: 40%;
            left: 12%;
        }

        .playbook-intro__float-item:nth-child(5) {
            bottom: 10%;
            left: 2%;
        }

        .playbook-intro__float-item:nth-child(6) {
            bottom: 6%;
            right: 2%;
        }
    }
}

@media (max-width: 575px) {
    .playbook-intro {
        --bt-playbook-intro-note-size: var(--font-size-14);
        /* เล็กลงราว 17% จากชุดเดิม (64 / 22vmin / 84) ที่จอ 375 จึงได้ 68px แทน 82px
           การ์ดสี่ใบมุมเบียดบล็อกข้อความน้อยลง */
        --bt-playbook-intro-float-size: clamp(56px, 18vmin, 68px);
        --bt-playbook-intro-float-radius: var(--radius-1);
        --bt-playbook-intro-lead-size: var(--font-size-18);

        /* จอแคบข้อความกินเต็มความกว้าง สองใบที่เกาะขอบระดับกึ่งกลางจะไปทับพอดี
           จึงเหลือเฉพาะสี่ใบมุมที่อยู่เหนือ-ใต้บล็อกข้อความ ความสมมาตรยังอยู่ครบ */
        .playbook-intro__float-item:nth-child(3),
        .playbook-intro__float-item:nth-child(4) {
            display: none;
        }

        .playbook-intro__float-item:nth-child(1) {
            top: 2%;
        }

        .playbook-intro__float-item:nth-child(2) {
            top: 8%;
        }

        .playbook-intro__float-item:nth-child(5) {
            bottom: 8%;
        }

        .playbook-intro__float-item:nth-child(6) {
            bottom: 4%;
        }
    }

    .playbook-intro__title-break {
        display: none;
    }
}


/* ==========================================================================
   Section: Playbook Benefit — What you get (personalized-playbook.html)
   ใช้ component หัวข้อและ grid ของ Bootstrap ชุดเดียวกับ section อื่นในเว็บ
   ภายในการ์ดเป็น UI ที่สร้างจาก HTML/CSS และ interaction เดิม ไม่ใช้ภาพ mockup สำเร็จ
   ========================================================================== */
.playbook-benefit {
    --bt-playbook-benefit-padding-y: var(--section-padding-y);
    --bt-playbook-benefit-lead-space: var(--space-12);
    --bt-playbook-benefit-lead-size: var(--section-topic-size-sm);
    --bt-playbook-benefit-lead-max-width: var(--layout-narrow-max);
    --bt-playbook-benefit-list-space: var(--space-16);
    --bt-playbook-benefit-list-row-gap: var(--space-12);
    --bt-playbook-benefit-list-gutter: var(--space-12);
    --bt-playbook-benefit-media-height: 320px;
    /* เพดานการย่อของทั้งก้อนเนื้อหาในกรอบ (js/playbook-benefit-media.js อ่านไปใช้)
       1 = ไม่บังคับ ปล่อยให้ย่อเท่าที่จำเป็นเพื่อให้พอดีกรอบ */
    --bt-playbook-benefit-fit-max: 1;
    /* ---------- พื้นหลังจุดไข่ปลา (พอร์ตจาก DotPattern ของ React) ----------
       ต้นฉบับตั้งไว้ตาราง 16px สี neutral-400 ที่ 80% ซึ่งบนพื้นกระดาษอ่อนของการ์ดนี้
       จุดจะเด่นเกินจนแย่งสายตาจากเนื้อหา และห่างจนเห็นเป็นจุด ๆ ไม่ใช่เนื้อกระดาษ
       จึงถี่ขึ้นเป็น 10px และลดความเข้มเหลือ 38% ให้อ่านเป็นผิวสัมผัสจาง ๆ แทน
       -at คือจุดศูนย์กลางของ mask ค่าตั้งต้นอยู่กึ่งกลางขอบล่าง ทับรายใบได้ด้วย modifier */
    /* หลังการ์ดที่สอดอยู่หลังแผงคะแนนของใบ Skill โผล่ออกมาที่มุมขวาล่าง
       ค่าติดลบคือระยะที่การ์ดเลยขอบกรอบออกไป ส่วนนั้นถูก overflow ตัดทิ้ง */
    --bt-playbook-benefit-skill-card-width: 265px;
    --bt-playbook-benefit-skill-card-bottom: -74px;
    /* ความสูงของแถบที่ไล่จางตรงขอบล่าง เหนือแถบนี้การ์ดทึบเต็มตามปกติ
       เป็น px ไม่ใช่ % แถบจึงสูงเท่าเดิมเสมอ ไม่ยืดตามขนาดการ์ด */
    --bt-playbook-benefit-skill-card-fade: 112px;
    --bt-playbook-benefit-dots-gap: 10px;
    --bt-playbook-benefit-dots-radius: 1px;
    --bt-playbook-benefit-dots-ink: color-mix(in srgb, var(--color-neutral-400) 38%, transparent);
    --bt-playbook-benefit-dots-fade: 300px;
    --bt-playbook-benefit-dots-at: 50% 100%;
    --bt-playbook-benefit-media-padding: var(--space-8);
    --bt-playbook-benefit-media-gap: var(--bt-playbook-benefit-media-item-gap);
    /* ขนาด/น้ำหนัก/สีของการ์ดตัวอย่างยึดตามต้นฉบับใน dna-quiz-flow
       (สีม่วง-ชมพู-เหลืองเป็นชุดสีของหน้านั้นโดยเฉพาะ ไม่มีใน token กลางของเว็บ) */
    --bt-playbook-benefit-media-label-size: var(--font-size-16);
    --bt-playbook-benefit-media-copy-size: 13px;
    --bt-playbook-benefit-card-padding: var(--space-4);
    --bt-playbook-benefit-violet: #9c91ff;
    --bt-playbook-benefit-pink: #f178d8;
    --bt-playbook-benefit-yellow: #f2ea83;
    --bt-playbook-benefit-ok-ink: #15803d;
    --bt-playbook-benefit-warn-ink: #8a5a00;
    --bt-playbook-benefit-media-ink: var(--color-text-muted);
    --bt-playbook-benefit-media-line: rgba(17, 19, 24, 0.08);
    --bt-playbook-benefit-media-paper: #FFF;
    --bt-playbook-benefit-serif: 'Baskervville', var(--font-family-base);
    --bt-playbook-benefit-motion-lead: 200ms;
    --bt-playbook-benefit-motion-chip: 520ms;
    --bt-playbook-benefit-motion-card: 640ms;
    --bt-playbook-benefit-motion-bar: 1300ms;
    --bt-playbook-benefit-motion-value: 440ms;
    --bt-playbook-benefit-compare-width: 264px;
    --bt-playbook-benefit-compare-ratio: 5 / 7;
    --bt-playbook-benefit-compare-radius: var(--space-4);
    --bt-playbook-benefit-compare-chip-inset: var(--space-3);
    --bt-playbook-benefit-compare-shadow: 0 10px 30px rgba(17, 19, 24, 0.15), 0 2px 6px rgba(17, 19, 24, 0.09);
    --bt-playbook-benefit-chip-gap: 6px;
    --bt-playbook-benefit-chip-padding-y: 2px;
    --bt-playbook-benefit-media-item-gap: var(--space-3);
    --bt-playbook-benefit-traits-gap: var(--space-4);
    --bt-playbook-benefit-media-copy-line-height: 1.35;
    --bt-playbook-benefit-skill-bar-height: var(--border-width-2);
    --bt-playbook-benefit-compare-handle-size: var(--space-10);
    --bt-playbook-benefit-compare-chip-bg: rgba(17, 19, 24, 0.62);
    --bt-playbook-benefit-compare-handle-shadow: 0 4px 14px rgba(17, 19, 24, 0.28);
    --bt-playbook-benefit-media-space: var(--space-6);
    --bt-playbook-benefit-index-size: var(--section-small-size);
    --bt-playbook-benefit-index-star-gap: var(--space-2);
    --bt-playbook-benefit-item-title-size: var(--section-topic-size-sm);
    --bt-playbook-benefit-item-title-space: var(--space-2);
    --bt-playbook-benefit-copy-size: var(--section-body-size);
    --bt-playbook-benefit-copy-space: var(--space-2);
    --bt-playbook-benefit-note-space: var(--space-12);
    --bt-playbook-benefit-note-size: var(--section-small-size);

    padding: var(--bt-playbook-benefit-padding-y) var(--space-0);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .playbook-benefit__lead {
        max-width: var(--bt-playbook-benefit-lead-max-width);
        margin: var(--bt-playbook-benefit-lead-space) var(--space-0) var(--space-0);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-benefit-lead-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-relaxed);
    }

    /* ช่องไฟระหว่างสามการ์ดกว้างกว่า gutter มาตรฐาน ให้แต่ละกรอบแยกกันชัด */
    .playbook-benefit__list {
        /* --bs-gutter-x: var(--bt-playbook-benefit-list-gutter); */

        margin-top: var(--bt-playbook-benefit-list-space);
        row-gap: var(--bt-playbook-benefit-list-row-gap);
        list-style: none;
    }

    /* กรอบตัวอย่างหน้าจอ ใช้ความสูงขั้นต่ำแทนสัดส่วนตายตัว เพราะพอคอลัมน์แคบลง
       กล่องแบบสัดส่วนจะเตี้ยลงสวนทางกับข้อความที่ตัดบรรทัดมากขึ้นจนเนื้อหาล้นกรอบ
       ค่านี้สูงพอให้ช่องที่เนื้อหาเยอะที่สุดพอดีทุกขนาดจอ สามช่องจึงสูงเท่ากันเสมอ
       เนื้อหาข้างในวางกึ่งกลางแนวตั้ง */
    .playbook-benefit__media {
        position: relative;
        height: var(--bt-playbook-benefit-media-height);
        padding: var(--bt-playbook-benefit-media-padding);
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: var(--bt-playbook-benefit-media-gap);
        border-radius: var(--card-radius);
        background: var(--color-surface-paper);
        overflow: hidden;
    }

    /* ต้นฉบับเป็น <svg> ที่วาดวงกลมใน <pattern> แล้วเจาะด้วย mask
       ที่นี่ใช้ radial-gradient ซ้ำเป็นตารางแทน ได้ภาพเดียวกันโดยไม่ต้องเพิ่ม element
       และไม่ต้องมี id ไม่ซ้ำแบบที่ useId() ของ React ทำให้ */
    .playbook-benefit__media::before {
        content: '';
        position: absolute;
        inset: var(--space-0);
        z-index: 0;
        pointer-events: none;
        background-image: radial-gradient(circle at var(--bt-playbook-benefit-dots-radius) var(--bt-playbook-benefit-dots-radius),
                var(--bt-playbook-benefit-dots-ink) var(--bt-playbook-benefit-dots-radius),
                transparent 0);
        background-size: var(--bt-playbook-benefit-dots-gap) var(--bt-playbook-benefit-dots-gap);
        -webkit-mask-image: radial-gradient(var(--bt-playbook-benefit-dots-fade) circle at var(--bt-playbook-benefit-dots-at), #000, transparent);
        mask-image: radial-gradient(var(--bt-playbook-benefit-dots-fade) circle at var(--bt-playbook-benefit-dots-at), #000, transparent);
    }

    /* สองใบนี้ใช้ภาพสำเร็จแทน component ภาพมีขอบในตัวแล้วจึงไม่ต้องเว้นระยะในกรอบ
       ลายจุดของ CSS ยังเปิดไว้ ภาพที่พื้นหลังโปร่งจะเห็นลายทะลุขึ้นมาเป็นพื้นเดียวกับใบแรก */
    /* ใบที่เป็น component เนื้อหาอยู่กลางกรอบ ลายจุดจึงตามไปอยู่กลางด้วย
       ส่วนใบที่เป็นภาพใช้ค่าตั้งต้น (ขอบล่าง) */
    .playbook-benefit__media--dots-center {
        --bt-playbook-benefit-dots-at: 50% 50%;
    }

    /* ใบ Skill: ลายจุดเป็นวงจำกัดอยู่กลางกรอบ ไม่ลามจนเต็มการ์ด
       กรอบกว้าง 396 สูง 320 ครึ่งเส้นทแยงคือ 254px ค่าเดิม 300px จึงเลยทุกมุมไปหมด
       140px ทำให้วงจบก่อนถึงขอบทุกด้าน (เหลือขอบว่างข้างละ ~58px บน-ล่าง ~20px) */
    .playbook-benefit__card--skill .playbook-benefit__media {
        --bt-playbook-benefit-dots-fade: 200px;
    }

    /* กล่องที่ย่อได้ทั้งก้อนเมื่อเนื้อหาสูงเกินกรอบ (ค่าตัวคูณมาจาก js/playbook-benefit-media.js)
       ย่อด้วย transform ไม่ใช่การบีบ gap/font ทีละค่า สัดส่วนภายในจึงเหมือนเดิมเป๊ะ
       และเพราะ transform ไม่กระทบ layout การตัดบรรทัดของข้อความก็ไม่เปลี่ยนตาม
       z-index ยกให้อยู่เหนือชั้นลายจุด เพราะ ::before เป็น element ที่ positioned */
    .playbook-benefit__fit {
        position: relative;
        z-index: 1;
        flex: 0 0 auto;
        width: 100%;
        display: flex;
        flex-direction: column;
        gap: var(--bt-playbook-benefit-media-gap);
        transform: scale(var(--bt-playbook-benefit-fit, 1));
        transform-origin: center center;
    }

    .playbook-benefit__compare {
        position: relative;
        /* กรอบสูงตายตัวแล้ว จึงให้ "ความสูง" เป็นตัวตั้งแทนความกว้าง
           ความกว้างไหลตามสัดส่วนการ์ดจริง (5:7) เอง การ์ดจึงพอดีความสูงเสมอ
           โดยสัดส่วนไม่เพี้ยน และไม่ต้องย่อด้วย transform ให้ภาพเบลอ
           max-width กันไว้เผื่อกรอบแคบกว่าความกว้างที่สัดส่วนต้องการ */
        align-self: center;
        height: 100%;
        width: auto;
        max-width: min(100%, var(--bt-playbook-benefit-compare-width));
        aspect-ratio: var(--bt-playbook-benefit-compare-ratio);
        border-radius: var(--bt-playbook-benefit-compare-radius);
        overflow: hidden;
        isolation: isolate;
        background: var(--color-surface-soft);
        box-shadow: var(--bt-playbook-benefit-compare-shadow);
        cursor: ew-resize;
        touch-action: pan-y;
        user-select: none;
    }

    .playbook-benefit__compare-side {
        position: absolute;
        inset: var(--space-0);
        overflow: hidden;
        pointer-events: none;
    }

    .playbook-benefit__compare-side--before {
        z-index: 2;
        clip-path: inset(0 50% 0 0);
        will-change: clip-path;
    }

    .playbook-benefit__compare-card {
        position: absolute;
        inset: var(--space-0);
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

    .playbook-benefit__compare-chip {
        position: absolute;
        top: var(--bt-playbook-benefit-compare-chip-inset);
        z-index: 6;
        padding: var(--space-1) var(--space-2);
        border-radius: var(--pill-radius);
        color: var(--color-neutral-0);
        background: var(--bt-playbook-benefit-compare-chip-bg);
        backdrop-filter: blur(6px);
        font-size: var(--font-size-12);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
        letter-spacing: 0.03em;
        pointer-events: none;
        transition: opacity 180ms var(--ease-standard);
    }

    .playbook-benefit__compare-chip--before {
        left: var(--bt-playbook-benefit-compare-chip-inset);
    }

    .playbook-benefit__compare-chip--after {
        right: var(--bt-playbook-benefit-compare-chip-inset);
    }

    .playbook-benefit__compare-divider {
        position: absolute;
        top: var(--space-0);
        bottom: var(--space-0);
        left: 50%;
        z-index: 10;
        width: var(--border-width-2);
        margin-left: calc(var(--border-width-2) / -2);
        background: var(--color-neutral-0);
        box-shadow: 0 0 0 var(--border-width-1) rgba(17, 19, 24, 0.18);
        pointer-events: none;
    }

    .playbook-benefit__compare-handle {
        position: absolute;
        top: 50%;
        left: 50%;
        width: var(--bt-playbook-benefit-compare-handle-size);
        height: var(--bt-playbook-benefit-compare-handle-size);
        padding: var(--space-0);
        display: grid;
        place-items: center;
        border: var(--border-width-2) solid var(--color-neutral-0);
        border-radius: var(--radius-round);
        color: var(--color-text-primary);
        background: var(--color-neutral-0);
        box-shadow: var(--bt-playbook-benefit-compare-handle-shadow);
        cursor: ew-resize;
        pointer-events: auto;
        transform: translate(-50%, -50%);
        transition: transform 120ms var(--ease-standard);
    }

    .playbook-benefit__compare-handle .bt-icon {
        font-size: var(--font-size-18);
    }

    @media (hover: hover) and (pointer: fine) {
        .playbook-benefit__compare-handle:hover {
            transform: translate(-50%, -50%) scale(1.05);
        }
    }

    /* กดแล้วยุบเล็กน้อย ให้รู้ว่าจับติดแล้วระหว่างลาก */
    .playbook-benefit__compare-handle:active {
        transform: translate(-50%, -50%) scale(0.96);
    }

    /* ---------- 02 สินทรัพย์ที่ถนัด + จุดแข็ง/ข้อควรระวัง ---------- */
    .playbook-benefit__assets,
    .playbook-benefit__trait,
    .playbook-benefit__skill {
        padding: var(--bt-playbook-benefit-card-padding);
        border-radius: var(--card-radius);
        background: var(--bt-playbook-benefit-media-paper);
    }

    /* กล่องสินทรัพย์ใช้พื้นม่วงจาง ๆ กับขอบม่วงโปร่งตามต้นฉบับ */
    .playbook-benefit__assets {
        border-color: color-mix(in srgb, var(--bt-playbook-benefit-violet) 24%, transparent);
        background: color-mix(in srgb, var(--bt-playbook-benefit-violet) 8%, var(--color-neutral-0));
    }

    .playbook-benefit__assets-label {
        color: var(--bt-playbook-benefit-media-ink);
        font-size: var(--bt-playbook-benefit-media-label-size);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
    }

    .playbook-benefit__chips {
        margin-top: var(--space-1);
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-2);
    }

    .playbook-benefit__chip {
        display: inline-flex;
        align-items: center;
        gap: var(--bt-playbook-benefit-chip-gap);
        padding: var(--bt-playbook-benefit-chip-padding-y) var(--space-2);
        border-radius: var(--pill-radius);
        color: var(--bt-playbook-benefit-violet);
        background: color-mix(in srgb, var(--bt-playbook-benefit-violet) 26%, var(--color-neutral-0));
        font-size: var(--bt-playbook-benefit-media-copy-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--line-height-normal);
    }

    .playbook-benefit__chip .bt-icon {
        font-size: var(--font-size-12);
    }

    /* motion ภายในกรอบ: เริ่มเมื่อกรอบเข้าจอครั้งแรก (js เติม .is-revealed) และเล่นครั้งเดียว
       หน่วง --bt-playbook-benefit-motion-lead ไว้ก่อน เพื่อรอ data-reveal ของ section พาการ์ดขึ้นมาก่อน */
    .playbook-benefit__chip {
        opacity: 0;
        transform: translateY(6px);
        transition:
            opacity var(--bt-playbook-benefit-motion-chip) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            transform var(--bt-playbook-benefit-motion-chip) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms);
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__chip {
        opacity: 1;
        transform: translateY(0);
    }

    .playbook-benefit__chip:nth-child(1) {
        --playbook-benefit-motion-delay: var(--bt-playbook-benefit-motion-lead);
    }

    .playbook-benefit__chip:nth-child(2) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 70ms);
    }

    .playbook-benefit__chip:nth-child(3) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 140ms);
    }

    .playbook-benefit__chip:nth-child(4) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 210ms);
    }

    .playbook-benefit__chip:nth-child(5) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 280ms);
    }

    /* การ์ดสองใบสูงตามเนื้อหาของตัวเอง ไม่บังคับให้เท่ากัน จะได้ไม่เหลือที่ว่างในใบที่สั้นกว่า */
    .playbook-benefit__traits {
        display: grid;
        gap: var(--bt-playbook-benefit-media-gap);
    }

    /* ขึ้นต่อจาก chip ชุดสุดท้าย เรียงตามลำดับการอ่าน จุดแข็ง → สิ่งที่ต้องระวัง */
    .playbook-benefit__trait {
        opacity: 0;
        transform: translateY(8px);
        transition:
            opacity var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            transform var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms);
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__trait {
        opacity: 1;
        transform: translateY(0);
    }

    .playbook-benefit__trait:nth-child(1) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 300ms);
    }

    .playbook-benefit__trait:nth-child(2) {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 390ms);
    }

    .playbook-benefit__trait-head {
        margin-bottom: var(--bt-playbook-benefit-media-item-gap);
        display: flex;
        align-items: center;
        gap: var(--space-2);
        color: var(--bt-playbook-benefit-ok-ink);
        font-size: var(--bt-playbook-benefit-media-label-size);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
        letter-spacing: 0.04em;
    }

    .playbook-benefit__trait--warn .playbook-benefit__trait-head {
        color: var(--bt-playbook-benefit-warn-ink);
    }

    .playbook-benefit__trait-head .bt-icon {
        font-size: var(--font-size-16);
    }

    /* บรรทัดย่อยเยื้องให้ตรงกับข้อความของหัวเรื่อง (ข้ามความกว้างไอคอน + ช่องไฟ) */
    .playbook-benefit__trait-item {
        margin-left: calc(var(--font-size-16) + var(--space-2));
        color: var(--bt-playbook-benefit-media-ink);
        font-size: var(--bt-playbook-benefit-media-copy-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--bt-playbook-benefit-media-copy-line-height);
        margin-bottom: var(--space-1);
    }

    /* ---------- 03 Skill ประจำการ์ด ---------- */
    /* การ์ดนี้สูงเท่าเนื้อหา ไม่ยืดเต็มเฟรม (กรอบแม่จัดกึ่งกลางแนวตั้งให้เอง) */
    .playbook-benefit__skill {
        position: relative;
        overflow: hidden;
    }

    .playbook-benefit__skill>* {
        position: relative;
    }

    /* อยู่หลังแผงคะแนน (z-index ต่ำกว่า __fit ที่เป็น 1) แต่เหนือชั้นลายจุด
       สูงกว่าแผงจึงโผล่พ้นขอบบน-ล่าง อ่านเป็นการ์ดที่สอดอยู่ข้างหลัง
       ส่วนที่เลยกรอบถูก overflow: hidden ของ media ตัดให้เอง */
    /* ของที่เพิ่มเข้ามาในใบ 1 และ 3 ใช้กลไกเดียวกับชิป/จุดแข็งที่มีอยู่เดิมทุกอย่าง:
       เริ่มจาง+เลื่อนเล็กน้อย รอ .is-revealed จาก js/playbook-benefit-media.js แล้วค่อยเข้าที่
       หน่วงไล่กันทีละ 70ms ต่อจาก --motion-lead เท่ากับจังหวะของชิป */
    /* ไอคอนสินทรัพย์เริ่มซ้อนรวมกันอยู่กลางกรอบ แล้วค่อยกระจายออกไปตำแหน่งของตัวเอง

       ระยะกระจาย --fin-x / --fin-y (เวกเตอร์จากตำแหน่งจริงย้อนกลับมาที่กึ่งกลาง)
       วัดจากของจริงแล้วเขียนลงมาโดย js/playbook-benefit-media.js ไม่ได้ฮาร์ดโค้ดไว้ที่นี่
       เพราะเปอร์เซ็นต์ใน translate อ้างขนาดของตัว element เอง ไม่ใช่ของกรอบ
       ย้ายตำแหน่งไอคอนเมื่อไหร่ จุดรวมกลางจึงตามไปเองโดยไม่ต้องแก้ตัวเลขที่นี่ด้วย
       ถ้า JS ไม่ทำงาน ค่าตั้งต้นเป็น 0 ไอคอนก็แค่อยู่ที่เดิมแล้ว fade เข้ามา ไม่พัง

       ใช้ property translate แยกจาก transform เพื่อให้ transform ว่างไว้ทำ scale
       ไอคอนจึงโตขึ้นระหว่างที่กระจายออก ไม่ใช่แค่เลื่อนเฉย ๆ */
    .playbook-benefit__finance-icon,
    .playbook-benefit__finance-mark {
        /* --fin-home-x คือ offset ที่ต้องติดตัวตลอดเวลา ไม่ใช่ระยะกระจาย
           ใบกลางใช้จัดกึ่งกลางด้วย -50% ถ้าไม่แยกออกมา มันจะหายไปตอนกระจายเสร็จ */
        --fin-home-x: 0px;
        --fin-x: 0px;
        --fin-y: 0px;

        opacity: 0;
        translate: calc(var(--fin-home-x) + var(--fin-x)) var(--fin-y);
        transform: scale(0.72);
        transition:
            opacity var(--bt-playbook-benefit-motion-chip) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            translate var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            rotate var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            transform var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms);
    }

    /* ตอนกองรวมกลางยังไม่เอียง ค่อยบิดเข้าที่พร้อมกับที่กระจายออก
       ต้องใช้ :not(.is-revealed) เพราะ rotate ของแต่ละใบอยู่ที่ตัวปรับแต่ง
       ถ้าเขียน rotate: 0 ไว้ในกฎกลาง จะโดนตัวปรับแต่งที่ specificity เท่ากันแต่มาทีหลังทับ */
    .playbook-benefit__media:not(.is-revealed) .playbook-benefit__finance-icon,
    .playbook-benefit__media:not(.is-revealed) .playbook-benefit__finance-mark {
        rotate: 0deg;
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__finance-icon,
    .playbook-benefit__media.is-revealed .playbook-benefit__finance-mark {
        opacity: 1;
        translate: var(--fin-home-x) 0;
        transform: scale(1);
    }


    .playbook-benefit__finance-icon--card {
        --playbook-benefit-motion-delay: var(--bt-playbook-benefit-motion-lead);
    }

    .playbook-benefit__finance-icon--receipt {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 70ms);
    }

    .playbook-benefit__finance-icon--banknote {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 140ms);
    }

    .playbook-benefit__finance-icon--money {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 210ms);
    }

    .playbook-benefit__finance-mark {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + 280ms);
    }

    /* ไล่จางจากด้านล่างให้กลืนไปกับพื้นกรอบ แทนที่จะถูก overflow: hidden ตัดเป็นเส้นตรง
       ใช้ mask ไม่ใช่การเอาสีพื้นมาทับ เพราะการ์ดจะค่อย ๆ โปร่งจริง
       ลายจุดที่อยู่ข้างหลังจึงทะลุขึ้นมาแทนที่ ไม่ใช่ถูกกลบไปด้วย

       เงากับ mask อยู่บน element เดียวกันไม่ได้: เงาของ drop-shadow ตกอยู่นอกกล่อง
       แต่ mask ครอบแค่ในกล่อง (mask-repeat: no-repeat) อะไรที่อยู่นอกนั้นถูกตัดทิ้งหมด
       เงาจึงหายไปทั้งดวง และเงานี่แหละคือสิ่งเดียวที่แยกกระดาษขาวของการ์ด
       ออกจากพื้นกรอบที่ขาวพอกัน พอหายไปขอบบนของการ์ดเลยกลืนหายตามไปด้วย

       แยกเป็นสองชั้นแทน: กล่องนอกถือเงา ภาพข้างในถือ mask
       เงาจึงคิดจากภาพที่ผ่าน mask มาแล้ว ได้เงาที่จางหายพร้อมกับขอบล่างของการ์ดพอดี */
    .playbook-benefit__skill-card {
        position: absolute;
        z-index: 0;
        width: var(--bt-playbook-benefit-skill-card-width);
        display: block;
        filter: drop-shadow(0 12px 28px rgba(17, 19, 24, 0.14));
        pointer-events: none;
    }

    /* จุดที่จางสนิทไม่ใช่ 100% แต่เป็น 100% + --skill-card-bottom (ค่าติดลบ)
       เพราะการ์ดยื่นพ้นขอบกรอบลงไปเท่านั้นพอดี ถ้าไล่ถึง 100% จุดจางสุดจะตกอยู่นอกกรอบ
       ขอบที่คนเห็นจริงจึงยังทึบอยู่ครึ่งหนึ่งแล้วถูก overflow ตัดเป็นเส้นตรงเหมือนเดิม
       ส่วนจุดเริ่มไล่นับถอยขึ้นมาจากตรงนั้นเท่ากับ --skill-card-fade การไล่จึงกินแค่แถบล่าง
       ไม่ลามขึ้นไปทำให้ส่วนบนของการ์ดซีด
       ทั้งสองจุดผูกกับ token ชุดเดียวกัน ขยับระยะที่ยื่นพ้นกรอบเมื่อไหร่ แถบก็เลื่อนตามเอง

       mask-repeat ต้องเป็น no-repeat ค่าเริ่มต้นคือ repeat ซึ่งจะเอาไล่สีไปปูซ้ำใต้กล่องต่อ
       กลายเป็นทึบสลับจางเป็นแถบ ๆ */
    .playbook-benefit__skill-card-art {
        width: 100%;
        height: auto;
        display: block;
        mask-image: linear-gradient(to bottom,
                #000 calc(100% + var(--bt-playbook-benefit-skill-card-bottom) - var(--bt-playbook-benefit-skill-card-fade)),
                transparent calc(100% + var(--bt-playbook-benefit-skill-card-bottom)));
        mask-repeat: no-repeat;
        mask-size: 100% 100%;
    }

    /* กึ่งกลางแนวนอนด้วย left 50% + translateX(-50%) จึงอยู่กลางเสมอไม่ว่ากรอบกว้างเท่าไหร่ */
    .playbook-benefit__skill-card--back {
        left: 50%;
        bottom: var(--bt-playbook-benefit-skill-card-bottom);
        /* ชิ้นใหญ่กว่าชิป จึงใช้ duration ชุด card และเลื่อนขึ้นจากขอบล่างไกลกว่าเล็กน้อย
           translateX(-50%) ต้องติดไปด้วยทุกสถานะ เพราะเป็นตัวจัดกึ่งกลาง */
        opacity: 0;
        transform: translateX(-50%) translateY(18px);
        transition:
            opacity var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--bt-playbook-benefit-motion-lead),
            transform var(--bt-playbook-benefit-motion-card) var(--ease-standard) var(--bt-playbook-benefit-motion-lead);
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__skill-card--back {
        opacity: 1;
        transform: translateX(-50%) translateY(0);
    }

    .playbook-benefit__skill-title {
        color: var(--bt-playbook-benefit-media-ink);
        font-size: var(--bt-playbook-benefit-media-label-size);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
        letter-spacing: 0.04em;
    }

    .playbook-benefit__skill-bars {
        margin-top: var(--space-3);
        display: grid;
        gap: var(--space-2);
    }

    .playbook-benefit__skill-row {
        display: grid;
        grid-template-columns: auto 1fr auto;
        align-items: center;
        gap: var(--space-3);
    }

    .playbook-benefit__skill-label {
        color: var(--bt-playbook-benefit-media-ink);
        font-size: var(--bt-playbook-benefit-media-copy-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-normal);
        white-space: nowrap;
    }

    .playbook-benefit__skill-track {
        position: relative;
        height: var(--bt-playbook-benefit-skill-bar-height);
        border-radius: var(--pill-radius);
        background: var(--bt-playbook-benefit-media-line);
    }

    /* แท่งเริ่มจาก 0 แล้ววิ่งไปถึงค่าจริงเมื่อการ์ดเข้ามาในจอ
       (js/playbook-benefit-media.js เป็นคนใส่ is-revealed) ไล่ทีละแท่งด้วย transition-delay */
    .playbook-benefit__skill-fill {
        position: absolute;
        top: var(--space-0);
        left: var(--space-0);
        width: var(--space-0);
        height: 100%;
        border-radius: var(--pill-radius);
        background: var(--playbook-benefit-skill-color);
        transition: width var(--bt-playbook-benefit-motion-bar) var(--ease-standard);
    }

    /* แต่ละแถวใช้สีของตัวเองตามต้นฉบับ ไล่ ชมพู → เหลือง → ม่วง */
    .playbook-benefit__skill-row:nth-child(1) .playbook-benefit__skill-fill {
        --playbook-benefit-skill-color: var(--bt-playbook-benefit-pink);
    }

    .playbook-benefit__skill-row:nth-child(2) .playbook-benefit__skill-fill {
        --playbook-benefit-skill-color: var(--bt-playbook-benefit-yellow);
    }

    .playbook-benefit__skill-row:nth-child(3) .playbook-benefit__skill-fill {
        --playbook-benefit-skill-color: var(--bt-playbook-benefit-violet);
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__skill-fill {
        width: var(--playbook-benefit-skill-width, 0);
    }

    .playbook-benefit__skill-row:nth-child(1) .playbook-benefit__skill-fill {
        transition-delay: var(--bt-playbook-benefit-motion-lead);
    }

    .playbook-benefit__skill-row:nth-child(2) .playbook-benefit__skill-fill {
        transition-delay: calc(var(--bt-playbook-benefit-motion-lead) + 90ms);
    }

    .playbook-benefit__skill-row:nth-child(3) .playbook-benefit__skill-fill {
        transition-delay: calc(var(--bt-playbook-benefit-motion-lead) + 180ms);
    }

    /* ตัวเลขโผล่ตอนแถบของแถวนั้นวิ่งจบพอดี ไม่เฉลยค่าก่อนแถบเล่าเสร็จ
       (หน่วง = lead + stagger ของแถว + ความยาวการวิ่งของแถบ) */
    .playbook-benefit__skill-value {
        color: var(--bt-playbook-benefit-media-ink);
        font-family: var(--bt-playbook-benefit-serif);
        font-size: var(--bt-playbook-benefit-media-label-size);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
        opacity: 0;
        transform: translateX(4px);
        transition:
            opacity var(--bt-playbook-benefit-motion-value) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms),
            transform var(--bt-playbook-benefit-motion-value) var(--ease-standard) var(--playbook-benefit-motion-delay, 0ms);
    }

    .playbook-benefit__media.is-revealed .playbook-benefit__skill-value {
        opacity: 1;
        transform: translateX(0);
    }

    .playbook-benefit__skill-row:nth-child(1) .playbook-benefit__skill-value {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + var(--bt-playbook-benefit-motion-bar));
    }

    .playbook-benefit__skill-row:nth-child(2) .playbook-benefit__skill-value {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + var(--bt-playbook-benefit-motion-bar) + 90ms);
    }

    .playbook-benefit__skill-row:nth-child(3) .playbook-benefit__skill-value {
        --playbook-benefit-motion-delay: calc(var(--bt-playbook-benefit-motion-lead) + var(--bt-playbook-benefit-motion-bar) + 180ms);
    }

    /* ดาวนำหน้าเลขลำดับ สูงเท่ากับความสูงบรรทัดของข้อความพอดี
       จึงโตหรือเล็กตามขนาดตัวอักษรเองทุก breakpoint โดยไม่ต้องตั้งค่าแยก */
    .playbook-benefit__index-star {
        flex: 0 0 auto;
        height: 1em;
        width: auto;
    }

    .playbook-benefit__index {
        margin-top: var(--bt-playbook-benefit-media-space);
        display: flex;
        align-items: center;
        gap: var(--bt-playbook-benefit-index-star-gap);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-benefit-index-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-small-line-height);
        letter-spacing: var(--letter-spacing-index);

        strong {
            font-weight: var(--font-weight-medium);
        }
    }

    .playbook-benefit__item-title {
        margin-top: var(--bt-playbook-benefit-item-title-space);
        font-size: var(--bt-playbook-benefit-item-title-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--section-topic-line-height-sm);
    }

    .playbook-benefit__copy {
        margin-top: var(--bt-playbook-benefit-copy-space);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-benefit-copy-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }

    .playbook-benefit__note {
        margin: var(--bt-playbook-benefit-note-space) var(--space-0) var(--space-0);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-benefit-note-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-small-line-height);
        text-align: center;
    }
}

/* ---------- Card 1–3 composition ----------
   คง layout หลักของ section เดิมไว้ แล้วปรับเฉพาะลำดับชั้นของ UI ภายใน visual */
.playbook-benefit {
    --bt-playbook-benefit-panel-shadow: 0 10px 22px rgba(17, 19, 24, 0.06), 0 2px 6px rgba(17, 19, 24, 0.04);
    /* ไอคอนสินทรัพย์ spectrum: ขนาด ความอิ่มสี และเงา คุมจากสามค่านี้ที่เดียว
       เงาตั้งไว้จาง ๆ พอให้ภาพไม่ลอยแบนติดพื้น ไม่ได้ต้องการให้เห็นเป็นเงาชัด ๆ */
    --bt-playbook-benefit-finance-art-size: 56px;
    --bt-playbook-benefit-finance-art-size-lg: var(--space-16);
    --bt-playbook-benefit-finance-mark-size: var(--space-10);

    /* wrapper ใช้ระบุชนิดการ์ดเท่านั้น ต้องไม่เพิ่ม spacing หรือเปลี่ยน layout เดิม */
    .playbook-benefit__card {
        /* ความหนาแน่นของเนื้อหาในกรอบผูกกับความกว้าง "คอลัมน์" ไม่ใช่ความกว้างจอ
           คอลัมน์แคบ 343px เกิดขึ้นทั้งช่วง 992-1399 (สามช่อง) และต่ำกว่า 576 (ช่องเดียว)
           ส่วนช่วง 768-991 กลับมากว้าง 516-696px ถ้าไล่เขียนเป็น media query
           จะต้องลดแล้วคืนแล้วลดอีก สามรอบและพลาดง่าย
           ประกาศ container ที่นี่ แล้วให้กรอบข้างในถามความกว้างของตัวเองแทน จบในกฎเดียว
           (query ตัวเองไม่ได้ ต้องถามจากกล่องนอก จึงมาอยู่ที่ __card ไม่ใช่ __media) */
        container-type: inline-size;

        width: 100%;
        min-width: 0;
        padding: var(--space-0);
        border: 0;
        background: transparent;
        box-shadow: none;
    }

    /* Card 1: ดันการ์ดเทียบขึ้นจากขอบบน 20% และใช้ finance icons
       เป็นจุดนำสายตารอบการ์ดตาม reference */
    .playbook-benefit__card--compare .playbook-benefit__media {
        padding: var(--space-0);
        overflow: clip;
    }

    .playbook-benefit__card--compare .playbook-benefit__compare {
        position: absolute;
        top: 26%;
        left: 50%;
        z-index: 2;
        width: 280px;
        max-width: 80%;
        height: auto;
        transform: translateX(-50%);
    }

    /* วาง handle ตรงกึ่งกลางของพื้นที่การ์ดที่ถูก clip แสดงจริง */
    .playbook-benefit__card--compare .playbook-benefit__compare-handle {
        top: 32%;
    }

    /* ไอคอนสินทรัพย์เป็นภาพ spectrum ลอยเปล่า ๆ ไม่มีเฟรม พื้นหลัง หรือเส้นขอบ
       เงาใช้ drop-shadow ไม่ใช่ box-shadow เพราะภาพเป็น PNG โปร่ง
       box-shadow จะวาดเป็นกรอบสี่เหลี่ยมรอบกล่อง ส่วน drop-shadow เดินตามรูปทรงจริงของภาพ
       ความสูงไม่ได้ล็อกไว้ ปล่อยให้ไปตามสัดส่วนของไฟล์ (arrow-up ไม่ได้จัตุรัสเป๊ะ) */
    .playbook-benefit__finance-icon {
        position: absolute;
        z-index: 3;
        width: var(--bt-playbook-benefit-finance-art-size);
        height: auto;
        display: block;
        filter: saturate(1.2);
        pointer-events: none;
    }

    /* ตัวปรับแต่งเหลือแค่ตำแหน่ง ลำดับชั้น และองศาเอียง
       สีกับพื้นหลังเดิมเป็นของเฟรมที่ถอดออกไปแล้ว

       เอียงด้วย property rotate ไม่ใช่ transform เพราะ transform ถูก animation ตอน reveal
       ใช้อยู่ (translateY + scale) ถ้าเอา rotate ไปใส่รวมในนั้น ต้องเขียนซ้ำทั้งสองสถานะ
       ของทุกใบ และพลาดที่เดียวไอคอนจะหมุนกลับตอนเล่นจบ
       property rotate แยกชั้นกับ transform จึงอยู่ร่วมกันได้โดยไม่ต้องแตะ motion เดิม
       องศาสลับบวก-ลบไม่ให้เอียงทางเดียวกันหมด ทุกตัวอยู่ในช่วง ±10 องศา */
    .playbook-benefit__finance-icon--card {
        top: 6%;
        left: 6%;
        z-index: 1;
        rotate: 8deg;
    }

    .playbook-benefit__finance-icon--receipt {
        top: 76%;
        left: 8%;
        rotate: -6deg;
    }

    .playbook-benefit__finance-icon--banknote {
        top: 54%;
        right: 6%;
        z-index: 1;
        rotate: -5deg;
    }

    /* ย้ายการจัดกึ่งกลางจาก transform มาไว้ที่ property translate
       ถ้าคงไว้ใน transform ค่า translateX(-50%) จะถูกคิดในแกนที่หมุนไปแล้ว ตำแหน่งจะเพี้ยนตามองศา
       ผลพลอยได้คือไม่ต้องมี motion rule เฉพาะของใบนี้อีก ใช้ชุดกลางร่วมกับตัวอื่นได้เลย */
    .playbook-benefit__finance-icon--money {
        top: 12%;
        left: 50%;
        z-index: 4;
        width: var(--bt-playbook-benefit-finance-art-size-lg);
        rotate: 4deg;

        --fin-home-x: -50%;
    }

    .playbook-benefit__finance-mark {
        position: absolute;
        top: 5%;
        right: 12%;
        z-index: 1;
        width: var(--bt-playbook-benefit-finance-mark-size);
        height: auto;
        filter: saturate(1.5);
        rotate: -10deg;
    }

    /* Card 2: วางเป็นสามแผงซ้อนเหลื่อมแบบรายการใน reference
       ใช้ rotate property แยกจาก transform เพื่อไม่ชน motion เดิมของแต่ละแผง */
    .playbook-benefit__card--traits .playbook-benefit__media {
        --bt-playbook-benefit-media-gap: var(--bt-playbook-benefit-traits-gap);

        padding: var(--bt-playbook-benefit-media-padding);
    }

    .playbook-benefit__card--skill .playbook-benefit__fit {
        max-width: 480px;
        margin-inline: auto;
        margin-top: var(--space-6);
    }

    .playbook-benefit__card--traits .playbook-benefit__assets,
    .playbook-benefit__card--traits .playbook-benefit__trait {
        border-color: var(--color-border-subtle);
        background: color-mix(in srgb, var(--color-neutral-0) 96%, var(--color-surface-paper));
        box-shadow: var(--bt-playbook-benefit-panel-shadow);
    }

    .playbook-benefit__card--traits .playbook-benefit__assets {
        position: relative;
        z-index: 3;
        width: 100%;
        padding: var(--space-4);
        rotate: 1.2deg;
        margin-left: var(--space-3);
    }

    .playbook-benefit__card--traits .playbook-benefit__traits {
        width: 100%;
        gap: var(--space-4);
    }

    .playbook-benefit__card--traits .playbook-benefit__trait {
        position: relative;
        width: 100%;
        padding: var(--space-4);
    }

    .playbook-benefit__card--traits .playbook-benefit__trait:first-child {
        z-index: 2;
        width: 92%;
        justify-self: center;
        rotate: -1.2deg;
        margin-right: var(--space-16);
    }

    .playbook-benefit__card--traits .playbook-benefit__trait:last-child {
        z-index: 1;
        width: 82%;
        justify-self: center;
        rotate: 2.2deg;
        margin-left: var(--space-8);
    }

    .playbook-benefit__card--traits .playbook-benefit__trait-head {
        margin-bottom: var(--space-3);
    }

    .playbook-benefit__card--traits .playbook-benefit__trait-item {
        margin-bottom: 2px;
    }

    /* Card 3: ให้ Skill เป็น dashboard หลักเพียงใบเดียว มีเงาและพื้นที่หายใจมากขึ้น
       bar หนาขึ้นเพื่อสร้างลำดับ คะแนนยังใช้ animation เดิม */
    .playbook-benefit__card--skill .playbook-benefit__media {
        padding: var(--space-6);
        justify-content: center;
    }

    .playbook-benefit__card--skill .playbook-benefit__skill {
        width: 100%;
        margin-inline: auto;
        padding: var(--space-4);
        border-color: var(--color-border-subtle);
        background: color-mix(in srgb, var(--color-neutral-0) 97%, var(--color-surface-paper));
        box-shadow: var(--bt-playbook-benefit-panel-shadow);
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-title {
        font-size: var(--font-size-16);
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-bars {
        margin-top: var(--space-6);
        gap: var(--space-4);
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-row {
        grid-template-columns: minmax(88px, auto) 1fr auto;
        gap: var(--space-4);
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-label {
        font-size: 13px;
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-track {
        height: var(--space-2);
    }

    .playbook-benefit__card--skill .playbook-benefit__skill-value {
        min-width: var(--space-10);
        font-size: var(--font-size-20);
        text-align: center;
        color: var(--bt-playbook-steps-preview-ink);
    }

}

/* คอลัมน์แคบกว่า 380px เนื้อหาในกรอบตัวอย่างตัดบรรทัดเพิ่มจนล้น
   ใบ "จุดแข็ง" ต้องการความสูง 425px ในกรอบที่ให้ได้ 256px
   ย่อด้วย scale ไม่ไหว เพราะต้องย่อถึง 0.60 ตัวอักษร 13px จะเหลือ 7.8px อ่านไม่ออก
   จึงลดความหนาแน่นภายในลงหนึ่งขั้นแทน (ระยะขอบ ช่องไฟ ขนาดตัวอักษร)
   เนื้อหาเหลือ 341px ในกรอบที่ขยายเป็น 280px ย่อแค่ 0.82 ซึ่งเป็นเพดานเดิมของ fit ก็เข้าพอดี
   เกณฑ์ 380px มาจากความกว้างคอลัมน์จริง: กว้างสุด 396px (สามช่องที่ 1400 ขึ้นไป) ต้องไม่เข้าเงื่อนไข
   ส่วน 343px (ทั้งช่วง 992-1399 และต่ำกว่า 576) ต้องเข้า */
@container (max-width: 379px) {
    .playbook-benefit__media {
        --bt-playbook-benefit-media-padding: var(--space-5);
        --bt-playbook-benefit-media-item-gap: var(--space-2);
        --bt-playbook-benefit-traits-gap: var(--space-2);
        --bt-playbook-benefit-media-label-size: var(--font-size-14);
        --bt-playbook-benefit-media-copy-size: 12px;
        --bt-playbook-benefit-card-padding: var(--space-3);
    }
}


@media (max-width: 1199px) {
    .playbook-benefit {
        --bt-playbook-benefit-media-height: 320px;
        /* ย่อทั้งก้อนลงเท่ากันหมด แทนการไล่ลดขนาดทีละ element
           สัดส่วนภายในจึงคงเดิมทุกอย่าง */
        --bt-playbook-benefit-fit-max: 0.72;

        /* 100vw รวมความกว้าง scrollbar ด้วย ถ้าไม่กันไว้จะดันจนเกิด scroll แนวนอน
           ใช้ clip ไม่ใช่ hidden เพราะ hidden จะทำให้ section กลายเป็น scroll container
           (ซึ่งจะไปตัด sticky/fixed ที่อยู่ข้างในด้วย) */
        overflow-x: clip;


        .playbook-benefit__card--skill .playbook-benefit__media {
            --bt-playbook-benefit-skill-card-width: 76%;
            --bt-playbook-benefit-skill-card-bottom: calc(189px - 76.86cqi);

            padding: var(--space-4);
        }

        .playbook-benefit__card--skill .playbook-benefit__skill-bars {
            margin-top: var(--space-4);
            gap: var(--space-2);
        }
    }

}

/* หลุดออกจาก .container มาเต็มความกว้างจอ เฉพาะช่วงสามคอลัมน์ (992-1199)
   ช่วงนี้ .container ตรึงที่ 960px คอลัมน์หดจาก 396 เหลือ 269px ซึ่งแคบเกินกว่า
   เนื้อหาในกรอบตัวอย่างจะอยู่ได้ การคืนความกว้างให้จึงตรงปัญหากว่าไปไล่ย่อเนื้อหา
   ต่ำกว่า 992 เหลือแถวละช่อง คอลัมน์กว้างเต็มอยู่แล้ว ไม่ต้องหลุดออกมา
   ระยะ 32px วัดจากขอบจอถึงขอบการ์ด จึงต้องหักครึ่ง gutter ของ .row ออกก่อน
   เพราะคอลัมน์มี padding ของตัวเองอยู่แล้ว ไม่งั้นจะกลายเป็น 44px */
@media (min-width: 992px) and (max-width: 1199px) {
    .playbook-benefit__list {
        margin-inline: calc(50% - 50vw);
        padding-inline: calc(var(--space-8) - 0.5 * var(--bs-gutter-x));
    }
}

/* ---------- ใบ Skill ช่วงสามคอลัมน์ (992-1199) ----------
   ใบนี้ไม่เข้าพวกกับการย่อทั้งก้อน เพราะของสองชิ้นที่ต้องเข้าคู่กันอยู่คนละชั้น
   แผงคะแนน (.playbook-benefit__skill) อยู่ใน .playbook-benefit__fit ซึ่งโดนย่อ
   ส่วนการ์ด The Contrarian (.playbook-benefit__skill-card-art) เป็น absolute
   อยู่นอกกล่องนั้น จึงไม่โดนย่อ

   ซ้ำร้าย กล่อง fit เป็น element ในสายน้ำปกติ ความกว้างมันหดตามคอลัมน์อยู่แล้ว
   ย่อซ้ำด้วย scale อีกชั้นจึงเป็นการหดสองรอบ แผงเหลือ 79% ของกรอบ
   ทั้งที่ตอน desktop กิน 88% นั่นคือสาเหตุที่แผงดูลีบผิดส่วนไปจากการ์ด

   จึงปลดเพดานคืนให้แผงขึ้นขนาดจริงของมัน แล้วไปย่อการ์ดตามกรอบแทน
   ผลที่ได้ที่ 1199: แผงกว้าง 86.8% ของกรอบ (desktop 87.9%)
   การ์ดกว้าง 67.0% (desktop 66.9%) และโผล่เหนือแผง 61px (desktop 67px)
   ทั้งสามค่าอยู่ในสเกลเดียวกับ desktop

   จำกัดช่วงไว้ที่ 992 ขึ้นไป ต่ำกว่านั้นเหลือคอลัมน์เดียว กรอบกว้าง 704px+
   แต่กล่อง fit ติด max-width: 480px ไว้ สัดส่วนจึงคนละเรื่องกัน ปล่อยใช้ค่าเดิม */
@media (min-width: 992px) and (max-width: 1199px) {
    .playbook-benefit__card--skill .playbook-benefit__media {
        --bt-playbook-benefit-fit-max: 1;

        /* เป็น % ของกรอบ ไม่ใช่ px ตายตัว การ์ดจึงหดตามคอลัมน์เองตลอดช่วงนี้
           (คอลัมน์ไล่จาก 362px ที่ 1199 ลงไป 293px ที่ 992 ไม่ได้หยุดที่ค่าเดียว
           ตั้งเป็น px ค่าใดค่าหนึ่งจะถูกแค่ปลายเดียว อีกปลายพลาดไป 50px)
           67% ให้ผลเท่า 265px ของ desktop พอดีตอนคอลัมน์กว้าง 396px */
        --bt-playbook-benefit-skill-card-width: 67%;

        /* ระยะที่การ์ดยื่นพ้นขอบล่างของกรอบ ต้องลดตามความสูงการ์ดที่เตี้ยลงด้วย
           ไม่งั้นการ์ดจะจมลงไปใต้กรอบเท่าเดิม เหลือโผล่เหนือแผงไม่พอให้เห็นชื่อการ์ด
           76.86cqi คือส่วนที่แปรตามความกว้างคอลัมน์ (cqi = 1% ของความกว้าง .playbook-benefit__card)
           หักจาก 230px คงที่ สูตรนี้ให้ -74px เท่าค่า desktop พอดีเมื่อคอลัมน์กว้าง 396px
           จึงต่อเนื่องกับ breakpoint บนโดยไม่มีรอยสะดุด */
        --bt-playbook-benefit-skill-card-bottom: calc(230px - 76.86cqi);
    }
}

@media (max-width: 991px) {
    .playbook-benefit {
        --bt-playbook-benefit-padding-y: var(--section-padding-y-sm);
        --bt-playbook-benefit-list-space: var(--space-12);
        --bt-playbook-benefit-item-title-size: var(--section-topic-size-sm);
        --bt-playbook-benefit-lead-size: var(--section-body-size);
        /* ต่ำกว่า lg เหลือแถวละช่อง คอลัมน์กว้างเต็ม เนื้อหาจึงกลับมาสั้นเท่าจอใหญ่ */
        --bt-playbook-benefit-media-height: 320px;

        .playbook-benefit__card--skill .playbook-benefit__media {
            --bt-playbook-benefit-skill-card-width: 64%;
            /* หน่วย 1% ของความกว้างคอลัมน์ ปกติคือ 1cqi ช่วง 576-767 จะถูกแทนด้วย 1% ของ artboard
               (ดูบล็อก artboard ด้านล่าง) สูตรจึงยังเป็นชุดเดียว ไม่ต้องเขียนซ้ำ */
            --bt-playbook-benefit-skill-card-bottom: calc(200px - 76.86 * var(--bt-playbook-benefit-col-unit, 1cqi));
        }
    }
}

@media (max-width: 767px) {
    .playbook-benefit {
        --bt-playbook-benefit-list-row-gap: var(--space-10);
        --bt-playbook-benefit-media-height: 260px;

        .playbook-benefit__copy {
            text-wrap: balance;
        }
    }
}

@media (max-width: 575px) {
    .playbook-benefit {
        --bt-playbook-benefit-list-space: var(--space-8);

        .playbook-benefit__copy {
            text-wrap: auto;
        }
    }
}

/* ---------- 576-767: กรอบตัวอย่างเป็น "artboard" ย่อทั้งแผ่นตามความกว้างคอลัมน์ ----------
   ช่วงนี้ยังเป็นสองคอลัมน์ (col-sm-6) คอลัมน์หดจาก 332px ที่ 767 เหลือ 260px ที่ 576
   ตัวหนังสือในกรอบขนาดคงที่ พอกรอบแคบลง บรรทัดก็ตัดเพิ่ม เนื้อหาสูงขึ้นจนล้นกรอบ
   (ใบ "จุดแข็ง" ต้องการ 461px ที่ 576 เทียบกับ 340px ที่ 767) และของตกแต่งที่เป็น px
   ก็ไม่หดตาม หน้าตาแต่ละความกว้างจึงไม่เหมือนกันเลย

   แทนที่จะไล่ลดทีละค่า ให้กรอบจัดวางที่ความกว้างเดียวตลอดช่วง คือ 332px (เท่าตอน 767
   ที่แสดงพอดีอยู่แล้ว) แล้วย่อทั้งกรอบด้วย zoom = ความกว้างคอลัมน์จริง / 332
   ทุกอย่างข้างใน ทั้งตัวหนังสือ ระยะ ไอคอน การ์ดพื้นหลัง ย่อพร้อมกันในอัตราเดียว
   การตัดบรรทัดจึงเหมือน 767 ทุกประการ

   ใช้ zoom ไม่ใช่ transform: scale เพราะ zoom ย่อ "พื้นที่ที่กินใน layout" ไปด้วย
   กรอบที่ย่อแล้วจึงกินที่เท่าคอลัมน์จริง ข้อความใต้กรอบเลื่อนขึ้นมาชิดพอดี
   ถ้าเป็น transform กรอบจะยังจองที่ 332x260 เดิม ล้นคอลัมน์และทิ้งช่องว่างไว้ข้างล่าง

   ตัวคูณ zoom คำนวณโดย js/playbook-benefit-media.js (CSS หารความยาวสองค่าตรง ๆ ไม่ได้)
   JS จะติดคลาส is-artboard เมื่อเห็น token นี้เท่านั้น ถ้า JS ไม่ทำงาน กรอบก็แสดงแบบปกติ */
@media (min-width: 576px) and (max-width: 767px) {
    .playbook-benefit {
        --bt-playbook-benefit-artboard-width: 332px;

        .playbook-benefit__media.is-artboard {
            /* 1% ของ artboard แทน 1cqi สูตรที่อิงความกว้างคอลัมน์ (เช่นตำแหน่งการ์ดพื้นหลังใบ Skill)
               จึงได้ค่าเท่าตอน 767 ด้วย ถ้าปล่อยเป็น cqi จะไปอิงคอลัมน์จริงที่แคบกว่า
               แล้วถูก zoom ย่อซ้ำอีกรอบ ตำแหน่งจะไม่ตรง 767 */
            --bt-playbook-benefit-col-unit: calc(var(--bt-playbook-benefit-artboard-width) / 100);

            width: var(--bt-playbook-benefit-artboard-width);
            zoom: var(--bt-playbook-benefit-zoom, 1);
        }
    }
}

/* เคยมีชุดกฎจูนใบ Skill ทีละ element ที่ ≤575 อยู่ตรงนี้ (ระยะขอบ ระยะใน และจัด grid ใหม่
   เป็นสองคอลัมน์) ถอดออกแล้วเพราะซ้อนกับ --bt-playbook-benefit-fit-max ที่ย่อทั้งก้อน
   อยู่แล้ว กลายเป็นย่อสองชั้น แผงเหลือ 201px ในกรอบที่มีที่ว่าง 279px
   และแถวคะแนนถูกบังคับตัดบรรทัดทั้งที่ยังไม่จำเป็น
   วัดที่ 375px แล้ว grid สามคอลัมน์ของ desktop ยังอยู่ได้ (91/68/40px) ป้ายไม่ตัดบรรทัด
   ถ้าวันหลังอยากให้แท่งคะแนนลงไปอยู่คนละบรรทัดจริง ๆ ค่อยเขียน breakpoint กลับมาใหม่
   นั่นเป็นการเปลี่ยน layout ซึ่งปุ่มย่อสเกลทำแทนไม่ได้ */

/* ท้าย section เดียวกัน: อีก 4 อย่างในเล่ม + ปุ่มปิดท้าย
   การ์ดชุดนี้เป็นกล่องข้อความล้วน จึงมีพื้นและขอบของตัวเอง ต่างจากการ์ด 3 ใบด้านบน
   ที่เป็นกรอบรอภาพ แต่ยังใช้ radius/เส้นขอบ/สีตัวอักษรชุดเดียวกัน */
.playbook-benefit {
    --bt-playbook-benefit-extra-space: var(--space-24);
    --bt-playbook-benefit-extra-title-size: var(--section-topic-size-sm);
    --bt-playbook-benefit-extra-list-space: var(--space-10);
    --bt-playbook-benefit-extra-list-row-gap: var(--space-12);
    --bt-playbook-benefit-extra-item-title-size: var(--section-topic-size-sm);
    --bt-playbook-benefit-extra-icon-size: var(--font-size-18);
    --bt-playbook-benefit-extra-rule-length: 96px;
    --bt-playbook-benefit-extra-rule-space: var(--space-3);
    --bt-playbook-benefit-action-space: var(--space-12);

    .playbook-benefit__extra {
        margin-top: var(--bt-playbook-benefit-extra-space);
    }

    .playbook-benefit__extra-title {
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-benefit-extra-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-topic-line-height);
        text-align: center;
    }

    /* ใช้ gutter มาตรฐานของ Bootstrap ชุดเดียวกับ grid ในหน้า Index */
    .playbook-benefit__extra-list {
        margin-top: var(--bt-playbook-benefit-extra-list-space);
        row-gap: var(--bt-playbook-benefit-extra-list-row-gap);
        list-style: none;
    }

    /* คั่นแต่ละช่องด้วยเส้น-ดาวแนวตั้งชุดเดียวกับ section Expectation ของหน้าแรก
       ภาพวาดมาเป็นแนวนอนจึงหมุน 90° กล่องจึงกว้าง = ความยาวเส้น และสูง = ความยาวหารอัตราส่วนภาพ
       (1023:112 ≈ 9.13) ความยาวเส้นใช้ค่าชุดเดียวกับ Expectation และไล่ลงตามขนาดจอเหมือนกัน
       เส้นวางกลางร่องระหว่าง column พอดี (offset ของ absolute นับจากขอบ padding
       จึงถอยออกเท่ากับ padding ซ้ายทั้งก้อน) ช่องแรกของแต่ละแถวไม่มีเส้น */
    .playbook-benefit__extra-item {
        /* gutter มาตรฐานอย่างเดียวทำให้เส้นเบียดตัวหนังสือ จึงเว้นพื้นที่ให้เส้นเพิ่ม
           ทั้งสองข้างเท่ากันผ่าน --bt-playbook-benefit-extra-rule-space
           (ปรับค่านี้ค่าเดียว ระยะซ้ายและขวาขยับพร้อมกันเสมอ) */
        --bt-playbook-benefit-extra-item-inset: calc(var(--bs-gutter-x) / 2 + var(--bt-playbook-benefit-extra-rule-space));

        position: relative;
        padding-inline: var(--bt-playbook-benefit-extra-item-inset);
        padding-left: calc(var(--bt-playbook-benefit-extra-item-inset) * 2);

        /* เส้นคั่นวางที่ขอบซ้ายของคอลัมน์พอดี (left: 0 + translateX(-50%))
           ขอบนั้นคือกึ่งกลางของช่องว่างระหว่างสองคอลัมน์จริง ๆ เพราะทั้งสองฝั่งกัน
           ระยะในเท่ากันข้างละ inset เส้นกลางของ 4 คอลัมน์จึงตรงกึ่งกลางจอพอดี
           (ถ้าถอย -inset แบบเดิม เส้นจะเลยออกไปทางซ้ายเท่ากับ inset ทุกเส้น) */
        &::before {
            content: '';
            position: absolute;
            top: 50%;
            left: var(--space-0);
            width: var(--bt-playbook-benefit-extra-rule-length);
            height: calc(var(--bt-playbook-benefit-extra-rule-length) / 9.13);
            background: url('../images/line-star.webp') center / contain no-repeat;
            transform: translate(-50%, -50%) rotate(90deg);
        }

        &:first-child::before {
            display: none;
        }
    }

    .playbook-benefit__extra-icon {
        display: none;
        color: var(--color-accent-primary);
        font-size: var(--bt-playbook-benefit-extra-icon-size);
    }

    .playbook-benefit__extra-item-title {
        margin-top: var(--space-3);
        font-size: var(--bt-playbook-benefit-extra-item-title-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--section-topic-line-height-sm);
    }

    .playbook-benefit__action {
        margin-top: var(--bt-playbook-benefit-action-space);
        display: flex;
        justify-content: center;
    }
}

/* ---------- ช่วง 992-1199: คง 4 ช่องแถวเดียวเหมือน desktop ----------
   เดิมต่ำกว่า xl ตกไปใช้ col-sm-6 กลายเป็น 2x2 ซึ่งกินความสูงเป็นเท่าตัว
   ทั้งที่ความกว้างยังพอ เพียงแต่ .container บีบไว้เหลือ 960px
   markup จึงเติม col-lg-3 ให้ 4 ช่องเริ่มตั้งแต่ lg แล้วปลดแถวนี้ออกจาก container
   มาใช้ความกว้างจอเต็ม ๆ แทน ช่องละ ~292px กว้างกว่าตอน desktop (243px) ด้วยซ้ำ */
@media (min-width: 992px) and (max-width: 1199px) {
    .playbook-benefit__extra-list {
        /* เทคนิคเดียวกับ .playbook-benefit__list ด้านบน: ถอยออกจาก .container
           ไปจนสุดขอบ viewport (section มี overflow-x: clip กันไม่ให้เกิด scroll แนวนอน) */
        margin-inline: calc(50% - 50vw);
        /* ระยะ 32px นับจากขอบจอถึง "ตัวหนังสือ" ไม่ใช่ขอบกล่องแถว
           ตัวหนังสือถูก padding-left ของช่องดันเข้ามาอีก inset x 2 = 24px อยู่แล้ว
           แถวจึงเหลือระยะของตัวเองแค่ 8px ผลรวมจึงเป็น 32px พอดี */
        padding-inline: var(--space-2);
    }

    /* ลดระยะในของแต่ละช่องลงครึ่งหนึ่งจาก desktop (48/24 -> 24/12)
       ช่องแคบกว่า desktop แต่ไม่ได้แคบมาก ถ้าคงระยะเดิมไว้จะกินพื้นที่ตัวหนังสือไปเปล่า ๆ
       ลดผ่าน inset ค่าเดียว ซ้าย-ขวายังคงอัตราส่วน 2:1 เท่าเดิม เส้นคั่นจึงอยู่ในจังหวะเดิม

       ต้องเขียนคู่กับ .playbook-benefit ด้วย เพราะกฎตั้งต้นอยู่ในบล็อก nest ของ section
       ซึ่งคอมไพล์ออกมาเป็นสองคลาส media query ไม่ได้เพิ่ม specificity ให้ ถ้าเขียนคลาสเดียวจะแพ้ */
    .playbook-benefit .playbook-benefit__extra-item {
        --bt-playbook-benefit-extra-item-inset: var(--space-3);
    }
}

/* ต่ำกว่า lg เหลือแถวละ 2 ช่อง ช่องที่ 3 จึงขึ้นต้นแถวใหม่และไม่มีเส้นคั่น */
@media (max-width: 991px) {
    .playbook-benefit {
        .playbook-benefit__extra-item:nth-child(3)::before {
            display: none;
        }
    }
}

@media (max-width: 991px) {
    .playbook-benefit {
        --bt-playbook-benefit-extra-rule-length: 72px;
        --bt-playbook-benefit-extra-space: var(--space-16);
        --bt-playbook-benefit-action-space: var(--space-10);
        /* เหลือแถวละ 2 ช่อง (หรือ 1 ช่องต่ำกว่า 576) แถวเรียงลงล่างเยอะขึ้น
           ระยะ 48px ของจอกว้างจึงยืดเกินจำเป็น ลดเหลือ 32px ให้เกาะกลุ่มกันขึ้น */
        --bt-playbook-benefit-extra-list-row-gap: var(--space-8);

        /* จอกว้างวางเป็นแถวเดียว 4 ช่อง ระยะซ้ายเว้นเป็นสองเท่าเพื่อกันเส้นคั่นเบียดตัวหนังสือ
           และตัวหนังสือชิดซ้ายให้ขอบซ้ายของทุกช่องตรงกันเป็นคอลัมน์
           ต่ำกว่า 992 เหลือ 2 ช่อง (และ 1 ช่องต่ำกว่า 576) ขอบซ้ายที่ว่าไม่มีให้เรียงแล้ว
           คืนระยะซ้าย-ขวาให้เท่ากันและจัดเนื้อหากึ่งกลาง ช่องจึงสมดุลในตัวเอง
           ผลพลอยได้คือเส้นคั่นที่เกาะขอบซ้ายของช่องมาอยู่กลางร่องพอดี
           (เดิมเยื้องไปทางช่องซ้ายเพราะสองฝั่งเว้นไม่เท่ากัน) */
        .playbook-benefit__extra-item {
            padding-left: var(--bt-playbook-benefit-extra-item-inset);
            text-align: center;
        }
    }
}

@media (max-width: 767px) {
    .playbook-benefit {
        --bt-playbook-benefit-extra-rule-length: 64px;
    }
}

/* จอเล็กสุด: ตัวอักษรลงหนึ่งขั้น
   รายการ "อีก 4 อย่าง" ยังเป็นสองคอลัมน์ (col-6) เส้นคั่นแนวตั้งกลางร่องจึงใช้กฎของช่วง ≤991 ต่อได้เลย
   (ช่องที่ 1 กับ 3 ขึ้นต้นแถว ไม่มีเส้น) */
@media (max-width: 575px) {
    .playbook-benefit {
        --bt-playbook-benefit-index-size: var(--font-size-12);
        --bt-playbook-benefit-item-title-size: var(--font-size-18);
        --bt-playbook-benefit-copy-size: var(--font-size-14);
        --bt-playbook-benefit-extra-title-size: var(--font-size-16);
        --bt-playbook-benefit-extra-item-title-size: var(--font-size-16);
        --bt-playbook-benefit-extra-list-space: var(--space-6);
        --bt-playbook-benefit-extra-list-row-gap: var(--space-6);

        /* สองคอลัมน์บนจอ 375 เหลือที่ให้ตัวหนังสือช่องละ 136px ข้อความตัดบรรทัดเหลือคำโดด
           ลดระยะเผื่อเส้นคั่น 12 -> 4px ระยะข้างของช่องจึงลดจาก 24 เหลือ 16px
           (ครึ่ง gutter ของ .row 12px + 4px) ตัวหนังสือได้ที่เพิ่มเป็น 152px
           ระยะซ้ายขวายังเท่ากัน เส้นคั่นจึงยังอยู่กลางร่องพอดี */
        --bt-playbook-benefit-extra-rule-space: var(--space-1);

        /* ให้บรรทัดยาวใกล้เคียงกัน ไม่ทิ้งคำท้ายไว้บรรทัดเดียว เช่น "ระดับความ / เสี่ยงที่แท้จริง" */
        .playbook-benefit__extra-item-title {
            margin-top: var(--space-0);
            text-wrap: balance;
        }

        /* คำอธิบายขึ้นบรรทัดใหม่ด้วย <br> ตรงรอยต่อของวลี พอช่องแคบลง ท่อนหลังตัดซ้ำอีกรอบ
           เหลือคำโดดอย่าง "เล่น" หรือ "จำลอง" ไว้บรรทัดสุดท้าย
           text-wrap: balance ของช่วง ≤767 ไม่ทำงานกับย่อหน้าที่มี <br> จึงใช้ pretty แทน
           ซึ่งดึงคำจากบรรทัดก่อนหน้าลงมาเป็นเพื่อนคำท้าย เช่น "วัดจากบูธที่เดินและเกม / ที่เล่น"
           คง <br> ไว้ จอที่กว้างพอยังตัดตรงวลีตามที่วางไว้ (ลองซ่อน <br> แล้วเบราว์เซอร์
           ไปตัดกลางวลีแทน เช่น "วัด / จากบูธ" และ "ใช้ / ต่อกับ") */
        .playbook-benefit__extra-item .playbook-benefit__copy {
            text-wrap: pretty;
        }
    }
}


/* ปิด motion ภายในกรอบตัวอย่างทั้งหมด ข้ามไปสถานะปลายทางทันที */
@media (prefers-reduced-motion: reduce) {
    .playbook-benefit {

        .playbook-benefit__chip,
        .playbook-benefit__trait,
        .playbook-benefit__skill-value,
        .playbook-benefit__skill-fill {
            transition: none;
        }

        .playbook-benefit__chip,
        .playbook-benefit__trait,
        .playbook-benefit__skill-value {
            opacity: 1;
            transform: none;
        }

        .playbook-benefit__compare-handle:active {
            transform: translate(-50%, -50%);
        }
    }
}

/* ==========================================================================
   Section: Identity Cards (personalized-playbook.html)
   เวที coverflow วาดด้วย transform 3 มิติ ระยะ/มุมเอียงคำนวณใน
   js/identity-cards-carousel.js ที่นี่กำหนดแค่ขนาดการ์ด มุมมอง และสภาพแวดล้อม
   ========================================================================== */
.identity-cards {
    --bt-identity-padding-y: var(--section-padding-y);
    --bt-identity-lead-space: var(--space-12);
    --bt-identity-lead-size: var(--section-topic-size-sm);
    --bt-identity-lead-max-width: var(--layout-narrow-max);
    --bt-identity-highlight-space: var(--space-3);
    --bt-identity-highlight-size: var(--section-topic-size-sm);
    /* กรอบการ์ดยึดขนาดของไฟล์ภาพนิ่ง (520x728) เป็นหลัก เพราะเป็นไฟล์ที่มีขอบมนและ
       พื้นหลังโปร่งมาแล้ว ภาพนิ่งจึงเต็มกรอบพอดีเป๊ะ ส่วนวิดีโอ (554x740) สัดส่วนกว้างกว่า
       เล็กน้อย อยู่ชั้นหลังและถูกกรอบการ์ดตัดส่วนเกินทิ้ง จึงไม่มีส่วนไหนโผล่พ้นภาพนิ่ง */
    --bt-identity-card-natural-width: 520;
    --bt-identity-card-natural-height: 728;
    /* ขอบมนวัดจากไฟล์ภาพนิ่งต้นฉบับ: รัศมี 21px บนภาพกว้าง 520px คิดเป็นสัดส่วนไว้
       เพื่อให้ความมนเท่าเดิมทุกขนาดที่การ์ดถูกย่อ-ขยาย */
    --bt-identity-card-radius: calc(var(--bt-identity-card-width) * 21 / var(--bt-identity-card-natural-width));
    --bt-identity-card-width: clamp(calc(var(--space-32) + var(--space-10)), 22vw, calc(var(--space-32) * 2));
    --bt-identity-card-ratio: var(--bt-identity-card-natural-width) / var(--bt-identity-card-natural-height);
    --bt-identity-perspective: 3;
    --bt-identity-stage-space: var(--space-12);
    --bt-identity-stage-padding-y: var(--space-10);
    --bt-identity-controls-space: var(--space-6);
    --bt-identity-caption-name-size: var(--font-size-28);
    --bt-identity-caption-name-ink: #000;
    --bt-identity-caption-count-size: var(--section-small-size);
    --bt-identity-ink: var(--color-text-primary);
    --bt-identity-ink-dim: var(--color-text-muted);
    --bt-identity-bg-opacity: 0.4;
    /* เลื่อนเฟรมภาพลง เพื่อให้เส้นรอยต่อผนัง-พื้นของห้องไปอยู่หลังแถวการ์ดพอดี
       การ์ดจึงอ่านเป็นของที่ตั้งอยู่บนพื้น ไม่ใช่ลอยอยู่หน้าภาพ */
    --bt-identity-bg-position: 72%;
    --bt-identity-veil-start: 38%;

    /* ---------- scroll-driven expand ----------
       section ค่อย ๆ ขยายจากแผงขอบมนที่แคบกว่าจอ จนเต็มขอบจอและมุมคลายเป็นเหลี่ยม
       ค่า 0-1 มาจาก js/scroll-expand.js ซึ่งผูกกับตำแหน่งของ section ในจอ ไม่ใช่เวลา
       เลื่อนขึ้นจึงย้อนกลับเอง (scrub ไม่ใช่ trigger)

       ใช้ scale ไม่ใช่ width เพราะ width บังคับ layout ใหม่ทุกเฟรม ส่วน scale อยู่บน
       compositor ล้วน และผลพลอยได้คือเนื้อหาข้างในย่อตามไปด้วยทั้งก้อน
       ทรงภายในจึงไม่เพี้ยนระหว่างทาง

       radius ต้องคิดแยก ไม่ใช่ปล่อยให้ scale จัดการ เพราะ scale จะทำให้มุม "โค้งขึ้น"
       ตอนขยาย ซึ่งกลับทางกับที่ต้องการ (ยิ่งเต็มจอยิ่งต้องเหลี่ยม)
       หาร scale กลับไว้ด้วย ค่าที่เห็นจริงจึงตรงกับ px ที่เขียนไว้ ไม่ใช่ถูกขยายตาม

       transform-origin ที่ขอบบน: ระหว่างย่อ ขอบล่างจะลอยขึ้นมาจากตำแหน่งจริง
       ถ้าใช้ center center ขอบบนจะลอยลงมาด้วย เห็นเป็นช่องว่างคั่นกับ section ก่อนหน้า */
    /* ความกว้างแผงตอนยังไม่ขยาย = 0.898 x ความกว้างจอ
       ตั้งจากจอ 1470px (ขนาดจอจริง) ให้ได้ราว 1320px ตามที่ต้องการ
       เป็นสัดส่วนไม่ใช่ px ตายตัว จอแคบลงแผงจึงหดตาม ระยะขอบข้างละ 5.1% เท่ากันทุกจอ */
    --bt-identity-expand-min: 0.898;
    --bt-identity-expand-radius: var(--space-8);
    --bt-scroll-expand: 1;

    --bt-identity-expand-scale: calc(var(--bt-identity-expand-min) + (1 - var(--bt-identity-expand-min)) * var(--bt-scroll-expand));

    position: relative;
    isolation: isolate;
    overflow: clip;
    padding: var(--bt-identity-padding-y) var(--space-0);
    border-radius: calc((1 - var(--bt-scroll-expand)) * var(--bt-identity-expand-radius) / var(--bt-identity-expand-scale));
    color: var(--bt-identity-ink);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);
    scale: var(--bt-identity-expand-scale);
    transform-origin: center top;

    /* ฉากห้องแสงสีเดียวกับ section concept ของหน้าแรก แต่ทึบกว่าเพราะที่นี่ไม่ต้องไล่จาง
       ทั้งผืน จางเฉพาะขอบบน-ล่างเพื่อไม่ให้เห็นรอยตัดกับ section พื้นขาวที่ประกบอยู่ */
    &::before {
        content: '';
        position: absolute;
        inset: var(--space-0);
        z-index: 0;
        background: url('../images/concept-room-bg3.webp') center var(--bt-identity-bg-position) / cover no-repeat;
        opacity: var(--bt-identity-bg-opacity);
        pointer-events: none;
    }

    /* ไล่สีขาวทับฉากอีกชั้น เข้มสุดที่ขอบล่างแล้วจางหายไปด้านบน วางเป็น ::after จึงอยู่เหนือ
       ::before (ฉากห้อง) แต่ยังต่ำกว่าเนื้อหา และไม่ติดทั้ง opacity และ mask ของฉาก */
    &::after {
        content: '';
        position: absolute;
        inset: var(--space-0);
        z-index: 0;
        background: linear-gradient(180deg,
                transparent var(--bt-identity-veil-start),
                var(--color-surface-page) 50%);
        pointer-events: none;
    }

    /* เนื้อหาทั้งหมดต้องอยู่เหนือฉาก เพราะฉากเป็น element ที่ positioned */
    .identity-cards__header,
    .identity-cards__carousel {
        position: relative;
        z-index: 1;
    }

    .identity-cards__header {
        text-align: center;
    }

    .identity-cards__eyebrow {
        justify-content: center;
        color: var(--bt-identity-ink-dim);

        &::after {
            display: none;
        }
    }

    .identity-cards__title {
        color: var(--bt-identity-ink);
        font-weight: var(--font-weight-medium);
    }

    .identity-cards__lead {
        max-width: var(--bt-identity-lead-max-width);
        margin: var(--bt-identity-lead-space) auto var(--space-0);
        color: var(--bt-identity-ink-dim);
        font-size: var(--bt-identity-lead-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-relaxed);
    }

    /* ข้อความธรรมดา ไม่มีกรอบ/พื้นหลัง สีรับมาจาก --bt-identity-ink ของ section
       ไม่ต้อง fit-content + margin auto เหมือนตอนเป็น badge แล้ว เพราะ header
       ของ section จัดกึ่งกลางด้วย text-align อยู่แล้ว */
    .identity-cards__highlight {
        margin: var(--bt-identity-highlight-space) auto var(--space-0);
        color: var(--bt-identity-ink-dim);
        font-size: var(--bt-identity-highlight-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-relaxed);
    }

    /* ชื่อบัตรใช้ไล่สี spectrum ชุดเดียวกับหัวข้อ โดยติด .bt-title-highlight ใน markup
       ไม่ได้ก๊อปค่าไล่สีมาเขียนซ้ำ จึงได้ทั้งสีและ animation ชุดเดียวกับที่อื่นของเว็บ
       เหลือสองอย่างที่ต้องกลบ เพราะ component นั้นออกแบบมาสำหรับหัวข้อ:
       ขนาด (ล็อกไว้ 64px แล้วไล่ลงตาม breakpoint) เปลี่ยนเป็นรับจากบรรทัดที่มันอยู่
       และน้ำหนัก medium ที่ Baskervville ไม่มี (โหลดมาแค่ 400) ถ้าไม่คืนเป็น regular
       เบราว์เซอร์จะปลอมตัวหนาให้จนตัวอักษรบวมผิดรูป
       ห้ามใส่ color หรือ background ตรงนี้ ไล่สีทำงานด้วย background-clip: text อยู่ */
    .identity-cards__highlight-plan {
        font-family: 'Baskervville', var(--font-family-base);
        font-size: inherit;
        font-weight: var(--font-weight-regular);
    }

    .identity-cards__carousel {
        margin-top: var(--bt-identity-stage-space);
    }

    /* ระยะมุมมองคิดจากความกว้างการ์ด เวทีจึงกว้างขึ้นตามจอโดยอัตราส่วนคงเดิม */
    .identity-cards__frame {
        padding: var(--bt-identity-stage-padding-y) var(--space-0);
        overflow: hidden;
        perspective: calc(var(--bt-identity-card-width) * var(--bt-identity-perspective));
        cursor: grab;
        outline: none;
        /* ลากแนวนอนเป็นของ carousel ส่วนแนวตั้งปล่อยให้หน้าเลื่อนตามปกติ */
        touch-action: pan-y;

        &:active {
            cursor: grabbing;
        }

        &:focus-visible {
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: calc(var(--border-width-2) * -1);
        }
    }

    .identity-cards__track {
        position: relative;
        height: calc(var(--bt-identity-card-width) * var(--bt-identity-card-natural-height) / var(--bt-identity-card-natural-width));
        transform-style: preserve-3d;
        user-select: none;
    }

    .identity-cards__card {
        position: absolute;
        top: var(--space-0);
        left: 50%;
        width: var(--bt-identity-card-width);
        aspect-ratio: var(--bt-identity-card-ratio);
        overflow: hidden;
        border-radius: var(--bt-identity-card-radius);
        background: var(--color-surface-soft);
        will-change: transform;
    }

    .identity-cards__card:not(.is-active) {
        cursor: pointer;
    }

    .identity-cards__video,
    .identity-cards__still {
        width: 100%;
        height: 100%;
        display: block;
        pointer-events: none;
        filter: saturate(1.2);
    }

    /* ภาพนิ่งเป็นตัวกำหนดกรอบ สัดส่วนตรงกับกรอบอยู่แล้วจึงพอดีโดยไม่ถูกตัด */
    .identity-cards__still {
        object-fit: contain;
    }

    /* วิดีโอกว้างกว่ากรอบราว 4.6% ให้เต็มกรอบแล้วเฉือนด้านข้างส่วนเกินทิ้ง
       ถ้าใช้ contain แทน จะเหลือแถบพื้นการ์ดโผล่บน-ล่างตอนวิดีโอเล่น */
    .identity-cards__video {
        object-fit: cover;
    }

    /* ภาพนิ่งทับวิดีโอไว้ แล้วจางออกเมื่อวิดีโอเริ่มเล่นจริง (คลาสมาจาก JS)
       ใบที่ไม่ได้อยู่กลางเวทีจึงเห็นเป็นการ์ดนิ่งเสมอ ไม่ใช่เฟรมค้างของวิดีโอ */
    .identity-cards__still {
        position: absolute;
        inset: var(--space-0);
        z-index: 1;
        transition: opacity var(--duration-base) var(--ease-standard);
    }

    .identity-cards__card.is-playing .identity-cards__still {
        opacity: 0;
    }

    /* ชั้นเงาของใบที่อยู่ถัดออกไป ความเข้มและด้านที่ไล่เงาคุมจาก JS ตามระยะห่างจากกลางเวที
       ไล่จากขอบซ้ายเป็นค่าตั้งต้น ใบฝั่งซ้ายจะถูกพลิกด้วย scaleX ให้เงาไปอยู่ขอบขวาแทน */
    .identity-cards__shade {
        position: absolute;
        inset: var(--space-0);
        z-index: 2;
        display: block;
        opacity: 0;
        background: linear-gradient(90deg,
                var(--color-neutral-950) 0%,
                color-mix(in srgb, var(--color-neutral-950) 48%, transparent) 36%,
                transparent 74%);
        pointer-events: none;
    }

    .identity-cards__caption {
        margin-top: var(--bt-identity-controls-space);
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--space-6);
        text-align: center;
    }

    .identity-cards__caption-name {
        color: var(--bt-identity-caption-name-ink);
        font-family: 'Baskervville', var(--font-family-base);
        font-size: var(--bt-identity-caption-name-size);
        line-height: var(--line-height-normal);
        letter-spacing: var(--letter-spacing-index);
    }

    .identity-cards__caption-count {
        color: var(--bt-identity-ink-dim);
        font-size: var(--bt-identity-caption-count-size);
        line-height: var(--section-small-line-height);
        letter-spacing: var(--letter-spacing-index);
    }
}

@media (max-width: 991px) {
    .identity-cards {
        --bt-identity-padding-y: var(--section-padding-y-sm);
        --bt-identity-lead-size: var(--section-body-size);
        --bt-identity-highlight-size: var(--section-body-size);
        --bt-identity-stage-space: var(--space-12);
        --bt-identity-caption-name-size: var(--font-size-24);
        --bt-identity-highlight-space: var(--space-2);
    }
}

@media (max-width: 575px) {
    .identity-cards {
        --bt-identity-card-width: clamp(calc(var(--space-32) + var(--space-8)), 54vw, calc(var(--space-32) + var(--space-24)));
        --bt-identity-caption-name-size: var(--font-size-18);
        --bt-identity-highlight-space: var(--space-3);
    }
}

@media (prefers-reduced-motion: reduce) {
    .identity-cards {
        .identity-cards__still {
            transition-duration: var(--duration-reduced);
        }
    }
}


/* ==========================================================================
   Section: Playbook Steps — How it works (personalized-playbook.html)
   หัวข้อใช้ component เดียวกับ section อื่น การ์ดขั้นตอนใช้พื้น/ขอบ/มุมโค้งชุดเดียว
   กับการ์ดอื่นในเว็บ ขั้นแรกเป็นการ์ดเต็มความกว้างเพราะมีปุ่มเริ่มต้นและภาพประกอบ
   ========================================================================== */
.playbook-steps {
    --bt-playbook-steps-padding-y: var(--section-padding-y);
    --bt-playbook-steps-lead-space: var(--space-12);
    --bt-playbook-steps-lead-size: var(--section-topic-size-sm);
    --bt-playbook-steps-lead-max-width: var(--layout-narrow-max);
    --bt-playbook-steps-list-space: var(--space-16);
    --bt-playbook-steps-list-gap: var(--space-6);
    --bt-playbook-steps-card-padding: var(--space-10);
    --bt-playbook-steps-number-size: var(--space-8);
    /* วงกลมลำดับขั้นใช้สีน้ำเงินชุดเดียวกับตัวเน้นอื่นใน section นี้ (ห้ามพลาด / ไอคอนธง) */
    --bt-playbook-steps-number-bg: var(--color-accent-primary);
    --bt-playbook-steps-index-size: var(--section-small-size);
    --bt-playbook-steps-item-title-size: var(--section-topic-size);
    --bt-playbook-steps-item-title-accent-gap: var(--space-1);
    --bt-playbook-steps-item-title-space: var(--space-6);
    --bt-playbook-steps-copy-size: var(--section-body-size);
    --bt-playbook-steps-copy-space: var(--space-3);
    --bt-playbook-steps-points-space: var(--space-6);
    --bt-playbook-steps-points-gap: var(--space-1);
    --bt-playbook-steps-highlight-space: var(--space-8);
    /* ข้อ "ห้ามพลาด" ใช้ขนาดของตัวเอง เล็กกว่าเนื้อหาในการ์ดหนึ่งขั้น */
    --bt-playbook-steps-highlight-size: var(--font-size-14);
    --bt-playbook-steps-point-icon-size: var(--font-size-16);
    --bt-playbook-steps-point-star-size: var(--font-size-12);
    --bt-playbook-steps-action-space: var(--space-8);
    --bt-playbook-steps-preview-padding: var(--space-6);
    --bt-playbook-steps-preview-ink: #111318;
    --bt-playbook-steps-preview-muted: #687078;
    --bt-playbook-steps-compare-ratio: 5 / 7;
    /* การ์ดกินสัดส่วนคงที่ของกรอบ เหลือที่ว่างสองข้างให้ป้ายเท่ากันทุกความกว้าง
       34% ไม่ใช่ 40% เพราะกรอบแคบลงแล้วป้ายต้องมีที่พอ ที่จอใหญ่ยังชน max 210px เท่าเดิม */
    --bt-playbook-steps-compare-width: clamp(140px, 34cqi, 210px);
    /* ---------- ไดอะแกรมการ์ด + ป้ายกระจาย (ปรับจาก AnimatedCard/Visual2 ของ React) ----------
       ต้นฉบับใช้ Tailwind + state ของ React ที่นี่เป็น CSS ล้วน สั่งด้วยคลาสเดียวจาก IntersectionObserver
       ease-back ทำให้การ์ด "เด้ง" เกินปลายทางนิดหนึ่งก่อนเข้าที่ ซึ่งเป็นความรู้สึกที่ขอมา */
    --bt-playbook-steps-diagram-card-duration: 620ms;
    --bt-playbook-steps-diagram-tag-duration: 560ms;
    --bt-playbook-steps-diagram-tag-lead: 320ms;
    --bt-playbook-steps-diagram-tag-step: 80ms;
    --bt-playbook-steps-diagram-ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
    /* ระยะที่ป้ายวิ่งออกมาจากหลังการ์ด คิดเป็นสัดส่วนของกรอบ (cqi) ไม่ใช่พิกเซลตายตัว
       ป้ายจึงออกมาไกลเท่ากันเสมอไม่ว่ากรอบจะกว้างแค่ไหน */
    --bt-playbook-steps-diagram-tag-travel: 30cqi;
    --bt-playbook-steps-diagram-tag-gap: var(--space-4);
    /* ระยะจากขอบการ์ดถึงป้าย วัดจากขอบคอลัมน์ ไม่ใช่จากขอบป้ายแต่ละใบ ทุกใบจึงห่างเท่ากัน */
    --bt-playbook-steps-diagram-tag-card-gap: var(--space-6);
    /* ระยะที่ป้ายแถวกลางดันออกห่างจากการ์ด ทำให้สามใบเรียงเป็นเส้นโค้งแทนที่จะตรงเป็นไม้บรรทัด
       ใส่ไว้ใน transform ไม่ใช่ margin กล่องป้ายจึงยังกว้างเท่าเดิม ข้อความไม่ถูกบีบจนตัดบรรทัด */
    --bt-playbook-steps-diagram-tag-stagger: var(--space-5);
    --bt-playbook-steps-diagram-tag-size: var(--font-size-12);
    --bt-playbook-steps-diagram-tag-icon-size: var(--font-size-14);
    --bt-playbook-steps-diagram-tag-icon-gap: var(--space-2);
    /* ไอคอนนั่งอยู่ในวงกลมพื้นเทาอ่อน ไม่ได้ลอยติดตัวอักษรเฉย ๆ */
    --bt-playbook-steps-diagram-tag-icon-chip: var(--space-6);
    --bt-playbook-steps-diagram-tag-icon-chip-bg: var(--color-neutral-100);
    /* เส้นขอบไล่สีชุดเดียวกับปุ่มซื้อบัตรบน header (--gradient-accent-spectrum)
       ไล่สีที่ border ตรง ๆ ไม่ได้ จึงซ้อนพื้นสองชั้น: ชั้นในทึบครอบแค่ padding-box
       ชั้นนอกเป็นไล่สีครอบถึง border-box ส่วนที่โผล่พ้นชั้นในออกมาคือเส้นขอบ
       (วิธีเดียวกับ .site-header .bt-action-button--primary) */
    --bt-playbook-steps-diagram-tag-fill: var(--color-neutral-0);
    --bt-playbook-steps-diagram-tag-border: var(--gradient-accent-spectrum);
    --bt-playbook-steps-diagram-tag-icon-ink: var(--color-neutral-900);
    /* ตารางเส้นบาง ๆ หลังการ์ด (GridLayer ของต้นฉบับ) เป็นระนาบอ้างอิงให้ป้ายที่กระจายออก
       ไม่ลอยอยู่บนพื้นขาวเปล่า ๆ เส้นจางมากและจางหายก่อนถึงขอบกรอบ จึงอ่านเป็นพื้นผิว ไม่ใช่ตาราง */
    --bt-playbook-steps-diagram-grid-size: 28px;
    --bt-playbook-steps-diagram-grid-width: 1px;
    --bt-playbook-steps-diagram-grid-ink: color-mix(in srgb, var(--color-neutral-400) 20%, transparent);
    --bt-playbook-steps-diagram-grid-fade: 40% 46%;
    --bt-playbook-steps-diagram-grid-fade-hold: 40%;
    --bt-playbook-steps-compare-radius: var(--space-4);
    --bt-playbook-steps-compare-chip-bg: rgba(17, 19, 24, 0.62);
    --bt-playbook-steps-compare-shadow: 0 10px 30px rgba(17, 19, 24, 0.15), 0 2px 6px rgba(17, 19, 24, 0.09);
    --bt-playbook-steps-caption-max-width: 280px;
    --bt-playbook-steps-persona-fade: 220ms;

    padding: var(--bt-playbook-steps-padding-y) var(--space-0);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .playbook-steps__lead {
        max-width: var(--bt-playbook-steps-lead-max-width);
        margin: var(--bt-playbook-steps-lead-space) var(--space-0) var(--space-0);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-steps-lead-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-relaxed);
    }

    .playbook-steps__list {
        margin-top: var(--bt-playbook-steps-list-space);
        margin-bottom: var(--space-0);
        row-gap: var(--bt-playbook-steps-list-gap);
        list-style: none;
    }

    /* การ์ดในแถวเดียวกันสูงเท่ากันแม้เนื้อหาไม่เท่ากัน */
    .playbook-steps__card {
        position: relative;
        height: 100%;
        padding: var(--bt-playbook-steps-card-padding);
        border-radius: var(--card-radius);
        background: var(--color-surface-paper);
    }

    /* ป้ายสถานะใช้หน้าตาชุดเดียวกับป้ายสิทธิ์ของบัตรในเว็บ คือ pill ฟ้าอ่อนขอบบาง
       (ค่าที่ใช้เป็น token ระดับ system ทั้งหมด ไม่ได้ดึงค่าจาก section อื่น) */
    /* อยู่ในกรอบตัวอย่างการ์ดตามลำดับเนื้อหาปกติ (ไม่ลอยทับ): จอแคบวางกลางเหนือการ์ด
       กรอบกว้างวางมุมบนขวาของคอลัมน์ข้อความ (ดู @container ด้านล่าง) */
    .playbook-steps__badge {
        width: fit-content;
        min-height: var(--space-5);
        margin: var(--space-0) auto var(--space-4);
        padding: var(--space-1) var(--space-3);
        display: flex;
        align-items: center;
        border-radius: var(--pill-radius);
        border: var(--rule-width-subtle) solid var(--color-blue-200);
        background: var(--color-blue-100);
        color: var(--color-blue-400);
        font-size: var(--section-tag-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-body-line-height);
        white-space: nowrap;
    }

    .playbook-steps__index {
        margin-bottom: var(--space-0);
        display: flex;
        align-items: center;
        gap: var(--space-3);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-steps-index-size);
        line-height: var(--line-height-1);
        letter-spacing: var(--letter-spacing-index);
    }

    .playbook-steps__number {
        width: var(--bt-playbook-steps-number-size);
        height: var(--bt-playbook-steps-number-size);
        display: grid;
        place-items: center;
        border-radius: var(--radius-round);
        color: var(--color-surface-page);
        background: var(--bt-playbook-steps-number-bg);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-medium);
        letter-spacing: var(--letter-spacing-0);
    }

    .playbook-steps__item-title {
        margin-top: var(--bt-playbook-steps-item-title-space);
        font-size: var(--bt-playbook-steps-item-title-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--section-topic-line-height-sm);
    }

    /* คำเน้นในหัวข้อย่อย ใช้ไล่สีสเปกตรัมกับ animation ชุดเดียวกับ .bt-title-highlight
       ของหัวข้อ h2 (background-size 200% เพื่อให้มีระยะให้ไล่ + keyframes ตัวเดียวกัน)
       แต่ไม่แตะขนาดกับน้ำหนัก ทุกอย่างรับมาจาก .playbook-steps__item-title ตามเดิม
       จงใจไม่ใช้ class .bt-title-highlight ตรง ๆ เพราะตัวนั้นบังคับขนาด 64px มาด้วย */
    .playbook-steps__item-title-accent {
        background-image: var(--spectrum);
        background-size: 200% 100%;
        background-clip: text;
        -webkit-background-clip: text;
        color: transparent;
        -webkit-text-fill-color: transparent;
        animation: bt-title-spectrum-flow 3s ease-in-out infinite alternate;

        /* ชุด has-ps / has-pe / has-px ความหมายเดียวกับของ .bt-title-highlight
           คือเว้นช่องว่างด้านที่ติดกับข้อความธรรมดา
           ค่าคนละตัวกับหัวข้อ h2 เพราะ h2 ใช้ --space-2 กับตัวอักษร 64px (ราว 12% ของขนาด)
           คำเน้นตรงนี้เป็น 24px (20px ที่ ≤991px) ถ้าใช้ 8px ตามจะเว้นเกินไปจนคำหลุดออกจากประโยค
           --space-1 คิดเป็นสัดส่วนใกล้เคียงกับที่ h2 ใช้ตอนย่อเหลือ 36px */
        &.has-ps {
            padding-left: var(--bt-playbook-steps-item-title-accent-gap);
        }

        &.has-pe {
            padding-right: var(--bt-playbook-steps-item-title-accent-gap);
        }

        &.has-px {
            padding-left: var(--bt-playbook-steps-item-title-accent-gap);
            padding-right: var(--bt-playbook-steps-item-title-accent-gap);
        }
    }

    @media (prefers-reduced-motion: reduce) {
        .playbook-steps__item-title-accent {
            animation: none;
        }
    }

    .playbook-steps__copy {
        margin-top: var(--bt-playbook-steps-copy-space);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-steps-copy-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }

    .playbook-steps__points {
        margin-top: var(--bt-playbook-steps-points-space);
        padding-left: var(--space-0);
        display: grid;
        gap: var(--bt-playbook-steps-points-gap);
        list-style: none;
    }

    .playbook-steps__points li {
        display: grid;
        grid-template-columns: auto 1fr;
        gap: var(--space-3);
        align-items: start;
        color: var(--color-text-secondary);
        font-size: var(--bt-playbook-steps-copy-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }

    /* ดาวนำหน้าแต่ละข้อคุมความสูงด้วย token ของตัวเอง (เล็กกว่าตัวอักษร) ความกว้างไหลตามสัดส่วนภาพ 95:100
       margin-top คิดจากครึ่งหนึ่งของ "ความสูงบรรทัดแรก ลบ ความสูงดาว" ดาวจึงอยู่กึ่งกลางบรรทัดแรกเสมอ */
    .playbook-steps__point-star {
        width: auto;
        height: var(--bt-playbook-steps-point-star-size);
        margin-top: calc((var(--line-height-relaxed) * var(--bt-playbook-steps-copy-size) - var(--bt-playbook-steps-point-star-size)) / 2);
    }

    /* ข้อที่ห้ามพลาดแยกออกจากลิสต์ ไม่มีพื้นหลัง ให้ไอคอนธงสีน้ำเงินกับคำว่า "ห้ามพลาด" เป็นตัวเน้นแทน
       ไม่มี padding จึงตรงแนวซ้ายกับหัวข้อย่อยด้านบน */
    .playbook-steps__highlight {
        margin-top: var(--bt-playbook-steps-highlight-space);
        margin-bottom: var(--space-0);
        display: grid;
        grid-template-columns: auto 1fr;
        gap: var(--space-2);
        align-items: start;
        color: var(--color-text-secondary);
        font-size: var(--bt-playbook-steps-highlight-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }

    .playbook-steps__highlight strong {
        color: var(--color-accent-primary);
        font-weight: var(--font-weight-medium);
    }

    /* ชุดเดียวกับ __highlight แต่เน้นทั้งบรรทัด สีกับน้ำหนักจึงเสมอกันหมด
       ไม่มี strong คั่นให้คำไหนเด่นกว่าคำไหน (ไอคอนกับกริดยังเป็นของ __highlight เดิม) */
    .playbook-steps__highlight--accent {
        color: var(--color-accent-primary);
        font-weight: var(--font-weight-medium);
    }

    /* ไอคอนจัดกึ่งกลางความสูงของบรรทัดแรก ชุดเดียวกับหัวข้อย่อย */
    .playbook-steps__highlight-icon {
        margin-top: calc((var(--line-height-relaxed) * var(--bt-playbook-steps-highlight-size) - var(--bt-playbook-steps-point-icon-size)) / 2);
        color: var(--color-accent-primary);
        font-size: var(--bt-playbook-steps-point-icon-size);
    }

    .playbook-steps__points strong {
        color: var(--color-text-primary);
        font-weight: var(--font-weight-medium);
    }

    .playbook-steps__action {
        margin-top: var(--bt-playbook-steps-action-space);
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--space-4);
    }

    /* ปุ่มดำล้วนไม่มีขอบ spectrum ชุดเดียวกับปุ่มซื้อบัตรของเว็บ */
    .playbook-steps__action .bt-action-button--primary {
        border-color: var(--bt-action-fill);
        background: var(--bt-action-fill);
    }

    .playbook-steps__note {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-light);
        line-height: var(--section-small-line-height);
    }

    /* นาฬิกาสูงเท่าขนาดตัวอักษรของข้อความพอดี (1em) และใช้สีเดียวกับข้อความ */
    .playbook-steps__note-icon {
        font-size: 1em;
    }

    /* ---------- ตัวอย่างการ์ดตัวตน (พอร์ตจาก .cr2 / .cr2-cap / .fam-badge / .hero-sig-c ของ dna-quiz-flow) ---------- */
    /* กรอบวัดความกว้างของตัวเอง (container query) เพื่อเลือกวางการ์ดคู่ข้อความหรือเรียงลงล่าง
       ไม่ผูกกับ breakpoint ของหน้า เพราะคอลัมน์นี้กว้างไม่ตรงกับขนาดจอ (อยู่ข้างข้อความบนจอใหญ่ อยู่ใต้ข้อความบนจอกลาง) */
    .playbook-steps__preview {
        container-type: inline-size;
        padding: var(--bt-playbook-steps-preview-padding);
        border-radius: var(--card-radius);
        /* background: var(--color-surface-page); */
    }

    .playbook-steps__preview-info {
        margin-top: var(--space-4);
        text-align: center;
    }

    /* กรอบการ์ดตัวอย่าง ความสูงมาจากสัดส่วนการ์ดจริง (520:728 = 5:7) */
    .playbook-steps__diagram {
        position: relative;
        /* ต้องกว้างเต็มกรอบ ไม่งั้นกล่องจะหดเท่าการ์ด แล้วจุดกึ่งกลางที่ป้ายใช้อ้างอิง
           จะไม่ตรงกับกึ่งกลางของกรอบ ป้ายก็จะเทไปข้างเดียว */
        width: 100%;
        display: grid;
        place-items: center;
        isolation: isolate;
    }

    /* ตารางเส้นบาง วาดด้วย repeating-linear-gradient สองชั้น (แนวตั้ง+แนวนอน)
       แล้วเจาะด้วย mask รูปวงรี ให้เส้นเข้มที่กลางแล้วจางหายก่อนถึงขอบ
       อยู่ใน ::before ที่ position: absolute จึงไม่กลายเป็นช่องของ grid ด้านนอก */
    .playbook-steps__diagram::before {
        content: '';
        position: absolute;
        z-index: 0;
        inset: var(--space-0);
        background-image:
            repeating-linear-gradient(to right,
                var(--bt-playbook-steps-diagram-grid-ink) var(--space-0) var(--bt-playbook-steps-diagram-grid-width),
                transparent var(--bt-playbook-steps-diagram-grid-width) var(--bt-playbook-steps-diagram-grid-size)),
            repeating-linear-gradient(to bottom,
                var(--bt-playbook-steps-diagram-grid-ink) var(--space-0) var(--bt-playbook-steps-diagram-grid-width),
                transparent var(--bt-playbook-steps-diagram-grid-width) var(--bt-playbook-steps-diagram-grid-size));
        /* รัศมีวงรีสั้นกว่าครึ่งกรอบทั้งสองแกน (246 จาก 308 และ 133 จาก 145) เส้นจึงหายสนิท
           ก่อนถึงขอบ ไม่ถูกตัดเป็นกรอบสี่เหลี่ยม ส่วน hold ที่ 40% ทำให้ยังเต็มความเข้ม
           ถึงแถบรอบ ๆ การ์ดพอดี แล้วไล่จางลงเรื่อย ๆ ความชัดเลยกระจุกอยู่กลางกรอบเท่านั้น */
        mask-image: radial-gradient(ellipse var(--bt-playbook-steps-diagram-grid-fade) at 50% 50%,
                #000 var(--bt-playbook-steps-diagram-grid-fade-hold), transparent);
        opacity: 0;
        transition: opacity var(--bt-playbook-steps-diagram-card-duration) var(--ease-standard);
        pointer-events: none;
    }

    .playbook-steps__diagram.is-revealed::before {
        opacity: 1;
    }

    /* แสงนวลหลังการ์ด ทำหน้าที่เดียวกับ EllipseGradient ของต้นฉบับ
       คือให้ป้ายที่กระจายออกไปมีพื้นรอง ไม่ลอยอยู่บนความว่าง */
    .playbook-steps__diagram-glow {
        position: absolute;
        z-index: 0;
        width: 116%;
        aspect-ratio: 16 / 10;
        border-radius: var(--radius-round);
        background: radial-gradient(closest-side,
                color-mix(in srgb, var(--color-accent-primary) 12%, transparent),
                transparent 72%);
        opacity: 0;
        transition: opacity var(--bt-playbook-steps-diagram-card-duration) var(--ease-standard);
        pointer-events: none;
    }

    .playbook-steps__diagram.is-revealed .playbook-steps__diagram-glow {
        opacity: 1;
    }

    /* การ์ดเด้งขึ้น: ขึ้นมาจากด้านล่างพร้อมขยายจากเล็ก แล้วเลยปลายทางนิดหนึ่งด้วย ease-back */
    .playbook-steps__diagram .playbook-steps__compare {
        z-index: 2;
        opacity: 0;
        transform: translateY(26px) scale(0.86);
        transition:
            opacity var(--bt-playbook-steps-diagram-card-duration) var(--ease-standard),
            transform var(--bt-playbook-steps-diagram-card-duration) var(--bt-playbook-steps-diagram-ease-back);
    }

    .playbook-steps__diagram.is-revealed .playbook-steps__compare {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

    /* ป้ายเริ่มซ้อนอยู่หลังการ์ดตรงกลาง แล้ววิ่งออกไปเกาะขอบซ้าย-ขวาของกรอบ
       แบ่งเป็นสองคอลัมน์ที่เรียงตัวเอง ไม่ได้กำหนดพิกัดทีละใบ เพราะกรอบนี้กว้างไม่เท่ากัน
       ในแต่ละจอ (เป็นคอลัมน์ขวาของการ์ดขั้นแรก) และข้อความในป้ายก็ยาวไม่เท่ากัน
       ถ้าวัดเป็นพิกเซลจากจุดกึ่งกลาง ป้ายจะล้นออกนอกการ์ดขาวตอนกรอบแคบ
       และชนกันเองทันทีที่ข้อความยาวจนต้องตัดบรรทัด */
    .playbook-steps__tags {
        position: absolute;
        inset: var(--space-0);
        z-index: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        pointer-events: none;
    }

    /* กว้างได้เท่าที่ยังไม่ถูกการ์ดบัง (ครึ่งกรอบ ลบครึ่งการ์ด ลบระยะห่าง)
       ข้อความที่ยาวกว่านั้นตัดบรรทัดแทนการมุดหายไปหลังการ์ด */
    /* เรียงชิดด้านที่ติดการ์ด ไม่ใช่ชิดขอบกรอบ เพราะข้อความแต่ละใบยาวไม่เท่ากัน
       ถ้าเกาะขอบกรอบ ด้านที่หันเข้าการ์ดจะกระดิกตามความยาวข้อความ ซ้าย-ขวาเหลื่อมไม่เท่ากัน
       ชิดด้านในแทน ทุกใบจึงห่างจากขอบการ์ดเท่ากันหมด แล้วปล่อยให้ด้านนอกเป็นฝั่งที่ไม่เสมอ */
    .playbook-steps__tag-col {
        /* กำหนด width ไม่ใช่ max-width: flex item จะกว้างเท่าใบที่ยาวสุดของตัวเองถ้าไม่บังคับ
           สองคอลัมน์มีใบยาวสุดไม่เท่ากัน ขอบด้านในจึงไม่ตรงกัน ซ้าย-ขวาเหลื่อมไม่เท่า */
        width: calc(50% - var(--bt-playbook-steps-compare-width) / 2 - var(--bt-playbook-steps-diagram-tag-card-gap));
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: var(--bt-playbook-steps-diagram-tag-gap);
    }

    .playbook-steps__tag-col--end {
        align-items: flex-start;
    }

    .playbook-steps__tag {
        /* ซ้ายแคบกว่าขวา เพราะวงกลมของไอคอนเป็นรูปทรงของตัวเองอยู่แล้ว
           ถ้าเว้นเท่ากันสองข้างวงจะดูลอยห่างขอบซ้ายเกินไป */
        padding: var(--space-1) var(--space-4) var(--space-1) var(--space-1);
        display: flex;
        align-items: center;
        gap: var(--bt-playbook-steps-diagram-tag-icon-gap);
        border: var(--rule-width-subtle) solid transparent;
        border-radius: var(--pill-radius);
        color: var(--color-text-primary);
        /* ชั้นในต้องทึบ ไม่งั้นไล่สีของขอบจะทะลุขึ้นมาย้อมทั้งใบ
           (พื้นเดิมโปร่ง 22% ไว้ให้ลายตารางทะลุ แต่ป้ายไม่ได้ทับการ์ดแล้ว จึงไม่เสียอะไร) */
        background:
            linear-gradient(var(--bt-playbook-steps-diagram-tag-fill), var(--bt-playbook-steps-diagram-tag-fill)) padding-box,
            var(--bt-playbook-steps-diagram-tag-border) border-box;
        font-size: var(--bt-playbook-steps-diagram-tag-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--line-height-relaxed);
        /* ไม่ตัดบรรทัดเด็ดขาด ป้ายเรียงชิดด้านที่ติดการ์ด ใบที่กว้างเกินคอลัมน์จึงล้น
           ออกไปทางด้านนอก ไม่ใช่เบียดเข้าหาการ์ด ระยะห่างจากการ์ดเลยคงที่เสมอ
           ไม่ว่าจะแก้ข้อความ ขนาดฟอนต์ หรือ padding ให้กว้างขึ้นแค่ไหน */
        white-space: nowrap;
        opacity: 0;
        /* ทั้งระยะวิ่งออกและระยะถอยเข้า วัดจาก "เข้าหาการ์ด" เหมือนกัน ต่างกันแค่ทิศของคอลัมน์
           คูณด้วย --steps-tag-dir ครั้งเดียว จึงไม่ต้องเขียน transform แยกซ้าย-ขวา */
        --steps-tag-dir: 1;
        --steps-tag-inset: var(--space-0);
        transform: translateX(calc((var(--bt-playbook-steps-diagram-tag-travel) + var(--steps-tag-inset)) * var(--steps-tag-dir))) scale(0.9);
        transition:
            opacity var(--bt-playbook-steps-diagram-tag-duration) var(--ease-standard) var(--steps-tag-delay, 0ms),
            transform var(--bt-playbook-steps-diagram-tag-duration) var(--bt-playbook-steps-diagram-ease-back) var(--steps-tag-delay, 0ms);
    }

    /* แถวกลางดันออกห่างจากการ์ด แถวบน-ล่างชิดการ์ดไว้ สามใบจึงเรียงเป็นเส้นโค้ง */
    .playbook-steps__tag:nth-child(2) {
        --steps-tag-inset: calc(var(--bt-playbook-steps-diagram-tag-stagger) * -1);
    }

    /* ไอคอนบอกหัวข้อของคำถามตั้งแต่ยังไม่อ่านข้อความ วางในวงกลมพื้นเทาอ่อน
       ทำวงกลมที่กล่องครอบอีกชั้น ไม่ได้ทำที่ตัว svg เพราะ .bt-icon ตั้ง width/height
       ไว้เป็น 1em ถ้าใส่พื้นกับ padding ทับ ขนาดวงจะผูกติดกับขนาดไอคอน
       ปรับสัดส่วนวงกับไอคอนแยกกันไม่ได้ */
    .playbook-steps__tag-chip {
        flex: none;
        width: var(--bt-playbook-steps-diagram-tag-icon-chip);
        height: var(--bt-playbook-steps-diagram-tag-icon-chip);
        display: grid;
        place-items: center;
        border-radius: var(--radius-round);
        background: var(--bt-playbook-steps-diagram-tag-icon-chip-bg);
    }

    .playbook-steps__tag-icon {
        font-size: var(--bt-playbook-steps-diagram-tag-icon-size);
        color: var(--bt-playbook-steps-diagram-tag-icon-ink);
    }

    .playbook-steps__diagram.is-revealed .playbook-steps__tag {
        opacity: 1;
        transform: translateX(calc(var(--steps-tag-inset) * var(--steps-tag-dir))) scale(1);
    }

    /* ไล่ออกทีละแถว ซ้าย-ขวาออกพร้อมกันเป็นคู่ เริ่มหลังการ์ดลงจอดแล้ว (lead) */
    .playbook-steps__tag:nth-child(1) {
        --steps-tag-delay: var(--bt-playbook-steps-diagram-tag-lead);
    }

    .playbook-steps__tag:nth-child(2) {
        --steps-tag-delay: calc(var(--bt-playbook-steps-diagram-tag-lead) + var(--bt-playbook-steps-diagram-tag-step));
    }

    .playbook-steps__tag:nth-child(3) {
        --steps-tag-delay: calc(var(--bt-playbook-steps-diagram-tag-lead) + var(--bt-playbook-steps-diagram-tag-step) * 2);
    }

    /* ชุดขวาของกรอบกลับทิศทั้งหมด ต่างกันแค่บรรทัดเดียว หน้าตาเหมือนชุดซ้ายทุกอย่าง */
    .playbook-steps__tag--alt {
        --steps-tag-dir: -1;
    }

    /* ช่วง 602-613px ยังวางขนาบข้างการ์ดได้ แต่ที่ว่างเหลือน้อยกว่า ถ้าดันออก 20px
       ป้ายแถวกลางจะพ้นขอบกรอบออกไป จึงลดระยะเหลื่อมลงให้พอดีกับที่ว่างที่มี */
    @container (max-width: 613px) {
        .playbook-steps__tags {
            --bt-playbook-steps-diagram-tag-stagger: var(--space-2);
        }
    }

    /* ป้ายตั้ง white-space: nowrap ไว้ และเรียงชิดด้านที่ติดการ์ด ใบที่กว้างเกินคอลัมน์
       จึงล้นออกทางด้านนอก ไม่ได้เบียดเข้าหาการ์ด กรอบแคบลงได้อีกมากก่อนจะมีปัญหา
       ที่ว่างนอกกรอบมี 64px (padding ของ preview 24 + ของการ์ดขั้นตอน 40)
       ใบที่ยาวสุด 178px เทียบกับครึ่งกรอบลบครึ่งการ์ด (34%) ลบระยะห่าง 24px
       คิดกลับได้ว่ากรอบ 467px คือจุดที่ล้นออกไป 48px ซึ่งยังอยู่ในที่ว่างที่มี
       แคบกว่านั้นจึงค่อยย้ายป้ายลงมาเรียงใต้การ์ด แล้วเปลี่ยนทิศที่วิ่งออกเป็นลอยขึ้น
       (ถ้าแก้ข้อความ ขนาดฟอนต์ หรือ padding ของป้าย ต้องคิดตัวเลขนี้ใหม่) */
    @container (max-width: 466px) {

        .playbook-steps__tags {
            position: static;
            margin-top: var(--space-4);
            flex-wrap: wrap;
            justify-content: center;
            gap: var(--bt-playbook-steps-diagram-tag-gap);
        }

        /* ยุบกล่องคอลัมน์ทิ้ง ป้ายทั้งหกจึงไหลต่อกันในชุดเดียว
           ถ้าคงกล่องไว้ สองคอลัมน์จะตัดแถวของใครของมัน ได้ผลเป็น 2-1-2-1 ไม่เต็มแถว */
        .playbook-steps__tag-col {
            display: contents;
        }

        /* เรียงใต้การ์ดแล้วป้ายกว้างได้เท่ากรอบเท่านั้น ล้นออกข้างไม่ได้ จึงให้ตัดบรรทัดแทน */
        .playbook-steps__tag {
            white-space: normal;
        }

        /* ไม่มีขอบซ้าย-ขวาให้เหลื่อมแล้ว ทุกใบจัดกึ่งกลางเท่ากัน */
        .playbook-steps__tag,
        .playbook-steps__tag--alt {
            --steps-tag-inset: var(--space-0);
            transform: translateY(var(--space-3)) scale(0.9);
        }

        .playbook-steps__diagram.is-revealed .playbook-steps__tag {
            transform: translateY(var(--space-0)) scale(1);
        }
    }

    /* เครื่องที่ตั้งค่าลด motion: ให้ทุกอย่างอยู่ปลายทางตั้งแต่แรก ไม่ต้องวิ่ง */
    @media (prefers-reduced-motion: reduce) {

        .playbook-steps__diagram::before,
        .playbook-steps__diagram-glow,
        .playbook-steps__diagram .playbook-steps__compare,
        .playbook-steps__tag {
            opacity: 1;
            transition: none;
        }

        .playbook-steps__diagram .playbook-steps__compare {
            transform: none;
        }

        .playbook-steps__tag,
        .playbook-steps__tag--alt {
            transform: translateX(calc(var(--steps-tag-inset) * var(--steps-tag-dir)));
        }
    }

    .playbook-steps__compare {
        position: relative;
        width: 100%;
        max-width: var(--bt-playbook-steps-compare-width);
        aspect-ratio: var(--bt-playbook-steps-compare-ratio);
        margin-inline: auto;
        border-radius: var(--bt-playbook-steps-compare-radius);
        overflow: hidden;
        isolation: isolate;
        background: var(--color-surface-soft);
        box-shadow: var(--bt-playbook-steps-compare-shadow);
    }

    .playbook-steps__compare-side {
        position: absolute;
        inset: var(--space-0);
        overflow: hidden;
        pointer-events: none;
    }

    .playbook-steps__compare-card {
        position: absolute;
        inset: var(--space-0);
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

    .playbook-steps__compare-chip {
        position: absolute;
        top: var(--space-3);
        z-index: 6;
        padding: var(--space-1) var(--space-2);
        border-radius: var(--pill-radius);
        color: var(--color-neutral-0);
        background: var(--bt-playbook-steps-compare-chip-bg);
        backdrop-filter: blur(6px);
        font-size: var(--font-size-12);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-1);
        letter-spacing: 0.03em;
        pointer-events: none;
        transition: opacity 180ms var(--ease-standard);
    }

    .playbook-steps__compare-chip--before {
        left: var(--space-3);
    }

    /* คำอธิบายใต้การ์ด */
    .playbook-steps__caption {
        max-width: var(--bt-playbook-steps-caption-max-width);
        margin-inline: auto;
        color: var(--bt-playbook-steps-preview-muted);
        font-size: var(--font-size-12);
        font-weight: var(--font-weight-regular);
        line-height: 1.5;

        b {
            color: var(--bt-playbook-steps-preview-ink);
            font-weight: var(--font-weight-bold);
        }
    }

    /* persona สองชุดซ้อนกันในช่องเดียว ความสูงจึงเท่าชุดที่ยาวกว่าเสมอ สลับแล้วไม่กระโดด */
    .playbook-steps__personas {
        margin-top: var(--space-3);
        display: grid;
    }

    .playbook-steps__persona {
        grid-area: 1 / 1;
        opacity: 0;
        visibility: hidden;
        transition:
            opacity var(--bt-playbook-steps-persona-fade) var(--ease-standard),
            visibility 0s linear var(--bt-playbook-steps-persona-fade);
    }

    .playbook-steps__persona.is-active {
        opacity: 1;
        visibility: visible;
        transition:
            opacity var(--bt-playbook-steps-persona-fade) var(--ease-standard),
            visibility 0s;
    }

    /* ป้ายตระกูลการ์ด */
    .playbook-steps__family {
        width: fit-content;
        margin: var(--space-0) auto var(--space-2);
        padding: 6px var(--space-4);
        display: flex;
        align-items: center;
        border-radius: var(--pill-radius);
        color: var(--bt-playbook-steps-preview-ink);
        background: linear-gradient(135deg, var(--color-neutral-0), var(--color-neutral-100));
        font-size: var(--font-size-14);
        font-weight: var(--font-weight-bold);
        line-height: var(--line-height-normal);
        letter-spacing: 0.01em;
    }

    /* นิยามบุคลิกของการ์ด */
    .playbook-steps__signature {
        max-width: 32ch;
        margin-inline: auto;
        color: var(--bt-playbook-steps-preview-muted);
        font-size: var(--font-size-14);
        font-weight: var(--font-weight-medium);
        line-height: 1.55;
    }

    /* กรอบกว้างพอ: ป้ายกำกับขึ้นไปอยู่มุมบนขวา ไดอะแกรมกินเต็มความกว้างของแถวล่าง
       ผังเดิมของกรอบนี้เป็นสองคอลัมน์ (การ์ดซ้าย-ข้อความ persona ขวา) แบ่งเป็นสามแถว
       1fr auto 1fr เพื่อให้ข้อความอยู่กึ่งกลางการ์ด พอ persona ถูกถอดออกไป
       แถวล่างที่เป็น 1fr ก็ยังกินความสูงเท่าแถวบนทั้งที่ไม่มีอะไรอยู่ กลายเป็นที่ว่าง
       เปล่า ๆ ครึ่งกรอบ และการ์ดก็ถูกบีบอยู่ในคอลัมน์ซ้ายจนกึ่งกลางไม่ตรงกับกรอบ */
    @container (min-width: 340px) {

        .playbook-steps__preview-body {
            display: grid;
            grid-template-rows: auto 1fr;
            row-gap: var(--space-4);
        }

        .playbook-steps__badge {
            justify-self: end;
            margin: var(--space-0);
        }
    }
}

/* ---------- ช่วง 992-1199: คืนผังไดอะแกรมให้เหมือน desktop ----------
   ช่วงนี้ .container ตรึงไว้ที่ 960px การ์ดขั้นแรกจึงเหลือ 856px คอลัมน์ขวา (col-7)
   ได้กรอบตัวอย่างแค่ 443px ไดอะแกรมเหลือ 395px ต่ำกว่าเกณฑ์ 467px ของ @container
   ป้ายทั้งหกจึงถูกสั่งให้ทิ้งตัวลงมาเรียงใต้การ์ดเป็น 2x3 การ์ดสูงขึ้นจาก 437px เป็น 490px
   ทั้งที่จอยังกว้างพอจะวางขนาบข้างได้สบาย เพียงแต่ถูก container บีบไว้

   แก้ที่ต้นเหตุคือความกว้าง ไม่ใช่ไปลดเกณฑ์ 467px ลง เพราะจอ ~632px (คอลัมน์เดียว)
   ไดอะแกรมก็กว้าง 456px เข้าเงื่อนไขเดียวกัน แต่ตรงนั้นต้องเรียงลงล่างจริง ๆ
   ลดเกณฑ์เมื่อไหร่จอนั้นพังตาม

   สองอย่างที่ทำ
   1) ปลดแถวออกจาก .container มาใช้ความกว้างจอเต็ม เว้นขอบ 32px (เทคนิคเดียวกับ
      .playbook-benefit__list) การ์ดได้ 1135px คืนมา
   2) สลับสัดส่วนคอลัมน์ใน markup เป็น col-lg-4 / col-lg-8 (xl ยังเป็น 5/7 เท่าเดิม)
      ที่ 992px ซึ่งแคบสุดของช่วง ไดอะแกรมจึงยังได้ 509px พ้นเกณฑ์
      คอลัมน์ข้อความเหลือ 267px ปุ่ม CTA กว้าง 251px ยังอยู่บรรทัดเดียว */
@media (min-width: 992px) and (max-width: 1199px) {
    .playbook-steps {
        /* ระยะในการ์ดลงมาเท่าช่วง ≤991 (40 -> 32) ค่า 40px เป็นของจอ xl ที่การ์ดกว้าง 1236px
           ช่วงนี้การ์ดแคบลงเหลือ 1135px ระยะเดิมจึงกินพื้นที่เนื้อหาเกินส่วน
           ต่ำกว่า 992 มีกฎของตัวเองอยู่แล้ว (≤991 = 32px, ≤575 = 24px) ไม่ต้องแตะ */
        --bt-playbook-steps-card-padding: var(--space-8);

        /* 100vw รวมความกว้าง scrollbar ถ้าไม่กันไว้แถวที่ full-bleed จะดันจนเกิด
           scroll แนวนอน ใช้ clip ไม่ใช่ hidden เพราะ hidden จะทำให้ section
           กลายเป็น scroll container แล้วไปตัดของที่ sticky/fixed ข้างใน */
        overflow-x: clip;
    }

    /* ระยะ 32px วัดจากขอบจอถึงขอบการ์ด จึงหักครึ่ง gutter ของ .row ออกก่อน
       เพราะ .playbook-steps__item มี padding ของตัวเองอยู่แล้ว ไม่งั้นจะกลายเป็น 44px */
    .playbook-steps__list {
        margin-inline: calc(50% - 50vw);
        padding-inline: calc(var(--space-8) - 0.5 * var(--bs-gutter-x));
    }
}

@media (max-width: 991px) {
    .playbook-steps {
        --bt-playbook-steps-padding-y: var(--section-padding-y-sm);
        --bt-playbook-steps-list-space: var(--space-12);
        --bt-playbook-steps-card-padding: var(--space-8);
        --bt-playbook-steps-item-title-size: var(--section-topic-size-sm);
        --bt-playbook-steps-lead-size: var(--section-body-size);
        --bt-playbook-steps-highlight-space: var(--space-6);

        .playbook-steps__preview {
            margin-top: var(--space-6);
        }
    }
}

/* ---------- ≤767: กรอบตัวอย่างขั้นแรกเป็น "artboard" ย่อทั้งแผ่นตามความกว้างคอลัมน์ ----------
   ปัญหาเดียวกับกรอบของ .playbook-benefit ในช่วงเดียวกัน
   กรอบตัวอย่างหดจาก 624px ที่ 767 เหลือ 480px ที่ 576 แต่ป้ายคำถามขนาดคงที่ (12px, nowrap)
   ขณะที่การ์ดหดตาม 34cqi ป้ายจึงล้นออกนอกกรอบมากขึ้นเรื่อย ๆ (ที่ 640 ล้นซ้าย 16px ขวา 14px)
   พอเนื้อในกรอบต่ำกว่าเกณฑ์ 467px ของ @container (ราวจอ 610) ป้ายทั้งหกก็ทิ้งตัวลงมา
   เรียงใต้การ์ดเป็น 2x3 หน้าตาแต่ละความกว้างจึงไม่เหมือน 767 เลย

   ให้กรอบจัดวางที่ 624px ตลอดช่วง (เท่าตอน 767 ที่แสดงพอดีอยู่แล้ว) แล้วย่อทั้งกรอบด้วย
   ตัวคูณ = ความกว้างคอลัมน์จริง / 624 การ์ด ป้าย ระยะ ตารางพื้นหลัง ย่อพร้อมกันในอัตราเดียว

   ย่อด้วย transform: scale ไม่ใช่ zoom (ต่างจากกรอบของ benefit) เพราะ zoom ใน Safari (WebKit)
   พังสองเรื่องที่กรอบนี้เจอ ทดสอบกับ WebKit ในเครื่องแล้วทั้งคู่
   1) หน่วย cqi ถูกคิดจากขนาดหลังย่อแล้วย่อซ้ำอีกรอบ การ์ดเล็กกว่าที่ควร (ที่ 640 เล็กไป 15%)
   2) ตัวอักษรที่ถูกย่อจนต่ำกว่า 9px ถูกดันกลับขึ้นมาเป็น 9px ขณะที่กล่องป้ายยังย่อตามปกติ
      ช่วง ≤575 ที่ย่อเหลือ 0.55-0.6 เท่า ป้ายจึงกว้างเกินที่ออกแบบไว้แล้วล้นกรอบ
   transform ย่อหลังจัดวางเสร็จแล้ว ทุกเบราว์เซอร์จึงเห็นกรอบเป็น 624px เหมือนกันหมด
   ทั้ง @container, cqi และขนาดตัวอักษร แล้วค่อยย่อทั้งแผ่นเป็นภาพเดียว

   transform ไม่คืนพื้นที่ใน layout กรอบยังจองความสูงเต็ม JS จึงวัดความสูงก่อนย่อ
   (--bt-playbook-steps-artboard-height) แล้ว margin-bottom ติดลบดึงส่วนที่ย่อหายไปกลับคืน
   ด้านกว้างไม่ต้องชดเชย ส่วนที่เกินคอลัมน์ไม่ดันอะไร และเบราว์เซอร์คิดพื้นที่เลื่อนจากกล่องหลังย่อ
   จึงไม่เกิด scroll แนวนอน margin-top 24px ของกรอบ (จากบล็อก ≤991) ก็ไม่ถูกย่อตามด้วย

   ตัวคูณกับความสูงคำนวณโดย js/playbook-steps-media.js (CSS หารความยาวสองค่าตรง ๆ ไม่ได้)
   JS จะติดคลาส is-artboard เมื่อเห็น token ความกว้างเท่านั้น ถ้า JS ไม่ทำงาน กรอบก็แสดงแบบปกติ

   กฎของโหมด artboard ครอบทั้ง ≤767 ช่วง ≤575 ใช้ชุดเดียวกัน ต่างกันแค่ขนาดกรอบกับระยะป้าย
   (ดูบล็อก ≤575 ด้านล่าง) */
@media (max-width: 767px) {
    .playbook-steps {
        --bt-playbook-steps-artboard-width: 624px;

        .playbook-steps__preview.is-artboard {
            width: var(--bt-playbook-steps-artboard-width);
            margin-bottom: calc(var(--bt-playbook-steps-artboard-height, 0px) * (var(--bt-playbook-steps-artboard-scale, 1) - 1));
            transform: scale(var(--bt-playbook-steps-artboard-scale, 1));
            transform-origin: left top;
        }
    }
}

@media (max-width: 575px) {
    .playbook-steps {
        --bt-playbook-steps-card-padding: var(--space-6);
        --bt-playbook-steps-number-size: var(--space-8);
        --bt-playbook-steps-item-title-size: var(--font-size-18);
        --bt-playbook-steps-copy-size: var(--font-size-14);
        --bt-playbook-steps-points-space: var(--space-3);
        --bt-playbook-steps-action-space: var(--space-6);

        /* จอแคบคำสุดท้ายของย่อหน้ามักตกลงไปอยู่บรรทัดใหม่คำเดียว (เช่น "คุณ" ในขั้นที่ 1)
           ให้เบราว์เซอร์เกลี่ยบรรทัดท้ายไม่ให้เหลือคำโดด */
        .playbook-steps__copy {
            text-wrap: pretty;
        }

        /* ---------- ไดอะแกรมขั้นแรก: ป้ายขนาบซ้าย-ขวาการ์ดเหมือนจออื่น (โหมด artboard) ----------
           ถ้าใช้กรอบ 624px ชุดเดียวกับ 576-767 ที่จอ 375 จะย่อเหลือ 0.47 เท่า ตัวหนังสือในป้าย
           เหลือราว 6px ช่วงนี้จึงเอาพื้นที่คืนมาสองทาง ให้ย่อน้อยที่สุดโดยผังยังเหมือนเดิม
           1) กรอบแคบลงเหลือ 568px: ระยะจากขอบการ์ดถึงป้ายลดจาก 24 เหลือ 12px (ในหน่วยของกรอบ)
              การ์ดยังกว้าง 34% ของกรอบ ป้ายใบที่ยาวสุดยังเหลือที่ก่อนถึงขอบกรอบราว 4px
              เนื้อในกรอบ 520px ยังเกินเกณฑ์ 467px ของ @container ป้ายจึงไม่ทิ้งตัวลงใต้การ์ด
           2) คอลัมน์ภาพกินเข้าไปใน padding ของการ์ดข้างละ 16px เหลือห่างขอบการ์ด 8px
              (ต้องปลด max-width: 100% ของ .row > * ด้วย ไม่งั้นความกว้างที่เพิ่มจะถูกตัดทิ้ง)
           ผลที่ได้ จอ 375 ย่อ 0.58 เท่า (ป้ายราว 7px) จอ 430 ย่อ 0.67 เท่า จอ 575 ย่อ 0.93 เท่า */
        --bt-playbook-steps-artboard-width: 568px;

        .playbook-steps__preview.is-artboard {
            --bt-playbook-steps-diagram-tag-card-gap: var(--space-3);
        }

        .playbook-steps__media {
            width: calc(100% + 2 * var(--space-4));
            max-width: none;
            margin-inline: calc(var(--space-4) * -1);
        }

        /* padding ล่างของกรอบเหลือเป็นที่ว่างซ้อนกับ padding ของการ์ดอีกชั้น และ row-gap ของ grid
           ก็เว้นไว้ให้ป้ายกำกับที่ถูกถอดออกจาก markup ไปแล้ว ใต้ไดอะแกรมจึงห่างขอบการ์ดเกินกว่าด้านบน
           ตัดสองส่วนนี้ออกให้บน-ล่างสมดุล (แตะแค่แนวตั้ง padding ซ้าย-ขวาคงไว้
           เพราะเป็นส่วนหนึ่งของความกว้างที่ @container และหน่วยของ artboard ใช้คิด)
           ปรับตามที่ขอให้เหลือ 12px (อยู่ในกรอบที่ถูกย่อ บนจอจริงจึงเห็นเล็กกว่านี้ตามอัตราย่อ) */
        .playbook-steps__preview {
            padding-bottom: var(--space-3);
        }

        .playbook-steps__preview-body {
            row-gap: var(--space-0);
        }

        .playbook-steps__note {
            gap: var(--space-2);
        }
    }
}


/* ≤991: การ์ดขั้นที่ 1 เรียงลำดับแบบเดียวกันทั้งจอกลางและมือถือ (เดิมทำไว้เฉพาะ ≤575) */
@media (max-width: 991px) {
    .playbook-steps {

        /* ---------- ขั้นที่ 1: ไดอะแกรมแทรกกลางระหว่างคำอธิบายกับปุ่ม ----------
           ลำดับตั้งแต่ ≤991 (ผังคอลัมน์เดียว): เลขขั้น > หัวข้อ > คำอธิบาย > ไดอะแกรม > ปุ่ม + เวลา (กึ่งกลาง) > ฟรีใบแรก
           ข้อความกับไดอะแกรมอยู่คนละคอลัมน์ใน markup จึงสลับลำดับข้ามกันเองไม่ได้
           ให้คอลัมน์ข้อความเป็น display: contents ลูกของมันขึ้นมาเป็นสมาชิกของแถวโดยตรง
           แล้วเรียงแถวเป็นแนวตั้งและจัดลำดับด้วย order ไม่ต้องแตะ markup
           คอลัมน์ที่หายไปพา padding ของ gutter ไปด้วย จึงคืนระยะนั้นให้ลูกแต่ละตัวแทน
           ขอบซ้ายของข้อความจึงตรงแนวเดิม */
        .playbook-steps__card--feature>.row {
            flex-direction: column;
        }

        .playbook-steps__card--feature>.row> :not(.playbook-steps__media) {
            display: contents;
        }

        /* align-self ไม่ใช่ align-items ที่แถว: แถวติดคลาส align-items-center ของ Bootstrap
           ซึ่งเป็น !important ลูกทุกตัวจึงถูกจัดกึ่งกลางแล้วหดเท่าเนื้อหา */
        .playbook-steps__card--feature>.row> :not(.playbook-steps__media)>* {
            align-self: stretch;
            padding-inline: calc(var(--bs-gutter-x) * .5);
        }

        .playbook-steps__card--feature .playbook-steps__media {
            order: 1;
        }

        /* ไดอะแกรมต่อจากคำอธิบายทันที: ตัด margin-bottom 16px ของ <p> (ค่าตั้งต้นของ Bootstrap)
           และลด margin-top 24px ของกรอบตัวอย่าง (จากบล็อก ≤991) เหลือ 8px */
        .playbook-steps__card--feature .playbook-steps__copy {
            margin-bottom: var(--space-0);
        }

        .playbook-steps__card--feature .playbook-steps__preview {
            margin-top: var(--space-2);
        }

        .playbook-steps__card--feature .playbook-steps__action {
            order: 2;
            flex-direction: column;
            align-items: center;
        }

        /* กึ่งกลางตามแนวปุ่มกับบรรทัดเวลาด้านบน: ช่องข้อความเดิมเป็น 1fr (ยืดเต็มแถว)
           เปลี่ยนเป็น auto แล้วจัดทั้งก้อน ไอคอน + ข้อความ ไว้กลาง grid */
        .playbook-steps__card--feature .playbook-steps__highlight {
            order: 3;
            grid-template-columns: auto auto;
            justify-content: center;
        }
    }
}


/* ==========================================================================
   Section: Playbook CTA — ปิดท้ายก่อน footer (personalized-playbook.html)
   ยกดีไซน์แผงมาจาก section CTA ของหน้าแรก (พื้น neutral-50 + แสงรัศมีสองมุม +
   มุมโค้ง card-radius + จัดกึ่งกลาง) ต่างกันที่เนื้อหาเป็นวันจัดงาน/สถานที่
   ซึ่งคั่นด้วยเส้น-ดาวแทนการทำเป็นการ์ดซ้อนในแผง
   ========================================================================== */
.playbook-cta {
    /* ระยะเท่ากับ section CTA ของหน้าแรกทุกขั้น: ตัว section เว้นเฉพาะด้านบน
       ปล่อยด้านล่างชิด footer ส่วนระยะในแผงไล่ลงตาม breakpoint เดียวกัน */
    --bt-playbook-cta-padding-top: var(--section-padding-y-sm);
    --bt-playbook-cta-panel-padding: var(--space-6);
    --bt-playbook-cta-media-gap: var(--space-10);
    --bt-playbook-cta-kv-radius: var(--radius-2);
    --bt-playbook-cta-facts-space: var(--space-16);
    --bt-playbook-cta-facts-row-gap: var(--space-10);
    --bt-playbook-cta-fact-label-size: var(--font-size-16);
    --bt-playbook-cta-fact-icon-size: var(--font-size-24);
    --bt-playbook-cta-fact-icon-gap: var(--space-2);
    --bt-playbook-cta-fact-icon-ink: var(--color-accent-primary);
    --bt-playbook-cta-fact-icon-stroke: 1.75;
    --bt-playbook-cta-fact-value-size: var(--font-size-24);
    --bt-playbook-cta-fact-sub-size: var(--section-subtext-size);
    --bt-playbook-cta-rule-length: var(--space-20);
    --bt-playbook-cta-note-space: var(--space-16);
    --bt-playbook-cta-note-size: var(--section-body-size);

    padding: var(--bt-playbook-cta-padding-top) var(--space-0) var(--space-0);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .playbook-cta__panel {
        /* ---------- scroll-driven expand ----------
           ชุดเดียวกับ .identity-cards แต่แผงนี้อยู่ใน .container อยู่แล้ว ไม่ได้เต็มจอ
           จึงต่างกันสองข้อ
           1) ย่อน้อยกว่ามาก (0.94 เทียบกับ 0.898) แผงมีขอบข้างละ 117px ของตัวเองอยู่แล้ว
              ถ้าย่อเท่ากันจะกลายเป็น 190px ดูลอยหลุดจากหน้าไปเลย
              0.94 ขยับความกว้าง 1236 -> 1162px คือเข้ามาอีกข้างละ 37px กำลังรู้สึกได้
           2) ไม่แตะ border-radius แผงนี้เป็นการ์ดตลอดทาง ไม่ได้จะขยายไปจนเต็มขอบจอ
              มุมจึงต้องคงที่ ต่างจาก identity-cards ที่ต้องคลายเป็นเหลี่ยมตอนเต็มจอ */
        --bt-playbook-cta-expand-min: 0.94;
        --bt-scroll-expand: 1;

        position: relative;
        overflow: hidden;
        padding: var(--bt-playbook-cta-panel-padding);
        border-radius: var(--card-radius);
        scale: calc(var(--bt-playbook-cta-expand-min) + (1 - var(--bt-playbook-cta-expand-min)) * var(--bt-scroll-expand));
        transform-origin: center top;
        background:
            radial-gradient(circle at 18% 0%, color-mix(in srgb, var(--color-blue-100) 72%, transparent) 0%, transparent 34%),
            radial-gradient(circle at 92% 100%, color-mix(in srgb, var(--color-kv-spectrum-4) 12%, transparent) 0%, transparent 34%),
            var(--color-neutral-50);
        text-align: center;
    }

    /* ของใน [data-reveal] เริ่มจากต่ำกว่าตำแหน่งจริง --reveal-y (80px) แล้วค่อยลอยขึ้น
       แต่แผงนี้ overflow: hidden ระยะ 80px ดันบรรทัดสุดท้ายพ้นขอบแผงลงไป
       และ IntersectionObserver คิดพื้นที่ทับซ้อนหลังถูก ancestor clip แล้ว
       มันจึงไม่เห็น element นั้นเลย -> ไม่ติด is-revealed -> ไม่ลอยขึ้น -> ไม่มีวันถูกเห็น
       วนกลับที่เดิมเป็นวงปิด บรรทัด "จัดโดย efin.finance" เลยหายไปทั้งบรรทัด
       ไม่ได้ตกเฟรมเพราะ layout ตำแหน่งจริงของมันอยู่ในแผงเรียบร้อย
       ย่อระยะลอยของทุกอย่างในแผงให้พอดีกับ padding ของแผง ก็หลุดวงจรนี้
       (ระยะ 80px ออกแบบมาสำหรับ section เต็มหน้า ไม่ใช่กล่องที่ถูก clip อยู่แล้ว) */
    .playbook-cta__panel [data-reveal] {
        --reveal-y: var(--bt-playbook-cta-panel-padding);
    }

    .playbook-cta__body {
        padding-right: var(--bt-playbook-cta-media-gap);
    }

    /* ภาพเต็มความกว้างคอลัมน์ สัดส่วนคงตามไฟล์จริง (778x972) ไม่ครอป */
    .playbook-cta__kv {
        width: 100%;
        height: auto;
        display: block;
        border-radius: var(--bt-playbook-cta-kv-radius);
    }

    .playbook-cta__title {
        max-width: var(--layout-narrow-max);
        margin: var(--space-0) auto;
        font-weight: var(--font-weight-medium);
        text-wrap-style: balance;
    }

    .playbook-cta__facts {
        margin: var(--bt-playbook-cta-facts-space) var(--space-0) var(--space-0);
        row-gap: var(--bt-playbook-cta-facts-row-gap);
    }

    /* คั่นสองช่องด้วยเส้น-ดาวแนวตั้งชุดเดียวกับ section Expectation ของหน้าแรก
       (ภาพวาดมาแนวนอนจึงหมุน 90° และกำหนดความยาวตายตัวเพราะยืดตามเนื้อหาไม่ได้) */
    .playbook-cta__fact {
        position: relative;

        &::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 0;
            width: var(--bt-playbook-cta-rule-length);
            height: calc(var(--bt-playbook-cta-rule-length) / 9.13);
            background: url('../images/line-star.webp') center / contain no-repeat;
            transform: translate(-50%, -50%) rotate(90deg);
        }

        &:first-child::before {
            display: none;
        }
    }

    /* ไอคอนนำหน้าป้ายกำกับ บอกว่าช่องนี้เป็นวันหรือสถานที่ตั้งแต่ยังไม่อ่านข้อความ
       วางเป็น inline flex เพื่อให้ไอคอนกับตัวอักษรยังอยู่กึ่งกลางร่วมกับแผงที่จัดกลาง */
    .playbook-cta__fact-label {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--bt-playbook-cta-fact-icon-gap);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-cta-fact-label-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--section-small-line-height);
        letter-spacing: var(--letter-spacing-index);
    }

    .playbook-cta__fact-icon {
        font-size: var(--bt-playbook-cta-fact-icon-size);
        color: var(--bt-playbook-cta-fact-icon-ink);
        stroke-width: var(--bt-playbook-cta-fact-icon-stroke);
    }

    .playbook-cta__fact-value {
        margin-top: var(--space-6);
        display: grid;
        gap: var(--space-2);

        strong {
            font-size: var(--bt-playbook-cta-fact-value-size);
            font-weight: var(--font-weight-medium);
            line-height: var(--section-topic-line-height-sm);
        }

        span {
            /* color: var(--color-text-muted); */
            font-size: var(--bt-playbook-cta-fact-sub-size);
            font-weight: var(--font-weight-light);
            line-height: var(--section-body-line-height);
        }
    }

    .playbook-cta__note {
        margin: var(--bt-playbook-cta-note-space) auto var(--space-0);
        padding-bottom: var(--space-3);
        color: var(--color-text-muted);
        font-size: var(--bt-playbook-cta-note-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }
}

/* จอที่แบ่งสองฝั่ง คอลัมน์ขวาเหลือ 7/12 ของแผง ตัวอักษรชุดเดิมที่ออกแบบมาตอนเนื้อหา
   กินเต็มความกว้างจึงอึดอัด ลดลงหนึ่งขั้นของสเกลทุกตัว
   (48→40, 64→56, 24→20, 18→16, 16→14)
   ครอบด้วย min-width เพราะจอที่เล็กกว่านี้คอลัมน์ซ้อนกันแล้ว ความกว้างกลับมาเต็มแผง
   ขนาดเดิมจึงยังพอดีอยู่ ไม่ต้องลดตาม */
@media (min-width: 992px) {
    .playbook-cta {
        --bt-playbook-cta-fact-label-size: var(--font-size-14);
        --bt-playbook-cta-fact-icon-size: var(--font-size-20);
        --bt-playbook-cta-fact-value-size: var(--font-size-20);
        --bt-playbook-cta-fact-sub-size: var(--font-size-16);
        --bt-playbook-cta-note-size: var(--font-size-16);

        /* ใช้ token ที่ component เปิดไว้ให้ ไม่เขียนทับ font-size ตรง ๆ
           line-height ของ .bt-section-title เป็น 140% จึงย่อตามเองอยู่แล้ว */
        .playbook-cta__title {
            --bt-section-title-size: var(--font-size-32);
        }

        /* .bt-title-highlight ไม่มี token ของตัวเอง ต้องเขียนทับขนาดโดยจำกัดขอบเขต
           ไว้ที่หัวข้อของ section นี้ ไม่ให้ไปโดน highlight ของ section อื่น */
        .playbook-cta__title .bt-title-highlight {
            font-size: var(--font-size-48);
        }
    }
}

/* ต่ำกว่า xl หัวข้อลงมาอยู่ที่ขั้นเล็กสุดของสเกลหัวข้อทั้งหมด
   สเกลกลางของ .bt-section-title ไม่ได้ไล่ลงตรง ๆ ตามขนาดจอ: 992-1199 ได้ 32/48
   แต่ 576-991 กลับขึ้นไป 40/56 (เพราะคอลัมน์ซ้อนกันแล้ว ความกว้างกลับมาเต็มแผง)
   ซึ่งใหญ่เกินไปสำหรับแผงนี้ จึงตรึงไว้ที่ 28/36 ตลอดตั้งแต่ 1199 ลงไป
   คู่ 28/36 เป็นคู่ที่สเกลกลางใช้อยู่แล้วที่ขั้นเล็กสุด (≤575) ค่าตรงนั้นจึงไม่ขยับ */
@media (max-width: 1199px) {
    .playbook-cta {

        /* ต้องเขียนคู่กับ .bt-section-title และประกาศ font-size ซ้ำด้วย
           เพราะสเกลกลางที่ไล่ขนาดตามจอใช้ selector section[aria-labelledby] h2.bt-section-title
           ซึ่ง specificity สูงกว่าคลาสเดี่ยว และสั่ง font-size ตรง ๆ ไม่ได้ผ่าน token
           ถ้าทับแค่ token ค่าจะถูกตั้งไว้แต่ไม่มีใครอ่าน หัวข้อยังเป็น 40px ตามสเกลกลาง */
        .playbook-cta__title.bt-section-title {
            --bt-section-title-size: var(--font-size-28);

            font-size: var(--bt-section-title-size);
        }

        .playbook-cta__title .bt-title-highlight {
            font-size: var(--font-size-36);
        }
    }
}

/* ---------- ช่วง lg (992-1199) : ย่อเนื้อหาในแผง ความกว้างแผงเท่าเดิม ----------
   .container ตรึงที่ 960px แผงเหลือ 856px คอลัมน์ขวา (col-lg-7) ได้ 485px
   ช่องข้อมูลจึงเหลือช่องละ 197px แต่ "31 ตุลาคม – 1 พฤศจิกายน 2569" ที่ 20px ยาวเกินนั้น
   ค่าของทั้งสองช่องเลยตัดเป็นสองบรรทัด และตัดผิดจุดด้วย เพราะภาษาไทยไม่มีช่องว่าง
   ระหว่างคำ เบราว์เซอร์แยก "สามย่านมิตร/ทาวน์" และ "1/พฤศจิกายน" ออกจากกัน
   (ลอง text-wrap: balance แล้วยังตัดผิดจุดเหมือนเดิม)

   ไล่ลดขนาดแล้ววัดจุดตัดจริงทีละขั้น 18/16/15 ยังสองบรรทัด ลงมาที่ 14px ทั้งสองค่า
   จึงกลับมาอยู่บรรทัดเดียวพอดี ป้ายกับข้อความรองลดตามให้ลำดับความสำคัญไม่กลับหัว
   (ป้าย 14→12, ค่า 20→14, ข้อความรอง 16→12, หมายเหตุ 16→14)
   เส้นคั่นย่อจาก 80px เหลือ 64px ให้พอดีกับก้อนข้อความที่เตี้ยลงเป็น 91px

   หัวข้อไม่แตะ คงขนาดของช่วง ≥992 ไว้ (32/48) ลองลดแล้วก็ยังสามบรรทัดอยู่ดี
   ต้องลงไปถึง 24/36 ถึงจะเหลือสองบรรทัด ซึ่งเล็กเกินไปสำหรับหัวข้อปิดท้าย */
@media (min-width: 992px) and (max-width: 1199px) {
    .playbook-cta {
        /* ช่องไฟแนวตั้งลดลงหนึ่งขั้น ตัวอักษรเล็กลงแล้ว ถ้าคงไว้ 64px
           ก้อนข้อความจะกระจัดกระจายไม่เกาะกลุ่ม */
        --bt-playbook-cta-facts-space: var(--space-10);
        --bt-playbook-cta-note-space: var(--space-10);
        --bt-playbook-cta-media-gap: var(--space-8);

        --bt-playbook-cta-fact-label-size: var(--font-size-12);
        --bt-playbook-cta-fact-icon-size: var(--font-size-16);
        --bt-playbook-cta-fact-value-size: var(--font-size-18);
        --bt-playbook-cta-fact-sub-size: var(--font-size-14);
        --bt-playbook-cta-rule-length: var(--space-16);
        --bt-playbook-cta-note-size: var(--font-size-14);

        .playbook-cta__fact-value {
            margin-top: var(--space-3);
        }
    }
}

@media (max-width: 991px) {
    .playbook-cta {
        --bt-playbook-cta-panel-padding: var(--space-8);
        --bt-playbook-cta-facts-space: var(--space-12);
        --bt-playbook-cta-fact-value-size: var(--font-size-20);
        --bt-playbook-cta-fact-sub-size: var(--section-body-size);
        --bt-playbook-cta-note-space: var(--space-12);

        /* ไม่มีคอลัมน์ข้าง ๆ ให้เว้นระยะแล้ว ถ้าคงไว้ข้างเดียวข้อความที่จัดกึ่งกลาง
           จะเยื้องซ้ายไปครึ่งหนึ่งของระยะนั้น */
        .playbook-cta__body {
            padding-right: calc(var(--bs-gutter-x) * .5);
            margin-top: var(--space-10);
        }

        .playbook-cta__note {
            padding-bottom: var(--space-0);
        }

        .playbook-cta__kv {
            width: 50%;
            margin-inline: auto;
        }
    }
}

/* จอเล็กสุดแผงกินเต็มความกว้าง section จึงไม่ต้องเว้นระยะอีก (เท่ากับ .cta ของหน้าแรก)
   และจอเดียวคอลัมน์ สองช่องเรียงลงล่าง เส้นคั่นจึงเปลี่ยนจากแนวตั้งเป็นแนวนอน */
@media (max-width: 575px) {
    .playbook-cta {
        --bt-playbook-cta-padding-top: var(--space-0);
        --bt-playbook-cta-note-size: var(--section-small-size);
        --bt-playbook-cta-panel-padding: var(--space-4) var(--space-4) var(--space-8) var(--space-4);
        --bt-playbook-cta-fact-label-size: var(--font-size-14);
        --bt-playbook-cta-fact-value-size: var(--font-size-18);
        /* ร่องระหว่างสองแถวมีเส้นคั่นนั่งอยู่ตรงกลาง 40px เดิมเหลือข้างละไม่ถึง 16px
           ขยายเป็น 48px เท่าร่องของรายการ "อีก 4 อย่าง" ใน section benefit */
        --bt-playbook-cta-facts-row-gap: var(--space-16);
        --bt-playbook-cta-kv-radius: var(--radius-1);
        --bt-playbook-cta-fact-icon-size: var(--font-size-16);

        .playbook-cta__fact-value {
            margin-top: var(--space-3);
        }

        /* ขั้นถัดลงมาจากคู่ 28/36 ของ ≤1199 (เขียนคู่ selector แบบเดียวกันด้วยเหตุผลเดียวกัน) */
        .playbook-cta__title.bt-section-title {
            --bt-section-title-size: var(--font-size-24);

            font-size: var(--bt-section-title-size);
        }

        .playbook-cta__title .bt-title-highlight {
            font-size: var(--font-size-32);
        }

        /* แผงแคบจนภาพครึ่งความกว้างเล็กเกินไป ให้ภาพกินเต็มคอลัมน์ */
        .playbook-cta__kv {
            width: 100%;
        }

        /* ภาพเส้น-ดาววาดมาแนวนอนอยู่แล้ว จึงแค่ไม่หมุน แล้ววางกึ่งกลางร่องระหว่างสองแถว
           (ร่องอยู่นอกกล่องของช่อง จึงถอยขึ้นไปครึ่งหนึ่งของ row-gap) */
        .playbook-cta__fact::before {
            top: calc(var(--bt-playbook-cta-facts-row-gap) / -2);
            left: 50%;
            transform: translate(-50%, -50%);
        }
    }
}


/* ปิด motion ของตัวอย่างการ์ดในขั้นตอนที่ 1 สลับ persona ทันทีไม่ค่อย ๆ จาง */
@media (prefers-reduced-motion: reduce) {
    .playbook-steps {

        .playbook-steps__compare-chip,
        .playbook-steps__persona,
        .playbook-steps__persona.is-active {
            transition: none;
        }
    }
}

/* ==========================================================================
   Section: Playbook Ticket — เปรียบเทียบสิทธิ์ (personalized-playbook.html)
   หัวข้อใช้ component เดียวกับ section อื่น ตารางใช้เส้นคั่นบาง ๆ และไอคอนจาก
   sprite เดิมของเว็บ (icon-check / icon-minus) แทนการเขียนคำว่าได้/ไม่ได้
   ========================================================================== */
.playbook-ticket {
    --bt-playbook-ticket-padding-y: var(--section-padding-y);
    --bt-playbook-ticket-table-space: var(--space-16);
    --bt-playbook-ticket-cell-padding-y: var(--space-3);
    --bt-playbook-ticket-cell-padding-x: var(--space-6);
    --bt-playbook-ticket-plan-width: calc(var(--space-32) + var(--space-16));
    --bt-playbook-ticket-card-space: var(--space-20);
    --bt-playbook-ticket-plan-size: var(--section-topic-size-sm);
    --bt-playbook-ticket-feature-size: var(--section-small-size);
    --bt-playbook-ticket-mark-size: var(--font-size-24);
    --bt-playbook-ticket-features-space: var(--space-3);
    --bt-playbook-ticket-features-gap: var(--space-2);
    --bt-playbook-ticket-feature-icon-size: var(--font-size-20);

    padding: var(--bt-playbook-ticket-padding-y) var(--space-0);
    color: var(--color-text-primary);
    background: var(--color-surface-page);
    font-family: var(--font-family-base);

    .playbook-ticket__header {
        text-align: center;
    }

    /* จัดกึ่งกลางและตัดเส้น-ดาวท้ายบรรทัดออกเหมือน section ก่อนหน้าของหน้านี้ */
    .playbook-ticket__eyebrow {
        justify-content: center;

        &::after {
            display: none;
        }
    }

    /* ชื่อบัตรในหัวข้อใช้ serif ชุดเดียวกับหัวตารางและการ์ดราคา ชื่อ Ultimate ทั้งสาม
       ที่จึงเป็นตัวเดียวกัน ผูกไว้กับหัวข้อของ section นี้เท่านั้น ไม่แตะ .bt-title-highlight
       ตัวกลางที่ section อื่นกับหน้าแรกใช้ร่วมกัน
       (Baskervville โหลดมาแค่น้ำหนัก 400 ต้องคืนเป็น regular ไม่งั้นเบราว์เซอร์ปลอมตัวหนาให้) */
    .playbook-ticket__title .bt-title-highlight {
        font-family: 'Baskervville', var(--font-family-base);
        font-weight: var(--font-weight-regular);
    }

    /* ลดเฉพาะจอ desktop ที่ตัวกลางเป็น 64px จอ ≤991px ไม่แตะ ปล่อยไล่ตามชุดเดิม 56/40/36
       (ต้องครอบด้วย min-width ไม่งั้นกฎนี้ชนะ media query ของ .bt-title-highlight ทุกช่วงจอ
       เพราะ specificity สูงกว่า แล้วจอเล็กจะค้างที่ 56px) */
    @media (min-width: 992px) {
        .playbook-ticket__title .bt-title-highlight {
            font-size: var(--font-size-56);
        }
    }

    /* ---------- การ์ดราคา (เป็นของ section นี้ล้วน ไม่อ้างอิง class ของ section อื่น) ---------- */
    .playbook-ticket__plan {
        --bt-playbook-ticket-plan-padding: var(--space-8);
        --bt-playbook-ticket-plan-title-size: var(--font-size-32);
        --bt-playbook-ticket-plan-icon-size: var(--space-20);
        /* บน-ล่าง space-8: ไม่มีบรรทัดราคาเดิม (ขีดฆ่า) แล้ว กล่องเตี้ยลง เพิ่มคืนให้สูงใกล้เดิม */
        --bt-playbook-ticket-price-padding: var(--space-8) var(--space-6);
        --bt-playbook-ticket-ribbon-clearance: var(--space-8);
        --bt-playbook-ticket-price-size: var(--section-heading-size);
        --bt-playbook-ticket-plan-bg-size: auto 1580px;
        --bt-playbook-ticket-plan-bg-position: 46% 74%;

        /* 992–1199px กล่องราคากว้างแค่ 190px ราคา "2,500 บาท" จะตก "บาท" ลงบรรทัดใหม่
           ขณะที่ "1,500 บาท" ยังพอดีบรรทัด ตัวเลขสองกล่องจึงไม่เสมอกัน ลด padding ข้างลงนิดให้พอ */
        @media (min-width: 992px) and (max-width: 1199px) {
            --bt-playbook-ticket-price-padding: var(--space-8) var(--space-5);
        }

        position: relative;
        overflow: hidden;
        padding: var(--bt-playbook-ticket-plan-padding);
        border: var(--border-width-1) solid var(--color-border-subtle);
        border-radius: var(--card-radius);
        /* ทินต์อ่อนทับภาพฉากของบัตร Ultimate ให้ตัวหนังสืออ่านได้เต็มที่ */
        background:
            linear-gradient(color-mix(in srgb, var(--color-neutral-0) 72%, transparent),
                color-mix(in srgb, var(--color-surface-page) 64%, transparent)),
            url('../images/ultimate-bg.webp') var(--bt-playbook-ticket-plan-bg-position) / var(--bt-playbook-ticket-plan-bg-size) no-repeat;
    }

    /* ริบบอนส่วนลดเกาะมุมบนขวา มุมบนขวาไม่ต้องลบเอง เพราะการ์ดตัดขอบตัวเองด้วย
       overflow: hidden อยู่แล้ว จึงโค้งรับมุมการ์ดพอดี เหลือแค่ลบมุมล่างซ้าย */
    .playbook-ticket__plan-ribbon {
        position: absolute;
        top: var(--space-0);
        right: var(--space-0);
        z-index: 2;
        padding: var(--space-2) var(--space-4);
        border-radius: var(--radius-0) var(--radius-0) var(--radius-0) var(--radius-1);
        color: var(--color-neutral-0);
        background: var(--color-danger-600);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-1);
        white-space: nowrap;

        strong {
            font-weight: var(--font-weight-medium);
        }
    }

    .playbook-ticket__plan-icon {
        width: var(--bt-playbook-ticket-plan-icon-size);
        height: auto;
        display: block;
        filter: saturate(1.5);
    }

    .playbook-ticket__plan-eyebrow {
        margin-bottom: var(--space-3);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        line-height: var(--line-height-1);
        letter-spacing: var(--letter-spacing-label);
        text-transform: uppercase;
    }

    .playbook-ticket__plan-title {
        font-family: 'Baskervville', var(--font-family-base);
        font-size: var(--bt-playbook-ticket-plan-title-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-1);
        letter-spacing: var(--letter-spacing-0);
        text-transform: uppercase;
    }

    .playbook-ticket__prices {
        margin-top: var(--space-6);
        display: grid;
        grid-template-columns: repeat(2, minmax(var(--space-0), 1fr));
        border-top: var(--border-width-1) solid var(--color-border-subtle);
        border-bottom: var(--border-width-1) solid var(--color-border-subtle);
    }

    /* ปุ่มเลือกราคา: ล้างหน้าตาปุ่มมาตรฐานของเบราว์เซอร์ แล้ววาดเป็นกล่องตัวเลือกเอง */
    .playbook-ticket__price {
        position: relative;
        padding: var(--bt-playbook-ticket-price-padding);
        display: grid;
        /* ชื่อบัตรกับราคาห่างกันพอดี (ไม่มีบรรทัดราคาเดิมคั่นกลางแล้ว) */
        gap: var(--space-4);
        justify-items: start;
        border: var(--border-width-1) solid transparent;
        border-radius: var(--space-0);
        color: inherit;
        background: transparent;
        font: inherit;
        text-align: left;
        cursor: pointer;
        transition:
            border-color var(--duration-base) var(--ease-standard),
            background-color var(--duration-base) var(--ease-standard);

        &:hover {
            background: color-mix(in srgb, var(--color-blue-100) 55%, transparent);
        }

        &:focus-visible {
            outline: var(--border-width-2) solid var(--color-focus-ring);
            outline-offset: calc(var(--border-width-2) * -1);
        }

        &.is-active {
            border-color: var(--color-accent-primary);
            background: color-mix(in srgb, var(--color-blue-100) 72%, transparent);
        }
    }

    /* วงกลมบอกสถานะเลือก วาดจาก ::after ของบรรทัดชื่อบัตร เพื่อให้อยู่แนวเดียวกันเสมอ */
    .playbook-ticket__price-day {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-2);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        line-height: var(--line-height-1);

        &::after {
            content: '';
            width: var(--space-4);
            height: var(--space-4);
            flex: 0 0 auto;
            border: var(--border-width-2) solid var(--color-border-strong);
            border-radius: var(--radius-round);
        }
    }

    .playbook-ticket__price.is-active .playbook-ticket__price-day::after {
        border-color: var(--color-accent-primary);
        background:
            radial-gradient(circle at 50% 50%,
                var(--color-accent-primary) 0 var(--space-1),
                transparent var(--space-1));
    }

    .playbook-ticket__price-compare {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        color: var(--color-text-muted);
        font-size: var(--section-small-size);
        line-height: var(--line-height-1);
    }

    .playbook-ticket__price-value {
        font-size: var(--bt-playbook-ticket-price-size);
        font-weight: var(--font-weight-medium);
        line-height: var(--line-height-1);

        small {
            color: var(--color-text-muted);
            font-size: var(--section-body-size);
            font-weight: var(--font-weight-regular);
        }
    }

    .playbook-ticket__price.is-active .playbook-ticket__price-value {
        color: var(--color-accent-primary);
    }

    .playbook-ticket__action {
        width: 100%;
        margin-top: var(--space-6);
    }

    /* ปุ่มซื้อบัตรเป็นสีดำล้วนไม่มีขอบ spectrum ให้หน้าตาตรงกับปุ่มซื้อบัตรของเว็บ
       (--bt-action-fill เป็น custom property ของ component .bt-action-button ใน main.css
       ไม่ใช่ค่าจาก section อื่น) */
    .playbook-ticket__action.bt-action-button--primary {
        border-color: var(--bt-action-fill);
        background: var(--bt-action-fill);
    }

    /* จอกว้างวางการ์ดเป็นแนวนอน: ซ้ายคือหัวการ์ดแล้วตามด้วยรายการสิทธิ์ ขวาเป็นราคาแล้วปุ่มซื้อ
       ราคาคร่อมสองแถวบนและรายการสิทธิ์คร่อมสองแถวล่าง สองคอลัมน์จึงไล่ความสูงไปด้วยกัน
       ไม่ทิ้งช่องว่างใต้หัวการ์ดแบบที่จะเกิดถ้าแบ่งเป็นแถวละคู่ตรง ๆ */

    @media (min-width: 992px) {
        .playbook-ticket__plan {
            display: grid;
            grid-template-columns: minmax(var(--space-0), 1fr) minmax(var(--space-0), 1fr);
            grid-template-areas:
                "head      purchase"
                "features  purchase";
            column-gap: var(--space-12);
            row-gap: var(--space-6);
            align-content: start;
        }

        /* ไอคอนอยู่ข้างชื่อบัตร (คร่อมสองบรรทัด) ไม่ใช่ซ้อนอยู่ด้านบน การ์ดจึงเตี้ยลง */
        .playbook-ticket__plan-header {
            grid-area: head;
            display: grid;
            grid-template-columns: auto minmax(var(--space-0), 1fr);
            column-gap: var(--space-4);
            align-items: center;
        }

        .playbook-ticket__plan-icon {
            grid-row: 1 / 3;
        }

        .playbook-ticket__plan-eyebrow {
            align-self: end;
        }

        .playbook-ticket__plan-title {
            align-self: start;
        }

        /* ราคา + ปุ่มซื้อ คร่อมสองแถวเพื่อจัดคอลัมน์ ไม่ใช่เพื่อให้ยืดเต็มความสูง
           ปุ่มจึงต่อใต้ราคาทันที (margin-top ของ .playbook-ticket__action) ไม่ตกไปก้นการ์ด */
        .playbook-ticket__purchase {
            grid-area: purchase;
            align-self: start;
            /* ริบบอนส่วนลดลอยอยู่มุมบนขวาของการ์ด พอราคาย้ายมาอยู่คอลัมน์ขวา
               ต้องเผื่อที่ให้มันด้วย ไม่งั้นปุ่มราคาใบขวาจะไปชนใต้ริบบอนพอดี */
            margin-top: var(--bt-playbook-ticket-ribbon-clearance);
        }

        .playbook-ticket__features {
            grid-area: features;
            align-self: start;
            margin-top: var(--space-0);
        }
    }

    /* ช่วง lg คอลัมน์แคบสุดของผังสองคอลัมน์นี้ ร่องกลาง 48px กินที่ของรายการสิทธิ์
       และบล็อกราคามากเกินไป ลดเหลือ 32px เฉพาะช่วงนี้ (ตั้งแต่ xl ขึ้นไปคงเดิม) */
    @media (min-width: 992px) and (max-width: 1199px) {
        .playbook-ticket__plan {
            column-gap: var(--space-8);
        }
    }

    @media (min-width: 1500px) {
        .playbook-ticket__plan {
            column-gap: var(--space-16);
        }
    }

    /* ริบบอนส่วนลดเกาะมุมบนขวาของการ์ด มุมบนขวาไม่ต้องลบเอง เพราะการ์ดตัดขอบตัวเอง
       ด้วย overflow: hidden อยู่แล้ว จึงโค้งรับมุมการ์ดพอดี เหลือแค่ลบมุมล่างซ้าย */
    .playbook-ticket__plan-ribbon {
        position: absolute;
        top: var(--space-0);
        right: var(--space-0);
        z-index: 2;
        padding: var(--space-2) var(--space-4);
        border-radius: var(--radius-0) var(--radius-0) var(--radius-0) var(--radius-1);
        color: var(--color-neutral-0);
        background: var(--color-danger-600);
        font-size: var(--section-small-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-1);
        white-space: nowrap;

        strong {
            font-weight: var(--font-weight-medium);
        }
    }

    /* ป้ายแนะนำบัตรที่คุ้มกว่า วางต่อท้ายราคาเดิมในกล่องราคา ใช้สี accent ชุดเดียวกับ
       ไอคอนติ๊กถูกในตารางเปรียบเทียบ ไม่ใช่สีแดงของป้ายส่วนลด */
    .playbook-ticket__price-badge {
        display: inline-block;
        padding: var(--space-1) var(--space-2);
        border-radius: var(--radius-1);
        color: var(--color-neutral-0);
        background: var(--color-accent-primary);
        font-size: var(--font-size-12);
        font-weight: var(--font-weight-medium);
        line-height: var(--line-height-1);
        white-space: nowrap;
    }

    /* รายการสิทธิ์ของบัตร ใช้ไอคอนติ๊กถูกในวงกลมชุดเดียวกับตารางเปรียบเทียบ */
    .playbook-ticket__features {
        margin-top: var(--bt-playbook-ticket-features-space);
        margin-bottom: var(--space-0);
        padding-left: var(--space-0);
        display: grid;
        gap: var(--bt-playbook-ticket-features-gap);
        list-style: none;
    }

    .playbook-ticket__features li {
        display: grid;
        grid-template-columns: auto 1fr;
        gap: var(--space-3);
        align-items: start;
        color: var(--color-text-secondary);
        font-size: var(--bt-playbook-ticket-feature-size);
        font-weight: var(--font-weight-light);
        line-height: var(--line-height-relaxed);
    }

    .playbook-ticket__feature-icon {
        margin-top: calc((var(--line-height-relaxed) * var(--section-body-size) - var(--bt-playbook-ticket-feature-icon-size)) / 2);
        color: var(--color-accent-primary);
        font-size: var(--bt-playbook-ticket-feature-icon-size);
    }

    /* จอแคบกว่าตารางให้เลื่อนดูในแนวนอนได้ แทนที่จะบีบคอลัมน์จนอ่านไม่ออก */
    /* ตารางเทียบสิทธิ์กว้างเท่าการ์ดบัตรด้านล่าง ใช้โครง grid ชุดเดียวกัน (10 คอลัมน์ตั้งแต่ lg) */
    .playbook-ticket__compare-row {
        margin-top: var(--bt-playbook-ticket-table-space);
    }

    /* การ์ดบัตรแคบกว่าตาราง จัดกลางด้วย grid ของ Bootstrap (10 คอลัมน์ตั้งแต่ lg ขึ้นไป) */
    .playbook-ticket__card-row {
        margin-top: var(--bt-playbook-ticket-card-space);
    }

    .playbook-ticket__table {
        width: 100%;
        border-collapse: collapse;
        table-layout: fixed;
    }

    .playbook-ticket__feature {
        padding: var(--bt-playbook-ticket-cell-padding-y) var(--bt-playbook-ticket-cell-padding-x);
        color: var(--color-text-secondary);
        font-size: var(--bt-playbook-ticket-feature-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-relaxed);
        text-align: left;
    }

    /* หัวคอลัมน์ของตารางเปรียบเทียบ (คนละตัวกับการ์ดราคาด้านล่าง) */
    /* ชื่อบัตรบนหัวตารางใช้ serif ชุดเดียวกับ .playbook-ticket__plan-title ของการ์ดด้านล่าง
       ชื่อบัตรจึงอ่านเป็นของสิ่งเดียวกันทั้งสองที่ (Baskervville โหลดมาแค่น้ำหนัก 400
       ถ้าใส่ medium เบราว์เซอร์จะปลอมตัวหนาให้เอง เส้นจะเละ) */
    .playbook-ticket__col {
        width: var(--bt-playbook-ticket-plan-width);
        padding: var(--bt-playbook-ticket-cell-padding-y) var(--bt-playbook-ticket-cell-padding-x);
        font-family: 'Baskervville', var(--font-family-base);
        font-size: var(--bt-playbook-ticket-plan-size);
        font-weight: var(--font-weight-regular);
        line-height: var(--line-height-1);
        text-align: center;
    }

    .playbook-ticket__cell {
        padding: var(--bt-playbook-ticket-cell-padding-y) var(--bt-playbook-ticket-cell-padding-x);
        text-align: center;
    }

    /* คอลัมน์ Ultimate เป็นตัวเอก ยกพื้นขึ้นมาหนึ่งขั้นให้อ่านเป็นแถบเดียวตลอดตาราง */
    .playbook-ticket__cell--highlight {
        background: var(--color-surface-paper);
    }

    thead .playbook-ticket__cell--highlight {
        height: var(--space-16);
        border-radius: var(--card-radius) var(--card-radius) var(--space-0) var(--space-0);
    }

    tbody tr:last-child .playbook-ticket__cell--highlight {
        border-radius: var(--space-0) var(--space-0) var(--card-radius) var(--card-radius);
    }

    tbody tr {
        border-top: var(--border-width-1) solid var(--color-border-faint);
    }

    .playbook-ticket__mark {
        font-size: var(--bt-playbook-ticket-mark-size);
        vertical-align: middle;
    }

    /* ติ๊กถูกใช้สี accent ของระบบ ส่วนขีดคือ "ไม่ได้รับ" ใช้สีจางระดับข้อความรอง */
    .playbook-ticket__mark--yes {
        color: var(--color-accent-primary);
    }

    .playbook-ticket__mark--no {
        color: var(--color-text-muted);
    }
}

@media (max-width: 991px) {
    .playbook-ticket {
        --bt-playbook-ticket-padding-y: var(--section-padding-y-sm);
        --bt-playbook-ticket-table-space: var(--space-12);
        --bt-playbook-ticket-plan-width: var(--space-32);
        --bt-playbook-ticket-plan-size: var(--section-body-size);
        --bt-playbook-ticket-features-space: var(--space-6);

        .playbook-ticket__prices {
            margin-top: var(--space-8);
        }
    }
}

@media (max-width: 575px) {
    .playbook-ticket {
        --bt-playbook-ticket-cell-padding-x: var(--space-2);
        --bt-playbook-ticket-cell-padding-y: var(--space-2);
        --bt-playbook-ticket-plan-width: 110px;
        --bt-playbook-ticket-feature-size: var(--section-small-size);
        --bt-playbook-ticket-mark-size: var(--font-size-20);
        /* หัวคอลัมน์ ULTIMATE / EXPLORER ที่ 16px กว้าง 89px แต่ช่องเหลือ 64px (80 หัก padding)
           สองชื่อจึงล้นมาชนกันกลางตาราง ลดเป็น 12px (67px) และลด padding ข้างของหัวคอลัมน์
           แทนการขยายคอลัมน์ ช่องชื่อสิทธิ์ทางซ้ายจึงกว้างเท่าเดิม ไม่ตัดบรรทัดเพิ่ม */
        --bt-playbook-ticket-plan-size: var(--font-size-14);

        .playbook-ticket__col {
            padding-inline: var(--space-1);
        }

        /* token นี้ประกาศไว้ที่ตัวการ์ดเอง (ไม่ใช่ที่ section) จึงต้องทับที่ระดับเดียวกัน
        แนวตั้งคงไว้ แนวนอนลดลง ให้กล่องราคาสองใบมีที่มากขึ้น
        ระยะในกล่องราคาลด 24 -> 16px ด้วยเหตุผลเดียวกัน */
        .playbook-ticket__plan {
            --bt-playbook-ticket-price-size: var(--font-size-32);
            --bt-playbook-ticket-plan-padding: var(--space-8) var(--space-5);
            --bt-playbook-ticket-price-padding: var(--space-4);
            --bt-playbook-ticket-plan-title-size: var(--font-size-28);
        }

        /* ราคาเดิม "2,500 บาท" + ป้าย "คุ้มกว่า" ต้องใช้ 123px แต่กล่องมีที่ 101px ที่จอ 375
           ราคาเดิมจึงตัดเป็นสองบรรทัด ตัวเลขราคาของสองกล่องเลยไม่อยู่แนวเดียวกัน
           ลดราคาเดิมเป็น 12px และระยะข้างของป้ายเหลือ 4px รวมเหลือ 106px
           อยู่บรรทัดเดียวได้ถึงจอ 360 (กล่องมีที่ 110px)
           จอที่แคบกว่านั้นให้ป้ายตกลงบรรทัดใหม่ทั้งก้อน ไม่ให้ราคากับคำว่า "บาท" แยกกัน */
        .playbook-ticket__price-compare {
            margin-top: var(--space-2);
            flex-wrap: wrap;
            font-size: var(--font-size-12);

            s {
                white-space: nowrap;
            }
        }

        .playbook-ticket__price-badge {
            padding-inline: var(--space-1);
        }

        .playbook-ticket__price-value {

            small {
                font-size: var(--section-small-size);
            }
        }

        .playbook-ticket__plan-icon {
            margin-bottom: var(--space-4);
        }

        .playbook-ticket__plan-eyebrow {
            margin-bottom: var(--space-2);
        }
    }
}

/* ---------- จุดตามเมาส์ (js/cursor-dot.js) ----------
   จุดสีดำเล็ก ๆ ไม่มีขอบ (สีขาวบนพื้นมืด) เลื่อนตามเมาส์ด้วย transform (จาก JS) ส่วนหน้าตาอยู่ที่ ::before
   จุดกึ่งกลางวางที่ปลายเมาส์ อยู่บนสุดของหน้าแต่ไม่รับการคลิก ขนาดคงที่ (ไม่ขยายตอนชี้ปุ่ม) */
.cursor-dot {
    --bt-cursor-dot-size: 10px;

    position: fixed;
    top: 0;
    left: 0;
    z-index: 10000;
    width: 0;
    height: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--duration-standard) var(--ease-standard);
    will-change: transform;

    &::before {
        content: '';
        position: absolute;
        top: calc(var(--bt-cursor-dot-size) / -2);
        left: calc(var(--bt-cursor-dot-size) / -2);
        width: var(--bt-cursor-dot-size);
        height: var(--bt-cursor-dot-size);
        border-radius: 50%;
        background: var(--color-text-primary);
    }

    &.is-visible {
        opacity: 1;
    }

    /* พื้นมืดใต้เมาส์ (js/cursor-dot.js ตรวจแล้วใส่คลาส) เปลี่ยนเป็นจุดสีขาว */
    &.is-on-dark::before {
        background: var(--color-neutral-0);
    }
}
