/* =========================================================================
   Praphankaeng storefront design system
   Single stylesheet for every frontend page. No external dependencies.
   Section map:
     01 tokens          07 forms            13 cart drawer
     02 reset/base      08 cards            14 toasts
     03 layout          09 feedback         15 product
     04 typography      10 tables           16 account / auth / checkout
     05 links           11 header/nav       17 utilities
     06 buttons         12 footer           18 motion / print
   ========================================================================= */

/* -- 01 tokens -----------------------------------------------------------
   ธีม "พรีเมียมพื้นขาว" (ปรับ 2026-08-17): พื้นหลักเป็นขาวล้วน เทากลางอ่อน
   สำหรับพื้นรอง/เส้นแบ่ง — สีแบรนด์ชุดเดิมทำหน้าที่ accent เท่านั้น
   (เขียวมะกอกของใบยอ/ใบมะกรูด แดงอิฐของพริกแห้ง และเหลืองขมิ้น — คงไว้ทุกตัว)

   ชื่อ token ทั้งหมดเป็นชื่อเดิมโดยตั้งใจ — หน้า checkout/บัญชี/auth ใช้ตัวเดียวกันนี้
   การเปลี่ยนชื่อจะทำให้หน้าที่ไม่ได้อยู่ในรอบ redesign กลายเป็นไม่มีสีเงียบ ๆ
   คู่สีที่เป็น "ข้อความบนพื้น" ทุกคู่ถูกวัดคอนทราสต์แล้วผ่าน WCAG AA (≥4.5:1)
   ------------------------------------------------------------------------ */
:root {
    color-scheme: light;

    --paper: #ffffff;
    --surface: #ffffff;
    --surface-muted: #f6f5f2;
    --surface-sunken: #edebe6;
    --ink: #2e2d28;
    --ink-strong: #1a1a15;
    /* วัดใหม่ 2026-08-17 บนพื้นชุดขาว (WCAG relative luminance):
       surface/paper 6.22 · muted 5.70 · sunken 5.22 · leaf-soft 5.49 — ผ่านทุกพื้น
       ⚠️ ถ้าทำพื้นรองเข้มขึ้นเมื่อไหร่ ต้องวัดคู่นี้ซ้ำก่อนเสมอ */
    --muted: #62615a;
    /* ใช้กับของประดับเท่านั้น (~3.2:1) ห้ามใช้กับข้อความที่ต้องอ่าน */
    --muted-soft: #96938c;
    --line: #e9e7e2;
    --line-strong: #d7d4cd;

    /* เขียวมะกอก — สีหลักของแบรนด์ ใช้กับปุ่มหลักและลิงก์ (6.4:1 บนขาว) */
    --leaf: #5e6426;
    --leaf-dark: #464b1c;
    --leaf-soft: #f0f2e5;
    /* แดงอิฐพริกแห้ง — ใช้เป็นสีสถานะผิดพลาดและป้ายลดราคา (6.2:1 บนขาว) */
    --chili: #a83e28;
    --chili-soft: #fbeee8;
    /* เหลืองขมิ้นเข้ม — ต้องเข้มพอเป็น "ตัวหนังสือ" ได้ เพราะ .stock-low ใช้เป็น color */
    --amber: #8a5a0f;
    --amber-soft: #f8f1e1;
    --success: #3f6b3a;
    --success-soft: #edf3ea;

    /* ทองของกรอบภาพ — ใช้ตกแต่งเท่านั้น สว่างเกินกว่าจะเป็นสีข้อความ */
    --gold: #c4ab8e;
    --gold-soft: #f6f1e8;

    --focus: #5e6426;

    --radius-xs: 4px;
    --radius-sm: 6px;
    --radius: 8px;
    --radius-lg: 14px;
    --radius-pill: 999px;

    /* เงาชุดเบา (2026-08-17) — พื้นขาวล้วนทำให้เงาเดิมอ่านหนักเกินจริง
       ลดทั้งระยะและความทึบลง ให้การ์ด/เมนูลอยแบบ "แตะเบา ๆ" ไม่ใช่ "ลอยสูง" */
    --shadow-xs: 0 1px 2px rgba(26, 25, 21, .05);
    --shadow-sm: 0 4px 14px rgba(26, 25, 21, .06);
    --shadow: 0 12px 28px rgba(26, 25, 21, .08);
    --shadow-lg: 0 22px 48px rgba(26, 25, 21, .13);

    --font-sans: "IBM Plex Sans Thai", "Noto Sans Thai", "Sarabun", Inter, ui-sans-serif,
        system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    /* หัวเรื่อง/ตัวเลขราคา — เซอริฟไทยที่มีน้ำหนักตัวอักษรครบ ถ้าโหลดไม่สำเร็จตกไปที่ระบบ */
    --font-display: "Noto Serif Thai", "IBM Plex Serif Thai", "Sarabun", Georgia,
        "Times New Roman", serif;
    /* ลายมือ — ใช้กับหมายเหตุสั้น ๆ เท่านั้น ห้ามใช้กับเนื้อหาที่ต้องอ่านยาว */
    --font-hand: "Charmonman", "Sriracha", cursive;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    --container: 1200px;
    --container-narrow: 860px;
    --header-height: 68px;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 72px;

    --ease: cubic-bezier(.22, .61, .36, 1);
    /* จังหวะช้ากว่า --ease ใช้กับพาเนลเรื่องเล่าที่เลื่อนทับทั้งจอ */
    --ease-story: cubic-bezier(.16, 1, .3, 1);
}

:root[data-theme="dark"] {
    color-scheme: dark;

    /* โหมดกลางคืนของ fresco = สีหมึกอุ่น ไม่ใช่เทาน้ำเงิน เพื่อให้ภาพวาดสีเบจ/ทอง
       ยังอ่านเป็นภาพเดียวกัน พื้นหลังเทาเย็นทำให้ทองกลายเป็นสีเขียวขุ่น */
    --paper: #1a1915;
    --surface: #22211c;
    --surface-muted: #292821;
    --surface-sunken: #141310;
    --ink: #ebe5da;
    --ink-strong: #ffffff;
    --muted: #a8a294;
    --muted-soft: #857f72;
    --line: #3a382f;
    --line-strong: #4e4b3f;

    --leaf: #b3bd6e;
    --leaf-dark: #cdd68f;
    --leaf-soft: #262a17;
    --chili: #e8917a;
    --chili-soft: #2e1d18;
    --amber: #dfb163;
    --amber-soft: #2c2417;
    --success: #8dc084;
    --success-soft: #1e2a1b;

    --gold: #d8c1a1;
    --gold-soft: #2b2519;

    --focus: #b3bd6e;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-sm: 0 6px 16px rgba(0, 0, 0, .34);
    --shadow: 0 14px 34px rgba(0, 0, 0, .42);
    --shadow-lg: 0 26px 60px rgba(0, 0, 0, .55);
}

/* -- 02 reset / base ----------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-height) + 16px);
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

body.is-locked {
    overflow: hidden;
}

img,
svg,
video {
    display: block;
    max-width: 100%;
}

/**
 * 🔴 กฎ `display: block` ข้างบน **ชนะ `[hidden] { display: none }` ของเบราว์เซอร์**
 *    (author stylesheet ชนะ UA stylesheet) → `<img hidden>` / `<video hidden>`
 *    ยังโผล่อยู่ทั้งที่โค้ดสั่งซ่อนไปแล้ว และไม่มีอะไรฟ้องเลยเพราะไม่ใช่ error
 *
 * กับดักนี้เกิดซ้ำเป็นครั้งที่ 3 ในโปรเจกต์นี้ (ก่อนหน้า: `.offer-copy[hidden]`
 * และ `.button[hidden]` ของแถบโหลดสินค้าหน้าแรก — CLAUDE.md §21.4)
 * · คราวนี้จึงวางกฎประกบไว้ **ติดกับต้นเหตุ** ไม่ใช่ไล่แปะทีละ element
 *   ซึ่งเป็นวิธีที่ทำให้มันกลับมาได้เรื่อย ๆ
 */
img[hidden],
svg[hidden],
video[hidden] {
    display: none;
}

img {
    height: auto;
}

hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: var(--space-5) 0;
}

/* Base size for ui_icon() anywhere in body copy. Without this an inline icon
   has no intrinsic size and the SVG stretches to fill its container — buttons
   were fine because they set their own size, but a bare icon in a list or a
   paragraph rendered enormous. Component rules below override as needed. */
.icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -.18em;
}

.icon > svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
}

::selection {
    background: var(--leaf);
    color: #fff;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    padding: 10px 16px;
    background: var(--ink-strong);
    color: #fff;
    border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
    left: 0;
}

.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;
}

/* -- 03 layout ----------------------------------------------------------- */
.container {
    width: 100%;
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 20px;
}

.container-narrow {
    max-width: var(--container-narrow);
}

.section {
    padding: var(--space-8) 0;
}

.section-tight {
    padding: var(--space-7) 0;
}

/* แถบสลับพื้น — เดิมประกาศไว้ในสไตล์เฉพาะหน้าแรก พอหน้าแรกถูกเขียนใหม่
   คลาสนี้เลยหายไปทั้งที่หน้าอื่นเรียกใช้อยู่ ย้ายมาไว้ที่ส่วนกลางแล้ว */
.band {
    background: var(--surface-muted);
    border-block: 1px solid var(--line);
}

/* ข้อความแจ้งผล (เพิ่มลงตะกร้าแล้ว ฯลฯ) บนหน้าที่กินพื้นที่เต็มจอ
   ต้องลอยทับ ไม่ใช่ดันเนื้อหาลง — ดู $chromeless ใน frontend/layout.php */
.flash-floating {
    position: fixed;
    z-index: 40;
    top: calc(var(--header-height) + var(--space-4));
    inset-inline: 0;
    width: min(560px, calc(100% - 32px));
    margin-inline: auto;
    pointer-events: none;
}

.flash-floating > * { pointer-events: auto; }

.flash-floating:empty { display: none; }

.section-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
    flex-wrap: wrap;
}

.section-header h2 {
    margin: 0;
}

.section-header p {
    margin: 6px 0 0;
    color: var(--muted);
}

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-bottom: var(--space-6);
}

.page-head h1 {
    margin: 0;
}

.page-head p {
    margin: 8px 0 0;
    color: var(--muted);
    max-width: 60ch;
}

.grid {
    display: grid;
    gap: var(--space-5);
}

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

.split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--space-6);
    align-items: start;
}

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

/* 🔴 ตัวปรับสองตัวนี้ต้องเปิด flex เองด้วย ไม่ใช่ปรับแค่ `gap`
   ────────────────────────────────────────────────────────────────────
   ของเดิมประกาศแค่ `gap` โดยคาดว่าจะถูกใช้คู่กับ `.stack` เสมอ
   แต่ในความเป็นจริงมีคนเขียน `class="stack-lg"` เดี่ยว ๆ อยู่ **40 จุด
   ใน 18 ไฟล์** รวมคอลัมน์หลักของเกือบทุกหน้าบัญชี · ผลคือ element
   เป็น block, `gap` ถูกเมินทั้งบรรทัด, **การ์ดทุกใบติดกันที่ 0px**
   โดยไม่มี error ที่ไหนเลย (วัดด้วย getBoundingClientRect ก่อนแก้: 0,0,0,0)

   ⚠️ ตัวปรับที่ทำงานเองไม่ได้ = กับดักที่รอคนถัดไปเหยียบ · การไล่เติม
      `.stack` ทีละจุดแก้อาการวันนี้ แต่ไม่ได้แก้ว่าพรุ่งนี้จะพลาดอีก

   ✅ ยังใช้ `class="stack stack-sm"` ได้เหมือนเดิมทุกประการ — `.stack-sm`
      ประกาศทีหลัง `gap` จึงชนะตามลำดับ cascade
   ✅ `<ol>`/`<ul>` ไม่เสียเลข/จุดนำหน้า — เบราว์เซอร์สมัยใหม่คง
      `display: list-item` ไว้ใน flex container (พิสูจน์ด้วยภาพหน้าจอแล้ว) */
.stack-sm,
.stack-lg {
    display: flex;
    flex-direction: column;
}

.stack-sm { gap: var(--space-2); }
.stack-lg { gap: var(--space-6); }

.row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.sticky-aside {
    position: sticky;
    top: calc(var(--header-height) + 20px);
}

@media (max-width: 991px) {
    .split { grid-template-columns: minmax(0, 1fr); }
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sticky-aside { position: static; }
}

@media (max-width: 640px) {
    .section { padding: var(--space-7) 0; }
    .grid-2,
    .grid-3,
    .grid-4 { grid-template-columns: minmax(0, 1fr); }
}

/* -- 04 typography -------------------------------------------------------
   หัวเรื่องใช้เซอริฟ เนื้อความใช้ซานเซอริฟ — ความต่างของสองตระกูลคือสิ่งที่ทำให้
   หน้าอ่านเป็น "บทความ" ไม่ใช่ "หน้าสินค้า" ซึ่งเป็นแกนของงาน redesign รอบนี้
   h3/h4 ยังเป็นซานเซอริฟ เพราะเป็นหัวข้อในการ์ด/ฟอร์มที่ต้องอ่านไว ไม่ใช่หัวบทความ
   ------------------------------------------------------------------------ */
h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--space-3);
    color: var(--ink-strong);
    font-weight: 700;
    line-height: 1.22;
    letter-spacing: -.01em;
}

h1, h2 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: 1.18;
    letter-spacing: -.015em;
}

h1 { font-size: clamp(1.9rem, 1.35rem + 1.7vw, 2.65rem); }
h2 { font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); }
h3 { font-size: 1.25rem; }
h4 { font-size: 1.08rem; }

/* หมายเหตุลายมือ — สั้น ๆ เท่านั้น (1–2 บรรทัด) ฟอนต์ลายมือไทยอ่านยาวไม่ไหว
   และตัวสระบนล่างของมันชนกันเมื่อ line-height ต่ำกว่านี้ */
.hand-note {
    font-family: var(--font-hand);
    font-size: 1.06rem;
    line-height: 1.75;
    color: var(--muted);
}
h5 { font-size: 1rem; }
h6 { font-size: .92rem; }

p {
    margin: 0 0 var(--space-3);
}

p:last-child {
    margin-bottom: 0;
}

.lead {
    font-size: 1.08rem;
    color: var(--muted);
}

.eyebrow {
    display: inline-block;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--leaf);
    margin-bottom: var(--space-3);
}

.muted { color: var(--muted); }
.small { font-size: .875rem; }
.tiny { font-size: .78rem; }
.strong { font-weight: 700; }
.mono { font-family: var(--font-mono); font-size: .875em; }
.strike { text-decoration: line-through; }
.nowrap { white-space: nowrap; }

.price {
    font-weight: 700;
    color: var(--ink-strong);
    font-variant-numeric: tabular-nums;
}

.price-lg {
    font-size: 1.75rem;
    line-height: 1.1;
}

.price-was {
    color: var(--muted);
    text-decoration: line-through;
    font-weight: 500;
    margin-inline-start: 8px;
    font-size: .9em;
}

.clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.clamp-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.prose {
    max-width: 72ch;
    color: var(--ink);
}

.prose h2 { margin-top: var(--space-6); }
.prose h3 { margin-top: var(--space-5); }
.prose ul,
.prose ol { padding-inline-start: 1.25em; margin: 0 0 var(--space-4); }
.prose li { margin-bottom: 6px; }
.prose img { border-radius: var(--radius); margin: var(--space-4) 0; }

.prose blockquote {
    margin: var(--space-4) 0;
    padding: var(--space-3) var(--space-4);
    border-inline-start: 3px solid var(--leaf);
    background: var(--leaf-soft);
    border-radius: 0 var(--radius) var(--radius) 0;
    color: var(--ink);
}

/* -- 05 links ------------------------------------------------------------ */
a {
    color: var(--leaf);
    text-decoration: none;
}

a:hover {
    color: var(--leaf-dark);
}

.text-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: var(--leaf);
}

.text-link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.text-link .icon {
    transition: transform .18s var(--ease);
}

.text-link:hover .icon {
    transform: translateX(3px);
}

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 0 0 var(--space-4);
    padding: 0;
    list-style: none;
    font-size: .85rem;
    color: var(--muted);
}

.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--leaf); }

.breadcrumb li + li::before {
    content: "/";
    margin-inline-end: 6px;
    color: var(--line-strong);
}

.breadcrumb [aria-current="page"] {
    color: var(--ink);
    font-weight: 600;
}

/* -- 06 buttons ---------------------------------------------------------- */
.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    min-height: 44px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: none;
    font: inherit;
    font-weight: 600;
    font-size: .95rem;
    line-height: 1.2;
    color: var(--ink);
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    transition: background-color .16s var(--ease), border-color .16s var(--ease),
        color .16s var(--ease), transform .16s var(--ease), box-shadow .16s var(--ease);
}

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

.button[disabled],
.button[aria-disabled="true"],
.button.is-disabled {
    opacity: .55;
    pointer-events: none;
}

.button-primary {
    background: var(--leaf);
    border-color: var(--leaf);
    color: #fff;
}

.button-primary:hover {
    background: var(--leaf-dark);
    border-color: var(--leaf-dark);
    color: #fff;
}

.button-secondary {
    background: var(--surface);
    border-color: var(--line-strong);
    color: var(--ink);
}

.button-secondary:hover {
    border-color: var(--leaf);
    color: var(--leaf);
}

.button-ghost {
    background: transparent;
    border-color: transparent;
    color: var(--ink);
}

.button-ghost:hover {
    background: var(--surface-muted);
    color: var(--ink);
}

.button-danger {
    background: transparent;
    border-color: var(--line-strong);
    color: var(--chili);
}

.button-danger:hover {
    background: var(--chili-soft);
    border-color: var(--chili);
    color: var(--chili);
}

.button-solid-danger {
    background: var(--chili);
    border-color: var(--chili);
    color: #fff;
}

.button-solid-danger:hover {
    filter: brightness(.94);
    color: #fff;
}

.button-sm {
    padding: 7px 14px;
    min-height: 36px;
    font-size: .85rem;
}

.button-lg {
    padding: 14px 26px;
    min-height: 52px;
    font-size: 1rem;
}

.button-block {
    display: flex;
    width: 100%;
}

.button .icon,
.icon-button .icon {
    display: inline-flex;
    width: 18px;
    height: 18px;
    flex: none;
}

.button .icon svg,
.icon-button .icon svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.icon-button {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    cursor: pointer;
    transition: border-color .16s var(--ease), color .16s var(--ease), background-color .16s var(--ease);
}

.icon-button:hover {
    border-color: var(--leaf);
    color: var(--leaf);
}

/* ── ตัวสลับภาษาหน้าร้าน ──
   เป็นลิงก์คู่ ไม่ใช่ dropdown ที่ต้องใช้ JavaScript — สองภาษาแสดงเป็นปุ่มคู่
   ได้เลย และใช้ได้แม้สคริปต์ไม่ทำงาน (ดูหมายเหตุใน partials/header.php)

   🔴 ธงเป็น SVG ในโค้ด ไม่ใช่ emoji — Windows ไม่มีฟอนต์ธงชาติ ผู้ใช้จะเห็น
      เป็นตัวอักษรสองตัวซ้อนกรอบ ซึ่งดูเหมือนฟอนต์พัง (กฎเดียวกับหลังบ้าน) */
.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.lang-option {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 9px;
    border-radius: calc(var(--radius) - 3px);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--muted);
    text-decoration: none;
    transition: background-color .16s var(--ease), color .16s var(--ease);
}

.lang-option:hover { color: var(--ink); background: var(--surface-muted); }

/* ภาษาที่ใช้อยู่ต้องต่างจากตัวอื่นด้วย **สีพื้น** ไม่ใช่แค่สีตัวอักษร —
   ความต่างที่อาศัยสีอย่างเดียวมองไม่ออกสำหรับคนตาบอดสี */
.lang-option.is-active {
    color: var(--surface);
    background: var(--leaf);
}

.lang-option .locale-flag {
    width: 18px;
    height: 13px;
    flex: none;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}

.lang-option .locale-flag-code {
    display: inline-grid;
    place-items: center;
    font-size: .55rem;
    background: var(--surface-muted);
    color: var(--muted);
}

/* ในลิ้นชักมือถือ ปุ่มภาษากว้างเต็มแถวเพื่อให้กดโดนด้วยนิ้ว */
.drawer-nav .lang-switch { width: 100%; }
.drawer-nav .lang-option { flex: 1; justify-content: center; padding: 9px; }

.button.is-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.button.is-busy::after {
    content: "";
    position: absolute;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    color: #fff;
    animation: pk-spin .7s linear infinite;
}

.button-secondary.is-busy::after,
.button-ghost.is-busy::after {
    color: var(--ink);
}

@keyframes pk-spin {
    to { transform: rotate(360deg); }
}

.cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* -- 07 forms ------------------------------------------------------------ */
.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field > label,
.label {
    font-size: .85rem;
    font-weight: 600;
    color: var(--ink);
}

.label .req {
    color: var(--chili);
    margin-inline-start: 2px;
}

.input,
.select,
.textarea {
    width: 100%;
    padding: 11px 14px;
    min-height: 44px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: .95rem;
    transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}

.input::placeholder,
.textarea::placeholder {
    color: var(--muted-soft);
}

.input:focus,
.select:focus,
.textarea:focus {
    outline: none;
    border-color: var(--leaf);
    /* วงโฟกัสอิงสีแบรนด์ผ่าน color-mix — ค่า rgba ตายตัวเดิมเป็นสี teal
       ของแบรนด์ยุคก่อน และไม่ปรับตามโหมดมืด */
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 16%, transparent);
}

.textarea {
    min-height: 110px;
    resize: vertical;
}

.select {
    appearance: none;
    padding-inline-end: 38px;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2377736d' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 18px;
}

[dir="rtl"] .select {
    background-position: left 12px center;
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"],
.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea {
    border-color: var(--chili);
}

.field-error {
    font-size: .8rem;
    color: var(--chili);
}

.field-hint {
    font-size: .8rem;
    color: var(--muted);
}

.field-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
}

.field-row-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}

@media (max-width: 640px) {
    .field-row,
    .field-row-3 { grid-template-columns: minmax(0, 1fr); }
}

.check {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: .9rem;
    cursor: pointer;
}

.check input {
    margin-top: 3px;
    width: 17px;
    height: 17px;
    accent-color: var(--leaf);
    flex: none;
}

.input-group {
    display: flex;
    align-items: stretch;
}

.input-group .input {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.input-group .button {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
}

.search-field {
    position: relative;
    display: flex;
    align-items: center;
}

.search-field .icon {
    position: absolute;
    inset-inline-start: 12px;
    width: 18px;
    height: 18px;
    color: var(--muted);
    pointer-events: none;
}

.search-field .icon svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
}

.search-field .input {
    padding-inline-start: 40px;
}

.password-field {
    position: relative;
}

.password-field .input {
    padding-inline-end: 46px;
}

.password-toggle {
    position: absolute;
    inset-inline-end: 6px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
}

.password-toggle:hover {
    color: var(--ink);
    background: var(--surface-muted);
}

.password-toggle svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.quantity {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
}

.quantity button {
    width: 40px;
    border: 0;
    background: transparent;
    color: var(--ink);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .16s var(--ease);
}

.quantity button:hover {
    background: var(--surface-muted);
}

.quantity button[disabled] {
    opacity: .4;
    cursor: not-allowed;
}

.quantity input {
    width: 54px;
    border: 0;
    border-inline: 1px solid var(--line);
    background: transparent;
    color: var(--ink);
    text-align: center;
    font: inherit;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
}

.quantity input::-webkit-outer-spin-button,
.quantity input::-webkit-inner-spin-button {
    appearance: none;
    margin: 0;
}

.quantity input:focus {
    outline: none;
}

.option-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.option {
    position: relative;
}

.option input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer;
}

.option span {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 9px 14px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface);
    font-size: .88rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .16s var(--ease), background-color .16s var(--ease);
}

.option span small {
    font-weight: 500;
    color: var(--muted);
}

.option input:checked + span {
    border-color: var(--leaf);
    background: var(--leaf-soft);
    color: var(--leaf-dark);
}

.option input:focus-visible + span {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.option input:disabled + span {
    opacity: .45;
    cursor: not-allowed;
}

/* ═══ รายละเอียดการจัดส่ง (บัญชีของฉัน → สถานะการจัดส่งสินค้า) ═══ */

/*
 * ⚠️ auto-fit + minmax ทำให้ยุบเหลือคอลัมน์เดียวเองบนมือถือ โดยไม่ต้องมี
 *    media query — และ `minmax(0, …)` กันไม่ให้ที่อยู่ยาว ๆ ดันคอลัมน์
 *    จนทั้งหน้าเลื่อนแนวนอน (กับดักเดียวกับ §14.6/§19.5)
 */
/* ── แผงยืนยันการรับสินค้า ─────────────────────────────────────────────────
   🔴 `<details>` ถูกเลือกแทน JavaScript โดยตั้งใจ — กล่องกรอกเหตุผลต้องกางได้
      แม้สคริปต์ไม่โหลด · แต่ marker สามเหลี่ยมของเบราว์เซอร์ทำให้ปุ่มดูไม่เหมือน
      ปุ่มอื่นข้าง ๆ จึงต้องซ่อน (ต้องใส่ทั้ง `list-style` และ pseudo ของ WebKit
      เพราะแต่ละเบราว์เซอร์วาดคนละทาง)
   ⚠️ `summary` เป็นเป้าแตะ — สืบทอด `min-height: 44px` จาก `.button` อยู่แล้ว
      ห้ามเขียนทับด้วยความสูงที่เล็กกว่านั้น */
.delivery-dispute > summary {
    list-style: none;
    cursor: pointer;
}

.delivery-dispute > summary::-webkit-details-marker {
    display: none;
}

/* กล่องที่กางออกมาต้องกว้างเต็มแถว ไม่ใช่เบียดอยู่ข้างปุ่ม */
.delivery-dispute[open] {
    flex-basis: 100%;
}

.delivery-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-block: 1px solid var(--line);
}

.delivery-fact {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.delivery-fact-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .78rem;
    color: var(--muted);
}

.delivery-fact-label .icon {
    flex: none;
    width: 15px;
    height: 15px;
}

.delivery-fact-value {
    font-size: .9rem;
    color: var(--ink-strong);
    overflow-wrap: anywhere;
}

/* --- ไทม์ไลน์เหตุการณ์พัสดุ --- */

.delivery-trail {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-muted);
}

.delivery-trail > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    padding: 10px var(--space-3);
    min-height: 44px;          /* เป้าแตะขั้นต่ำ */
    cursor: pointer;
    list-style: none;
}

.delivery-trail > summary::-webkit-details-marker { display: none; }

/*
 * 🔴 ข้อความไทยทั้งก้อนต้องอยู่ใน element เดียว — ปล่อยเป็นลูกโดยตรงของ flex
 *    จะถูกตัดบรรทัด **ทีละคำ** ซึ่งเทสต์ผ่านหมดและเห็นจากภาพหน้าจอเท่านั้น (§4)
 */
.delivery-trail-latest {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-width: 0;
    flex: 1 1 240px;
    font-size: .9rem;
}

.delivery-trail-latest .icon {
    flex: none;
    width: 18px;
    height: 18px;
    color: var(--leaf);
    margin-top: 2px;
}

.delivery-trail-latest .tiny { display: block; }

.delivery-trail-toggle {
    color: var(--muted);
    text-decoration: underline;
    white-space: nowrap;
}

.delivery-trail[open] .delivery-trail-toggle::after { content: " ▲"; }
.delivery-trail:not([open]) .delivery-trail-toggle::after { content: " ▼"; }

.delivery-timeline {
    list-style: none;
    margin: 0;
    padding: 0 var(--space-3) var(--space-3) var(--space-3);
    border-top: 1px solid var(--line);
}

.delivery-timeline > li {
    position: relative;
    display: flex;
    gap: 10px;
    padding: 10px 0 10px 4px;
}

/* เส้นเชื่อมระหว่างจุด — ไม่ลากเลยจุดสุดท้าย */
.delivery-timeline > li:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 8px;
    top: 22px;
    bottom: -2px;
    width: 1px;
    background: var(--line-strong);
}

.delivery-timeline-dot {
    flex: none;
    width: 9px;
    height: 9px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--line-strong);
}

.delivery-timeline > li.is-latest .delivery-timeline-dot {
    background: var(--leaf);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 18%, transparent);
}

.delivery-timeline > li > div {
    min-width: 0;
    font-size: .88rem;
}

.delivery-timeline .tiny { display: block; }

/*
 * กลุ่มตัวเลือกแบบติ๊กได้หลายข้อ (ใช้ที่ฟอร์มสมัครเป็นผู้ประกอบการ)
 *
 * 🔴 คลาส `.choice-grid` / `.choice` ถูกเขียนไว้ในวิวตั้งแต่แรก **แต่ไม่เคยมี CSS**
 *    ผลคือ label ทุกอันไหลต่อกันเป็นบรรทัดเดียวแล้วตัดคำกลางชื่อช่องทาง
 *    ("หน้าร้านจริง / ตลาด" ขึ้นบรรทัดใหม่คนละครึ่ง) และพื้นที่แตะเล็กกว่า 44px
 *    ซึ่งบนมือถือคือติ๊กพลาดช่องข้าง ๆ
 *
 * ⚠️ พื้นที่แตะครอบทั้งกล่อง ไม่ใช่แค่ตัวสี่เหลี่ยม — `min-height: 44px`
 *    เป็นเกณฑ์ขั้นต่ำของ touch target ไม่ใช่ค่าที่เลือกให้ดูสวย
 */
.choice-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-2);
}

@media (min-width: 640px) {
    .choice-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.choice {
    display: flex;
    gap: 10px;
    align-items: center;
    min-height: 44px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm, 8px);
    background: var(--surface);
    cursor: pointer;
    transition: border-color .16s var(--ease), background-color .16s var(--ease);
}

