/* ============================================================
   ธาตุทอง GPAS | deck.css เครื่องยนต์สไลด์ (ยกมาจากโครงการก่อนหน้า)
   ผิวธีม B อยู่ท้ายไฟล์ ส่วนที่ 24
   เวทีคงที่ 1920 คูณ 1080 ใช้ร่วมกันทุกชุด แก้ไฟล์นี้แล้วเปลี่ยนพร้อมกันทุกชุด

   โทเคนสีและตัวอักษรเป็นค่าเดียวกับหน้า Hub เพื่อให้สื่อสองชุดนี้
   ดูเป็นตระกูลเดียวกัน ถ้าแก้สีที่นี่ ต้องแก้ที่ assets/theme.css ให้ตรงกันเสมอ

   กติกาการออกแบบสี่ข้อ
     1. มุมฉากทุกจุด ยกเว้นปุ่มลอยซึ่งเป็นวงกลม
     2. เงาทึบไม่ฟุ้ง ใช้ระยะเยื้องแทนการเบลอ
     3. เส้นขอบหมึกหนา 2.5px สีเดียวกับตัวอักษร
     4. คู่สี deep เท่านั้นที่ใช้กับตัวอักษรได้ คู่สีสดใช้ได้เฉพาะเส้นขอบ พื้น และสัญลักษณ์

   กติกา line-height ของภาษาไทย ห้ามลดต่ำกว่าค่าเหล่านี้
     หัวเรื่องใหญ่ 1.30  หัวเรื่องกลาง 1.34  หัวเรื่องเล็ก 1.40  เนื้อความ 1.55

   ★ ค่าที่ใช้จริง ผูกกับขั้นของบันไดขนาด (ปรับ 2 ตุลาคม 2569 เดิมมี 15 ค่า)
     72 และ 54px ใช้ 1.3   44px ใช้ 1.35   36px ใช้ 1.4
     30 และ 26px ใช้ 1.6   23px ใช้ 1.55   20px (ป้าย) ใช้ 1.5
     ยิ่งตัวใหญ่ยิ่งต้องการความสูงบรรทัดน้อยลง ทุกค่าไม่ต่ำกว่าพื้นของภาษาไทยข้างบน
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Anuphan:wght@500;600;700&family=Noto+Sans+Thai:wght@400;500;600&family=JetBrains+Mono:wght@400;600&display=swap');

:root {
    --paper: #f5efe3;
    --card: #fffaf1;
    --ink: #0f2a3d;
    --muted: #4b6070;
    --line: rgba(15, 42, 61, .18);
    --rule: 2.5px solid var(--ink);

    /* ชุดสีห้าตัว ค่าเดียวกับ assets/theme.css ของหน้า Hub */
    --c1: #d9642b;
    --c1-deep: #9e4516;
    --c1-soft: rgba(217, 100, 43, .10);
    --c2: #1f63b5;
    --c2-deep: #184d8c;
    --c2-soft: rgba(31, 99, 181, .10);
    --c3: #0e8a8a;
    --c3-deep: #0a6363;
    --c3-soft: rgba(14, 138, 138, .10);
    --c4: #c99414;
    --c4-deep: #7a5700;
    --c4-soft: rgba(201, 148, 20, .14);
    --c5: #c0304a;
    --c5-deep: #9b1c30;
    --c5-soft: rgba(192, 48, 74, .10);

    /* ชื่อเชิงความหมายของโครงการนี้ รหัสสองสีตามข้อ 10 ที่ล็อกไว้
       สถานะ เข้าได้ คือการไม่ทำเครื่องหมายโดยเจตนา ไม่ใช่สีที่สาม */
    --out: var(--c5);
    --out-deep: var(--c5-deep);
    --out-soft: var(--c5-soft);
    --guard: var(--c3);
    --guard-deep: var(--c3-deep);
    --guard-soft: var(--c3-soft);
    --label: var(--c4-deep);

    /* สีประจำขั้น GPAS 5 Steps ล็อกไว้ ใช้ตรงกันทุกชิ้นงาน (หน้า Hub สไลด์ เอกสาร แม่แบบครู)
       คู่ deep เท่านั้นที่ใช้กับตัวอักษรได้ */
    --c6: #3f8a4f;
    --c6-deep: #2e6a3b;
    --c6-soft: rgba(63, 138, 79, .12);
    --st-g: var(--c3);   --st-g-deep: var(--c3-deep);   --st-g-soft: var(--c3-soft);
    --st-p: var(--c2);   --st-p-deep: var(--c2-deep);   --st-p-soft: var(--c2-soft);
    --st-a1: var(--c1);  --st-a1-deep: var(--c1-deep);  --st-a1-soft: var(--c1-soft);
    --st-a2: var(--c4);  --st-a2-deep: var(--c4-deep);  --st-a2-soft: var(--c4-soft);
    --st-s: var(--c6);   --st-s-deep: var(--c6-deep);   --st-s-soft: var(--c6-soft);

    --font-display: 'Anuphan', 'Noto Sans Thai', system-ui, sans-serif;
    --font-body: 'Noto Sans Thai', system-ui, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, monospace;

    --shadow: 8px 8px 0 rgba(15, 42, 61, .18);
    --tap: 44px;
    --fs: 1;
    /* ตัวคูณขนาดอักษรทั้งชุด ตั้งค่าโดย deck.js */

    /* ★ บันไดขนาดตัวอักษรเจ็ดขั้น ห้ามใช้ค่านอกบันไดนี้ทั้งใน CSS และใน HTML
       หลักที่ใช้ตั้ง ปัญหาไม่ได้อยู่ที่ตัวอักษรเล็กอย่างเดียว
       แต่อยู่ที่อัตราส่วนหัวเรื่องต่อเนื้อความ ค่าเดิม 76 ต่อ 26 คือห่าง 2.9 เท่า มากเกินไป
       ค่าปัจจุบัน 72 ต่อ 30 คือ 2.4 เท่า ใกล้ค่า 2.3 ที่ชุดสื่ออีกชุดพิสูจน์จากห้องเรียนจริงมาแล้วสามรอบ
       ถ้าจะขยายหัวเรื่อง ต้องขยายเนื้อความตามเสมอ */
    --size-h1: calc(72px * var(--fs));
    --size-h2: calc(54px * var(--fs));
    --size-h3: calc(36px * var(--fs));
    --size-body: calc(30px * var(--fs));
    --size-small: calc(26px * var(--fs));
    --size-tiny: calc(23px * var(--fs));
    --size-label: calc(20px * var(--fs));
}

/* ============================================================
   1. เวทีคงที่ ห้ามแก้บล็อกนี้
   ============================================================ */
html,
body {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
    background: #08151f;
}

*,
*::before,
*::after {
    box-sizing: border-box;
    border-radius: 0;
}

.deck-viewport {
    position: fixed;
    inset: 0;
    overflow: hidden;
}

.deck-stage {
    position: absolute;
    left: 0;
    top: 0;
    width: 1920px;
    height: 1080px;
    overflow: hidden;
    transform-origin: 0 0;
}