.choice:hover {
    border-color: var(--line-strong);
}

/* ⚠️ ห้ามซ่อน outline — คนที่เดินด้วยคีย์บอร์ดจะไม่รู้ว่าตัวเองอยู่ช่องไหน */
.choice:focus-within {
    border-color: var(--leaf);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 14%, transparent);
}

.choice input {
    flex: none;
    width: 18px;
    height: 18px;
    accent-color: var(--leaf);
    cursor: pointer;
}

/* ข้อความไทยทั้งก้อนต้องเป็น flex item เดียว ไม่งั้นถูกตัดบรรทัดทีละคำ (CLAUDE.md §4) */
.choice > span {
    min-width: 0;
}

.choice:has(input:checked) {
    border-color: var(--leaf);
    background: color-mix(in srgb, var(--leaf) 6%, var(--surface));
}

.choice-card {
    position: relative;
    display: block;
}

.choice-card input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer;
}

.choice-card > span {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: var(--space-4);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
    transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}

.choice-card input:checked + span {
    border-color: var(--leaf);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 14%, transparent);
}

.choice-card input:disabled + span {
    opacity: .5;
    cursor: not-allowed;
}

.choice-card strong {
    display: block;
    color: var(--ink-strong);
}

.choice-card small {
    color: var(--muted);
}

/* -- 08 cards ------------------------------------------------------------ */
.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-xs);
}

.card-body {
    padding: var(--space-5);
}

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

.card-head h2,
.card-head h3 {
    margin: 0;
    font-size: 1.05rem;
}

.card-foot {
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--line);
    background: var(--surface-muted);
    border-radius: 0 0 var(--radius) var(--radius);
}

.panel {
    padding: var(--space-5);
    background: var(--surface-muted);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-4);
}

.stat {
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.stat .stat-label {
    display: block;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    margin-bottom: 6px;
}

/* 🔴 ต้องเป็น block — `.stat-label` ข้างบนเป็น block อยู่แล้ว และ `.stat-meta`
   ข้างล่างตั้ง `margin-top: 4px` ซึ่ง **ไม่มีผลกับ inline element เลย**
   ทั้งคู่คือหลักฐานว่าคอมโพเนนต์นี้ออกแบบมาให้เรียงลง แต่ไม่เคยมีหน้าไหน
   ใช้ value คู่กับ meta พร้อมกัน บั๊กจึงไม่เคยถูกเห็น
   อาการก่อนแก้ (วัดจากหน้า /account จริง): "0 คำสั่งซื้อที่ยังไม่ได้ชำระ"
   ไหลอยู่บรรทัดเดียวกัน และคำอธิบายของช่องขวาสุดถูกตัดขาดที่ขอบการ์ด */
.stat .stat-value {
    display: block;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ink-strong);
    font-variant-numeric: tabular-nums;
}

.stat .stat-meta {
    display: block;
    font-size: .82rem;
    color: var(--muted);
    margin-top: 4px;
}

/* -- 09 feedback --------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    background: var(--surface-muted);
    color: var(--muted);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .02em;
    white-space: nowrap;
}

.badge-leaf { background: var(--leaf-soft); color: var(--leaf-dark); }
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-warn { background: var(--amber-soft); color: var(--amber); }
.badge-danger { background: var(--chili-soft); color: var(--chili); }
.badge-outline { background: transparent; border: 1px solid var(--line-strong); color: var(--ink); }

.badge-dot::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.tag {
    position: absolute;
    top: 10px;
    inset-inline-start: 10px;
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    background: var(--ink-strong);
    /* ต้องเป็น --paper ไม่ใช่ #fff — โหมดมืด ink-strong พลิกเป็นขาว ตัวอักษรขาว
       ตายตัวจะกลายเป็นขาวบนขาว (ป้าย "สินค้าหมด" เคยล่องหนทั้งใบในโหมดมืด) */
    color: var(--paper);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.tag-leaf { background: var(--leaf); }
.tag-red { background: var(--chili); }
.tag-gold { background: var(--amber); }

.alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--line);
    border-inline-start-width: 3px;
    border-radius: var(--radius);
    background: var(--surface-muted);
    color: var(--ink);
    font-size: .92rem;
    margin-bottom: var(--space-4);
}

.alert:last-child { margin-bottom: 0; }
.alert .icon { flex: none; width: 18px; height: 18px; margin-top: 2px; }
.alert .icon svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.alert ul { margin: 4px 0 0; padding-inline-start: 1.1em; }

.alert-success { background: var(--success-soft); border-color: var(--line); border-inline-start-color: var(--success); }
.alert-success .icon { color: var(--success); }
.alert-error { background: var(--chili-soft); border-color: var(--line); border-inline-start-color: var(--chili); }
.alert-error .icon { color: var(--chili); }
.alert-warn { background: var(--amber-soft); border-color: var(--line); border-inline-start-color: var(--amber); }
.alert-warn .icon { color: var(--amber); }
.alert-info { background: var(--leaf-soft); border-color: var(--line); border-inline-start-color: var(--leaf); }
.alert-info .icon { color: var(--leaf); }

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-3);
    padding: var(--space-8) var(--space-5);
}

.empty-state .empty-art {
    width: 56px;
    height: 56px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--surface-muted);
    color: var(--muted);
}

.empty-state .empty-art svg {
    width: 26px;
    height: 26px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.empty-state h3 { margin: 0; }
.empty-state p { margin: 0; color: var(--muted); max-width: 44ch; }

.skeleton {
    background: linear-gradient(90deg, var(--surface-muted) 25%, var(--surface-sunken) 37%, var(--surface-muted) 63%);
    background-size: 400% 100%;
    animation: pk-shimmer 1.3s ease infinite;
    border-radius: var(--radius-sm);
}

@keyframes pk-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-top: var(--space-6);
    padding: 0;
    list-style: none;
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    font-size: .9rem;
    font-weight: 600;
}

.pagination a:hover {
    border-color: var(--leaf);
    color: var(--leaf);
}

.pagination .active span,
.pagination [aria-current="page"] {
    background: var(--leaf);
    border-color: var(--leaf);
    color: #fff;
}

.pagination .disabled span {
    opacity: .45;
}

/* หน้าเดียว = ไม่ต้องมีตัวแบ่งหน้า (เจตนาเดียวกับกติกา §9.15 ของฝั่ง admin)
   เทมเพลต default_full ของหน้าร้านถูกล็อกห้ามแก้ (testTheStorefrontKeepsItsOwnPagerMarkup)
   จึงซ่อนที่ชั้น CSS แทน — เลขหน้าเดี่ยว ๆ ที่กดแล้วไม่ไปไหนอ่านว่า "ปุ่มเสีย"
   เบราว์เซอร์ที่ไม่รู้จัก :has จะเห็นเลข 1 เหมือนเดิม = ถอยแบบปลอดภัย */
nav:has(> .pagination > li:only-child) {
    display: none;
}

/* -- 10 tables ----------------------------------------------------------- */
.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: .92rem;
    min-width: 560px;
}

.table th,
.table td {
    padding: 12px 16px;
    text-align: start;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

.table thead th {
    background: var(--surface-muted);
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
    font-weight: 700;
    white-space: nowrap;
}

.table tbody tr:last-child td {
    border-bottom: 0;
}

.table tbody tr:hover {
    background: var(--surface-muted);
}

.table .num {
    text-align: end;
    font-variant-numeric: tabular-nums;
}

.summary-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.summary-list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    color: var(--muted);
    font-size: .93rem;
}

/* A plain bullet-free list of reassurance points (delivery, secure payment…). */
.trust-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: .9rem;
    color: var(--muted);
}

.trust-list li {
    display: flex;
    align-items: flex-start;
    gap: 9px;
}

.trust-list .icon {
    color: var(--leaf);
    margin-top: .15em;
}

.summary-list li strong {
    color: var(--ink-strong);
    font-variant-numeric: tabular-nums;
}

.summary-list li.is-total {
    padding-top: 10px;
    border-top: 1px solid var(--line);
    font-size: 1.05rem;
    color: var(--ink-strong);
    font-weight: 600;
}

.summary-list li.is-total strong {
    font-size: 1.3rem;
}

.summary-list li.is-discount strong {
    color: var(--success);
}

/* -- voucher box (หน้าตะกร้า) -------------------------------------------
 *
 * 🔴 ปุ่มและช่องกรอกสูง 44px ตามขั้นต่ำของพื้นที่แตะบนมือถือ — ปุ่มที่เล็กกว่านี้
 *    ทำให้ลูกค้ากดพลาดแล้วตีความว่าระบบไม่ตอบสนอง
 * ⚠️ ข้อความ error ใช้สีเข้มพอให้อัตราคอนทราสต์ผ่าน 4.5:1 บนพื้นกระดาษ
 *    และมีไอคอนกำกับ ไม่พึ่งสีอย่างเดียว
 */
.voucher-box {
    padding-top: var(--space-4);
    border-top: 1px solid var(--line);
}

.voucher-label {
    display: block;
    margin-bottom: 6px;
    font-size: .85rem;
    font-weight: 600;
    color: var(--ink-strong);
}

.voucher-row {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.voucher-input {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm, 8px);
    background: var(--paper);
    color: var(--ink-strong);
    font: inherit;
    text-transform: uppercase;
}

.voucher-input:focus-visible {
    outline: 2px solid var(--leaf);
    outline-offset: 1px;
}

.voucher-input[aria-invalid="true"] {
    border-color: var(--danger, #b42318);
}

.voucher-row .button {
    min-height: 44px;
    white-space: nowrap;
}

.voucher-applied {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    font-size: .9rem;
    color: var(--success);
}

.voucher-error {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 8px 0 0;
    font-size: .85rem;
    color: var(--danger, #b42318);
}

.voucher-hints {
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: .82rem;
    color: var(--muted);
}

/* -- ป้ายดีล + กล่องข้อเสนอ (หน้ารายการ/หน้าสินค้า) --------------------
 *
 * 🔴 ป้ายดีลใช้สีต่างจาก "ลดราคา" (แดง) เพราะเป็นเงื่อนไขคนละอย่าง —
 *    ลดราคา = ถูกลงทันที · ดีล = ต้องซื้อครบจำนวนก่อน
 *    สีเดียวกันจะทำให้ลูกค้าคาดว่าราคาที่เห็นถูกลงแล้ว
 * ⚠️ ไม่พึ่งสีอย่างเดียว — ข้อความบนป้ายบอกเงื่อนไขครบในตัวเอง
 */
.tag-deal {
    background: color-mix(in srgb, var(--leaf) 88%, black 6%);
    color: #fff;
}

.offer-box {
    padding: 14px 16px;
    border: 1px dashed color-mix(in srgb, var(--leaf) 45%, var(--line));
    border-radius: var(--radius-sm, 8px);
    background: color-mix(in srgb, var(--leaf) 6%, transparent);
}

.offer-heading {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 8px;
    font-size: .92rem;
    font-weight: 600;
    color: var(--ink-strong);
}

.offer-heading .icon { color: var(--leaf); }

.offer-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: .88rem;
}

.offer-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
}

.offer-code {
    padding: 1px 7px;
    border: 1px dashed color-mix(in srgb, var(--leaf) 55%, var(--line));
    border-radius: 4px;
    background: var(--paper);
    color: var(--ink-strong);
    font-size: .82rem;
    /* แตะเดียวเลือกทั้งโค้ด — ทางคัดลอกสำหรับคนที่ไม่มีปุ่ม (ไม่มี JS/บริบทไม่ปลอดภัย) */
    user-select: all;
}

/* ปุ่มคัดลอกโค้ด — โผล่เฉพาะเมื่อ clipboard ใช้ได้ (site.js ถอด hidden ให้)
   🔴 ต้องมีกฎ [hidden] ประกบเสมอ — `display: inline-flex` ของคลาสนี้ชนะ
   `[hidden]{display:none}` ของเบราว์เซอร์ แล้วปุ่มจะโผล่ทั้งที่ไม่มี JS
   (จับได้จาก harness ไม่มี JS — ไม่ใช่จากการอ่านโค้ด) */
.offer-copy[hidden] { display: none; }

.offer-copy {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-inline-start: auto;
    padding: 5px 12px;
    min-height: 36px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: .78rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .16s var(--ease), color .16s var(--ease);
}

.offer-copy:hover {
    border-color: var(--leaf);
    color: var(--leaf);
}

.offer-copy .icon { width: 14px; height: 14px; }

/* สถานะ "คัดลอกแล้ว" — สีเปลี่ยนพร้อมข้อความ ไม่พึ่งสีเพียงลำพัง */
.offer-copy.is-copied {
    border-color: var(--success);
    color: var(--success);
}

.voucher-hints code {
    display: inline-block;
    margin-right: 4px;
    padding: 1px 6px;
    border: 1px dashed var(--line);
    border-radius: 4px;
    background: color-mix(in srgb, var(--leaf) 8%, transparent);
    color: var(--ink-strong);
    font-size: .8rem;
}

/* -- 11 header / nav ----------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 60;
    background: color-mix(in srgb, var(--paper) 88%, transparent);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid var(--line);
    transition: box-shadow .2s var(--ease);
}

.site-header.is-stuck {
    box-shadow: var(--shadow-sm);
}

@supports not (backdrop-filter: blur(4px)) {
    .site-header { background: var(--paper); }
}

.nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: var(--header-height);
    padding-block: 10px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--ink-strong);
    font-weight: 800;
    letter-spacing: -.01em;
    line-height: 1.1;
    flex: none;
}

.brand:hover { color: var(--ink-strong); }

/**
 * ตราสัญลักษณ์ของร้าน — **ไม่มีพื้นสีครอบ** และขนาดลื่นไหลตามจอ
 *
 * 🔴 ห้ามใส่ `background`/`border-radius` กลับเข้ามา — โลโก้ที่ร้านอัปโหลดเอง
 *    ถูกวางไว้ในกล่องนี้ พื้นสีจึงกลายเป็น "กรอบสี" รอบโลโก้ของลูกค้า
 *    และมุมมนจะตัดขอบโลโก้ที่เป็นสี่เหลี่ยมทิ้งโดยไม่มีใครสั่ง
 *
 * 🔴 `color` ต้องเป็นสีแบรนด์ ไม่ใช่ `#fff` — ตราใบไม้สำรอง (ตอนที่ยังไม่ได้
 *    อัปโหลดโลโก้) วาดด้วย `stroke: currentColor` ถ้าปล่อยเป็นขาวหลังถอดพื้นสี
 *    มันจะเป็นขาวบนขาว = หายไปทั้งอัน โดยไม่มี error ให้เห็น
 *
 * ⚠️ mobile-first: ค่าฐานคือขนาดบนมือถือ แล้ว `clamp()` ขยายขึ้นตามความกว้างจอ
 *    — ไม่ใช่ px คงที่ที่ล้นแถบนำทางบนจอ 320px
 */
.brand-mark {
    display: grid;
    place-items: center;
    width: clamp(30px, 7.5vw, 40px);
    height: clamp(30px, 7.5vw, 40px);
    color: var(--leaf);
    flex: none;
}

.brand-mark svg {
    width: 82%;
    height: 82%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/**
 * ช่องภาพของโลโก้ที่อัปโหลดเอง
 *
 * `contain` = เห็นโลโก้เต็มใบเสมอ ไม่ว่าไฟล์จะเป็นจัตุรัสหรือแนวนอน
 * ⚠️ ห้าม `overflow: hidden` — เมื่อไม่มีพื้นสีมุมมนแล้วก็ไม่มีอะไรต้องตัด
 *    มีแต่จะตัดโลโก้แนวนอนทิ้งเมื่อมันกว้างกว่ากล่อง
 */
.brand-mark-image {
    width: auto;
    min-width: clamp(30px, 7.5vw, 40px);
    max-width: clamp(88px, 26vw, 132px);
}

.brand-mark-image img {
    width: auto;
    max-width: 100%;
    height: clamp(30px, 7.5vw, 40px);
    object-fit: contain;
    object-position: left center;
}

/**
 * โลโก้เวอร์ชันธีมมืด (slot `logo_dark` ในหน้า Branding)
 *
 * สลับฝั่ง CSS เพราะธีมถูกเลือกในเบราว์เซอร์ (localStorage → `data-theme`)
 * เซิร์ฟเวอร์ไม่มีทางรู้ · `has-dark-logo` ถูกเติมจากฝั่ง PHP เฉพาะเมื่อ
 * อัปโหลดเวอร์ชันมืดไว้จริง — ไม่ได้อัปโหลด = โลโก้สว่างใช้ทั้งสองธีม
 */
.brand-logo-dark { display: none; }
[data-theme="dark"] .has-dark-logo .brand-logo-light { display: none; }
[data-theme="dark"] .has-dark-logo .brand-logo-dark { display: inline-block; }

.brand-text {
    display: flex;
    flex-direction: column;
}

.brand-text small {
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--muted);
}

.nav-search {
    flex: 1 1 auto;
    max-width: 420px;
    min-width: 0;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex: none;
}

.nav-links a {
    position: relative;
    color: var(--ink);
    font-size: .94rem;
    font-weight: 500;
    padding: 6px 0;
}

.nav-links a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    border-radius: 2px;
    background: var(--leaf);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform .2s var(--ease);
}

.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after {
    transform: scaleX(1);
}

.nav-links a[aria-current="page"] {
    color: var(--leaf-dark);
    font-weight: 600;
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-inline-start: auto;
    flex: none;
}

.cart-button .cart-count {
    position: absolute;
    top: -6px;
    inset-inline-end: -6px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-pill);
    background: var(--chili);
    color: #fff;
    font-size: .7rem;
    font-weight: 700;
    line-height: 1;
}

.cart-button .cart-count[data-count="0"] {
    display: none;
}

.cart-button.is-bumped {
    animation: pk-bump .4s var(--ease);
}

@keyframes pk-bump {
    30% { transform: scale(1.14); }
    60% { transform: scale(.96); }
    100% { transform: scale(1); }
}

.menu-toggle {
    display: none;
}

/* account dropdown */
.menu {
    position: relative;
}

.menu-panel {
    position: absolute;
    top: calc(100% + 8px);
    inset-inline-end: 0;
    min-width: 220px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity .16s var(--ease), transform .16s var(--ease), visibility .16s;
    z-index: 70;
}

.menu.is-open .menu-panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.menu-panel a,
.menu-panel button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: .92rem;
    text-align: start;
    cursor: pointer;
}

.menu-panel a:hover,
.menu-panel button:hover {
    background: var(--surface-muted);
    color: var(--ink);
}

.menu-panel .menu-sep {
    height: 1px;
    margin: 6px 4px;
    background: var(--line);
}

.menu-panel .menu-head {
    padding: 10px 12px 8px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 4px;
}

.menu-panel .menu-head strong {
    display: block;
    font-size: .93rem;
    color: var(--ink-strong);
}

.menu-panel .menu-head small {
    color: var(--muted);
    font-size: .8rem;
    word-break: break-all;
}

.menu-panel form {
    margin: 0;
}

/* mobile drawer */
.nav-drawer {
    position: fixed;
    inset: 0;
    z-index: 90;
    visibility: hidden;
}

.nav-drawer.is-open {
    visibility: visible;
}

.drawer-scrim {
    position: absolute;
    inset: 0;
    background: rgba(20, 19, 18, .45);
    opacity: 0;
    transition: opacity .22s var(--ease);
}

.nav-drawer.is-open .drawer-scrim,
.cart-drawer.is-open .drawer-scrim {
    opacity: 1;
}

.drawer-panel {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    width: min(340px, 86vw);
    display: flex;
    flex-direction: column;
    background: var(--paper);
    box-shadow: var(--shadow-lg);
    transform: translateX(-100%);
    transition: transform .26s var(--ease);
}

.nav-drawer.is-open .drawer-panel {
    transform: translateX(0);
}

.drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4);
    border-bottom: 1px solid var(--line);
}

/* ⚠️ เดิมหัวลิ้นชักตั้งขนาดเองด้วย `style="font-size:1.05rem"` ในวิว
   1.05rem เป็นขั้นที่มีอยู่จริงในระบบ (`.card-head h2/h3` ใช้ค่านี้)
   แต่การเขียนไว้ใน inline style แปลว่าสเกลถูกกำหนดจากที่ที่ไม่มีใครไปตามอ่าน */
.drawer-head h2,
.drawer-head h3 {
    margin: 0;
    font-size: 1.05rem;
}

.drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-4);
}

.drawer-foot {
    padding: var(--space-4);
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.drawer-nav {
    display: flex;
    flex-direction: column;
}

.drawer-nav a {
    padding: 12px 4px;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
    font-weight: 600;
}

.drawer-nav a[aria-current="page"] {
    color: var(--leaf-dark);
}

/* Declared before the media query on purpose: an equal-specificity rule placed
   after it would win the cascade and keep the mobile search row hidden, which
   left phone visitors with no way to search at all. */
.header-search-row {
    display: none;
}

@media (max-width: 1080px) {
    .nav-search { max-width: 260px; }
    .nav-links { gap: var(--space-3); }
}

@media (max-width: 900px) {
    .nav-links { display: none; }
    .menu-toggle { display: inline-flex; }
    .nav-search { display: none; }
    .header-search-row {
        display: block;
        padding-bottom: 12px;
    }
}

/* -- 12 footer -----------------------------------------------------------
   ฟุตเตอร์แบบย่อ (2026-08-25): สองแถว ไม่มีหัวข้อกลุ่ม
     แถวบน  แบรนด์ + คำโปรยหนึ่งบรรทัด | ลิงก์ที่ยังไม่มีที่อื่น
     แถวล่าง ลิงก์นโยบายอินไลน์ + ลิขสิทธิ์ + คำรับรองการชำระเงิน

   ของเดิมเป็นตาราง 4 คอลัมน์ที่ยุบเป็นรายการลิงก์ยาว 11 บรรทัดบนมือถือ —
   ซึ่งเป็นสิ่งสุดท้ายที่ลูกค้าเห็นก่อนออกจากหน้า
   ------------------------------------------------------------------------ */
.site-footer {
    margin-top: var(--space-8);
    border-top: 1px solid var(--line);
    background: var(--surface-muted);
}

.footer-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-5);
    flex-wrap: wrap;
    padding: var(--space-6) 0 var(--space-5);
}

.footer-brand {
    /* คำโปรยหนึ่งบรรทัดที่ยาวเกิน ~46 ตัวอักษรจะอ่านยากขึ้นเรื่อย ๆ
       ปล่อยให้ยาวเต็มความกว้างคือการเอาที่ของลิงก์ไปโดยไม่ได้อะไรเพิ่ม */
    max-width: 46ch;
}

.footer-tagline {
    margin: var(--space-3) 0 0;
    color: var(--muted);
    font-size: .9rem;
    line-height: 1.65;
}

/* ลิงก์แถวบน — เป็นแถวเดียวบนจอกว้าง และตัดบรรทัดเองเมื่อที่ไม่พอ
   🔴 เป้าแตะสูงอย่างน้อย 44px ตามกติกาการสัมผัส — ลิงก์ตัวหนังสือล้วน
      ที่สูงเท่าบรรทัดเดียวคือเป้าที่กดพลาดตลอดบนมือถือ */
.footer-nav,
.footer-policies {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px var(--space-4);
}

.footer-nav a,
.footer-policies a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--ink);
}

.footer-nav a {
    font-size: .93rem;
    font-weight: 600;
}

.footer-nav a:hover,
.footer-policies a:hover {
    color: var(--leaf);
}

.footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-5);
    flex-wrap: wrap;
    padding: var(--space-2) 0 var(--space-4);
    border-top: 1px solid var(--line);
}

.footer-policies a {
    color: var(--muted);
    font-size: .84rem;
}

.footer-legal {
    display: flex;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    flex-wrap: wrap;
    margin: 0;
    color: var(--muted);
    font-size: .82rem;
}

.footer-secure {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.footer-secure svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    flex: none;
}

@media (max-width: 860px) {
    .footer-top {
        flex-direction: column;
        gap: var(--space-3);
        padding-bottom: var(--space-3);
    }

    /* ⚠️ ข้อความไทยที่เป็นลูกโดยตรงของ flex container จะถูกตัดบรรทัด "ทีละคำ"
          (§4) — ที่นี่ปลอดภัยเพราะทุกลูกเป็น element ไม่ใช่ text node ลอย ๆ
          แต่ห้ามใครมาแทรกข้อความเปล่า ๆ เข้าไปในสามกล่องนี้ */
    .footer-bottom {
        flex-direction: column;
        align-items: flex-start;
        /* ⚠️ ปุ่ม "กลับขึ้นด้านบน" เป็น `position: fixed` มุมล่างซ้าย (20px + สูง ~44px)
              ฟุตเตอร์ที่สั้นลงแล้วทำให้บรรทัดลิขสิทธิ์ไปอยู่ใต้ปุ่มพอดี
              — เว้นที่ให้พ้นปุ่ม แทนที่จะปล่อยให้ทับข้อความบรรทัดสุดท้ายของหน้า */
        padding-bottom: 84px;
    }
}

/* -- 13 cart drawer ------------------------------------------------------ */
.cart-drawer {
    position: fixed;
    inset: 0;
    z-index: 95;
    visibility: hidden;
}

.cart-drawer.is-open {
    visibility: visible;
}

.cart-drawer .drawer-panel {
    inset-inline-start: auto;
    inset-inline-end: 0;
    width: min(420px, 92vw);
    transform: translateX(100%);
}

.cart-drawer.is-open .drawer-panel {
    transform: translateX(0);
}

.mini-line {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
}

.mini-line:last-child {
    border-bottom: 0;
}

.mini-line img,
.mini-line .thumb-fallback {
    width: 64px;
    height: 64px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    background: var(--surface-muted);
}

.mini-line .thumb-fallback {
    display: grid;
    place-items: center;
    color: var(--muted-soft);
}

.mini-line h4 {
    margin: 0 0 2px;
    font-size: .92rem;
    font-weight: 600;
}

.mini-line .mini-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 8px;
}

.cart-drawer-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ink-strong);
}

/* -- 14 toasts ----------------------------------------------------------- */
/* Bottom-centred so toasts never sit on top of the cart drawer (right edge)
   or the back-to-top button (left edge). */
.toast-host {
    position: fixed;
    z-index: 120;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    pointer-events: none;
    width: max-content;
    max-width: min(420px, calc(100vw - 40px));
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-inline-start: 3px solid var(--leaf);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow);
    color: var(--ink);
    font-size: .9rem;
    pointer-events: auto;
    animation: pk-toast-in .24s var(--ease);
}

.toast.is-leaving {
    animation: pk-toast-out .2s var(--ease) forwards;
}

.toast-success { border-inline-start-color: var(--success); }
.toast-error { border-inline-start-color: var(--chili); }
.toast-warn { border-inline-start-color: var(--amber); }

.toast .icon { flex: none; width: 18px; height: 18px; margin-top: 1px; }
.toast .icon svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.toast-success .icon { color: var(--success); }
.toast-error .icon { color: var(--chili); }
.toast-warn .icon { color: var(--amber); }

.toast button {
    margin-inline-start: auto;
    border: 0;
    background: none;
    color: var(--muted);
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0 2px;
}

@keyframes pk-toast-in {
    from { opacity: 0; transform: translateY(10px); }
}

@keyframes pk-toast-out {
    to { opacity: 0; transform: translateY(6px); }
}

/* -- 15 product ---------------------------------------------------------- */
.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: var(--space-5);
}

.product-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}

.product-card:hover {
    transform: translateY(-3px);
    border-color: var(--line-strong);
    box-shadow: var(--shadow-sm);
}

.product-media {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    background: var(--surface-muted);
    overflow: hidden;
}

.product-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .4s var(--ease);
}

.product-card:hover .product-media img {
    transform: scale(1.04);
}

.product-media .thumb-fallback {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    color: var(--muted-soft);
}

.product-media .thumb-fallback svg {
    width: 38px;
    height: 38px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
}

.product-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: var(--space-4);
    flex: 1;
}

.product-kicker {
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
}

.product-body h3 {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.35;
}

.product-body h3 a {
    color: var(--ink-strong);
}

.product-body h3 a:hover {
    color: var(--leaf);
}

.product-body > p {
    color: var(--muted);
    font-size: .875rem;
    margin: 0;
}

.product-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: var(--space-3);
}

.rating {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--muted);
    font-size: .8rem;
}

.rating svg {
    width: 14px;
    height: 14px;
    fill: var(--amber);
    stroke: none;
}

.stock-note {
    font-size: .8rem;
    font-weight: 600;
}

/* ไอคอนเตือนสารก่อภูมิแพ้บนหัวข้อใน .prose — สีขมิ้นให้อ่านเป็น "คำเตือน"
   โดยไม่แดงเท่าระดับ error (ข้อมูล ไม่ใช่ความผิดพลาด) */
.allergen-flag { color: var(--amber); }

.stock-in { color: var(--success); }
.stock-low { color: var(--amber); }
.stock-out { color: var(--chili); }

.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: var(--space-5);
}

.chip-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--ink);
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .16s var(--ease), background-color .16s var(--ease), color .16s var(--ease);
}

.chip:hover {
    border-color: var(--leaf);
    color: var(--leaf);
}

.chip[aria-pressed="true"],
.chip.is-active {
    background: var(--leaf);
    border-color: var(--leaf);
    color: #fff;
}

.chip .chip-remove {
    display: inline-grid;
    place-items: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .25);
    font-size: .7rem;
    line-height: 1;
}

/* product detail */
.product-detail {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: var(--space-7);
    align-items: start;
}

.gallery {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.gallery-main {
    position: relative;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface-muted);
}

.gallery-main img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gallery-thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: 10px;
}

.gallery-thumb {
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface-muted);
    cursor: pointer;
    transition: border-color .16s var(--ease);
}

.gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gallery-thumb[aria-selected="true"] {
    border-color: var(--leaf);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--leaf) 22%, transparent);
}