.slide {
    position: absolute;
    inset: 0;
    width: 1920px;
    height: 1080px;
    overflow: hidden;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    background-image:
        linear-gradient(rgba(15, 42, 61, .075) 1.2px, transparent 1.2px),
        linear-gradient(90deg, rgba(15, 42, 61, .075) 1.2px, transparent 1.2px),
        linear-gradient(rgba(15, 42, 61, .035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(15, 42, 61, .035) 1px, transparent 1px);
    background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
    background-position: -1px -1px;
    transition: opacity .22s ease;
}

.slide.active {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
}

.slide.s-dark,
.slide.dark {
    background: var(--ink);
    color: var(--paper);
    background-image: none;
}

.slide.s-dark .muted,
.slide.dark .muted {
    color: rgba(245, 239, 227, .62);
}

.slide.s-paper-alt {
    background: var(--card);
}

@media (prefers-reduced-motion: reduce) {
    .slide {
        transition: none;
    }
}

/* ============================================================
   2. แถบบนและแถบล่าง สร้างด้วยสคริปต์ ความสูง 88px ตามกติกาภาษาไทย
   ============================================================ */
.bar-top,
.slide-head {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 88px;
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 0 76px;
    border-bottom: 1px solid var(--line);
    /* ชื่อช่วงเป็นภาษาไทย ใช้ฟอนต์ไทย ไม่ถ่าง ไม่ตัวพิมพ์ใหญ่ */
    font-family: var(--font-body);
    font-weight: 600;
    font-size: var(--size-label);
    color: var(--label);
}

.s-dark .bar-top,
.s-dark .slide-head {
    border-bottom-color: rgba(245, 239, 227, .18);
    color: #f2c45a;
}

.bar-bot,
.slide-foot {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 74px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 76px;
    border-top: 1px solid var(--line);
    font-family: var(--font-body);
    font-size: var(--size-label);
    color: var(--muted);
}

.s-dark .bar-bot,
.s-dark .slide-foot {
    border-top-color: rgba(245, 239, 227, .18);
    color: rgba(245, 239, 227, .55);
}

.pg {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   3. พื้นที่เนื้อหา inset บนต้องตรงกับความสูงแถบบนเป๊ะ
   ============================================================ */
.slide-pad {
    position: absolute;
    inset: 88px 76px 74px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
}

/* ============================================================
   3ก. ★ หน้าที่เนื้อหายาวเกินหนึ่งจอ ให้เลื่อนอ่าน ไม่ตัดทิ้ง

   เดิมกรอบเนื้อหาใช้ overflow: hidden คู่กับการย่ออัตโนมัติถึงพื้น 0.85
   ผลคือหน้าที่ล้นมากถูกตัดทิ้งอย่างเงียบ ๆ และหน้าที่ย่อได้ก็ตัวอักษรเล็กจนอ่านยาก
   ตอนนี้การย่อเหลือบทบาทเดียวคือกลืนเศษไม่เกินห้าเปอร์เซ็นต์ ที่เหลือให้เลื่อนอ่าน

   ⚠️ ล้อเมาส์ไม่เปลี่ยนหน้าอีกแล้ว ทำหน้าที่เลื่อนอ่านอย่างเดียว
      เปลี่ยนหน้าด้วยลูกศรซ้ายขวา ปุ่มบนแถบเครื่องมือ หรือปัดนิ้วแนวนอน
   ============================================================ */

/* เลิกจัดกึ่งกลางทันทีที่ล้น เพราะ justify-content: center
   ทำให้ flexbox ดันเนื้อหาล้นออกทั้งบนและล่างเท่ากัน หัวเรื่องจึงหายไปพร้อมบรรทัดท้าย */
.slide-pad.is-over {
    justify-content: flex-start;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
}

/* แถบเลื่อนต้องเข้าชุดกับสไลด์ ไม่ใช่แถบเทาของระบบ */
.slide-pad.is-over::-webkit-scrollbar { width: 10px; }
.slide-pad.is-over::-webkit-scrollbar-track { background: transparent; }
.slide-pad.is-over::-webkit-scrollbar-thumb {
    background: rgba(15, 42, 61, .30);
    border: 3px solid transparent;
    background-clip: content-box;
}
.slide-pad.is-over::-webkit-scrollbar-thumb:hover { background: rgba(15, 42, 61, .52); background-clip: content-box; }
.s-dark .slide-pad.is-over::-webkit-scrollbar-thumb { background: rgba(245, 239, 227, .34); background-clip: content-box; }
.slide-pad.is-over { scrollbar-width: thin; scrollbar-color: rgba(15, 42, 61,.30) transparent; }
.s-dark .slide-pad.is-over { scrollbar-color: rgba(245, 239, 227,.34) transparent; }

/* ขอบล่างไล่จาง บอกว่ายังมีเนื้อหาต่อ หายไปเมื่ออ่านถึงท้ายหน้า
   ผู้ฟังบนจอโปรเจกเตอร์ไม่ได้จับเมาส์ จึงต้องมีสัญญาณทางสายตา */
.slide.is-scrollable::after {
    content: '';
    position: absolute;
    inset-inline: 76px;
    bottom: 74px;
    height: 96px;
    background: linear-gradient(to top, var(--paper) 12%, transparent);
    pointer-events: none;
    opacity: 1;
    transition: opacity .25s ease;
    z-index: 2;
}
.slide.s-paper-alt.is-scrollable::after { background: linear-gradient(to top, var(--card) 12%, transparent); }
.slide.s-dark.is-scrollable::after { background: linear-gradient(to top, var(--ink) 12%, transparent); }
.slide.is-scrollable.at-end::after { opacity: 0; }

/* ป้ายบอกวิธี แสดงจนกว่าจะเริ่มเลื่อน */
.slide.is-scrollable::before {
    content: 'เลื่อนลงเพื่ออ่านต่อ';
    position: absolute;
    inset-inline-start: 50%;
    bottom: 92px;
    transform: translateX(-50%);
    z-index: 3;
    font-family: var(--font-body);
    font-size: calc(20px * var(--fs));
    line-height: 1.5;
    color: var(--paper);
    background: rgba(22, 35, 58, .88);
    padding: 6px 18px;
    pointer-events: none;
    opacity: 1;
    transition: opacity .25s ease;
}
.slide.is-scrollable.at-end::before { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
    .slide.is-scrollable::after,
    .slide.is-scrollable::before { transition: none; }
}

.slide-pad.top {
    justify-content: flex-start;
    padding-top: 30px;
}

/* ============================================================
   4. ตัวอักษร ค่า line-height ทุกค่าผ่านเกณฑ์ภาษาไทยแล้ว
   ============================================================ */
h1,
h2,
h3,
h4 {
    font-family: var(--font-display);
    font-weight: 600;
    margin: 0;
    text-wrap: balance;
}

h1 {
    font-size: var(--size-h1);
    line-height: 1.30;
    letter-spacing: -.015em;
}

h2 {
    font-size: var(--size-h2);
    line-height: 1.3;
    letter-spacing: -.01em;
}

h3 {
    font-size: var(--size-h3);
    line-height: 1.4;
}

p,
li {
    font-size: var(--size-body);
    line-height: 1.6;
    margin: 0;
}

.lead {
    font-size: calc(44px * var(--fs));
    /* ★ ข้อความนำเป็นตัว 44px ค่า 1.56 ทำให้บรรทัดห่างเกินจนดูขาดจากกัน
       ข้อนี้จึงลดลงสวนทางกับข้ออื่นโดยเจตนา ยิ่งตัวใหญ่ ยิ่งต้องการความสูงบรรทัดน้อยลง */
    line-height: 1.35;
    max-width: 62ch;
}

.small {
    font-size: var(--size-small);
    line-height: 1.6;
}

.tiny {
    font-size: var(--size-tiny);
    line-height: 1.55;
}

strong {
    font-weight: 600;
}

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

.mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.eyebrow,
.kicker {
    /* ป้ายนำเหนือหัวเรื่อง ฟอนต์ไทย ไม่ถ่าง ไม่ตัวพิมพ์ใหญ่ มีขีดสั้นนำหน้า (02-DESIGN-SYSTEM ข้อ 4.3) */
    display: flex;
    align-items: center;
    gap: 14px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: var(--size-label);
    line-height: 1.5;
    color: var(--label);
    margin: 0 0 18px;
}

.eyebrow::before,
.kicker::before {
    content: "";
    flex: none;
    width: 36px;
    height: 4px;
    background: currentColor;
}

.s-dark .eyebrow,
.s-dark .kicker {
    color: #f2c45a;
}

.slide-pad>.kicker {
    align-self: flex-start;
}

.rule-bar {
    height: 4px;
    width: 108px;
    background: var(--label);
    margin: 22px 0;
}

.s-dark .rule-bar {
    background: #f2c45a;
}

.hairline {
    height: 1px;
    background: var(--line);
    margin: 32px 0;
}

.s-dark .hairline {
    background: rgba(245, 239, 227, .2);
}

/* ============================================================
   5. โครงคอลัมน์
   ============================================================ */
/* ★ ห้ามใส่ min-height: 0 ให้ .grid เด็ดขาด
   .slide-pad เป็น flex คอลัมน์ ลูกทุกตัวมี min-height: auto โดยปริยาย จึงไม่มีทางหดต่ำกว่าเนื้อหาของตัวเอง
   เคยมี min-height: 0 ตรงนี้ ผลคือเมื่อหน้ายาวเกินกรอบ flex จะบีบเฉพาะตาข่ายการ์ดให้เตี้ยลงจนพอดี
   การ์ดข้างในไม่ได้เล็กตาม จึงทะลุออกด้านล่างไปทับกล่องที่อยู่ถัดไป
   และเพราะกรอบถูกบีบจนพอดี fitSlidePad จึงมองไม่เห็นว่าล้น ไม่เปิดเลื่อนอ่าน และขึ้นป้าย 100% ทั้งที่หน้าซ้อนทับอยู่
   เมื่อไม่มีบรรทัดนั้น ตาข่ายจะสูงเท่าเนื้อหาเสมอ หน้าที่ยาวจะล้นจริง และกลไกเลื่อนอ่านจะรับช่วงต่อ */
.grid {
    display: grid;
    gap: 34px;
}

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

.g3 {
    grid-template-columns: repeat(3, 1fr);
}

.g4 {
    grid-template-columns: repeat(4, 1fr);
}

.g-2-1 {
    grid-template-columns: 1.6fr 1fr;
}

/* ============================================================
   6. การ์ด เงาทึบไม่ฟุ้ง เส้นขอบหมึกหนา
   ============================================================ */
.card {
    background: var(--card);
    border: var(--rule);
    box-shadow: var(--shadow);
    padding: 32px 38px;
    min-width: 0;
}

.card h3 {
    margin-bottom: 16px;
}

.card p,
.card li {
    font-size: var(--size-small);
    line-height: 1.6;
}

.s-dark .card {
    background: rgba(245, 239, 227, .06);
    border-color: rgba(245, 239, 227, .34);
    color: var(--paper);
    box-shadow: none;
}

.s-dark .card .muted {
    color: rgba(245, 239, 227, .62);
}

.card.out {
    border-inline-start: 10px solid var(--out);
}

.card.in {
    border-inline-start: 10px solid var(--guard);
}

.note {
    border: 2.5px dashed var(--out);
    background: var(--out-soft);
    padding: 24px 30px;
    font-size: var(--size-small);
    line-height: 1.6;
}

.s-dark .note {
    background: rgba(207, 58, 82, .14);
    border-color: #f09aa6;
    color: var(--paper);
}

/* ============================================================
   7. ป้ายและสถิติ
   ============================================================ */
.tag {
    display: inline-block;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: var(--size-label);
    padding: 6px 14px;
    border: 2px solid var(--ink);
    background: var(--card);
}

.tag.out {
    border-color: var(--out);
    color: var(--out-deep);
    background: var(--out-soft);
}

.tag.in {
    border-color: var(--guard);
    color: var(--guard-deep);
    background: var(--guard-soft);
}

.stat {
    text-align: center;
    padding: 22px 18px 26px;
    border: var(--rule);
    background: var(--card);
    box-shadow: var(--shadow);
}

.stat .v {
    font-family: var(--font-display);
    font-size: calc(106px * var(--fs));
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.stat .k {
    font-size: var(--size-small);
    line-height: 1.6;
    color: var(--muted);
    margin-top: 8px;
}

.stat.out .v {
    color: var(--out-deep);
}

.stat.in .v {
    color: var(--guard-deep);
}

.big-num {
    font-family: var(--font-display);
    font-size: calc(360px * var(--fs));
    line-height: .82;
    letter-spacing: -.04em;
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   8. ตาราง
   ============================================================ */
table {
    border-collapse: collapse;
    width: 100%;
}

th,
td {
    text-align: start;
    padding: 16px 22px;
    border-bottom: 1px solid var(--line);
    font-size: var(--size-small);
    line-height: 1.6;
    vertical-align: top;
}

th {
    font-family: var(--font-body);
    font-size: var(--size-label);
    color: var(--muted);
    font-weight: 600;
    border-bottom: var(--rule);
}

tr.hi td {
    background: var(--c4-soft);
}

.s-dark th,
.s-dark td {
    border-bottom-color: rgba(245, 239, 227, .2);
}

.s-dark th {
    color: rgba(245, 239, 227, .66);
    border-bottom-color: rgba(245, 239, 227, .45);
}

/* ============================================================
   9. แถบตำแหน่งหกขั้น
   ============================================================ */
.move {
    padding: 22px 18px 24px;
    border: var(--rule);
    background: var(--card);
    text-align: center;
    box-shadow: var(--shadow);
}

.move .mv-t {
    font-family: var(--font-display);
    font-size: var(--size-h3);
    font-weight: 600;
    line-height: 1.4;
    margin: 4px 0 8px;
}

.move .mv-s {
    font-size: calc(26px * var(--fs));
    line-height: 1.6;
    color: var(--muted);
}

.move.out {
    background: var(--out-soft);
    border-color: var(--out);
}

.move.in {
    background: var(--guard-soft);
    border-color: var(--guard);
}

.bar-track {
    height: 44px;
    background: var(--line);
    position: relative;
}

.bar-fill {
    height: 100%;
    background: var(--guard);
}

/* ============================================================
   10. ความหนาแน่นสูง ใช้กับหน้าที่มีตารางยาว
   ============================================================ */
.dense .card p,
.dense .card li {
    font-size: calc(26px * var(--fs));
    line-height: 1.6;
}

.dense th,
.dense td {
    /* ★ ระยะเท่ากับค่าปกติเดิมก่อนบีบ ความต่างของ dense เหลือเพียงขนาดตัวอักษร 26 กับ 30 */
    padding: 14px 18px;
    font-size: calc(26px * var(--fs));
    line-height: 1.6;
}

.dense .grid {
    gap: 26px;
}

.dense .card {
    padding: 26px 30px;
}

/* ============================================================
   11. ชุดควบคุมของผู้บรรยาย เป็นแถบแนวนอนกลางขอบล่าง

   เป็นเครื่องมือของผู้บรรยาย ไม่ใช่ของผู้ชม จึงจางสนิทจนกว่าจะขยับเมาส์
   และการกดคีย์เปลี่ยนหน้าไม่ปลุกแถบขึ้นมา เพื่อไม่ให้กะพริบรบกวนผู้ฟังทุกครั้งที่เปลี่ยนหน้า
   ดูตรรกะการปลุกที่ deck.js หัวข้อ 6ก และท้ายตัวจัดการคีย์บอร์ด
   ============================================================ */
/* ★ ย้ายจากขอบซ้ายกึ่งกลางแนวตั้ง มาเป็นแถบนอนกลางขอบล่าง แก้ 13 กันยายน 2569

   ที่มา แถบนี้วางด้วย fixed จึงกินพื้นที่ของ **จอจริง** คงที่ คือ 16 ถึง 60 พิกเซล
   แต่ระยะขอบของสไลด์คือ padding 76px ซึ่งเป็นพิกเซลของ **เวที 1920**
   และเวทีถูกย่อด้วย f เท่ากับ min(w/1920, h/1080) ระยะขอบจริงจึงเป็น 76 คูณ f ซึ่งหดตามจอ
   เงื่อนไขที่ทับกันคือ 76f น้อยกว่า 60 นั่นคือ f ต่ำกว่า 0.79 เมื่อไหร่ทับทันที
   จอ 1440 คูณ 900 ทับ 3px จอ 1280 คูณ 800 ทับ 9px จอ 1024 คูณ 768 ทับ 20px
   ซึ่งครอบคลุมโปรเจกเตอร์ 16 ต่อ 10 และ 4 ต่อ 3 แทบทั้งหมด

   ขอบล่างกลางจอทับได้อย่างมากแค่ .slide-foot ซึ่งมีข้อความเฉพาะริมซ้ายกับริมขวา
   ตรงกลางว่างทุกหน้า จึงเป็นพิกเซลที่เสียหายน้อยที่สุดบนสไลด์
   ขอบขวาแก้ไม่ได้ เพราะ padding เป็น 76px เท่ากันสองข้าง ปัญหาจะย้ายตามไปแบบกระจกเงา */
.ctrl {
    position: fixed;
    inset-inline-start: 50%;
    inset-block-end: 14px;
    transform: translateX(-50%);
    z-index: 3000;
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: 8px;
    /* กันไม่ให้ยาวไปชนปุ่มเฟืองมุมล่างซ้ายและปุ่มแชตมุมล่างขวา
       ปุ่มลอยสองปุ่มกว้าง 54px ห่างขอบ 20px จึงกันไว้ข้างละ 100px */
    max-width: calc(100vw - 200px);
    /* จางสนิทจนกว่าจะขยับเมาส์ เพื่อไม่ให้รบกวนสายตาผู้ชมระหว่างบรรยาย
       ตอนเต็มจอยิ่งต้องหายสนิท เพราะไม่มีขอบจอให้แถบไปเกาะ */
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease;
}

.ctrl.awake {
    opacity: 1;
    pointer-events: auto;
}

/* ตอนเต็มจอไม่มีขอบจอให้แถบไปเกาะ จึงต้องหายสนิทกว่าปกติ
   และหน่วงนานขึ้นก่อนซ่อน เพราะเมาส์บนจอโปรเจกเตอร์เล็งยากกว่า */
html.fs-on .ctrl:not(.awake),
html.fs-on .fab:not(.awake) {
    opacity: 0;
    pointer-events: none;
}

.ctrl button,
.ctrl a {
    width: var(--tap);
    height: var(--tap);
    /* ★ ห้ามให้บีบ ตั้งแต่แถบเป็นแนวนอนและมี max-width */
    flex: none;
    display: grid;
    place-items: center;
    background: var(--card);
    color: var(--ink);
    border: 2px solid var(--ink);
    border-radius: 10px;
    cursor: pointer;
    text-decoration: none;
    font-family: var(--font-body);
    box-shadow: 0 2px 8px rgba(14, 22, 38, .35);
}

.ctrl button:hover,
.ctrl a:hover {
    background: var(--c4);
    color: var(--ink);
}

.ctrl button[aria-pressed="true"] {
    background: var(--out);
    color: var(--paper);
    border-color: var(--out-deep);
}

.ctrl button:disabled {
    opacity: .4;
    cursor: not-allowed;
}

/* ★ เส้นคั่นต้องตั้งขึ้น ไม่ใช่นอน ตั้งแต่แถบเปลี่ยนเป็นแนวนอน 13 กันยายน 2569 */
.ctrl .sep {
    width: 2px;
    height: 26px;
    background: rgba(15, 42, 61, .45);
    border-radius: 2px;
    flex: none;
}

.ctrl :focus-visible {
    outline: 3px solid var(--c4);
    outline-offset: 2px;
}

/* ป้ายตัวเลขสองอันนี้ต้องมีพื้นหลังของตัวเอง ห้ามปล่อยเป็นตัวอักษรลอย
   เพราะบนจอ 16 ต่อ 9 เวทีจะเต็มจอพอดี ชุดควบคุมจึงทับบนพื้นกระดาษ
   ถ้าใช้สีอ่อนตามพื้นหลังเวทีมืด ตัวเลขจะกลืนหายทันทีในสถานการณ์บรรยายจริง */
.ctrl .fitbadge.clip {
    background: var(--out);
    color: #fff;
}

/* ★ ตั้งแต่แถบเป็นแนวนอน ป้ายต้องสูงเท่าปุ่ม ไม่เช่นนั้นจะลอยอยู่กลางแถว
   และป้ายย่อหน้าต้องไม่ตัดบรรทัด เพราะข้อความ ย่อ 95% กว้างเกิน 44px จะดันแถบให้สูงขึ้น */
.ctrl .fsval,
.ctrl .pgval {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 12px;
    line-height: 1.30;
    width: var(--tap);
    min-height: var(--tap);
    display: grid;
    place-items: center;
    text-align: center;
    color: var(--paper);
    background: rgba(22, 35, 58, .9);
    border-radius: 8px;
    padding: 3px 0;
    font-variant-numeric: tabular-nums;
    flex: none;
}

.ctrl .fitbadge {
    width: auto;
    min-width: var(--tap);
    padding: 3px 9px;
    white-space: nowrap;
}

/* แถบความคืบหน้าขอบบนจอ บอกว่าเหลืออีกกี่หน้าโดยไม่ต้องอ่านตัวเลข */
.progress {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    height: 5px;
    width: 0;
    background: linear-gradient(90deg, var(--c4), var(--c5));
    z-index: 2000;
    transition: width .4s cubic-bezier(.16, 1, .3, 1);
}

.hint {
    position: fixed;
    inset-block-end: 88px;
    inset-inline-start: 50%;
    transform: translateX(-50%);
    background: rgba(13, 16, 23, .92);
    color: rgba(245, 239, 227, .9);
    border: 1px solid rgba(245, 239, 227, .22);
    padding: 12px 22px;
    font-size: 17px;
    line-height: 1.56;
    font-family: var(--font-body);
    opacity: 0;
    transition: opacity .3s ease;
    pointer-events: none;
    z-index: 3400;
}

.hint.show {
    opacity: 1;
}

/* ============================================================
   12. ปุ่มลอยของ AI เป็นวงกลม ข้อยกเว้นเดียวของกฎมุมฉาก
   เฟืองอยู่มุมล่างซ้าย แชตอยู่มุมล่างขวา ไม่ชนกับแถบเครื่องมือซึ่งอยู่กลางขอบล่าง
   เพราะแถบเครื่องมือถูกจำกัดความกว้างไว้ที่ 100vw ลบ 200px กันไว้ข้างละ 100px
   ============================================================ */
.fab {
    position: fixed;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ink);
    color: var(--paper);
    border: 2px solid rgba(245, 239, 227, .3);
    cursor: pointer;
    z-index: 3200;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, .35);
    transition: transform .14s ease, background .2s ease;
}

.fab:hover {
    background: #173b53;
    transform: translateY(-2px);
}

.fab:active {
    transform: translateY(1px);
}

.fab:focus-visible {
    outline: 3px solid #f2c45a;
    outline-offset: 3px;
}

.fab-set {
    inset-block-end: 20px;
    inset-inline-start: 20px;
}

.fab-chat {
    inset-block-end: 20px;
    inset-inline-end: 20px;
}

.fab-chat.ready {
    background: var(--c3-deep);
}

/* ============================================================
   12ก. เครื่องมือเฉพาะผู้ตรวจงาน

   ★ ปุ่มเฟืองและปุ่มแชตแสดงเสมอกับทุกคน ไม่มีประตูซ่อนอีกแล้ว
     รุ่นก่อนหน้าซ่อนไว้จนกว่าจะเปิดโหมดผู้บรรยาย
     ผลคือผู้ใช้เปิดสไลด์มาแล้วไม่เห็นปุ่มใดเลย และไม่มีอะไรบอกว่าต้องเปิดอย่างไร
     ปุ่มลัด Ctrl Shift P ที่เคยใช้เปิด ยังชนกับหน้าต่างส่วนตัวของ Firefox
     และเมนูคำสั่งของ DevTools ใน Chrome จึงถูกถอนออกทั้งหมด

   เหลือไว้เฉพาะ .present-only ซึ่งใช้กับป้ายบอกเปอร์เซ็นต์การย่อ
   เป็นเครื่องมือของคนตรวจงาน ไม่ใช่ของผู้ชม เปิดด้วย ?present=1 อย่างเดียว
   ============================================================ */
html:not(.present-on) .present-only {
    display: none !important;
}

/* ============================================================
   13. หน้าต่างตั้งค่า เป็นกล่องกลางจอ
   ต่างจากหน้าต่างแชตซึ่งลอยจากมุมล่างขวา ดูหัวข้อ 14
   ============================================================ */
.ov {
    position: fixed;
    inset: 0;
    background: rgba(13, 16, 23, .78);
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    z-index: 9000;
}

.ov.show {
    display: flex;
}

.ov-panel {
    width: min(560px, 96vw);
    max-height: 88vh;
    height: auto;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule);
    box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
    display: flex;
    flex-direction: column;
    font-family: var(--font-body);
}

.ov-head {
    padding: 18px 22px;
    border-bottom: var(--rule);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex: none;
}

.ov-head h3 {
    font-size: 21px;
    line-height: 1.40;
}

.ov-body {
    padding: 20px 22px;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
}

.ov-foot {
    padding: 14px 22px 18px;
    border-top: 1px solid var(--line);
    flex: none;
}

.ov .x {
    background: transparent;
    border: 0;
    font-size: 24px;
    cursor: pointer;
    color: var(--muted);
    line-height: 1;
    padding: 4px 8px;
}

.ov .x:hover {
    color: var(--ink);
}

.fld {
    display: block;
    margin-bottom: 14px;
}

.fld span {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    margin-bottom: 5px;
    font-family: var(--font-body);
}

.fld input,
.fld select,
.fld textarea {
    width: 100%;
    padding: 10px 12px;
    border: 2px solid var(--ink);
    background: var(--card);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 15px;
}

.fld input.mono,
.fld select {
    font-family: var(--font-mono);
    font-size: 14px;
}

.btn {
    padding: 10px 18px;
    border: 2px solid var(--ink);
    background: var(--card);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 15px;
    cursor: pointer;
    box-shadow: 3px 3px 0 var(--ink);
}

.btn:hover {
    background: var(--ink);
    color: var(--paper);
}

.btn:active {
    transform: translate(2px, 2px);
    box-shadow: 1px 1px 0 var(--ink);
}

.btn.primary {
    background: var(--ink);
    color: var(--paper);
}

.btn.primary:hover {
    background: #173b53;
}

.btn.ghost {
    box-shadow: none;
}

.btn:disabled {
    opacity: .45;
    cursor: not-allowed;
    box-shadow: none;
}

.btnrow {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
}

.pv {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.pv button {
    padding: 8px 14px;
    border: 2px solid var(--ink);
    background: var(--card);
    font-family: var(--font-body);
    font-size: 14px;
    cursor: pointer;
}

/* ============================================================
   14. หน้าต่างแชต ลอยขึ้นมาจากมุมล่างขวา เหนือปุ่มแชตพอดี
   ไม่ใช้ .ov เพราะแชตต้องเปิดค้างไว้ได้ขณะเลื่อนสไลด์ ห้ามมีพื้นหลังคลุมจอ
   ขนาดตัวอักษรในบล็อกนี้ไม่ใช้ตัวคูณ --fs เพราะแผงลอยอยู่นอกเวที
   ============================================================ */
.chatp {
    position: fixed;
    inset-inline-end: 18px;
    inset-block-end: 88px;
    z-index: 3100;
    width: min(430px, calc(100vw - 36px));
    height: min(760px, calc(100vh - 130px));
    display: none;
    flex-direction: column;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule);
    box-shadow: 0 14px 34px rgba(15, 42, 61, .4);
    font-family: var(--font-body);
    overflow: hidden;
}

.chatp.show {
    display: flex;
}

.chatp .ov-head {
    flex: none;
}

.chatp .ov-body {
    flex: 1 1 auto;
    min-height: 0;
}

.chatp .ov-foot {
    flex: none;
}

.scope {
    display: flex;
    gap: 6px;
    margin-bottom: 12px;
}

.scope button {
    flex: 1 1 auto;
    padding: 8px 10px;
    border: 2px solid var(--ink);
    background: var(--card);
    font-family: var(--font-body);
    font-size: 14px;
    cursor: pointer;
}

.scope button.on {
    background: var(--ink);
    color: var(--paper);
}

.ctx-here {
    font-family: var(--font-body);
    font-size: 13px;
    color: var(--muted);
    margin-bottom: 12px;
}

.msg {
    margin-bottom: 14px;
    font-size: 15px;
    line-height: 1.72;
}

.msg .who {
    display: block;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    color: var(--muted);
    margin-bottom: 3px;
}

.msg.me .bub {
    background: var(--c2-soft);
    border-inline-start: 3px solid var(--c2-deep);
    padding: 10px 14px;
}

.msg.ai .bub {
    background: var(--card);
    border: 1px solid var(--line);
    padding: 12px 16px;
}

.msg.ai .bub p {
    font-size: 15px;
    line-height: 1.72;
    margin: 0 0 .6em;
}

.msg.ai .bub p:last-child {
    margin-bottom: 0;
}

.msg.ai .bub ul,
.msg.ai .bub ol {
    margin: .4em 0;
    padding-inline-start: 1.3em;
}

.msg.ai .bub li {
    font-size: 15px;
    line-height: 1.72;
}

.chat-starter {
    display: block;
    width: 100%;
    text-align: start;
    padding: 9px 13px;
    border: 1px solid var(--line);
    background: var(--card);
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.56;
    cursor: pointer;
    color: var(--ink);
}

.chat-starter:hover {
    border-color: var(--ink);
    background: var(--c2-soft);
}

.muted-s {
    color: var(--muted);
    font-size: 13px;
    line-height: 1.6;
}

.chat-in {
    display: flex;
    gap: 8px;
}

.chat-in textarea {
    flex: 1 1 auto;
    resize: none;
    min-height: 46px;
}

/* ---- ผิวของการตอบแบบทยอยพิมพ์ ----
   ถ้าไม่มีบล็อกนี้ ระบบยังทำงานได้ แค่ไม่มีจุดกะพริบและเคอร์เซอร์ */
.typing-dots {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 0;
}

.typing-dots span {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c1);
    opacity: .35;
    animation: chatDot 1.05s infinite ease-in-out;
}