/* ── วิดีโอสินค้าในแกลเลอรี ─────────────────────────────────────────────
   ตัวเล่นบนเวทีใช้ `contain` ไม่ใช่ `cover` — วิดีโอแนวนอน 16:9 ในกรอบ 1:1
   ถ้า cover จะถูกครอบหัวท้ายทิ้ง ซึ่งกับรูปสินค้ายังพอรับได้ แต่กับวิดีโอ
   ที่มีข้อความ/หน้าคนอยู่ในเฟรม คือการตัดเนื้อหาทิ้งจริง ๆ                */
.gallery-video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
    display: block;
}

.gallery-zoom {
    position: absolute;
    inset-block-end: 10px;
    inset-inline-end: 10px;
}

.gallery-main.is-video .gallery-zoom {
    /* ย้ายขึ้นมุมบน — มุมล่างขวาเป็นที่ของปุ่มเต็มจอของตัวเล่นวิดีโอเอง */
    inset-block-start: 10px;
    inset-block-end: auto;
}

.gallery-thumb {
    position: relative;
}

.gallery-thumb video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    background: #000;
    pointer-events: none;
}

/* ▶ ทับหมุดวิดีโอเสมอ — ไม่มี ffmpeg จึงไม่มีภาพปกจริง เฟรมแรกอาจเป็นจอดำล้วน
   ป้ายนี้คือสิ่งเดียวที่บอกว่าหมุดนี้เป็นวิดีโอไม่ใช่รูปที่โหลดพัง             */
.gallery-thumb-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: #fff;
    pointer-events: none;
    /* มีภาพปกแล้ว — ฝ้าบาง ๆ พอให้ ▶ อ่านออกบนภาพสว่าง โดยไม่บังภาพปก */
    background: linear-gradient(to bottom, rgba(0, 0, 0, .06), rgba(0, 0, 0, .34));
}

/* ยังไม่มีภาพปก — พื้นทึบทำให้ดูตั้งใจ ไม่ใช่ "รูปโหลดไม่ขึ้น" */
/* ป้าย "มีคลิป" มุมล่างซ้ายของรูป — คนละมุมกับ .tag (บนซ้าย) ที่เป็นเรื่องราคา/สต๊อก */
.tag-video {
    top: auto;
    inset-block-end: 10px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    text-transform: none;
    letter-spacing: 0;
    background: rgba(0, 0, 0, .68);
    color: #fff;
}

.tag-video .icon {
    width: .85rem;
    height: .85rem;
}

/* ป้าย "มีคลิป" บนการ์ดสินค้า — อยู่แถวเดียวกับสถานะสต๊อก จึงยืมขนาดตัวอักษรมาให้เท่ากัน
   ⚠️ ไม่ใช้ `.badge` — `.badge` เป็น nowrap และแถวนี้แคบบนมือถือ (CLAUDE.md §15.9) */
.media-note {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: .78rem;
    color: var(--muted);
}

.gallery-thumb-play.is-blank {
    background: linear-gradient(160deg, #3a3f45, #14171a);
}

.gallery-thumb-play .icon {
    width: 1.7rem;
    height: 1.7rem;
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .7));
}

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

.buy-box .price-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.tabs {
    display: flex;
    gap: var(--space-4);
    border-bottom: 1px solid var(--line);
    margin-bottom: var(--space-5);
    overflow-x: auto;
}

.tab {
    padding: 12px 2px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--muted);
    font: inherit;
    font-weight: 600;
    font-size: .95rem;
    white-space: nowrap;
    cursor: pointer;
    transition: color .16s var(--ease), border-color .16s var(--ease);
}

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

.tab[aria-selected="true"] {
    color: var(--leaf-dark);
    border-bottom-color: var(--leaf);
}

.tab-panel[hidden] {
    display: none;
}

.spec-list {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 10px var(--space-4);
    margin: 0;
    font-size: .92rem;
}

.spec-list dt {
    color: var(--muted);
}

.spec-list dd {
    margin: 0;
    color: var(--ink);
}

@media (max-width: 900px) {
    .product-detail { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
    .spec-list { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .spec-list dd { margin-bottom: 10px; }
}

.accordion-item {
    border-bottom: 1px solid var(--line);
}

.accordion-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-4) 0;
    border: 0;
    background: none;
    color: var(--ink-strong);
    font: inherit;
    font-weight: 600;
    text-align: start;
    cursor: pointer;
}

.accordion-trigger .icon {
    flex: none;
    transition: transform .2s var(--ease);
}

.accordion-trigger[aria-expanded="true"] .icon {
    transform: rotate(180deg);
}

.accordion-panel {
    padding: 0 0 var(--space-4);
    color: var(--muted);
}

.accordion-panel[hidden] {
    display: none;
}

/* -- 15ก การ์ดคู่มือทำอาหาร (หน้าแรก) ------------------------------------
   การ์ดคู่มือเคยเป็นกล่องข้อความล้วนที่หน้าตาเหมือนกันทุกใบ ต้องอ่านหัวเรื่อง
   ถึงจะแยกออก · รูปปกทำให้แยกได้ในแวบเดียว และเป็นสิ่งที่ทำให้ส่วนนี้ไม่ถูก
   เลื่อนผ่านไปเฉย ๆ ระหว่างทางลงไปหาฟุตเตอร์

   🔴 กรอบรูปจองสัดส่วนไว้ด้วย `aspect-ratio` เสมอ — รูป lazy-load ที่ไม่มีที่จอง
      จะดันเนื้อหาใต้มันลงตอนโหลดเสร็จ (CLS) ซึ่งเป็นจังหวะที่ผู้ใช้กำลังจะกดพอดี
   ------------------------------------------------------------------------ */
.guide-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: inherit;
    transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}

.guide-card:hover {
    /* `a:hover` (0,1,1) เจาะจงกว่า `.guide-card` (0,1,0) — ไม่ทับคืน
       ตัวหนังสือทั้งการ์ดจะเปลี่ยนเป็นสีลิงก์ตอนชี้ ซึ่งอ่านว่า "ทั้งกล่องเป็นลิงก์เดียว
       ที่กำลังจะเปลี่ยนสถานะ" แทนที่จะเป็นการ์ดเนื้อหาที่กดได้ */
    color: inherit;
    transform: translateY(-3px);
    border-color: var(--line-strong);
    box-shadow: var(--shadow-sm);
}

.guide-media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    background: var(--surface-muted);
    overflow: hidden;
}

.guide-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .4s var(--ease);
}

.guide-card:hover .guide-media img {
    transform: scale(1.04);
}

/* ยังไม่มีรูปปก — ไอคอนประจำประเภทบนพื้นโทนเดียวกับป้าย ไม่ใช่กล่องเปล่า */
.guide-media-blank {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
}

.guide-media-blank svg {
    /* ใหญ่พอที่จะอ่านว่า "ภาพประกอบตามประเภท" ไม่ใช่กล่องว่างที่มีจุดเล็ก ๆ
       — วัดจากภาพหน้าจอจริง 44px ยังจมหายไปในกรอบ 4:3 */
    width: 64px;
    height: 64px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.2;
    opacity: .8;
}

/* ป้ายประเภท — ไอคอนคู่กับสีเสมอ ห้ามสื่อด้วยสีอย่างเดียว (ตาบอดสี/พิมพ์ขาวดำ) */
.guide-type {
    position: absolute;
    top: 10px;
    left: 10px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: calc(100% - 20px);
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    background: var(--surface);
    box-shadow: var(--shadow-xs);
    font-size: .74rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.guide-type svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    flex: none;
}

/* ป้าย "มีคลิปสอน" อยู่คนละมุมกับป้ายประเภท — สองอย่างเกิดพร้อมกันได้และบอก
   คนละเรื่อง (ชนิดเนื้อหา · รูปแบบสื่อ) ใช้มุมเดียวกันจะแย่งกันจนหายไปหนึ่งอัน */
.guide-video {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    border-radius: var(--radius-pill);
    background: rgba(26, 25, 21, .72);
    color: #fff;
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.guide-video svg {
    width: 12px;
    height: 12px;
    fill: currentColor;
    stroke: none;
    flex: none;
}

/* โทนสีประจำประเภท — ใช้กับพื้นภาพประกอบและสีตัวอักษรของป้าย */
.guide-media.tone-leaf { background: var(--leaf-soft); color: var(--leaf); }
.guide-media.tone-gold { background: var(--gold-soft); color: #7a5f36; }
.guide-media.tone-chili { background: var(--chili-soft); color: var(--chili); }
.guide-media.tone-amber { background: var(--amber-soft); color: var(--amber); }

/* หน้าคู่มือเต็ม — รูปปกใบเดียวกับการ์ด วางเต็มความกว้างเหนือเนื้อหา */
.guide-article {
    overflow: hidden;
}

.guide-article-media {
    aspect-ratio: 16 / 9;
    background: var(--surface-muted);
}

.guide-article-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.guide-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: var(--space-4);
    flex: 1 1 auto;
}

.guide-title {
    margin: 0;
    font-size: 1rem;
    line-height: 1.45;
    color: var(--ink-strong);
}

.guide-summary {
    margin: 0;
    color: var(--muted);
    font-size: .88rem;
    line-height: 1.6;
}

/* ตัวชี้ทางออกของการ์ด — ดันไปชิดล่างเสมอ การ์ดที่คำโปรยยาวไม่เท่ากัน
   จะได้มีเส้นฐานเดียวกันทั้งแถว */
.guide-more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: auto;
    padding-top: 4px;
    color: var(--leaf);
    font-size: .85rem;
    font-weight: 600;
}

.guide-more svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    transition: transform .2s var(--ease);
}

.guide-card:hover .guide-more svg {
    transform: translateX(3px);
}

/* -- 16 account / auth / checkout ---------------------------------------- */
.account-layout {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: var(--space-6);
    align-items: start;
}

.account-nav {
    position: sticky;
    top: calc(var(--header-height) + 20px);
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.account-nav a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    color: var(--ink);
    font-size: .93rem;
    font-weight: 500;
}

.account-nav a:hover {
    background: var(--surface-muted);
}

.account-nav a[aria-current="page"] {
    background: var(--leaf-soft);
    color: var(--leaf-dark);
    font-weight: 600;
}

.account-nav .icon {
    width: 18px;
    height: 18px;
    flex: none;
    color: var(--muted);
}

.account-nav a[aria-current="page"] .icon {
    color: var(--leaf);
}

.account-nav .icon svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@media (max-width: 900px) {
    .account-layout { grid-template-columns: minmax(0, 1fr); }
    .account-nav {
        position: static;
        flex-direction: row;
        overflow-x: auto;
        gap: 6px;
    }
    .account-nav a { white-space: nowrap; }
}

/* รูปโปรไฟล์บนไอคอนบัญชีของหัวเว็บ — กลมและเต็มปุ่ม ไม่ใช่ไอคอนที่มีรูปข้างใน */
.icon-button.has-avatar {
    padding: 0;
    overflow: hidden;
}

.nav-avatar {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-pill);
    object-fit: cover;
    flex: none;
    display: block;
}

.nav-avatar-initials {
    display: grid;
    place-items: center;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--leaf-dark);
    background: var(--leaf-soft);
}

/* ══════════════════════════════════════════════════════════════════════
   โปรไฟล์ตัวเอง — แท็บ · รูปโปรไฟล์ · สถานะบัญชี · ประวัติการเข้าใช้งาน
   ทุกค่าอ้างโทเคนความหมาย (`--ink` · `--leaf` · `--chili` …) ไม่มี hex ดิบ
   จึงพลิกตามโหมดมืดได้เองเหมือนส่วนอื่นของหน้าร้าน
   ══════════════════════════════════════════════════════════════════════ */

/*
 * `.tab` เดิมเขียนไว้สำหรับ `<button aria-selected>` ของแท็บ JavaScript
 * แท็บของกลุ่มโปรไฟล์เป็น **ลิงก์ที่โหลดหน้าใหม่** (ตามแพตเทิร์นเดียวกับแท็บ
 * ของหลังบ้าน §18.1) จึงต้องมีสถานะ `aria-current="page"` คู่กัน
 *
 * ⚠️ ไม่ fork คอมโพเนนต์ใหม่ — ต่อ *ตารางสถานะ* ของตัวเดิม
 *    สอง `.tab` ที่หน้าตาไม่เหมือนกันในหน้าเดียวคือสิ่งที่ผู้ใช้อ่านว่าคนละระบบ
 */
a.tab {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    text-decoration: none;
}

a.tab:hover {
    color: var(--ink);
}

.tab[aria-current="page"] {
    color: var(--leaf-dark);
    border-bottom-color: var(--leaf);
}

.tab .icon {
    width: 17px;
    height: 17px;
}

/* ── รูปโปรไฟล์ ─────────────────────────────────────────────────────── */
.avatar-editor {
    display: flex;
    align-items: flex-start;
    gap: var(--space-5);
    flex-wrap: wrap;
}

.avatar-preview {
    --avatar-size: 96px;
    width: var(--avatar-size);
    height: var(--avatar-size);
    border-radius: var(--radius-pill);
    object-fit: cover;
    flex: none;
    border: 1px solid var(--line-strong);
    background: var(--surface-muted);
}

.avatar-preview-empty {
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 600;
    color: var(--muted);
    background: var(--surface-sunken);
}

.avatar-editor > .stack {
    flex: 1 1 260px;
    min-width: 0;
}

/* ── สถานะบัญชี ─────────────────────────────────────────────────────── */
.account-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4) var(--space-5);
    margin: 0;
}

.account-facts > div {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.account-facts dt {
    font-size: .82rem;
    color: var(--muted);
}

.account-facts dd {
    margin: 0;
    font-weight: 600;
    color: var(--ink);
}

/* ── ประวัติการเข้าใช้งาน ───────────────────────────────────────────── */
.activity-log {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.activity-item {
    /*
     * โทนของแถวประกาศเป็นตัวแปรระดับคอมโพเนนต์ตัวเดียว แล้วให้ทั้งไอคอนและพื้น
     * อ่านจากตัวนี้ — เพิ่มโทนใหม่จึงแก้ที่เดียว ไม่ใช่สองที่ที่จะเพี้ยนออกจากกัน
     */
    --activity-tone: var(--muted);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
}

.activity-item:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.activity-ok { --activity-tone: var(--success); }
.activity-info { --activity-tone: var(--muted); }
.activity-warn { --activity-tone: var(--amber); }
.activity-alert { --activity-tone: var(--chili); }

.activity-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: var(--radius-pill);
    color: var(--activity-tone);
    /* พื้นจาง ๆ จากสีโทนเดียวกัน — ไม่ต้องมีโทเคนพื้นแยกรายโทน */
    background: color-mix(in srgb, var(--activity-tone) 12%, transparent);
}

.activity-icon .icon {
    width: 17px;
    height: 17px;
}

.activity-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/*
 * 🔴 ต้องตัดข้อความยาวได้ — ชื่ออุปกรณ์และ IP ต่อกันแล้วยาวเกินจอมือถือ
 *    ปล่อยไว้จะดัน `body.scrollWidth` จนทั้งหน้าเลื่อนแนวนอน (§15.9 · §42.1)
 */
.activity-body > span {
    overflow-wrap: anywhere;
}

/* ── แถวความยินยอม / การกระทำที่มีปุ่มด้านขวา ──────────────────────── */
.consent-row {
    gap: var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
}

.consent-row:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

/*
 * 🔴 บนจอ 390px แถบแท็บล้น 28px (วัดจริง: nav 350px · เนื้อหา 378px)
 *    `.tabs` เลื่อนแนวนอนได้เองอยู่แล้วจึงไม่ทำให้ทั้งหน้าเลื่อน — แต่ **แท็บที่
 *    กำลังเปิดอยู่ถูกตัดไป 48px** ผู้ใช้จึงอ่านไม่ออกว่าตัวเองอยู่หน้าไหน
 *
 * ตัดไอคอนออกบนจอแคบ (ประหยัด ~25px ต่อแท็บ) แล้วทั้งสามแท็บพอดีจอ
 * ⚠️ ป้ายข้อความยังอยู่ครบ — ไอคอนเป็นตัวช่วยกวาดสายตา ไม่ใช่ตัวสื่อความหมาย
 *    (`aria-hidden` อยู่แล้ว จึงไม่มีผลกับโปรแกรมอ่านหน้าจอ)
 */
@media (max-width: 430px) {
    .tabs { gap: var(--space-3); }
    .tab .icon { display: none; }
}

@media (max-width: 640px) {
    .account-facts { grid-template-columns: minmax(0, 1fr); }
    .avatar-editor { gap: var(--space-4); }
    /*
     * ปุ่มลงมาอยู่ใต้ข้อความบนจอแคบ — บีบให้อยู่ข้างกันทำให้ทั้งสองฝั่ง
     * แคบจนตัดบรรทัดทีละคำ ซึ่งเป็นกับดักของข้อความไทยใน flex (§4)
     */
    .consent-row {
        flex-direction: column;
        align-items: flex-start;
    }
}

.auth-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    min-height: 100vh;
}

/*
 * 🔴 พื้นของแผงแบรนด์ต้องไม่ผูกกับ `--leaf`
 *
 * `--leaf` พลิกเป็นเขียวอ่อน (#b3bd6e) ในโหมดมืด เพราะที่อื่นใช้เป็น *สีตัวอักษร*
 * บนพื้นเข้ม · แต่ที่นี่ใช้เป็น *พื้น* และตัวอักษรเป็นสีขาวตายตัว
 * ผลคือในโหมดมืดหัวเรื่องกับ 3 ข้อดีของการสมัคร เหลือ contrast ~1.9:1
 * (เกณฑ์คือ 4.5:1) — อ่านแทบไม่ออกจนกว่าจะเปิดโหมดมืดมาดูเอง
 * ⚠️ โหมดสว่างเดิมถูกอยู่แล้ว (ขาวบน #5e6426 ได้ ~6.3:1) — เขียนค่าเดิมตรง ๆ
 *    ไม่ได้เปลี่ยนสี แค่เลิกพึ่งโทเคนที่พลิก · โหมดมืดใช้เขียวเข้มกว่า ได้ ~10:1
 */
.auth-aside {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--space-6);
    padding: var(--space-7) var(--space-7);
    background: #5e6426;
    color: #fff;
}

:root[data-theme="dark"] .auth-aside {
    background: #3c4118;
}

.auth-aside h2,
.auth-aside h1 {
    color: #fff;
}

.auth-aside p {
    color: rgba(255, 255, 255, .84);
}

.auth-aside .brand,
.auth-aside .brand:hover {
    color: #fff;
}

/* tagline ใต้ชื่อร้าน ("SOUTHERN THAI") — ค่าปกติคือ --muted ซึ่งบนแผงมะกอกเข้ม
   อ่านไม่ออกเลย (~1.8:1, บั๊กเดิมก่อนรอบธีมขาว)
   ขาวโปร่ง 82% composite แล้วได้ 4.87:1 บนแผงสว่าง / 7.82:1 บนแผงโหมดมืด */
.auth-aside .brand-text small {
    color: rgba(255, 255, 255, .82);
}

/**
 * แผงซ้ายของหน้าเข้าสู่ระบบเป็นพื้นเข้ม — ตราจึงต้องเป็นสีขาว
 * (ไม่ใช่พื้นสีครอบ แต่เป็นสีของตัวตราเอง ให้อ่านออกบนพื้นเข้ม)
 */
.auth-aside .brand-mark {
    background: none;
    color: #fff;
}

.auth-aside .auth-points {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.auth-aside .auth-points li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.auth-aside .auth-points .icon {
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 3px;
}

.auth-aside .auth-points .icon svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.auth-main {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-7) var(--space-5);
}

.auth-card {
    width: 100%;
    max-width: 420px;
}

.auth-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--muted);
    font-size: .82rem;
    margin: var(--space-4) 0;
}

.auth-divider::before,
.auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

.social-row {
    display: grid;
    gap: 10px;
}

/*
 * ปุ่มเข้าสู่ระบบด้วยบัญชีอื่น
 *
 * โลโก้ถูกตรึงไว้ชิดซ้ายด้วย `position:absolute` แทนที่จะไหลไปกับข้อความ
 * เพราะป้ายภาษาไทยยาวไม่เท่ากัน ("…ด้วย LINE" กับ "…ด้วย Facebook") ถ้าปล่อยให้
 * โลโก้อยู่ติดข้อความ มันจะเยื้องกันคนละตำแหน่งทั้งสามปุ่ม ซึ่งอ่านเป็นความไม่เรียบร้อย
 * มากกว่าที่จะอ่านเป็นการจัดกึ่งกลาง
 */
.social-button {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 12px 16px 12px 48px;
    min-height: 48px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    font-weight: 600;
    font-size: .93rem;
    text-align: center;
    transition: border-color .16s var(--ease), background-color .16s var(--ease), box-shadow .16s var(--ease);
}

.social-button:hover {
    border-color: var(--ink);
    color: var(--ink);
    background: var(--surface-muted);
}

.social-mark {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    flex: none;
}

/* ชุดไอคอนรวมวาดด้วย stroke — ตัวสำรองเมื่อยังไม่มีเครื่องหมายการค้าของเจ้านั้น */
.social-mark:not([viewBox]) svg,
.social-button .icon.social-mark svg {
    width: 100%;
    height: 100%;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
}

/*
 * ปุ่มเหล่านี้เป็นลิงก์ที่ยิงไปเซิร์ฟเวอร์แล้วเด้งต่อไปที่ผู้ให้บริการ — ระหว่างนั้น
 * จอไม่มีอะไรเปลี่ยนเลย · 🔴 การกดซ้ำไม่ใช่แค่ช้า: คำขอที่สองสร้าง `state` ใหม่
 * ทับของเดิมใน session แล้วคำขอแรกที่กลับมาจะถูกปฏิเสธด้วย
 * "Invalid social login state." ซึ่งอ่านไม่ออกเลยว่าเกิดจากการกดสองครั้ง
 */
.social-button.is-busy {
    pointer-events: none;
    color: var(--muted);
    background: var(--surface-muted);
}

.social-button.is-busy .social-mark {
    opacity: .45;
}

.social-button.is-busy .social-button-label::after {
    content: "";
    display: inline-block;
    vertical-align: -2px;
    margin-left: 8px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: pk-spin .7s linear infinite;
}

/*
 * แถบเตือน "ยังไม่ได้ยืนยันอีเมล"
 *
 * ⚠️ ข้อความกับปุ่มต้องเป็น **สอง flex item เท่านั้น** — ข้อความไทยที่วางเป็นลูก
 *    ของ flex container โดยตรงจะถูกตัดบรรทัดทีละคำ (CLAUDE.md §4) ซึ่งเทสต์
 *    ทุกตัวผ่านหมดและเห็นได้จากภาพหน้าจอเท่านั้น
 */
.verify-email-banner-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex: 1;
}

.verify-email-banner-body form {
    flex: none;
}

/* หน้าจอเล็กไม่มีแผงแบรนด์ด้านซ้าย — ถ้าไม่มีอะไรบอกว่านี่คือเว็บอะไร */
/* หน้ากรอกรหัสผ่านจะเหลือแค่ฟอร์มลอย ๆ ซึ่งเป็นหน้าตาเดียวกับหน้าหลอกลวง */
.auth-brand-compact {
    display: none;
    align-items: center;
    gap: 10px;
    margin-bottom: var(--space-5);
}

@media (max-width: 900px) {
    .auth-layout { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    .auth-aside { display: none; }
    .auth-main { padding: var(--space-6) var(--space-4); }
    .auth-brand-compact { display: flex; }
}

.steps {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
    flex-wrap: wrap;
}

.step {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    font-size: .9rem;
    font-weight: 600;
}

.step .step-num {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1px solid var(--line-strong);
    font-size: .8rem;
}

.step.is-current {
    color: var(--ink-strong);
}

.step.is-current .step-num {
    background: var(--leaf);
    border-color: var(--leaf);
    color: #fff;
}

.step.is-done .step-num {
    background: var(--success-soft);
    border-color: var(--success);
    color: var(--success);
}

.step-sep {
    flex: 1 1 20px;
    min-width: 20px;
    height: 1px;
    background: var(--line-strong);
}

.timeline {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.timeline li {
    position: relative;
    padding: 0 0 var(--space-5) var(--space-5);
    border-inline-start: 2px solid var(--line);
}

.timeline li:last-child {
    border-inline-start-color: transparent;
    padding-bottom: 0;
}

.timeline li::before {
    content: "";
    position: absolute;
    inset-inline-start: -7px;
    top: 3px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--line-strong);
}

.timeline li.is-done::before {
    background: var(--leaf);
    border-color: var(--leaf);
}

.timeline strong {
    display: block;
    color: var(--ink-strong);
    font-size: .95rem;
}

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

.order-line {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: center;
    padding: var(--space-4) 0;
    border-bottom: 1px solid var(--line);
}

.order-line:last-child {
    border-bottom: 0;
}

.order-line img,
.order-line .thumb-fallback {
    width: 72px;
    height: 72px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    background: var(--surface-muted);
}

.order-line .thumb-fallback {
    display: grid;
    place-items: center;
    color: var(--muted-soft);
}

@media (max-width: 640px) {
    .order-line {
        grid-template-columns: 64px minmax(0, 1fr);
    }
    .order-line > :last-child {
        grid-column: 1 / -1;
    }
}

/* -- 17 utilities -------------------------------------------------------- */
.mt-0 { margin-top: 0 !important; }
.mt-2 { margin-top: var(--space-2) !important; }
.mt-3 { margin-top: var(--space-3) !important; }
.mt-4 { margin-top: var(--space-4) !important; }
.mt-5 { margin-top: var(--space-5) !important; }
.mt-6 { margin-top: var(--space-6) !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-2 { margin-bottom: var(--space-2) !important; }
.mb-3 { margin-bottom: var(--space-3) !important; }
.mb-4 { margin-bottom: var(--space-4) !important; }
.mb-5 { margin-bottom: var(--space-5) !important; }
.mb-6 { margin-bottom: var(--space-6) !important; }
.ms-auto { margin-inline-start: auto !important; }
.me-auto { margin-inline-end: auto !important; }
.w-full { width: 100%; }
.text-center { text-align: center; }
.text-end { text-align: end; }
.flex-1 { flex: 1; }
.hidden { display: none !important; }

@media (max-width: 640px) {
    .hide-sm { display: none !important; }
}

@media (min-width: 901px) {
    .show-mobile { display: none !important; }
}

/* -- 18 motion / print --------------------------------------------------- */
/* Scoped to .js on purpose: the class is set by the inline head script, so if
   scripting is off or site.js fails to load these sections stay visible
   instead of silently disappearing. */
.js [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .5s var(--ease), transform .5s var(--ease);
    will-change: opacity, transform;
}

.js [data-reveal].is-visible {
    opacity: 1;
    transform: none;
}

.back-to-top {
    position: fixed;
    bottom: 20px;
    inset-inline-start: 20px;
    z-index: 80;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
    box-shadow: var(--shadow-sm);
}

.back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
    .js [data-reveal] { opacity: 1; transform: none; }
}

/* ── ผ่อนชำระกับ Atome ────────────────────────────────────────────────────
   สีมาจากชุด --leaf ของแบรนด์ ไม่ใช่สีของ Atome — หน้านี้เป็นของร้าน
   การใช้สีแบรนด์ผู้ให้บริการบนหน้าร้านอ่านเหมือนเป็นโฆษณาแทรก

   ⚠️ ข้อความในบล็อกนี้เป็นเรื่องเงิน ต้องผ่าน AA ทุกตัว จึงใช้ --muted
      (4.90:1 บน --leaf-soft) ไม่ใช่ --muted-soft ที่ได้แค่ 3.3:1 */

.instalment-hint {
    display: block;
    margin-top: .15rem;
    color: var(--leaf-dark);
    font-weight: 600;
}

.instalment-card {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding: .75rem .9rem;
    border: 1px solid var(--line);
    border-left: 3px solid var(--leaf);
    border-radius: var(--radius-sm);
    background: var(--leaf-soft);
}

.instalment-card strong { color: var(--leaf-dark); }
.instalment-card .muted { color: var(--muted); }

.instalment-schedule {
    margin: -.25rem 0 .25rem;
    padding: .75rem .9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-muted);
}

.instalment-schedule table {
    width: 100%;
    border-collapse: collapse;
}

.instalment-schedule caption {
    caption-side: top;
    text-align: left;
    padding-bottom: .4rem;
}

.instalment-schedule th,
.instalment-schedule td {
    padding: .3rem .25rem;
    text-align: left;
    font-weight: 400;
    border-bottom: 1px solid var(--line);
}

.instalment-schedule tfoot th,
.instalment-schedule tfoot td {
    border-bottom: 0;
    border-top: 2px solid var(--line-strong);
    padding-top: .45rem;
    font-weight: 600;
}

.instalment-schedule .ta-right { text-align: right; }

.instalment-terms {
    margin: .5rem 0 0;
    padding-left: 1.1rem;
    color: var(--muted);
}

/* ตารางงวดต้องเลื่อนในกล่องตัวเองบนจอแคบ ไม่ใช่ดันให้หน้าเลื่อนแนวนอน */
@media (max-width: 480px) {
    .instalment-schedule { overflow-x: auto; }
    .instalment-schedule table { min-width: 260px; }
}

/* ── ติดตามพัสดุ ───────────────────────────────────────────────────────────
   แผนที่วาดเป็น SVG ในโค้ด ไม่มี tile จากภายนอก (ดู TrackingMapRenderer)

   ⚠️ ทุกข้อความในหน้านี้ต้องผ่าน AA — เป็นหน้าที่ลูกค้าเปิดตอนกังวลว่าของถึงไหน
      สีอ่อนที่อ่านยากจะทำให้เขาโทรมาถามแทนที่จะอ่านเอง */

.track-head {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-5);
}

.track-status {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem .9rem;
    border-radius: var(--radius-pill);
    font-weight: 600;
    font-size: .92rem;
}