.typing-dots span:nth-child(2) {
    animation-delay: .16s;
}

.typing-dots span:nth-child(3) {
    animation-delay: .32s;
}

@keyframes chatDot {

    0%,
    70%,
    100% {
        opacity: .3;
        transform: translateY(0);
    }

    35% {
        opacity: 1;
        transform: translateY(-4px);
    }
}

.stream-cursor {
    display: inline-block;
    width: 2px;
    height: 1em;
    margin-inline-start: 2px;
    vertical-align: text-bottom;
    background: var(--c1);
    animation: chatCaret .85s step-end infinite;
}

@keyframes chatCaret {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0;
    }
}

/* ฟองคำตอบระหว่างที่ยังพิมพ์ไม่จบ แยกให้เห็นว่าต่างจากคำตอบที่จบแล้ว */
.msg-streaming {
    border-inline-start: 3px solid var(--c1);
    padding-inline-start: 10px;
}

.chat-stop {
    background: var(--out-deep) !important;
    color: var(--paper) !important;
    border-color: var(--out-deep) !important;
}

.chat-stop:hover {
    filter: brightness(1.12);
}

.chat-regen {
    display: block;
    margin: 10px auto 2px;
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.56;
    color: var(--ink);
    background: transparent;
    border: 1.5px dashed var(--line);
    padding: 7px 16px;
    min-height: 36px;
    cursor: pointer;
}

.chat-regen:hover {
    background: var(--c2-soft);
    border-color: var(--ink);
}

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

    .typing-dots span,
    .stream-cursor {
        animation: none;
    }

    .stream-cursor {
        opacity: 1;
    }
}