.track-status-active  { background: var(--leaf-soft);   color: var(--leaf-dark); }
.track-status-done    { background: var(--success-soft); color: var(--success); }
.track-status-problem { background: var(--chili-soft, #fdecea); color: var(--chili, #a83b2a); }

/* แถบความคืบหน้า — 44px ขึ้นไปต่อขั้นเพื่อให้แตะได้บนมือถือ */
.track-steps {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: .25rem;
    list-style: none;
    margin: 0 0 var(--space-6);
    padding: 0;
    counter-reset: none;
}

.track-step {
    position: relative;
    min-height: 44px;
    padding-top: 1.4rem;
    text-align: center;
    color: var(--muted);
    font-size: .78rem;
}

/* เส้นเชื่อมระหว่างขั้น — วาดจากขั้นที่สองขึ้นไปเพื่อไม่ให้เส้นโผล่ซ้ายสุด */
.track-step + .track-step::before {
    content: "";
    position: absolute;
    top: .42rem;
    left: -50%;
    width: 100%;
    height: 2px;
    background: var(--line-strong);
}

.track-step.is-done + .track-step::before,
.track-step.is-current::before { background: var(--leaf); }

.track-step-dot {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: .85rem;
    height: .85rem;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--line-strong);
}

.track-step.is-done .track-step-dot { background: var(--leaf); border-color: var(--leaf); }
.track-step.is-done .track-step-label { color: var(--ink); }

.track-step.is-current .track-step-dot {
    background: var(--surface);
    border-color: var(--leaf);
    box-shadow: 0 0 0 4px var(--leaf-soft);
}

.track-step.is-current .track-step-label { color: var(--leaf-dark); font-weight: 600; }

.track-layout {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--space-5);
    align-items: start;
}

/* แผนที่ */
.track-map { margin: 0; }

/* Google Maps จริง (เมื่อมีคีย์เปิดใช้) — SVG ข้างล่างคือทางถอย
   🔴 ต้องมีความสูงตายตัวก่อนแผนที่โหลด — แผนที่ในกล่องสูง 0 วาดไม่ขึ้น
   และการจองพื้นที่ไว้กัน layout shift ตอนสลับจาก SVG (CLS) */
.track-gmap {
    width: 100%;
    height: clamp(320px, 58vh, 560px);
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    background: var(--surface-muted);
}

/* กติกาเดิมของโปรเจกต์: [hidden] ต้องมีกฎประกบเมื่อ element มีกฎ display ของตัวเอง
   (site.css ตั้ง display ให้ svg ไว้ที่กฎ img,svg,video — เคยพลาดมาแล้ว 3 ครั้ง §25.3) */
.track-gmap[hidden] { display: none; }

.track-map svg {
    display: block;
    width: 100%;
    height: auto;
    max-height: 62vh;
    margin-inline: auto;
}

.track-map-land {
    fill: var(--surface-muted);
    stroke: var(--line-strong);
    stroke-width: 1.5;
}

.track-map-route {
    fill: none;
    stroke: var(--leaf);
    stroke-width: 2.5;
    stroke-dasharray: 7 5;
    stroke-linecap: round;
}

.track-map-pin circle { fill: var(--leaf); stroke: var(--surface); stroke-width: 2; }
.track-map-pin.is-latest circle { fill: var(--chili, #a83b2a); stroke-width: 3; }
.track-map-pin text { fill: var(--ink); font-size: 12px; font-weight: 600; }

/* ⚠️ หมุดล่าสุดเต้นเพื่อบอกว่าอันไหนคือปัจจุบัน — แต่ต้องเคารพ
   prefers-reduced-motion เพราะการเคลื่อนไหวซ้ำ ๆ รบกวนผู้ที่แพ้การเคลื่อนไหว */
@media (prefers-reduced-motion: no-preference) {
    .track-map-pin.is-latest circle { animation: track-pulse 2.2s ease-in-out infinite; }
}

@keyframes track-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .55; }
}

/* ไทม์ไลน์ */
.track-timeline { list-style: none; margin: 0; padding: 0; }

.track-event {
    display: grid;
    grid-template-columns: 7.5rem 1fr;
    gap: var(--space-3);
    padding: .7rem 0;
    border-bottom: 1px solid var(--line);
}

.track-event:last-child { border-bottom: 0; }
.track-event-time { color: var(--muted); font-size: .8rem; font-variant-numeric: tabular-nums; }
.track-event.is-latest strong { color: var(--leaf-dark); }

@media (max-width: 900px) {
    .track-layout { grid-template-columns: minmax(0, 1fr); }
    .track-map svg { max-height: 54vh; }
}

@media (max-width: 560px) {
    /* ป้ายขั้นตอนบนจอแคบ: ตัดเหลือตัวเลขไม่ได้เพราะต้องอ่านออกด้วยโปรแกรมอ่านหน้าจอ
       จึงย่อขนาดตัวอักษรแทนการซ่อน */
    .track-step-label { font-size: .68rem; }
    .track-event { grid-template-columns: minmax(0, 1fr); gap: .15rem; }
}

@media print {
    .site-header,
    .site-footer,
    .toast-host,
    .back-to-top,
    .nav-drawer,
    .cart-drawer,
    .no-print {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
    }

    .card,
    .table-wrap {
        border-color: #ccc;
        box-shadow: none;
    }
}

/* -- 19 แพ็กเกจสมาชิก & หน้าเลือกเมนู -------------------------------------
   ใช้กับ /subscriptions, /subscribe/{id} และ /account/subscriptions/{id}/menu
   ทั้งสามหน้าใช้โทเคนชุดเดิมของแบรนด์ ไม่มีสีใหม่ — แต่ละแพ็กเกจแยกด้วย
   --plan-accent ที่ผู้ดูแลตั้งเองได้ในหลังบ้าน (ค่าเริ่มต้นตกไปที่ --leaf)

   🔴 ข้อความทุกคู่สีในบล็อกนี้อยู่บนพื้น --surface/--surface-muted ซึ่งวัด
      คอนทราสต์แล้วผ่าน WCAG AA · --plan-accent ถูกใช้กับ "เส้น/พื้นอ่อน/ไอคอน"
      เท่านั้น ไม่เคยใช้เป็นสีข้อความยาว เพราะค่าที่ผู้ดูแลกรอกเองอาจสว่างเกิน
   ------------------------------------------------------------------------ */

/* ชื่อเดียวกับ .sr-only — วิวบางหน้าใช้ศัพท์ของ Bootstrap เพราะหลังบ้านใช้ตัวนั้น
   การมีสองชื่อดีกว่าการมีข้อความที่ควรซ่อนแล้วโผล่ออกมาเพราะพิมพ์คลาสผิด */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── ตัวสลับรอบสัปดาห์/เดือน ── */
.plan-period-switch {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    margin: 0 auto var(--space-5);
    background: var(--surface-muted);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
}

.section-tight .plan-period-switch { display: flex; width: fit-content; }

.plan-period-option {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: .9rem;
    /* 44px คือขนาดขั้นต่ำที่นิ้วกดพลาดยาก — ปุ่มสลับราคาถูกกดบนมือถือเป็นหลัก */
    min-height: 44px;
    padding: 0 20px;
    border-radius: var(--radius-pill);
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    transition: background .18s var(--ease), color .18s var(--ease);
}

.plan-period-option:hover { background: rgba(0, 0, 0, .05); }

.plan-period-option.is-active {
    background: var(--surface);
    color: var(--ink-strong);
    font-weight: 600;
    box-shadow: var(--shadow-xs);
}

/* ── การ์ดแพ็กเกจ ── */
.plan-card-grid { align-items: stretch; }

.plan-card {
    position: relative;
    border-top: 3px solid var(--plan-accent, var(--leaf));
}

.plan-card.is-featured {
    border-color: var(--plan-accent, var(--leaf));
    box-shadow: var(--shadow);
}

.plan-card .card-body { height: 100%; }

.plan-tagline {
    color: var(--plan-accent, var(--leaf));
    font-weight: 600;
    font-size: .9rem;
}

.plan-price-block { min-height: 60px; }

.plan-price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
}

.plan-price[hidden] { display: none; }

.plan-price-was {
    color: var(--muted);
    text-decoration: line-through;
    font-size: .95rem;
}

.plan-quota {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: var(--surface-muted);
    border-radius: var(--radius);
    font-size: .92rem;
}

.plan-quota .icon { color: var(--plan-accent, var(--leaf)); flex: none; }

.plan-promo-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 6px;
}

.plan-promo-list li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: .88rem;
    color: var(--amber);
}

.plan-promo-list .icon { flex: none; }

/* ── ตารางเปรียบเทียบ ── */
.plan-matrix-section { margin-top: var(--space-8); }
.plan-matrix-section h2 { margin-bottom: var(--space-2); }

.plan-matrix-head {
    color: var(--plan-accent, var(--leaf));
    font-weight: 700;
}

.plan-matrix .table th[scope="row"] {
    text-align: start;
    font-weight: 500;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.plan-matrix-group th {
    background: var(--surface-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .75rem;
    color: var(--muted);
}

.plan-matrix tr.is-highlight { background: var(--leaf-soft); }

.plan-matrix-note {
    display: block;
    font-size: .78rem;
    color: var(--muted);
}

.plan-yes { color: var(--success); display: inline-flex; }
.plan-yes .icon { width: 20px; height: 20px; }
/* เครื่องหมาย "ไม่มี" เป็นไอคอน minus — ใช้ --muted ไม่ใช่ --muted-soft เพราะบนแถว
   ไฮไลต์ (พื้น --leaf-soft) muted-soft ได้คอนทราสต์ไม่ถึง 3:1 สำหรับ graphical object */
.plan-no { color: var(--muted); font-size: 1.1rem; display: inline-flex; }
.plan-no .icon { width: 18px; height: 18px; }

/* ดาวกำกับสิทธิ์เด่นในตารางเปรียบเทียบ (ทั้งตารางเดสก์ท็อปและการ์ดมือถือ) */
.plan-star {
    width: 1em;
    height: 1em;
    color: var(--amber);
    margin-inline-end: 5px;
}

/* แถวไฮไลต์ฝั่งมือถือ — พื้นสีเดียวกับ tr.is-highlight ของตารางใหญ่
   ขยับขอบด้วย margin ติดลบเพื่อให้ตัวหนังสือยังตรงคอลัมน์กับแถวอื่น */
.plan-matrix-list-row.is-highlight {
    background: var(--leaf-soft);
    padding-inline: 10px;
    margin-inline: -10px;
    border-radius: var(--radius-sm);
}

/* ── หน้ารายละเอียดรายแพ็กเกจ (/subscriptions/{slug}) ──────────────────
   สรุปราคา+CTA อยู่ก่อนใน DOM (มือถือเห็นก่อน) · เดสก์ท็อปสลับด้วย order
   ไปเป็นคอลัมน์ขวาแบบ sticky — ห้ามสลับด้วยการย้าย DOM ไม่งั้นจอเล็กต้อง
   เลื่อนผ่านเงื่อนไขทั้งหน้ากว่าจะเจอราคา */
.plan-detail-head { margin-bottom: var(--space-6); }

.plan-detail-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

@media (min-width: 901px) {
    .plan-detail-layout { grid-template-columns: minmax(0, 1fr) 360px; gap: var(--space-6); }
    .plan-detail-summary { order: 2; position: sticky; top: calc(var(--header-height) + 20px); }
    .plan-detail-body { order: 1; }
}

.plan-detail-price-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.plan-detail-price-row + .plan-detail-price-row {
    padding-top: var(--space-3);
    border-top: 1px solid var(--line);
}

/* หัวข้อกลุ่มสิทธิ์ — ศัพท์ชุดเดียวกับหัวกลุ่มในตารางเปรียบเทียบหน้ารวม */
.plan-detail-group-title {
    margin-top: var(--space-4);
    padding-bottom: 6px;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
}

.plan-detail-conditions { gap: 0; }
.plan-detail-conditions .plan-matrix-list-row { padding-block: 10px; }
.plan-detail-conditions dd { text-align: end; }
.plan-value { font-weight: 600; color: var(--ink-strong); }

/* จอเล็ก: ตารางเทียบข้างกันอ่านไม่ได้ → พลิกเป็นการ์ดต่อแพ็กเกจ */
.plan-matrix-cards { display: none; }

.plan-matrix-list { margin: 0; display: grid; gap: 2px; }

.plan-matrix-list-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}

.plan-matrix-list-row:last-child { border-bottom: 0; }
.plan-matrix-list-row dt { margin: 0; font-size: .9rem; }
.plan-matrix-list-row dd { margin: 0; }
.plan-matrix-list-row.is-off dt { color: var(--muted); }

@media (max-width: 860px) {
    .plan-matrix { display: none; }
    .plan-matrix-cards { display: grid; gap: var(--space-4); }
}

/* ── หน้าเลือกเมนู ── */
.builder-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}

.builder-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--space-5);
    align-items: start;
}

.builder-summary-card { position: sticky; top: calc(var(--header-height) + 12px); }

.builder-summary-title {
    font-size: 1.05rem;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

.menu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: var(--space-4);
}

.menu-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}

.menu-card:hover { box-shadow: var(--shadow-sm); }

.menu-card.is-picked {
    border-color: var(--plan-accent, var(--leaf));
    box-shadow: 0 0 0 1px var(--plan-accent, var(--leaf));
}

/* 🔴 เมนูที่เลือกไม่ได้ยัง "อ่านได้" — หรี่จนอ่านไม่ออกเท่ากับซ่อนมันทิ้ง
   ซึ่งทำให้ผู้ใช้ไม่รู้ว่ามีเมนูนั้นอยู่ และไม่รู้ว่าต้องอัปเกรดเพื่ออะไร */
.menu-card.is-blocked { background: var(--surface-muted); }
.menu-card.is-blocked .menu-card-image { opacity: .55; }

.menu-card-image {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    display: block;
    background: var(--surface-sunken);
}

.menu-card-image-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted-soft);
}

.menu-card-image-empty .icon { width: 40px; height: 40px; }

.menu-card-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: var(--space-3);
    flex: 1;
}

.menu-card-badges { display: flex; flex-wrap: wrap; gap: 4px; min-height: 0; }

.menu-card-title {
    font-size: .98rem;
    margin: 0;
    line-height: 1.35;
}

/* ชื่อ/รูปเมนูบนหน้าเลือกเมนู คลิกไปหน้าสินค้าได้ — สีคงเดิม (ชื่อเขียวทั้งกริด
   อ่านเป็นโฆษณา) hover เป็นตัวบอกว่ากดได้ */
.menu-card-title a { color: inherit; }
.menu-card-title a:hover { color: var(--leaf); }
.menu-card-media-link { display: block; }
.builder-item-name:hover { color: var(--leaf); }

.menu-card-desc {
    margin: 0;
    font-size: .82rem;
    color: var(--muted);
}

.menu-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: auto;
}

.menu-card-points {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: .78rem;
    color: var(--amber);
}

.menu-card-points .icon { width: 14px; height: 14px; }

.menu-card-reason {
    margin: 0;
    display: flex;
    align-items: flex-start;
    gap: 6px;
    font-size: .8rem;
    color: var(--ink);
    background: var(--amber-soft);
    border-radius: var(--radius-sm);
    padding: 8px 10px;
}