/* ============================================================
   14ก. ★ กันขนาดตัวอักษรของเวทีรั่วเข้าแผงลอย เพิ่ม 11 กันยายน 2569

   ที่มาของบล็อกนี้ deck.css ตั้งขนาดไว้ที่ตัวเลือกระดับอิลิเมนต์ เช่น p, li, th, td
   โดยผูกกับตัวคูณ --fs ซึ่งคิดจากเวที 1920px
   หัวข้อ 14 ประกาศไว้ว่าแผงแชตไม่ใช้ตัวคูณนั้น แต่เขียนกฎครอบไว้เพียง p, ul, ol, li
   ตัวกรอง HTML ใน ai.js อนุญาต 14 แท็ก จึงมีแท็กที่ไม่มีกฎครอบและไหลไปรับขนาดของเวที
   อาการที่พบจริงคือตารางในคำตอบของแชตขึ้นมาที่ 26px คูณ --fs ในแผงกว้าง 430px

   บล็อกนี้ **เพิ่มกฎใหม่อย่างเดียว ไม่แก้กฎเดิมแม้แต่บรรทัดเดียว**
   และจำกัดขอบเขตอยู่ในแผงลอยสองแผงเท่านั้น คือ .chatp กับ .ov-panel ไม่แตะสไลด์
   ============================================================ */

/* 14ก.1 ตารางในคำตอบของแชตและในหน้าต่างตั้งค่า
   ★ ใช้ display block คู่กับ overflow-x auto เพราะตารางสี่คอลัมน์ในแผงกว้าง 430px
     ต่อให้ลดขนาดตัวอักษรแล้วก็ยังบีบจนอ่านไม่ออก การให้เลื่อนแนวนอนอ่านง่ายกว่าการบีบ */
.chatp table,
.ov-panel table {
    display: block;
    overflow-x: auto;
    max-width: 100%;
    margin: 10px 0;
    border-collapse: collapse;
}

.chatp th,
.chatp td,
.ov-panel th,
.ov-panel td {
    font-size: 13.5px;
    line-height: 1.55;
    padding: 7px 9px;
    white-space: normal;
    min-width: 7.5em;
}

.chatp th,
.ov-panel th {
    font-size: 13px;
}

/* 14ก.2 หัวข้อย่อยในคำตอบ กฎ h1 ถึง h4 ให้เฉพาะแบบอักษรกับน้ำหนัก ไม่ได้ให้ขนาด
   h4 จึงเท่ากับตัวเนื้อความพอดี และมองไม่ออกว่าเป็นหัวข้อ */
.chatp h4,
.ov-panel h4 {
    font-size: 16px;
    line-height: 1.5;
    margin: 1em 0 .35em;
}

.chatp h4:first-child,
.ov-panel h4:first-child {
    margin-top: 0;
}

/* 14ก.3 ปุ่มกากบาทของแผงแชต กฎเดิมผูกกับ .ov ซึ่งแผงแชตไม่ได้ใช้โดยเจตนา */
.chatp .x {
    background: transparent;
    border: 0;
    font-size: 24px;
    cursor: pointer;
    color: var(--muted);
    line-height: 1;
    padding: 4px 8px;
}

.chatp .x:hover {
    color: var(--ink);
}

/* 14ก.4 ช่องพิมพ์คำถาม กฎที่ให้ขนาดและกรอบคือ .fld textarea ซึ่งผูกกับ .fld */
.chat-in textarea {
    padding: 9px 11px;
    border: 2px solid var(--ink);
    background: var(--card);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 15px;
    line-height: 1.5;
}

.chat-in textarea:focus-visible {
    outline: 2px solid var(--c2-deep);
    outline-offset: 1px;
}

/* 14ก.5 ย่อหน้าที่ไม่มีคลาสในหน้าต่างตั้งค่า เช่นข้อความแจ้งข้อผิดพลาด
   ★ ต้องใช้ :not([class]) ถ้าเขียน .ov-panel p เฉย ๆ จะมีความจำเพาะสูงกว่า .muted-s
     แล้วไปทับขนาด 13px ของข้อความกำกับทั้งหมดในหน้าต่างนี้ ซึ่งเป็นผลข้างเคียงที่มองไม่เห็น
   ★ ค่า line-height ต้องเท่ากับ 1.72 ของ .msg.ai .bub p เป๊ะ ๆ
     เพราะสองกฎนี้ความจำเพาะเท่ากัน กฎนี้อยู่หลังจึงชนะ ถ้าตั้งค่าต่างกันย่อหน้าคำตอบจะขยับ */
.ov-panel p:not([class]),
.chatp p:not([class]) {
    font-size: 15px;
    line-height: 1.72;
}

/* ============================================================
   15. บล็อกผลลัพธ์ AI และแถบตรวจ เส้นประคือสัญญะว่ายังไม่ผ่านการตรวจ
   ============================================================ */
.ai-block {
    border: 2px solid var(--ink);
    background: var(--card);
    margin-top: 14px;
}

.ai-block__head {
    padding: 9px 14px;
    border-bottom: 1px solid var(--line);
    display: flex;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
}

.ai-block__meta {
    /* ชื่อบอตเป็นภาษาไทย ใช้ฟอนต์ไทย */
    font-family: var(--font-body);
    font-size: 13px;
    color: var(--muted);
}

.ai-block__body {
    padding: 14px 16px;
    font-size: 15px;
    line-height: 1.72;
}

.ai-block__body p,
.ai-block__body li {
    font-size: 15px;
    line-height: 1.72;
}

.ai-block__body table {
    margin-top: 8px;
}

.ai-block__body th,
.ai-block__body td {
    font-size: 14px;
    line-height: 1.56;
    padding: 8px 10px;
}

.verify {
    margin: 0 16px 16px;
    border: 2px dashed var(--out);
    background: var(--out-soft);
    padding: 12px 14px;
}

.verify.done {
    border-style: solid;
    border-color: var(--guard);
    background: var(--guard-soft);
}

.verify__head {
    font-size: 13px;
    line-height: 1.6;
    margin: 0 0 9px;
    color: var(--out-deep);
    font-weight: 600;
}

.verify.done .verify__head {
    color: var(--guard-deep);
}