.menu-card-reason .icon { flex: none; width: 15px; height: 15px; margin-top: 1px; }

.menu-card-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.menu-card-hint {
    margin: 0;
    font-size: .75rem;
    color: var(--muted);
}

.menu-step {
    appearance: none;
    /* 44×44 — ปุ่ม +/- ถูกกดถี่ที่สุดในหน้านี้ และกดพลาดหมายถึงสั่งอาหารผิด */
    width: 44px;
    height: 44px;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--ink);
    cursor: pointer;
    transition: background .18s var(--ease), border-color .18s var(--ease);
}

.menu-step:hover:not([disabled]) {
    background: var(--leaf-soft);
    border-color: var(--leaf);
}

.menu-step[disabled] { opacity: .4; cursor: not-allowed; }
.menu-step .icon { width: 18px; height: 18px; }

.menu-qty {
    flex: 1;
    text-align: center;
    font-weight: 700;
    font-size: 1.05rem;
}

/* ── แถบความคืบหน้า + กล่องสรุป ── */
.builder-progress { display: grid; gap: 6px; }

.builder-progress-bar {
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    overflow: hidden;
}

.builder-progress-fill {
    height: 100%;
    background: var(--plan-accent, var(--leaf));
    border-radius: inherit;
    transition: width .25s var(--ease);
}

.builder-progress-fill.is-complete { background: var(--success); }

.builder-progress-text { margin: 0; font-size: .88rem; }

.builder-item-list,
.builder-reward-list,
.builder-history {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.builder-item-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}

.builder-item-list li:last-child { border-bottom: 0; }

.builder-reward-list li,
.builder-history li {
    display: grid;
    gap: 2px;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}

.builder-reward-list li:last-child,
.builder-history li:last-child { border-bottom: 0; }

.builder-item-name { font-size: .9rem; font-weight: 500; }

.builder-item-remove {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    /* พื้นที่กดต้องพอสำหรับนิ้ว แม้ไอคอนจะเล็ก */
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
}

.builder-item-remove:hover { background: var(--chili-soft); color: var(--chili); }
.builder-item-remove .icon { width: 16px; height: 16px; }

.builder-price { margin: 0; display: grid; gap: 4px; }

.builder-price > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: .9rem;
}

.builder-price dt, .builder-price dd { margin: 0; }
.builder-price-discount { color: var(--chili); }

.builder-price-total {
    border-top: 1px solid var(--line);
    padding-top: 8px;
    margin-top: 4px;
    font-size: 1rem !important;
    font-weight: 700;
}

.builder-price-total dd { color: var(--ink-strong); font-size: 1.2rem; }

.builder-points,
.builder-gate-note,
.builder-change-note {
    margin: 0;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: .84rem;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
}

.builder-points { background: var(--amber-soft); color: var(--ink); }
.builder-points .icon { color: var(--amber); flex: none; width: 16px; height: 16px; }

/* 🔴 คำอธิบายว่าทำไมปุ่มชำระเงินยังกดไม่ได้ — ปุ่มที่ปิดโดยไม่บอกเหตุผล
   ผู้ใช้อ่านว่าเว็บเสีย ไม่ใช่ว่ายังทำไม่ครบ */
.builder-gate-note { background: var(--chili-soft); color: var(--ink); }
.builder-gate-note .icon { color: var(--chili); flex: none; width: 16px; height: 16px; }

.builder-change-note { background: var(--surface-muted); color: var(--muted); }
.builder-change-note .icon { flex: none; width: 16px; height: 16px; }

/* แถว "เอาเหมือนรอบที่แล้ว" — ข้อความยาวกับปุ่มสั้นในแถวเดียวกัน
   🔴 ข้อความต้องอยู่ใน `<span>` เดียว (ดู `.builder-gate-note`) — ข้อความไทย
   ที่เป็นลูกตรง ๆ ของ flex container จะถูกตัดบรรทัดทีละคำจนอ่านไม่ออก
   ซึ่งเห็นได้จากภาพหน้าจอเท่านั้น เทสต์ข้อความผ่านหมด */
.builder-copy-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
}

.builder-copy-row > span { flex: 1 1 260px; }
.builder-copy-row form { flex: none; }

/* ── แถบสรุปติดขอบล่าง (มือถือ) ── */
.builder-sticky {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 40;
    display: none;
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -8px 24px rgba(26, 25, 21, .07);
    padding: 10px 0 max(10px, env(safe-area-inset-bottom));
}

.builder-sticky-inner {
    max-width: var(--container);
    margin: 0 auto;
    padding-inline: var(--space-4);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

@media (max-width: 1000px) {
    .builder-layout { grid-template-columns: minmax(0, 1fr); }
    .builder-summary-card { position: static; }
}

@media (max-width: 720px) {
    .builder-sticky { display: block; }
    /* เว้นที่ให้แถบล่าง ไม่งั้นมันทับการ์ดเมนูใบสุดท้ายจนกดไม่ได้ */
    .builder-layout { padding-bottom: 84px; }
    .menu-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-3); }
    .builder-head { align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
    .plan-period-option,
    .menu-card,
    .menu-step,
    .builder-progress-fill { transition: none; }
}

/* -- 20 แต้มสะสม & ของรางวัล (หน้า /account/rewards) ----------------------- */

.points-hero {
    border-color: var(--gold);
    background: linear-gradient(135deg, var(--amber-soft), var(--surface) 65%);
}

.points-hero-value {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 6vw, 3rem);
    font-weight: 700;
    line-height: 1.1;
    color: var(--ink-strong);
}

.points-hero-icon { color: var(--amber); }
.points-hero-icon .icon,
.points-hero-icon svg { width: 44px; height: 44px; }

.reward-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-4);
}

.reward-card { height: 100%; }
.reward-card .card-body { height: 100%; }

/* 🔴 ของที่แลกไม่ได้ยังต้องอ่านออก — หรี่จนอ่านไม่ออกเท่ากับซ่อนทิ้ง
   แล้วลูกค้าจะไม่รู้ว่ามีอะไรให้สะสมแต้มไปเพื่ออะไร */
.reward-card.is-locked { background: var(--surface-muted); }

.reward-card-title { font-size: 1rem; line-height: 1.35; }

.reward-cost {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: auto;
    padding: 8px 10px;
    background: var(--amber-soft);
    border-radius: var(--radius-sm);
    font-size: .95rem;
}

.reward-cost .icon { color: var(--amber); flex: none; width: 16px; height: 16px; }

/* จำนวนสิทธิ์ที่เหลือ — อยู่ปลายอีกด้านของแถบราคา (ความเร่งด่วนคู่กับจุดตัดสินใจ) */
.reward-left {
    margin-inline-start: auto;
    font-size: .78rem;
    font-weight: 700;
    color: var(--chili);
    white-space: nowrap;
}

.reward-short {
    margin: 0;
    text-align: center;
    font-size: .82rem;
    color: var(--chili);
}

.grant-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
}

.grant-item {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

.grant-item:last-child { border-bottom: 0; }

/* สถานะ+ปุ่มต้องชิดขวาเสมอ แม้ตอนที่คอลัมน์ซ้ายยาวจนดันมันขึ้นบรรทัดใหม่
   (ไม่งั้นสิทธิ์ที่มีรหัส/คำอธิบายยาว จะจัดวางไม่เหมือนสิทธิ์อื่นในลิสต์เดียวกัน) */
.grant-item > :last-child { margin-inline-start: auto; }

/* รหัสถูกอ่านออกเสียงและพิมพ์ตาม — ต้องเป็น monospace และคัดลอกง่าย */
.grant-code {
    font-family: var(--font-mono);
    font-size: .9rem;
    letter-spacing: .06em;
    color: var(--ink-strong);
    background: var(--surface-sunken);
    border-radius: var(--radius-xs);
    padding: 2px 8px;
    align-self: flex-start;
    user-select: all;
}

@media (max-width: 560px) {
    .reward-grid { grid-template-columns: minmax(0, 1fr); }
}

/* แต้มที่กำลังจะหมดอายุ — ต้องเห็นตั้งแต่บนสุดของหน้า ไม่ใช่ซ่อนอยู่ในประวัติ */
.points-expiry {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 8px;
    padding: 8px 10px;
    background: var(--chili-soft);
    border-radius: var(--radius-sm);
    font-size: .84rem;
}

.points-expiry .icon { color: var(--chili); flex: none; width: 16px; height: 16px; }

/* กล่องเลือกสิทธิ์ของรางวัลในตะกร้า */
.reward-picker { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--line); }

.reward-picker-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.reward-picker-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

.reward-picker-list li:last-child { border-bottom: 0; }
.reward-picker-list li > :last-child { margin-inline-start: auto; }

/* -- 21 หน้าบัญชี: หัวข้อส่วน · แถวข้อมูล · สถิติบนมือถือ ------------------
   เพิ่ม 2026-08-18 ตอนปรับ UX หน้า account/subscriptions + account/rewards
   ------------------------------------------------------------------------ */

/* 🔴 หัวข้อ "ส่วน" ในคอลัมน์บัญชี — ก่อนหน้านี้เขียน style="font-size:1.15rem"
   ทับ h2 อยู่ 5 ที่ ซึ่งเป็นขนาดที่ไม่มีอยู่ในสเกลของระบบเลย
   ใช้ขนาดเดียวกับ h3 (1.25rem) เพื่อให้เป็น "ขั้น" จริงในสเกล ไม่ใช่ตัวเลขสุ่ม
   ลำดับที่ได้: h1 หน้า → .section-title ส่วน → .card-head หัวการ์ด → เนื้อหา */
.section-title {
    font-family: var(--font-sans);
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -.01em;
    margin: 0;
}

/* ค่าสถิติที่เป็น "ข้อความ/วันที่" ไม่ใช่ตัวเลขเด่น — 1.6rem ของ .stat-value
   ทำให้วันที่ยาวตัดบรรทัดกลางค่า · ใช้ขั้น 1.25rem ของสเกลแทนการตั้งเลขเอง */
.stat .stat-value-sm { font-size: 1.25rem; }

.section-title .icon,
.section-title svg { width: 20px; height: 20px; }

/* คำอธิบายใต้หัวข้อส่วน — อยู่คู่กับ .section-title ใน .section-head */
.section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.section-head p {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: .88rem;
}

/* 🔴 แถวข้อมูลที่มีหลายบรรทัด (สิทธิ์ · ประวัติแต้ม · โค้ดลุ้นโชค)
   ต้องเป็นคอลัมน์เสมอ — ของเดิมใช้ `.stack-sm` เดี่ยว ๆ ซึ่งเป็น "ตัวปรับ gap"
   ไม่ได้เปิด flex ให้ ทุก <span> จึงไหลต่อกันเป็นย่อหน้าเดียวอ่านไม่ออก
   คลาสนี้เป็นตาข่ายรับ: ต่อให้ลืมใส่ `.stack` แถวข้อมูลก็ยังเรียงลง */
.data-lines {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    min-width: 0;
}

.data-lines > * { max-width: 100%; }

/* ค่าที่อ่านเป็น "ตัวเลข/วันที่" ในแถวข้อมูล — ให้หลักตรงกันทุกแถว */
.data-meta {
    color: var(--muted);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}

/* ⚠️ 4 สถิติบนมือถือเดิมกลายเป็นกล่องเต็มความกว้าง 4 ใบซ้อนกัน = ~320px
   สำหรับข้อมูล 4 บรรทัดสั้น ๆ · จอแคบให้ 2 คอลัมน์ ค่ายังอ่านครบ */
@media (max-width: 620px) {
    .stat-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-2);
    }

    .stat { padding: var(--space-3); }

    /* ⚠️ "23 Aug 2026" ที่ 1.25rem ตัดบรรทัดกลางค่าเป็น "23 Aug" / "2026"
       ในคอลัมน์กว้าง ~150px · วันที่ที่ขาดครึ่งอ่านเป็นข้อมูลคนละชิ้น */
    .stat .stat-value-sm { font-size: 1.05rem; }

    /* คำอธิบายใต้หัวข้อส่วน ต้องลงบรรทัดของตัวเอง ไม่ใช่เบียดข้างหัวข้อ */
    .section-head {
        align-items: flex-start;
        flex-direction: column;
        gap: 2px;
    }

    .section-head p { margin-top: 0; }
}

/* แถวปุ่มจัดการ — งานที่ทำบ่อยอยู่ซ้าย ส่วนที่ย้อนกลับไม่ได้ถูกดันไปขวาสุด
   และคั่นด้วยเส้น เพื่อไม่ให้อยู่ติดกับปุ่มปลอดภัยจนกดพลาด */
.action-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.action-row .action-danger {
    margin-inline-start: auto;
    padding-inline-start: var(--space-3);
    border-inline-start: 1px solid var(--line);
}

@media (max-width: 620px) {
    .action-row .action-danger {
        margin-inline-start: 0;
        padding-inline-start: 0;
        border-inline-start: 0;
        padding-top: var(--space-2);
        border-top: 1px solid var(--line);
        width: 100%;
    }
}

/* -- 22 พาเนลตั้งค่าแบบพับได้ (การ์ด Subscription) -------------------------
   🔴 กติกา: พับ "ตัวควบคุม" ได้ แต่ "ค่าปัจจุบัน" ต้องอ่านได้โดยไม่ต้องกาง
      (บทเรียน CLAUDE.md §17 — ของที่ถูกยัดใน <details> ปิด กลายเป็นของหาย)
   ------------------------------------------------------------------------ */
.setting-fold { padding: 0; }

.setting-fold-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    cursor: pointer;
    list-style: none;
    /* เป้าแตะขั้นต่ำ 44px แม้ข้อความจะสั้น */
    min-height: 44px;
}

/* ลูกศรของเบราว์เซอร์ถูกแทนด้วยไอคอนของระบบ (Safari ใช้ pseudo คนละตัว) */
.setting-fold-head::-webkit-details-marker { display: none; }
.setting-fold-head::marker { content: ''; }

.setting-fold-head:hover { background: var(--surface-sunken); }

.setting-fold-head:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: -2px;
}

.setting-fold-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.setting-fold-label {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
}

/* 🔴 ค่าปัจจุบัน — นี่คือสิ่งที่ทำให้การพับไม่เท่ากับการซ่อน */
.setting-fold-value {
    font-weight: 600;
    color: var(--ink-strong);
    overflow-wrap: anywhere;
}

/* "ยังไม่ได้เลือก" ต้องอ่านออกว่าเป็นงานค้าง ไม่ใช่ค่าปกติ */
.setting-fold-value.is-empty {
    color: var(--chili);
    font-weight: 700;
}

.setting-fold-cue {
    flex: none;
    color: var(--muted);
    display: inline-flex;
    transition: transform .18s var(--ease);
}

.setting-fold[open] > .setting-fold-head > .setting-fold-cue { transform: rotate(180deg); }

.setting-fold[open] > .setting-fold-head {
    border-bottom: 1px solid var(--line);
}

/* เนื้อในของพาเนลได้ padding เท่าเดิมของ .panel */
.setting-fold > form { padding: var(--space-4); }

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