.verify__opts {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.verify__opt {
    padding: 6px 11px;
    border: 1px solid var(--ink);
    background: var(--card);
    font-family: var(--font-body);
    font-size: 13px;
    cursor: pointer;
}

.verify__opt[aria-pressed="true"] {
    background: var(--ink);
    color: var(--paper);
}

.notice {
    border: 2px solid var(--ink);
    background: var(--card);
    padding: 14px 16px;
    font-size: 14px;
    line-height: 1.62;
}

.notice--danger {
    border-color: var(--out);
    background: var(--out-soft);
}

/* ★ กล่องเดียวกันนี้ถูกใช้สองที่ ซึ่งต้องการขนาดคนละอย่าง
   ในแผงลอยนอกเวที เช่น หน้าต่างแชต ขนาด 14px แบบดิบถูกต้องแล้ว เพราะไม่ได้ถูกย่อขยายตามเวที
   แต่บนสไลด์ กล่องนี้เคยเป็น 14px ดิบเหมือนกัน จึงเล็กกว่ากล่อง .note ที่อยู่ข้าง ๆ เกือบครึ่ง
   และไม่ตอบสนองปุ่มย่อขยายตัวอักษรเลย เพราะไม่ได้ผูกกับ --fs
   กฎนี้จึงแก้เฉพาะกล่องที่อยู่บนสไลด์ โดยไม่แตะนิยามเดิมที่แผงลอยใช้อยู่ */
.slide .notice {
    padding: 22px 26px;
    font-size: var(--size-small);
    line-height: 1.66;
}

.slide .notice strong {
    display: inline-block;
    margin-bottom: 4px;
}

/* ============================================================
   16. โหมดแก้ข้อความหน้างาน
   ============================================================ */
[contenteditable="true"] {
    outline: 2px dashed var(--c2);
    outline-offset: 3px;
    background: var(--c2-soft);
}

/* ============================================================
   17. กิจกรรมโต้ตอบบนสไลด์ หน้าเหล่านี้จัดพื้นที่เอง
   deck.js จะข้ามการย่ออัตโนมัติให้สองคลาสนี้
   ============================================================ */
.ix-pad,
.demo-pad {
    justify-content: flex-start;
    padding-top: 24px;
}

.ix-btn {
    padding: 10px 20px;
    border: 2px solid var(--ink);
    background: var(--card);
    font-family: var(--font-body);
    font-size: var(--size-small);
    cursor: pointer;
    box-shadow: 3px 3px 0 var(--ink);
}

.ix-btn:hover {
    background: var(--ink);
    color: var(--paper);
}

.ix-btn:active {
    transform: translate(2px, 2px);
    box-shadow: 1px 1px 0 var(--ink);
}

.ix-btn.ghost {
    box-shadow: none;
}

.ix-btn:disabled {
    opacity: .45;
    cursor: not-allowed;
    box-shadow: none;
}

.ix-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* ============================================================
   18. เข้าถึงได้
   ============================================================ */
:focus-visible {
    outline: 3px solid var(--c4);
    outline-offset: 3px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
   19. ชั้นความเข้ากันได้กับสไลด์บรรยายหกชุดแรก

   สไลด์ 78 หน้าในโฟลเดอร์ slides ถูกเขียนขึ้นก่อนการยกเครื่องยนต์
   จึงใช้คำศัพท์คลาสอีกชุดหนึ่งที่ระบบสีใหม่ยังไม่มีนิยาม
   บล็อกนี้เติมนิยามที่ขาดโดยแปลงค่าเข้าโทเคนชุดใหม่ทุกตัว

   ชื่อคลาสในบล็อกนี้ถือว่าเลิกใช้แล้ว
   สไลด์ที่สร้างใหม่ทุกชุดให้ใช้คำศัพท์ในหัวข้อ 5 ถึง 10 เท่านั้น
   ============================================================ */

/* 19.1 นามแฝงของสีเดิม แปลงเข้าชุดห้าสีใหม่ */
:root {
    --vermillion: var(--c5);
    --teal: var(--c3);
    --gold: var(--c4);
    --gold-bright: #f2c45a;
    --ink-2: var(--muted);
}

/* 19.2 ชั้นเปิดเผยทีละส่วน เครื่องยนต์ใหม่ไม่มีการเปิดเผยทีละขั้น
   นิยามไว้เพื่อกันการซ่อนโดยไม่ตั้งใจ ถ้าภายหลังมีสไตล์ชีตอื่นมาซ่อน */
.reveal {
    opacity: 1;
    transform: none;
}

/* 19.3 พื้นหน้ากระดาษ ค่าเดียวกับพื้นฐาน จึงเป็นการประกาศไว้ให้ครบ */
.slide.s-paper {
    background: var(--paper);
}

/* 19.4 ตัวเลขลอยมุมล่างขวาของหน้าคั่นช่วง */
.numeral {
    position: absolute;
    inset-block-end: 96px;
    inset-inline-end: 84px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: calc(300px * var(--fs));
    line-height: 1;
    letter-spacing: -.04em;
    font-variant-numeric: tabular-nums;
    color: rgba(245, 239, 227, .10);
    pointer-events: none;
    user-select: none;
}

.slide:not(.s-dark) .numeral {
    color: rgba(15, 42, 61, .07);
}

/* 19.5 เส้นคั่นสั้นใต้หัวเรื่องของหน้าคั่นช่วง */
.rule {
    width: 190px;
    height: 8px;
    background: var(--gold-bright);
}

.slide:not(.s-dark) .rule {
    background: var(--c4);
}

/* 19.6 รายการมีลำดับและรายการขีด */
/* ★ font-size ของ ol ต้องเท่ากับ li เพื่อให้ em ของช่องเยื้องคิดจากขนาดเดียวกับหมายเลข
   เดิม 1.35em คิดจากตัวอักษรที่เล็กกว่า หมายเลขจึงล้นซ้ายและถูก .slide-pad (overflow hidden) ตัดทิ้ง */
.steps {
    margin: 0;
    font-size: var(--size-body);
    padding-inline-start: 2.1em;
}

.steps>li {
    font-size: var(--size-body);
    line-height: 1.6;
    margin-block-end: 18px;
    padding-inline-start: .35em;
}

.steps>li::marker {
    font-family: var(--font-mono);
    color: var(--label);
}

.dash {
    margin: 0;
    padding: 0;
    list-style: none;
}

.dash>li {
    position: relative;
    padding-inline-start: 1.5em;
    font-size: var(--size-small);
    line-height: 1.6;
    margin-block-end: 14px;
}

.dash>li::before {
    content: '';
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: .72em;
    width: 15px;
    height: 2.5px;
    background: var(--label);
}

.s-dark .dash>li::before {
    background: var(--gold-bright);
}

/* 19.7 ประโยคยกเน้น สองสีตามรหัสสองสีที่ล็อกไว้ */
.pull {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: calc(44px * var(--fs));
    /* ตัวแสดง 44px เท่ากับ .lead จึงใช้ความสูงบรรทัดชุดเดียวกัน */
    line-height: 1.35;
    border-inline-start: 10px solid var(--ink);
    padding: 10px 0 10px 30px;
    text-wrap: balance;
}

.s-dark .pull {
    border-inline-start-color: rgba(245, 239, 227, .5);
}

.pull.gold {
    border-inline-start-color: var(--c4);
}

.s-dark .pull.gold {
    border-inline-start-color: var(--gold-bright);
}

.pull.teal {
    border-inline-start-color: var(--guard);
}

.s-dark .pull.teal {
    border-inline-start-color: #5fd0c4;
}

/* 19.8 แผนภูมิแท่งแนวนอน หัวข้อ 9 มีเฉพาะรางกับแท่ง บล็อกนี้เติมแถวและป้าย */
.bars {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.bar-row {
    display: grid;
    grid-template-columns: 210px 1fr 130px;
    align-items: center;
    gap: 18px;
}

.bar-lab {
    font-size: var(--size-small);
    line-height: 1.6;
}

.bar-val {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: calc(26px * var(--fs));
    line-height: 1.6;
    text-align: end;
}

.s-dark .bar-track {
    background: rgba(245, 239, 227, .16);
}

.bar-fill.zero {
    background: var(--muted);
}

.bar-fill.neg {
    background: var(--out);
}

/* 19.9 แถบตำแหน่งหกขั้นแบบเดิม หัวข้อ 9 มีเฉพาะ move, mv-t และ mv-s */
.moves {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 16px;
}

.move .mv-n {
    font-family: var(--font-body);
    font-size: var(--size-label);
    color: var(--muted);
    line-height: 1.5;
}

.s-dark .move {
    background: rgba(245, 239, 227, .06);
    border-color: rgba(245, 239, 227, .34);
    color: var(--paper);
    box-shadow: none;
}

.s-dark .move .mv-n,
.s-dark .move .mv-s {
    color: rgba(245, 239, 227, .66);
}

/* 19.10 ป้ายสีที่ยังขาด */
.tag.warn {
    border-color: var(--c4);
    color: var(--c4-deep);
    background: var(--c4-soft);
}

.tag.gold {
    border-color: var(--c4);
    color: var(--c4-deep);
    background: var(--c4-soft);
}

.tag.teal {
    border-color: var(--guard);
    color: var(--guard-deep);
    background: var(--guard-soft);
}

.s-dark .tag {
    background: rgba(245, 239, 227, .08);
    color: var(--paper);
    border-color: rgba(245, 239, 227, .45);
}

.s-dark .tag.out {
    color: #f4a7b2;
    border-color: #f09aa6;
}

.s-dark .tag.in {
    color: #79dccf;
    border-color: #5fd0c4;
}

.s-dark .tag.warn,
.s-dark .tag.gold {
    color: var(--gold-bright);
    border-color: var(--gold-bright);
}

/* 19.11 กล่องสถิติแบบเดิม ใช้ n เป็นตัวเลขและ k เป็นคำบรรยาย
   สลับกับหัวข้อ 7 ซึ่งใช้ v เป็นตัวเลข จึงต้องกำหนดแยก */
.stat .n {
    font-family: var(--font-display);
    font-size: calc(106px * var(--fs));
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.s-dark .stat {
    background: rgba(245, 239, 227, .06);
    border-color: rgba(245, 239, 227, .34);
    color: var(--paper);
    box-shadow: none;
}

.s-dark .stat .k {
    color: rgba(245, 239, 227, .68);
}

/* 19.12 ช่องตารางจัดกึ่งกลาง */
th.c,
td.c {
    text-align: center;
}

/* 19.13 แถวตารางเน้น บนหน้าพื้นเข้ม */
.s-dark tr.hi td {
    background: rgba(242, 196, 90, .16);
}
/* ============================================================
   20. ส่วนเพิ่มของโครงการก่อนหน้า (พื้นหน้าเข้มถูกแทนที่ในส่วนที่ 24)
   เพิ่มกฎใหม่ล้วน ไม่แก้กฎเดิม
   ============================================================ */
.slide.s-dark {
    background-image:
        linear-gradient(rgba(245, 239, 227, .06) 1.2px, transparent 1.2px),
        linear-gradient(90deg, rgba(245, 239, 227, .06) 1.2px, transparent 1.2px),
        linear-gradient(rgba(245, 239, 227, .03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(245, 239, 227, .03) 1px, transparent 1px);
    background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
}
/* เส้นตรงสั้นใต้หัวเรื่องของหน้าปกและหน้าคั่น แทนเส้นโค้งเดิม ความสูงรวมใกล้ของเดิม หน้าจึงไม่ขยับ */
.title-rule { flex: none; width: 120px; height: 4px; background: var(--c3); margin: 40px 0 48px; }
/* ป้ายขั้น GPAS */
.st { display: inline-flex; align-items: center; justify-content: center; font-family: var(--font-body); font-weight: 600; font-size: var(--size-label); color: #fff; padding: 4px 14px; min-width: 56px; border-radius: 999px; }
.st-G { background: var(--st-g-deep); } .st-P { background: var(--st-p-deep); } .st-A1 { background: var(--st-a1-deep); } .st-A2 { background: var(--st-a2-deep); } .st-S { background: var(--st-s-deep); } .st-ink { background: var(--ink); }
.s-dark .st-ink { background: var(--paper); color: var(--ink); }
.card.bt-G { border-top: 12px solid var(--st-g); } .card.bt-P { border-top: 12px solid var(--st-p); } .card.bt-A1 { border-top: 12px solid var(--st-a1); } .card.bt-A2 { border-top: 12px solid var(--st-a2); } .card.bt-S { border-top: 12px solid var(--st-s); } .card.bt-ink { border-top: 12px solid var(--ink); }
.gpas5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: 20px; }
.gpas5 .card h3 { font-size: var(--size-h3); }
.gpas5 .card .en { font-family: var(--font-mono); font-size: var(--size-label); color: var(--muted); margin: 6px 0 10px; }
/* ตัวเลขใหญ่ */
.bignum { font-family: var(--font-display); font-weight: 700; font-size: calc(56px * var(--fs)); line-height: 1.3; }
.bignum.g { color: var(--st-g-deep); } .bignum.out { color: var(--out-deep); }
/* กล่องห้าม AI และกล่อง guardrail */
.noai-box { border: 3px dashed var(--out-deep); background: var(--out-soft); padding: 18px 22px; font-size: var(--size-small); line-height: 1.6; }
.noai-box .lbl, .guard-box .lbl { font-family: var(--font-body); font-size: var(--size-label); font-weight: 600; }
.noai-box .lbl { color: var(--out-deep); }
.guard-box { border: 3px solid var(--guard-deep); background: var(--guard-soft); padding: 18px 22px; font-size: var(--size-small); line-height: 1.6; }
.guard-box .lbl { color: var(--guard-deep); }
/* แถบเวลาและ QR บนสไลด์ */
.timer { display: inline-flex; align-items: center; gap: 14px; border: 2.5px solid var(--ink); background: var(--card); padding: 8px 16px; }
.timer .t { font-family: var(--font-mono); font-weight: 600; font-size: calc(36px * var(--fs)); min-width: 150px; text-align: center; }
.timer.done .t { color: var(--out-deep); }
.timer button { font-family: var(--font-body); font-size: var(--size-small); border: 2px solid var(--ink); background: var(--paper); padding: 6px 14px; cursor: pointer; }
.s-dark .timer { background: rgba(245, 239, 227, .08); border-color: rgba(245, 239, 227, .6); }
.s-dark .timer button { background: transparent; color: var(--paper); border-color: rgba(245, 239, 227, .6); }
.qr { background: #fff; padding: 12px; border: 2.5px solid var(--ink); display: inline-block; line-height: 0; }
.qr svg { width: 230px; height: 230px; }
.qr-cap { font-family: var(--font-mono); font-size: var(--size-label); margin-top: 8px; word-break: break-all; }
/* แผงสาธิต */
.dm { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr); }
.dm .panel { border: 2.5px solid var(--ink); background: var(--card); padding: 18px 20px; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.dm .panel h3 { margin: 0; }
.dm textarea, .dm input[type=text], .dm select { width: 100%; max-width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: var(--size-small); border: 2px solid var(--line); background: #fff; padding: 10px 12px; color: var(--ink); }
.dm textarea { min-height: 110px; resize: vertical; }
/* ช่องคำถามของหน้าสาธิต A0 และ A1 (ย้ายจาก style ในบรรทัด) */
.demo-q { flex: 1 1 900px; min-width: 0; font-family: var(--font-body); font-size: var(--size-small); padding: 10px 12px; border: 2px solid var(--line); background: #fff; color: var(--ink); }
/* ปุ่มลิงก์แทน QR แสดงเฉพาะโหมดอ่าน ดูส่วนที่ 22 */
.qr-link { display: none; }
.dm .out { flex: 1 1 auto; min-height: 0; overflow-y: auto; font-size: var(--size-small); }
.sorter { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; font-size: var(--size-small); }
.sorter .row { background: var(--card); border: 2px solid var(--line); padding: 8px 14px; display: flex; flex-direction: column; gap: 6px; }
.sorter .it { line-height: 1.35; }
.sorter .bs { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px; }
.sorter button { font-family: var(--font-mono); font-weight: 600; font-size: var(--size-label); border: 2px solid var(--ink); background: var(--paper); padding: 4px 8px; cursor: pointer; min-width: 52px; min-height: 40px; flex: none; }
.sorter button[aria-pressed="true"] { color: #fff; }
.sorter button.bG[aria-pressed="true"] { background: var(--st-g-deep); } .sorter button.bP[aria-pressed="true"] { background: var(--st-p-deep); } .sorter button.bA1[aria-pressed="true"] { background: var(--st-a1-deep); } .sorter button.bA2[aria-pressed="true"] { background: var(--st-a2-deep); } .sorter button.bS[aria-pressed="true"] { background: var(--st-s-deep); }
.sorter .fb { flex: 1 1 auto; margin-left: 8px; font-size: var(--size-tiny); color: var(--muted); line-height: 1.3; }
.sorter .fb.ok { color: var(--guard-deep); } .sorter .fb.no { color: var(--out-deep); }
.cycle { display: grid; grid-template-columns: repeat(7, 1fr); gap: 12px; }
.cycle .c { border: 2.5px solid var(--ink); background: var(--card); padding: 14px; }
.cycle .c.ai { border-style: dashed; background: var(--paper); }
.cycle .c .n { font-family: var(--font-body); font-weight: 600; font-size: var(--size-label); color: var(--muted); }
.cycle .c strong { display: block; font-family: var(--font-display); font-size: var(--size-small); line-height: 1.4; margin: 4px 0; }
.cycle .c .en { font-family: var(--font-mono); font-size: calc(20px * var(--fs)); color: var(--muted); line-height: 1.5; }
.cycle .c .who { margin-top: 8px; font-weight: 600; font-size: var(--size-tiny); }
.tree-s { font-family: var(--font-mono); font-size: var(--size-small); background: #fff; border: 2.5px solid var(--ink); padding: 18px 22px; white-space: pre; line-height: 1.6; }

/* 21. ขนาดตัวอักษรของผลลัพธ์ AI บนเวที 1920x1080 ใช้บันไดขนาดเดียวกับสไลด์ ปรับตาม --fs ได้ */
.slide .ai-block__meta { font-size: var(--size-label); }
.slide .ai-block__body,
.slide .ai-block__body p,
.slide .ai-block__body li { font-size: var(--size-tiny); line-height: 1.6; }
.slide .ai-block__body th,
.slide .ai-block__body td { font-size: var(--size-label); padding: 6px 10px; }
.slide .ai-block .btn { font-size: var(--size-label); }
.slide .verify__head { font-size: var(--size-label); }
.slide .verify__opt { font-size: var(--size-label); padding: 6px 12px; min-height: 40px; }
.slide .notice { font-size: var(--size-tiny); }

/* ============================================================
   23. จังหวะแนวตั้งและตำแหน่งหัวข้อ (2 ตุลาคม 2569 docs/handoff/02-DESIGN-SYSTEM.md ข้อ 3.3 และ 9.2)
   ใช้เฉพาะบนเวที (html:not(.reading)) โหมดอ่านบนมือถือมีกฎของตัวเองในส่วนที่ 22
   หลัก ใกล้กันในกลุ่ม ห่างกันระหว่างกลุ่ม ระยะทั้งหมดมาจากกฎชุดนี้ ไม่เขียน margin ในตัวใน build_decks.py
     ป้ายนำถึงหัวข้อ 12   หัวข้อถึงเนื้อหา 40   ระหว่างบล็อก 28   คำอธิบายใต้บล็อก 14
     ภายในการ์ด 12   ป้ายของกล่องถึงข้อความ 8   ระหว่างการ์ดในตาข่าย 28
   ============================================================ */
:root { --gap-eyebrow: 12px; --gap-title: 40px; --gap-block: 28px; --gap-caption: 14px; --gap-in: 12px; --gap-lbl: 8px; }

/* 23.1 หัวข้อตรึงที่ด้านบนของพื้นที่เนื้อหาทุกหน้าพื้นสว่าง ตำแหน่งเดียวกับหน้าสาธิต (ส่วนที่ 17)
   หน้าคั่นพื้นเข้มยังจัดกึ่งกลางตามเดิม */
html:not(.reading) .slide:not(.s-dark) .slide-pad { justify-content: flex-start; padding-top: 24px; }

/* 23.2 ลูกโดยตรงของพื้นที่เนื้อหา ไม่มี margin ของตัวเอง (ทุกหน้า ทั้งพื้นสว่างและพื้นเข้ม) */
html:not(.reading) .slide .slide-pad > * { margin-top: 0; margin-bottom: 0; }
html:not(.reading) .slide .slide-pad > * + * { margin-top: var(--gap-block); }
html:not(.reading) .slide .slide-pad > :is(.eyebrow, .kicker) + * { margin-top: var(--gap-eyebrow); }
html:not(.reading) .slide .slide-pad > :is(h1, h2) + * { margin-top: var(--gap-title); }
/* ข้อความรองที่ตามหัวข้อทันทีอยู่ชิดหัวข้อ เนื้อหาถัดไปจึงเว้นเท่าระยะหัวข้อ */
html:not(.reading) .slide .slide-pad > h2 + p { margin-top: 16px; }
html:not(.reading) .slide .slide-pad > h2 + p + * { margin-top: var(--gap-title); }
/* เส้นสั้นใต้หัวเรื่องของหน้าปกและหน้าคั่น คงระยะเดิม 40 และ 48 */
html:not(.reading) .slide .slide-pad > .title-rule { margin-top: 40px; }
html:not(.reading) .slide .slide-pad > .title-rule + * { margin-top: 48px; }
/* คำอธิบาย อ้างอิง และหมายเหตุใต้บล็อก อยู่ชิดสิ่งที่อธิบาย */
html:not(.reading) .slide .slide-pad > :not(h1, h2, .eyebrow, .kicker, .title-rule) + p:is(.small, .tiny) { margin-top: var(--gap-caption); }
/* หน้าสาธิตจัดพื้นที่ด้วย flex เอง ระยะหลังหัวข้อจึงสั้นกว่า เพื่อให้แผงสาธิตได้พื้นที่มากที่สุด */
html:not(.reading) .slide .slide-pad:is(.demo-pad, .ix-pad) > * + * { margin-top: 18px; }
html:not(.reading) .slide .slide-pad:is(.demo-pad, .ix-pad) > h2 + * { margin-top: 20px; }

/* 23.3 ประโยคสรุปท้ายหน้า (.lead ที่ไม่ได้อยู่ใต้หัวข้อ) เล็กกว่าหัวข้อ 36px ตัวหนา มีเส้นนำซ้าย
   .lead ขนาด 44px ใช้เฉพาะข้อความนำใต้หัวเรื่องของหน้าคั่น */
.slide:not(.s-dark) .lead { font-size: var(--size-h3); line-height: 1.4; }
.slide .slide-pad > :not(h1, h2, .title-rule, .eyebrow, .kicker) + .lead {
    font-family: var(--font-display); font-weight: 600; font-size: var(--size-h3); line-height: 1.4;
    border-inline-start: 6px solid var(--ink); padding-inline-start: 24px; max-width: none;
}
.slide.s-dark .slide-pad > :not(h1, h2, .title-rule, .eyebrow, .kicker) + .lead { border-inline-start-color: #f2c45a; }

/* 23.4 ข้อความในการ์ด การ์ดที่วางไม่เกิน 3 คอลัมน์ใช้ขนาดเนื้อความ 30px
   ตาข่าย 4 คอลัมน์ขึ้นไป หน้าแน่น (.dense) และวงรอบ 7 ขั้นคง 26px */
.slide-pad .card :is(p, li), .slide-pad .card p.small { font-size: var(--size-body); line-height: 1.6; }
.slide-pad :is(.g4, .gpas5, .dense, .cycle) .card :is(p, li), .slide-pad .dense .card p.small, .slide-pad.dense .card :is(p, li) { font-size: var(--size-small); }
.slide-pad .card p.tiny { font-size: var(--size-tiny); line-height: 1.55; }

/* 23.5 ภายในการ์ดและกล่อง ระยะค่าเดียว */
.slide .card > * { margin-top: 0; margin-bottom: 0; }
.slide .card > * + * { margin-top: var(--gap-in); }
.slide :is(.noai-box, .guard-box, .note) > * { margin-top: 0; margin-bottom: 0; }
.slide :is(.noai-box, .guard-box, .note) > * + * { margin-top: var(--gap-in); }
.slide :is(.noai-box, .guard-box) > .lbl + * { margin-top: var(--gap-lbl); }
.slide :is(.noai-box, .guard-box) > .lbl { display: block; line-height: 1.5; }
.slide th { line-height: 1.5; }
.slide .notice { line-height: 1.55; }
/* คอลัมน์ในตาข่ายที่ไม่มีกรอบ (div เปล่า) เรียงบล็อกด้วยระยะเดียว */
.slide .grid > :is(div:not([class]), div[class="reveal"]) > * { margin-top: 0; margin-bottom: 0; }
.slide .grid > :is(div:not([class]), div[class="reveal"]) > * + * { margin-top: 18px; }
.slide .grid > :is(div:not([class]), div[class="reveal"]) > * + p:is(.small, .tiny) { margin-top: var(--gap-caption); }
.grid { gap: var(--gap-block); }
.dense .grid { gap: 24px; }

/* 23.6 รายการ ระยะเยื้อง 2 ค่า รายการธรรมดา 1.3em และรายการมีหมายเลข (.steps) 2.1em ระยะระหว่างข้อ .45em */
.slide-pad :is(ol, ul):not(.steps, .dash, .rb-list) { padding-inline-start: 1.3em; margin: 0; }
.slide-pad :is(ol, ul):not(.steps, .dash, .rb-list) > li + li { margin-top: .45em; }
.steps > li { margin-block-end: 0; }
.steps > li + li, .dash > li + li { margin-top: .45em; }
.dash > li { margin-block-end: 0; padding-inline-start: 1.3em; }

/* รายการที่ตั้งขนาดไว้ที่ ol หรือ ul (.small .tiny) ให้ข้อในรายการใช้ขนาดนั้นจริง เดิม li ถูกกฎ p, li บังคับเป็น 30px */
.slide-pad :is(ol, ul).small > li { font-size: var(--size-small); line-height: 1.6; }
.slide-pad :is(ol, ul).tiny > li { font-size: var(--size-tiny); line-height: 1.55; }

/* 23.7 ชิ้นส่วนที่เคยเขียน style ในตัวใน build_decks.py */
.timer-row { display: flex; gap: 18px; align-items: center; }
.qr-box { text-align: center; }
.qr-box > .small { margin-top: 4px; }
.mw-1500 { max-width: 1500px; }
.ai-start { align-items: start; }
.ai-center { align-items: center; }
.code-box { margin: 0; white-space: pre-wrap; background: #fff; border: 2.5px solid var(--ink); padding: 16px 18px; font-family: var(--font-mono); }
.pre-wrap { white-space: pre-wrap; }
.on-dark { color: rgba(245, 239, 227, .9); }
.on-dark-2 { color: rgba(245, 239, 227, .85); }
.on-dark-3 { color: rgba(245, 239, 227, .75); }
.on-dark-4 { color: rgba(245, 239, 227, .7); }
.t-out { color: var(--out-deep); }
.t-guard { color: var(--guard-deep); }

/* 23.9 แถวปุ่มเปิดเครื่องมือภายนอก ไม่ใช้ในชุดนี้ (cbg-demos.js ส่วนเครื่องมือ, assets/dmt.js)
   บนเวทีกดปุ่มแล้วเปิดแผงทับทั้งจอ เพราะเครื่องมือในเวทีที่ถูกย่อด้วย transform รับตำแหน่งเมาส์คลาด
   ในโหมดอ่านซ่อนปุ่ม แสดงเครื่องมือในหน้าแทน ผู้อ่านกดโหลดเอง */
.tool-row { display: flex; flex-wrap: wrap; gap: 18px; align-items: center; }
.tool-btn {
    min-height: 56px;
    padding: 10px 24px;
    border: 2px solid var(--ink);
    background: var(--ink);
    color: var(--paper);
    font-family: var(--font-body);
    font-size: var(--size-small);
    font-weight: 600;
    cursor: pointer;
    box-shadow: 3px 3px 0 var(--out-deep);
}
.tool-btn:hover { transform: translate(-1px, -1px); }
.tool-btn:focus-visible { outline: 3px solid var(--out-deep); outline-offset: 3px; }
.tool-row > .small { flex: 1 1 400px; margin: 0; }
.tool-inline { display: none; flex-basis: 100%; }
html.reading .tool-btn { display: none; }
html.reading .tool-inline { display: block; }

/* 23.8 โหมดอ่าน ระยะแบบย่อชุดเดียวกัน */
html.reading .slide-pad > * + * { margin-top: 14px; }
html.reading .slide-pad > :is(.eyebrow, .kicker) + * { margin-top: 6px; }
html.reading .slide .card > * + *, html.reading .slide :is(.noai-box, .guard-box, .note) > * + * { margin-top: 8px; }
html.reading .slide :is(.noai-box, .guard-box) > .lbl + * { margin-top: 4px; }
html.reading .slide .slide-pad > :not(h1, h2, .title-rule, .eyebrow, .kicker) + .lead { font-size: 1.1rem; padding-inline-start: 12px; border-inline-start-width: 4px; }
html.reading .slide-pad .card :is(p, li) { font-size: var(--size-small); }

/* ============================================================
   22. โหมดอ่านบนมือถือ (docs/handoff/03-MOBILE-SPEC.md ข้อ 4)
   deck.js ใส่คลาส reading ที่ html เมื่อจอกว้าง 900px ลงไป หรือเมื่อผู้ใช้กดปุ่มโหมดอ่าน
   เลิกใช้เวที 1920x1080 ทุกหน้าเรียงลงเป็นเอกสารยาว กฎทั้งหมดอยู่ใต้ html.reading ไม่แก้บล็อกที่ 1
   ============================================================ */
html.reading,
html.reading body { height: auto; overflow: visible; background: var(--paper); }
html.reading body { padding-bottom: 84px; }
html.reading .deck-viewport { position: static; inset: auto; overflow: visible; }
html.reading .deck-stage { position: static; width: auto; height: auto; overflow: visible; transform: none !important; }

/* ขนาดตัวอักษร บันไดเดิมแทนด้วยค่า rem ทุกค่าไม่ต่ำกว่า 13px */
html.reading {
    --fs: .62;
    --size-h1: 1.9rem; --size-h2: 1.5rem; --size-h3: 1.2rem;
    --size-body: 1.05rem; --size-small: 1rem; --size-tiny: .92rem; --size-label: .84rem;
}
html.reading .slide {
    position: relative; inset: auto; width: auto; height: auto; min-height: 0; overflow: visible;
    visibility: visible; opacity: 1; pointer-events: auto; transition: none;
    border-bottom: 2.5px solid var(--ink);
    background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px;
    scroll-margin-top: 52px;
}
html.reading .slide.s-dark { background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px; }
html.reading .slide-pad {
    position: static; inset: auto; display: block; padding: 18px 16px 22px; overflow: visible; zoom: 1 !important;
}
html.reading .bar-top, html.reading .slide-head,
html.reading .bar-bot, html.reading .slide-foot { position: static; height: auto; min-height: 36px; padding: 8px 16px; gap: 10px; }
html.reading .bar-bot, html.reading .slide-foot { flex-wrap: wrap; }
html.reading .slide.is-scrollable::before,
html.reading .slide.is-scrollable::after { display: none; }

/* ทุกตาข่ายเหลือคอลัมน์เดียว (สำรวจครบ 4 ชุด: grid g2 g3 g4 g-2-1 gpas5 cycle dm sorter และ grid ที่ตั้งคอลัมน์ในบรรทัด) */
html.reading .grid, html.reading .g2, html.reading .g3, html.reading .g4, html.reading .g-2-1,
html.reading .gpas5, html.reading .cycle, html.reading .dm, html.reading .sorter {
    display: grid; grid-template-columns: 1fr !important; grid-template-rows: none; gap: 12px;
}
html.reading .card { padding: 14px 16px; box-shadow: 4px 4px 0 rgba(15, 42, 61, .16); }
html.reading .eyebrow, html.reading .kicker { gap: 10px; margin-bottom: 10px; }
html.reading .eyebrow::before, html.reading .kicker::before { width: 22px; height: 3px; }
html.reading .title-rule { width: 64px; height: 3px; margin: 18px 0 20px; }
html.reading .noai-box, html.reading .guard-box { padding: 12px 14px; }
html.reading .pull { padding: 6px 0 6px 16px; border-inline-start-width: 6px; }

/* ค่าที่เขียน calc(Npx * var(--fs)) ตรง ๆ */
html.reading .numeral { display: none; }
html.reading .big-num { font-size: 4rem; }
html.reading .stat .v, html.reading .stat .n { font-size: 2.4rem; }
html.reading .bignum { font-size: 1.9rem; }
html.reading .lead { font-size: 1.15rem; line-height: 1.55; }
html.reading .pull { font-size: 1.15rem; }
html.reading .cycle .c .en { font-size: var(--size-label); }

/* ของที่กว้างเกินจอ ให้เลื่อนในกล่อง */
html.reading .slide table { display: block; max-width: 100%; overflow-x: auto; }
html.reading .slide th, html.reading .slide td { padding: 8px 10px; }
html.reading .tree-s { overflow-x: auto; padding: 12px 14px; }
html.reading .slide img, html.reading .slide svg, html.reading .slide iframe { max-width: 100%; }

/* เครื่องมือของผู้บรรยาย ซ่อนในโหมดอ่าน (ตัวจับเวลาซ่อนทั้งกล่อง ข้อความข้างตัวจับเวลายังแสดง) */
html.reading .ctrl, html.reading #deckProgress, html.reading .timer, html.reading .fitbadge { display: none !important; }
html.reading .qr, html.reading .qr-cap { display: none; }
html.reading .qr-link {
    display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 8px 20px;
    border: 2px solid currentColor; font-family: var(--font-body); font-weight: 600; font-size: 1rem; color: inherit; text-decoration: none;
}
/* สาธิต AI สดต้องมีกุญแจ ซ่อนในโหมดอ่าน ปุ่มดูผลที่เตรียมไว้ยังใช้ได้ */
html.reading .ix-btn[id$="Run"] { display: none; }
html.reading .ix-btn { min-height: 44px; }
html.reading .demo-q { flex-basis: 100%; }
html.reading .dm .panel, html.reading .dm .out, html.reading .ix-scroll { max-height: none; overflow: visible; min-height: 0; }
/* เกมจัดขั้น GPAS แตะเลือกด้วยนิ้ว ปุ่มสูง 44px */
html.reading .sorter .bs { flex-wrap: wrap; }
html.reading .sorter button { min-height: 44px; min-width: 48px; }
html.reading .sorter .fb { flex-basis: 100%; margin-left: 0; }

/* แถบบนของโหมดอ่าน สร้างโดย deck.js */
.readbar { display: none; }
html.reading .readbar {
    display: flex; align-items: center; gap: 10px; position: sticky; top: 0; z-index: 3000;
    min-height: 52px; padding: 6px 12px 6px 16px; background: var(--ink); color: var(--paper); font-family: var(--font-body);
}
html.reading .readbar .rb-dot { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--c1); box-shadow: 0 0 0 4px rgba(217, 100, 43, .3); }
html.reading .readbar .rb-title { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 600; font-size: .95rem; }
html.reading .readbar summary,
html.reading .readbar .rb-btn {
    display: inline-flex; align-items: center; min-height: 40px; padding: 0 12px; border: 2px solid rgba(245, 239, 227, .6); border-radius: 999px;
    background: transparent; color: var(--paper); font: 600 .9rem var(--font-body); cursor: pointer; list-style: none; white-space: nowrap;
}
html.reading .readbar summary::-webkit-details-marker { display: none; }
html.reading .readbar details[open] summary { background: rgba(245, 239, 227, .16); }
html.reading .readbar .rb-list {
    position: absolute; left: 0; right: 0; top: 100%; margin: 0; padding: 6px 0 10px; list-style: none;
    max-height: 70vh; overflow-y: auto; background: var(--ink); border-top: 1px solid rgba(245, 239, 227, .18); box-shadow: 0 12px 24px rgba(15, 42, 61, .35);
}
html.reading .readbar .rb-list a { display: flex; align-items: center; min-height: 44px; padding: 6px 16px; color: var(--paper); text-decoration: none; font-size: .95rem; line-height: 1.4; }
html.reading .readbar .rb-list a:hover, html.reading .readbar .rb-list a:focus-visible { background: rgba(245, 239, 227, .12); }
html.reading .readbar .rb-list li:first-child a { color: #f2c45a; }
html.reading .hint { max-width: calc(100vw - 32px); }

/* แผงแชตและหน้าต่างตั้งค่าบนจอแคบ ใช้ทั้งสองโหมด */
@media (max-width: 600px) {
    .chatp { inset-inline: 0; inset-block-end: 0; width: 100%; height: 85vh; border-inline-width: 0; border-bottom-width: 0; }
    .ov { padding: 12px; }
    .ov-panel { width: calc(100vw - 24px); max-height: 90vh; }
}

/* ============================================================
   24. ธีม B สำหรับสไลด์ธาตุทอง (มติ Q1) เพิ่มกฎใหม่ล้วน
   พื้นหน้าเข้มไม่มีลายตาราง เส้นหนาใต้หัวเรื่อง เส้นสีทองใต้หัวเรื่องหน้าปก
   ============================================================ */
.slide.s-dark { background-image: none; }
.skin-label .slide:not(.s-dark) .slide-pad > h2 { border-bottom: 10px solid var(--ink); padding-bottom: 10px; }
.skin-label .title-rule { background: var(--c4); width: 220px; height: 10px; }
.qr.qr-wait { width: 254px; height: 254px; display: flex; align-items: center; justify-content: center; text-align: center; line-height: 1.4; font-family: var(--font-body); font-size: var(--size-label); color: var(--muted); border-style: dashed; padding: 16px; box-sizing: border-box; }
.health-note { border-left: 10px solid var(--c4); background: #fff; padding: 8px 14px; }
.s-dark .card { color: var(--ink); }
.skin-label .slide:not(.s-dark) { background-image: none !important; }
.skin-label .note { border: 2.5px solid var(--ink); border-left: 12px solid var(--c4); background: #fff; }
.skin-label .notice { border-radius: 0; }
/* รหัสหน้าในแถบล่าง ใช้อ้างอิงเวลาขอแก้รายหน้า (ดู docs/handoff/SLIDE-INDEX.md) */
.slide-foot .slide-code { font-family: var(--font-mono); font-size: var(--size-label); opacity: .75; margin-left: auto; margin-right: 24px; }
.en-inline { font-family: var(--font-mono); font-size: var(--size-small); font-weight: 400; color: var(--muted); }

/* ============================================================
   25. แม่แบบหน้า L1 ถึง L8 (4 ต.ค. 2569 แผน LAYOUT-PLAN-20261004 มติ L1 ถึง L8)
   ใช้กับหน้าที่มีคลาส .lay เท่านั้น ส่วน 1 ถึง 24 คงไว้เพื่อย้อนกลับได้
   ขนาดตัวอักษร เนื้อความ 34 หัวการ์ด 40 หัวข้อหน้า 60 ขั้นต่ำ 28 (เฉพาะอ้างอิงและป้าย)
   หัวข้ออยู่บน เนื้อหาจัดกลางในพื้นที่ที่เหลือ การ์ดในแถวเดียวกันสูงเท่ากันเสมอ
   ============================================================ */
:root {
    --v-h1: calc(80px * var(--fs)); --v-h2: calc(60px * var(--fs)); --v-big: calc(62px * var(--fs));
    --v-lead: calc(40px * var(--fs)); --v-h3: calc(40px * var(--fs)); --v-body: calc(34px * var(--fs));
    --v-small: calc(30px * var(--fs)); --v-min: calc(28px * var(--fs));
    --v-gap: 32px;
}
html.reading { --v-h1: 1.9rem; --v-h2: 1.5rem; --v-big: 1.45rem; --v-lead: 1.2rem; --v-h3: 1.15rem; --v-body: 1.05rem; --v-small: 1rem; --v-min: .92rem; --v-gap: 16px; }

html:not(.reading) .slide.lay .slide-pad { justify-content: flex-start; padding: 26px 0 26px; }
html:not(.reading) .slide.lay .slide-pad > * , html:not(.reading) .slide.lay .slide-pad > * + * { margin: 0; }
.slide.lay .slide-pad { color: var(--ink); }
.slide.lay :is(p, li, td, th, h1, h2, h3) { margin: 0; }

/* หัวหน้า */
.v-head { flex: none; }
.v-head .eyebrow { font-size: var(--v-min); margin: 0 0 10px; }
.slide.lay .v-head h2 { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h2); line-height: 1.22; padding-bottom: 18px; border-bottom: 6px solid var(--ink); max-width: none; }
.v-head h2 .en { font-family: var(--font-body); font-weight: 400; font-size: var(--v-small); color: var(--muted); margin-inline-start: 12px; }

/* เนื้อหา จัดกลางในพื้นที่ที่เหลือ */
.v-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--v-gap); margin-top: 34px; }
html.reading .v-body { margin-top: 14px; }
.v-src { flex: none; margin-top: 18px; font-size: var(--v-min); line-height: 1.45; color: var(--muted); }
.v-health { flex: none; margin-top: 16px; font-size: var(--v-min); line-height: 1.45; color: var(--muted); border-inline-start: 6px solid var(--c4); padding-inline-start: 16px; }
.v-health strong { color: var(--ink); }

/* แถวการ์ด ความสูงเท่ากัน */
.v-row { display: grid; gap: var(--v-gap); align-items: stretch; }
.v-row.c1 { grid-template-columns: 1fr; }
.v-row.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.v-row.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.v-row.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.v-row.c21 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.v-row.c12 { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
.v-label { font-family: var(--font-display); font-weight: 700; font-size: var(--v-small); color: var(--muted); margin-bottom: -14px; }

/* การ์ด */
.vc { background: var(--card); border: 2.5px solid var(--ink); box-shadow: var(--shadow); padding: 28px 32px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.vc > .vt { font-family: var(--font-body); font-weight: 600; font-size: var(--v-min); line-height: 1.3; align-self: flex-start; border: 2px solid currentColor; padding: 2px 12px; color: var(--muted); }
.vc h3 { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h3); line-height: 1.3; }
.vc p, .vc li { font-size: var(--v-body); line-height: 1.5; }
.vc .sm, .vc .sm li { font-size: var(--v-small); line-height: 1.5; }
.vc ul { margin: 0; padding-inline-start: 1.1em; }
.vc li + li { margin-top: 6px; }
.vc.k-G { border-top: 14px solid var(--st-g); } .vc.k-P { border-top: 14px solid var(--st-p); } .vc.k-A1 { border-top: 14px solid var(--st-a1); }
.vc.k-A2 { border-top: 14px solid var(--st-a2); } .vc.k-S { border-top: 14px solid var(--st-s); } .vc.k-ink { border-top: 14px solid var(--ink); }
.vc.k-out { border-top: 14px solid var(--out); } .vc.k-good { border-top: 14px solid var(--guard); }
.vc.hi { background: #fff; outline: 4px solid var(--out); outline-offset: -2px; }
.vc .big-n { font-family: var(--font-mono); font-weight: 700; font-size: var(--v-lead); line-height: 1.1; color: var(--ink); }
.vc.compact { padding: 22px 26px; gap: 8px; }
.vc.compact h3 { font-size: calc(36px * var(--fs)); }
html.reading .vc.compact h3 { font-size: var(--v-h3); }
.slide.lay .st { font-size: var(--v-min); padding: 4px 16px; vertical-align: middle; }

/* กล่องสรุป */
.v-call { background: #fff; border: 2.5px solid var(--ink); border-inline-start: 12px solid var(--ink); padding: 22px 30px; font-family: var(--font-display); font-weight: 600; font-size: var(--v-lead); line-height: 1.4; }
.v-call.gold { border-inline-start-color: var(--c4); }
.v-call.good { border-inline-start-color: var(--guard); background: var(--guard-soft); }
.v-call.out { border-inline-start-color: var(--out); background: var(--out-soft); }
.v-call.soft { font-family: var(--font-body); font-weight: 400; font-size: var(--v-body); line-height: 1.5; }
.v-call strong { font-weight: 700; }

/* แผงเปรียบเทียบ */
.vp { border: 2.5px solid var(--ink); padding: 26px 32px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.vp > .vl { font-family: var(--font-display); font-weight: 700; font-size: var(--v-small); }
.vp p, .vp li { font-size: var(--v-body); line-height: 1.5; }
.vp h3 { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h3); line-height: 1.3; }
.vp ul { margin: 0; padding-inline-start: 1.1em; }
.vp.bad { background: var(--out-soft); border-style: dashed; border-color: var(--out-deep); }
.vp.bad > .vl { color: var(--out-deep); }
.vp.good { background: var(--guard-soft); border-color: var(--guard-deep); }
.vp.good > .vl { color: var(--guard-deep); }
.vp.ex { background: var(--guard-soft); border-color: var(--guard-deep); }
.vp.ex > .vl { color: var(--guard-deep); }

/* L2 ประโยคเปิดใจ */
.v-quote { font-family: var(--font-display); font-weight: 700; font-size: var(--v-big); line-height: 1.35; max-width: 1600px; }
.v-quote-by { font-size: var(--v-small); color: var(--muted); margin-top: -10px; }

/* L5 ตาราง */
.v-tbl { width: 100%; border-collapse: collapse; background: var(--card); border: 2.5px solid var(--ink); }
.v-tbl th { font-family: var(--font-display); font-weight: 700; font-size: var(--v-small); text-align: start; padding: 14px 22px; background: var(--ink); color: var(--paper); }
.v-tbl td { font-size: var(--v-body); line-height: 1.45; padding: 14px 22px; border-top: 1.5px solid var(--line); vertical-align: middle; }
.v-tbl td.t { font-family: var(--font-mono); font-weight: 700; white-space: nowrap; }
.v-tbl.sm td { font-size: var(--v-small); }

/* L6 ขั้นตอน */
.v-steps { list-style: none; margin: 0; padding: 0; counter-reset: vs; display: flex; flex-direction: column; gap: 18px; }
.v-steps > li { counter-increment: vs; display: grid; grid-template-columns: 72px 1fr; gap: 24px; align-items: center; font-size: var(--v-body); line-height: 1.45; }
.v-steps > li::before { content: counter(vs); display: flex; align-items: center; justify-content: center; width: 72px; height: 72px; background: var(--ink); color: var(--paper); font-family: var(--font-mono); font-weight: 700; font-size: var(--v-h3); }
.v-steps.lg > li { font-size: var(--v-lead); font-family: var(--font-display); font-weight: 600; }
html.reading .v-steps > li { grid-template-columns: 40px 1fr; gap: 12px; }
html.reading .v-steps > li::before { width: 40px; height: 40px; }
.v-list { margin: 0; padding-inline-start: 1.2em; display: flex; flex-direction: column; gap: 14px; }
.v-list > li { font-size: var(--v-body); line-height: 1.45; }
.v-lead { font-family: var(--font-display); font-weight: 600; font-size: var(--v-lead); line-height: 1.4; }

/* L7 กิจกรรม ซ้ายคำสั่ง ขวาแผงกิจกรรม */
.v-actgrid { display: grid; grid-template-columns: minmax(0, 1fr) 520px; gap: 56px; align-items: center; }
.v-actgrid > .v-col { display: flex; flex-direction: column; gap: 28px; min-width: 0; }
.v-act { background: #fff; border: 2.5px solid var(--ink); box-shadow: var(--shadow); padding: 28px; display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.v-act .qr-box { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.v-act .qr { padding: 14px; }
.v-act .qr svg { width: 330px; height: 330px; }
.v-act .qr.qr-wait { width: 358px; height: 358px; font-size: var(--v-small); }
.v-act .qr-cap { font-size: var(--v-min); margin: 0; color: var(--muted); }
.v-act .qr-box > .v-actlbl { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h3); line-height: 1.25; margin: 0; }
.v-act .timer, .v-tbar .timer { display: flex; align-items: center; gap: 12px; }
.v-act .timer .t, .v-tbar .timer .t { font-family: var(--font-mono); font-weight: 700; font-size: calc(64px * var(--fs)); line-height: 1; min-width: 4.6ch; }
.v-act .timer button, .v-tbar .timer button { font-family: var(--font-body); font-size: var(--v-min); padding: 8px 16px; border: 2.5px solid var(--ink); background: var(--card); cursor: pointer; }
.v-act .timer.done .t, .v-tbar .timer.done .t { color: var(--out-deep); }
.v-tbar { display: flex; gap: var(--v-gap); align-items: stretch; }
.v-tbar > .v-call { flex: 1 1 auto; display: flex; align-items: center; }
.v-tbar > .v-tbox { flex: none; background: #fff; border: 2.5px solid var(--ink); box-shadow: var(--shadow); padding: 18px 26px; display: flex; flex-direction: column; justify-content: center; gap: 6px; }
.v-tbox .v-tl { font-size: var(--v-min); color: var(--muted); }
html.reading .v-actgrid { grid-template-columns: 1fr; gap: 16px; }
html.reading .v-act .qr, html.reading .v-act .qr-cap { display: none; }

/* L8 ขั้น GPAS แถบสีซ้ายเต็มความสูง */
.slide.lay.L8 .slide-pad { flex-direction: row; gap: 48px; align-items: stretch; }
.v-band { flex: none; width: 330px; color: #fff; padding: 36px 30px; display: flex; flex-direction: column; justify-content: center; gap: 14px; }
.v-band .code { font-family: var(--font-mono); font-weight: 700; font-size: calc(120px * var(--fs)); line-height: 1; }
.v-band .of { font-size: var(--v-min); opacity: .9; }
.slide.lay .v-band h2 { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h3); line-height: 1.3; color: #fff; border: 0; padding: 0; }
.v-band .en { font-size: var(--v-min); line-height: 1.35; opacity: .92; }
.v-band.b-G { background: var(--st-g-deep); } .v-band.b-P { background: var(--st-p-deep); } .v-band.b-A1 { background: var(--st-a1-deep); }
.v-band.b-A2 { background: var(--st-a2-deep); } .v-band.b-S { background: var(--st-s-deep); }
.v-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 26px; }
.v-goal { font-family: var(--font-display); font-weight: 600; font-size: var(--v-lead); line-height: 1.4; }
.v-goal strong { font-weight: 700; }
.v-aiself { display: grid; grid-template-columns: 1fr 1fr; border: 2.5px solid var(--ink); }
.v-aiself > div { padding: 18px 26px; font-size: var(--v-body); line-height: 1.45; }
.v-aiself > div + div { border-inline-start: 2.5px solid var(--ink); background: #fff; }
.v-aiself > div:first-child { background: var(--c4-soft); }
.v-aiself b { display: block; font-family: var(--font-display); font-size: var(--v-small); }
html.reading .slide.lay.L8 .slide-pad { flex-direction: column; gap: 14px; }
html.reading .v-band { width: auto; padding: 14px 16px; }
html.reading .v-aiself { grid-template-columns: 1fr; }
html.reading .v-aiself > div + div { border-inline-start: 0; border-top: 2.5px solid var(--ink); }

/* ภาพรวม 5 ขั้น */
.v-five { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 20px; }
.v-five > div { color: #fff; padding: 26px 22px; display: flex; flex-direction: column; gap: 10px; min-height: 330px; }
.v-five .code { font-family: var(--font-mono); font-weight: 700; font-size: calc(72px * var(--fs)); line-height: 1; }
.v-five h3 { font-family: var(--font-display); font-weight: 700; font-size: calc(34px * var(--fs)); line-height: 1.3; color: #fff; }
.v-five .en { font-size: var(--v-min); line-height: 1.35; opacity: .92; margin-top: auto; }
html.reading .v-five { grid-template-columns: 1fr; } html.reading .v-five > div { min-height: 0; }

/* วงรอบ 7 ขั้น */
.v-cycle { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 14px; }
.v-cycle > div { background: var(--card); border: 2.5px solid var(--ink); padding: 18px 16px; display: flex; flex-direction: column; gap: 10px; min-height: 340px; }
.v-cycle > div.ai { background: var(--c4-soft); border-style: dashed; }
.v-cycle .n { font-family: var(--font-mono); font-weight: 700; font-size: var(--v-min); color: var(--muted); }
.v-cycle strong { font-family: var(--font-display); font-size: var(--v-small); line-height: 1.3; }
.v-cycle .who { font-size: var(--v-min); font-weight: 600; align-self: flex-start; padding: 2px 10px; background: var(--ink); color: var(--paper); }
.v-cycle .ai .who { background: var(--c4-deep); }
.v-cycle .today { font-size: var(--v-min); line-height: 1.35; color: var(--muted); margin-top: auto; border-top: 1.5px solid var(--line); padding-top: 10px; }
html.reading .v-cycle { grid-template-columns: 1fr 1fr; } html.reading .v-cycle > div { min-height: 0; }

/* L1 ปกและหน้าคั่น */
.slide.lay.L1 .slide-pad { justify-content: center; padding: 0; }
.slide.lay.L1 h1 { font-family: var(--font-display); font-weight: 700; font-size: var(--v-h1); line-height: 1.2; color: var(--paper); max-width: 1600px; }
.slide.lay.L1 .eyebrow { font-size: var(--v-small); margin-bottom: 18px; }
.slide.lay.L1 .v-sub { font-size: var(--v-lead); line-height: 1.45; color: rgba(245, 239, 227, .9); max-width: 1500px; margin-top: 26px; }
.slide.lay.L1 .title-rule { margin: 40px 0 0; }
.v-coverfoot { display: grid; grid-template-columns: 1fr auto; gap: 48px; align-items: end; margin-top: 56px; }
.v-coverfoot p { font-size: var(--v-small); line-height: 1.5; color: rgba(245, 239, 227, .8); }
.v-coverfoot .qr-box { text-align: center; }
.v-coverfoot .qr svg { width: 240px; height: 240px; }
.v-coverfoot .qr-cap, .v-coverfoot .v-actlbl { font-size: var(--v-min); color: rgba(245, 239, 227, .8); margin-top: 8px; }
.v-coverfoot .qr.qr-wait { width: 268px; height: 268px; }

/* เผยทีละชั้น (data-step) ชั้นที่ยังไม่เผยกินที่เท่าเดิม หน้าจึงไม่กระโดด */
html:not(.reading) .slide.lay [data-step] { transition: opacity .35s ease, transform .35s ease; }
html:not(.reading) .slide.lay [data-step]:not(.shown) { opacity: 0; transform: translateY(10px); pointer-events: none; }
.v-stepdots { position: absolute; right: 76px; top: 30px; display: flex; gap: 8px; }
.v-stepdots i { width: 14px; height: 14px; border: 2px solid var(--ink); display: block; }
.v-stepdots i.on { background: var(--ink); }
html.reading .v-stepdots { display: none; }

/* แถบคำใบ้ แสดงเฉพาะหน้าแรก ด้านบน ไม่ทับเนื้อหา */
html:not(.reading) .hint { inset-block-start: 14px; inset-block-end: auto; }
.v-five > .v-band { width: auto; padding: 26px 22px; justify-content: flex-start; }
.v-p { font-size: var(--v-body); line-height: 1.5; }
.slide.lay .tag.spk-only { font-size: var(--v-min); }
.v-col > p:not([class]) { font-size: var(--v-body); }
html:not(.reading) .slide.lay.L1 .slide-pad { justify-content: center; padding: 0 0 20px; }
.v-actgrid .v-list > li, .v-actgrid .v-steps > li { font-size: calc(38px * var(--fs)); }
html.reading .v-actgrid .v-list > li, html.reading .v-actgrid .v-steps > li { font-size: var(--v-body); }
.v-row > .v-call { display: flex; align-items: center; }
.v-tbl.sm td { padding-block: 16px; }
/* ระยะระหว่างลูกของพื้นที่เนื้อหาในแม่แบบ ต้องชนะกฎล้างระยะด้านบน */
html:not(.reading) .slide.lay .slide-pad > .v-body { margin-top: 34px; }
html:not(.reading) .slide.lay .slide-pad > .v-src { margin-top: 18px; }
html:not(.reading) .slide.lay .slide-pad > .v-health { margin-top: 16px; }
html:not(.reading) .slide.lay.L1 .slide-pad > .eyebrow { margin-bottom: 18px; }
html:not(.reading) .slide.lay.L1 .slide-pad > .v-sub { margin-top: 26px; }
html:not(.reading) .slide.lay.L1 .slide-pad > .title-rule { margin-top: 40px; }
html:not(.reading) .slide.lay.L1 .slide-pad > .v-coverfoot { margin-top: 64px; }


/* ===== 26. Ice Breaking ชุด 6 และ 7 และ QR สองตัวบนปก (8 ต.ค. 2569) ===== */
.v-qr2 { display: flex; gap: 40px; align-items: flex-end; }
.v-five.sm > div { min-height: 0; padding: 18px 18px; }
.v-five.sm .code { font-size: calc(54px * var(--fs)); }
.v-five.sm h3 { font-size: calc(28px * var(--fs)); }
.v-bigtimer { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.v-bigtimer .v-tlabel { font-size: var(--v-small); color: var(--muted); margin: 0; }
.v-bigtimer .timer { flex-direction: column; gap: 26px; border: 0; background: none; padding: 0; }
.v-bigtimer .timer .t { font-size: calc(300px * var(--fs)); line-height: 1; min-width: 0; font-weight: 700; }
.v-bigtimer .timer button { font-size: var(--v-small); padding: 12px 34px; border: 2.5px solid var(--ink); background: #fff; }
.v-bigtimer .timer.done .t { color: var(--out-deep); }
.v-words { display: flex; flex-direction: column; gap: 16px; }
.v-wrow { display: flex; gap: 14px; }
.v-wrow input { flex: 1; min-width: 0; font: inherit; font-size: var(--v-small); padding: 12px 18px; border: 2.5px solid var(--ink); background: #fff; }
.v-wrow button, .v-count button { font-family: var(--font-body); font-size: var(--v-min); padding: 8px 18px; border: 2.5px solid var(--ink); background: var(--card); cursor: pointer; }
.v-wchips { display: flex; flex-wrap: wrap; gap: 14px; min-height: 64px; }
.v-wchip { display: inline-flex; align-items: center; gap: 12px; font-family: var(--font-display); font-weight: 700; font-size: var(--v-h3); background: #fff; border: 2.5px solid var(--ink); box-shadow: var(--shadow); padding: 6px 20px; border-radius: 999px; }
.v-wchip button { font-family: var(--font-body); font-size: var(--v-min); border: 0; background: none; color: var(--muted); cursor: pointer; padding: 0 4px; }
.v-wchip.ex { background: transparent; border-style: dashed; box-shadow: none; }
.v-wempty { color: var(--muted); font-size: var(--v-small); }
.v-count { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.v-count .n { font-family: var(--font-mono); font-weight: 700; font-size: calc(140px * var(--fs)); line-height: 1; }
.v-count .u { font-size: var(--v-small); color: var(--muted); }
.v-count .b { display: flex; gap: 12px; }
.v-count.ro .n { font-size: calc(200px * var(--fs)); }
html.reading .v-bigtimer .timer { display: flex !important; }
@media (max-width: 700px) {
  .v-bigtimer .timer .t { font-size: 96px; }
  .v-count .n, .v-count.ro .n { font-size: 72px; }
  .v-qr2 { flex-wrap: wrap; gap: 20px; }
}
@media (max-width: 700px) {
  .vc > .vt { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
  .v-tbar { flex-wrap: wrap; }
  .v-tbar > .v-tbox { flex: 1 1 100%; min-width: 0; }
  .v-tbar .timer { flex-wrap: wrap; }
  .v-tbar .timer .t { font-size: 44px; min-width: 0; }
  .vc .st { overflow-wrap: anywhere; }
}
@media (max-width: 700px) {
  .v-row.c4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.v-bigtimer .timer { display: grid; grid-template-columns: auto auto; justify-items: center; column-gap: 18px; }
.v-bigtimer .timer .t { grid-column: 1 / -1; }
