/* ============================================================
   StudentOS AI — ALT overlay
   ใช้เฉพาะบิลด์ ALT (รุ่นทดลองฟีเจอร์) — โหลดต่อจาก style.css
   หน้าที่เดียว: ทำให้ "รู้ทันทีว่านี่คือตัวทดลอง ไม่ใช่ตัวจริง"
   ไม่แตะ layout เดิมเลย เพื่อให้สลับ/อัปเดต style.css ได้อิสระ
   ============================================================ */

/* ══════════════════════════════════════════════════════════════════
   สีประจำวิชา
   ------------------------------------------------------------------
   ชุดนี้เป็น "ป้ายชื่อ" ไม่ใช่ "ระดับความด่วน" — ใช้บอกว่าอันไหนวิชาเดียวกัน
   สีความหมาย (แดง=ด่วน · เหลือง=ใกล้ · เขียว=สบาย) ยังสงวนไว้ให้ชิปสถานะ
   ห้ามให้องค์ประกอบเดียวใส่ทั้งสองระบบ ไม่งั้นสีแดงของวิชาคณิตจะถูกอ่านว่า "ด่วนมาก"
   ค่าเดียวกันทั้งธีมสว่างและมืด เพราะเป็นสีทึบที่คุมคอนทราสต์กับตัวหนังสือของตัวเองอยู่แล้ว
   ══════════════════════════════════════════════════════════════════ */
.sj-0 { --sj: #8593AB; --sj-on: #FFFFFF; }
.sj-1 { --sj: #E8474B; --sj-on: #FFFFFF; }
.sj-2 { --sj: #EE7F38; --sj-on: #FFFFFF; }
.sj-3 { --sj: #E5B93B; --sj-on: #3F2D00; }
.sj-4 { --sj: #2FB86B; --sj-on: #FFFFFF; }
.sj-5 { --sj: #23A0CE; --sj-on: #FFFFFF; }
.sj-6 { --sj: #3E72E0; --sj-on: #FFFFFF; }
.sj-7 { --sj: #A85AD6; --sj-on: #FFFFFF; }
.sj-8 { --sj: #E0609E; --sj-on: #FFFFFF; }
.sj-9  { --sj: #14A38B; --sj-on: #FFFFFF; }
.sj-10 { --sj: #6E67D6; --sj-on: #FFFFFF; }
.sj-11 { --sj: #C4553C; --sj-on: #FFFFFF; }
.sj-12 { --sj: #5E8C2E; --sj-on: #FFFFFF; }

/* จุดกลม — ใช้ในปฏิทินและรายการที่ต้องบอกแค่ว่า "วิชาไหน" */
.sjdot { width: 6px; height: 6px; border-radius: 50%; background: var(--sj); flex: none; }
/* แถบซ้าย — ใช้ในแถวคาบเรียน ให้รูปทรงเดียวกับตารางเรียนที่โรงเรียนแจก */
.sjbar { width: 3px; border-radius: 2px; background: var(--sj); flex: none; align-self: stretch; }

/* ป้ายเลขรุ่น — กลางบนจอ (1A6M2) ลอยเหนือทุกจอ แต่ไม่รับคลิก */
.ver-badge {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 90;
  pointer-events: none;
  font: 700 10px/1 'Space Mono', ui-monospace, monospace;
  letter-spacing: .14em;
  padding: 5px 9px 4px;
  border-radius: 999px;
  /* เดิมเป็นป้ายทองสด — มันถูกออกแบบมาเตือนว่า "นี่คือบิลด์ทดลอง" ตอนอยู่ใน alt/
     พอย้ายขึ้นตัวหลักแล้วความหมายนั้นหายไป เหลือแค่เลขรุ่น แต่สียังตะโกนอยู่
     และเป็นสีเดียวในจอที่ไม่ได้อยู่ในชุดสีน้ำเงินของแบรนด์เลย
     เปลี่ยนเป็นป้ายเงียบ ๆ กลืนกับพื้น — อยากรู้ก็อ่านได้ ไม่อยากรู้ก็ไม่สะดุดตา */
  color: rgba(214, 226, 255, .72);
  background: rgba(169, 188, 240, .14);
  border: 1px solid rgba(169, 188, 240, .22);
  backdrop-filter: blur(6px);
}

/* ปุ่มเพื่อนมุมขวาบน (1A6M2) — อยู่นอกกริดเมนู หน้าแรกจะได้ไม่ต้องเลื่อน */
.top-friends {
  position: absolute;
  top: 8px;
  right: 10px;
  z-index: 91;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--blue);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform .16s ease;
}
.top-friends svg { width: 17px; height: 17px; }
.top-friends:active { transform: scale(.9); }
.tf-badge {
  position: absolute;
  top: -3px; right: -3px;
  min-width: 15px; height: 15px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--pri-green);
  color: #fff;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}
.tf-badge[hidden] { display: none; }
.login-mode .top-friends { display: none; }

/* บรรทัดบอกรุ่นในหน้า login */
.alt-note {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted, #64748B);
  text-align: center;
}
.alt-note b { color: var(--warn, #B5730E); letter-spacing: .04em; }

/* ============================================================
   ปัดการ์ดงานในหน้าแรก (ฟีเจอร์เฉพาะ ALT)
   ปัดขวา = ทำเสร็จ · ปัดซ้าย = เลื่อนไปพรุ่งนี้
   โครง: .swipe (กรอบอยู่กับที่) > .sw-act สองชั้นซ้อนอยู่ล่าง + .rank-card ทับอยู่บน
   การ์ดทึบแสง ชั้นล่างจึงโผล่มาเองตอนการ์ดเลื่อนหนี ไม่ต้องสั่งซ่อน/แสดง
   ============================================================ */
.swipe {
  position: relative;
  margin-bottom: 10px;
  border-radius: var(--r-card, 18px);
}

/* ชั้นปุ่มที่ซ่อนอยู่ใต้การ์ด — JS ค่อย ๆ เพิ่ม opacity ตามระยะที่ปัด */
.sw-act {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 20px;
  border-radius: inherit;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  transition: opacity .12s linear;
}
.sw-act .sw-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .25);
  transition: transform .18s cubic-bezier(.2, .9, .3, 1.4);
}
.sw-act svg { width: 15px; height: 15px; }
.sw-act.done   { justify-content: flex-start; background: var(--pri-green, #1A8047); color: #fff; }
.sw-act.snooze { justify-content: flex-end; background: var(--pri-yellow, #E9A93C); color: var(--pri-yellow-text, #6B4708); }
.sw-act.snooze .sw-ic { background: rgba(0, 0, 0, .12); }
/* ปัดถึงระยะที่ปล่อยแล้วทำงานจริง — เด้งไอคอนให้รู้ตัวโดยไม่ต้องอ่าน */
.swipe.armed .sw-act .sw-ic { transform: scale(1.22); }

/* การ์ดที่ปัดได้ — เกาะที่ .sw-card ไม่ใช่ชื่อการ์ดของจอใดจอหนึ่ง
   เพราะท่านี้ใช้ทั้งการ์ดหน้าแรก (.rank-card) และการ์ดในตารางงาน (.tk) */
.swipe .sw-card {
  position: relative;
  z-index: 1;
  margin-bottom: 0;
  /* pan-y = แนวตั้งยกให้เบราว์เซอร์เลื่อนจอ แนวนอนเราเอาไว้ปัดเอง */
  touch-action: pan-y;
  transition: transform .26s cubic-bezier(.2, .9, .3, 1.1);
}
/* ระหว่างนิ้วยังจับอยู่ ต้องไม่มี transition ไม่งั้นการ์ดตามนิ้วไม่ทัน */
.swipe.sw-live .sw-card { transition: none; }
.swipe.sw-live .sw-card:active { transform: none; }
/* ปัดสำเร็จ — การ์ดไหลออกนอกจอแล้วจางหาย */
.swipe.sw-out { opacity: 0; transition: opacity .22s ease .04s; }
.swipe.sw-out .sw-card { transition: transform .22s cubic-bezier(.4, 0, 1, 1); }
/* การ์ดตารางงานมนน้อยกว่าการ์ดหน้าแรก ชั้นปุ่มที่อยู่ข้างล่างจึงต้องมนเท่ากัน
   ไม่งั้นตอนปัดจะเห็นมุมสีเขียว/เหลืองโผล่พ้นมุมการ์ด */
.swipe:has(.tk) { border-radius: 14px; }

/* ---------- ป้าย "เลื่อน" ข้างป้ายความสำคัญ ---------- */
.rc-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tag.snoozed {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--pri-yellow-soft, #FDF3E3);
  color: var(--pri-yellow-text, #8A5A05);
  box-shadow: inset 0 0 0 1px var(--pri-yellow, #E9A93C);
}
.tag.snoozed svg { width: 12px; height: 12px; }
/* ในแถวของหน้า "งาน" ป้ายอยู่บรรทัดเดียวกับกำหนดส่ง — เว้นหายใจให้หน่อย */
.am .tag.snoozed { margin-left: 2px; }

/* หัวข้อกลุ่มงานที่เลื่อนไว้ — เบากว่าหัวข้อหลัก เพราะไม่ใช่สิ่งที่ต้องทำก่อน */
.sec-label.soft {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--pri-yellow-text, #8A5A05);
  opacity: .85;
}
.sec-label.soft svg { width: 13px; height: 13px; }

/* ---------- วันที่ไม่มีงานค้าง ---------- */
.empty-stat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 16px 0 0;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--good-soft, #E7F6EC);
  color: var(--good, #1A8047);
  font-size: 12.5px;
  font-weight: 600;
}
.empty-stat b { font-weight: 700; }
.empty-stat svg { width: 14px; height: 14px; }
.empty-2nd {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
  padding: 8px 6px;
  border: none;
  background: transparent;
  color: var(--muted, #64748B);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.empty-2nd svg { width: 14px; height: 14px; }
.empty-2nd:active { transform: scale(.97); color: var(--blue, #1D4ED8); }

/* คำใบ้ว่าปัดได้ — วางเหนือการ์ดใบแรก */
.sw-hint {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: -4px 4px 9px;
  font-size: 11px;
  font-weight: 600;
  color: var(--faint, #94A3B8);
}
.sw-hint span { display: inline-flex; align-items: center; gap: 3px; }
.sw-hint svg { width: 13px; height: 13px; }
/* ลูกศรชี้ทิศที่ต้องปัดจริง: ซ้าย = "ทำเสร็จ →" · ขวา = "← เลื่อนพรุ่งนี้" */
.sw-hint .r svg { transform: rotate(180deg); }

/* ปุ่มเลิกทำใน toast */
.toast .tu {
  flex: none;
  align-self: center;
  border: 1px solid var(--line, rgba(15, 23, 42, .12));
  background: var(--card2, #F1F5F9);
  color: var(--blue, #1D4ED8);
  border-radius: 999px;
  padding: 7px 13px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.toast .tu:active { transform: scale(.95); }

@media (prefers-reduced-motion: reduce) {
  .swipe .rank-card, .sw-act, .sw-act .sw-ic { transition: none; }
}

/* เกร็ดความรู้ระหว่างรอ — เหลือที่เดียวคือระหว่าง OCR อ่านรูป
   (ฉากเปิดแอปที่เคยใช้ร่วมกันถูกเอาออกแล้ว จอแรกคือหน้าบัญชี) */
.scan-fact {
  margin: 10px 2px 0;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--muted);
}
.scan-fact[hidden] { display: none; }
.scan-fact.in { animation: fact-in .5s ease both; }
.scan-fact::before {
  content: 'รู้หรือไม่ · ';
  font-weight: 700;
  color: var(--blue);
}
@keyframes fact-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .scan-fact.in { animation: none; }
}
.sp-pct {
  flex: none;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-weight: 700;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   หน้าทำความรู้จัก (ครั้งแรกที่เปิดแอป)
   ============================================================ */
.ob-body {
  min-height: 100%;
  justify-content: center;
  padding-top: 26px;
  gap: 22px;
}
/* 1A9r · กฎ [hidden] ของเบราว์เซอร์คือ display:none ซึ่งอยู่ในชั้น UA — แพ้กฎของเราเอง
   ที่ตั้ง display:flex ให้ .scr-body ไว้ใน style.css เสมอ ต่อให้ไม่มี !important
   ผลคือ el.hidden = true ไม่ทำอะไรเลยกับกล่องพวกนี้
   โผล่ตอน 1A9m ที่หน้าต้อนรับกลายเป็นสี่ขั้นแล้วสลับขั้นด้วย .hidden:
   กด "ถัดไป" แล้วค่า hidden เปลี่ยนจริง แต่จอไม่ขยับ เพราะทุกขั้นถูกวาดพร้อมกันอยู่แล้ว
   บั๊กชนิดเดียวกันเคยเจอกับ .th-grid button มาแล้ว (ดูหมายเหตุแถว ๆ บรรทัด 4100)
   ทุกครั้งที่ตั้ง display ให้คลาสที่มีโอกาสถูกซ่อนด้วย hidden ต้องคืนกฎนี้ให้มันด้วย */
.scr-body[hidden], .home-body[hidden], .menu-body[hidden] { display: none; }
.ob-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 7px;
}
.ob-mark {
  width: 62px;
  height: 62px;
  border-radius: 19px;
  margin-bottom: 4px;
  box-shadow: var(--shadow-lg, 0 18px 40px rgba(15, 23, 42, .25));
}
.ob-eyebrow {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10.5px;
  letter-spacing: .06em;
  color: var(--faint, #94A3B8);
}
.ob-h { margin: 0; font-size: 25px; font-weight: 700; letter-spacing: -.032em; color: var(--ink); }
.ob-p { margin: 0; max-width: 285px; font-size: 13.5px; line-height: 1.65; color: var(--muted); }

.ob-card {
  background: var(--card);
  border-radius: 22px;
  box-shadow: var(--shadow);
  padding: 18px 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* ช่องกรอกหน้าตาเดียวกับฟอร์มหลัก (style.css คุมไว้เฉพาะ .fm-card) */
.ob-card input[type=text] {
  background: var(--card2); border: none; border-radius: 12px; min-height: 48px; padding: 0 13px;
  font-size: 15px; font-weight: 500; font-family: inherit; color: var(--ink); width: 100%;
  -webkit-appearance: none; appearance: none;
}
.ob-card input[type=text]:focus { outline: 2px solid var(--blue); outline-offset: -2px; }
.ob-card input[type=text].bad { outline: 2px solid var(--alert); animation: ob-shake .38s ease; }
@keyframes ob-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}
.ob-err { font-size: 12px; font-weight: 600; color: var(--alert); }
.ob-card input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
  background: var(--card2); border-radius: 99px; padding: 0; min-height: 0; outline: none;
}
.ob-card input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--card); box-shadow: 0 2px 8px rgba(15, 23, 42, .2), 0 0 0 2px var(--blue); cursor: pointer;
}
.ob-card input[type=range]::-moz-range-thumb {
  width: 20px; height: 20px; border: none; border-radius: 50%;
  background: var(--card); box-shadow: 0 2px 8px rgba(15, 23, 42, .2), 0 0 0 2px var(--blue); cursor: pointer;
}

.ob-quick { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.ob-quick button {
  border: none; background: var(--card2); color: var(--muted); border-radius: 12px; min-height: 40px;
  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: transform .14s ease, background .14s ease, color .14s ease;
}
.ob-quick button:active { transform: scale(.96); }
.ob-quick button.on {
  background: var(--blue-soft); color: var(--blue-deep);
  box-shadow: inset 0 0 0 1.5px var(--blue);
}
.ob-note { margin: 2px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--faint); }
.ob-act { display: flex; flex-direction: column; gap: 8px; }

/* ฉาก "ยินดีที่ได้รู้จัก ___" */
.ob-welcome {
  position: absolute;
  inset: 0;
  z-index: 20;
  background: var(--scr);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 30px;
  text-align: center;
  opacity: 0;
  transition: opacity .35s ease;
}
.ob-welcome[hidden] { display: none; }
.ob-welcome.on { opacity: 1; }
.obw-ring {
  width: 96px; height: 96px; border-radius: 50%;
  background: var(--blue-soft); color: var(--blue);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 8px;
}
.obw-ring svg { width: 40px; height: 40px; }
.ob-welcome.on .obw-ring { animation: obw-pop .6s cubic-bezier(.2, .8, .3, 1.4) both; }
@keyframes obw-pop { from { transform: scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
.obw-h { font-size: 15.5px; color: var(--muted); }
.obw-name {
  font-size: 30px; font-weight: 700; letter-spacing: -.034em; color: var(--blue-deep);
  line-height: 1.25; word-break: break-word; max-width: 100%;
}
.obw-p { margin: 8px 0 0; max-width: 280px; font-size: 13.5px; line-height: 1.7; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .ob-welcome.on .obw-ring, .ob-card input[type=text].bad { animation: none; }
  .ob-welcome { transition: none; }
}

/* ============================================================
   1C09 · รอบแก้คอนทราสต์ของโทเคนตัวอักษรจาง (วัดเอง ไม่ใช่กะเอา)
   ============================================================
   กวาดคู่สีที่จอ "ฉัน" ใช้จริงครบทั้ง 15 ธีม แล้วเจอห้าจุดที่ต่ำกว่า 4.5:1
   ซึ่งเป็นเกณฑ์ของตัวอักษรขนาดปกติ (ค่าชิดขวาของลิสต์คือ 12px = ตัวเล็ก
   จึงไม่เข้าข้อยกเว้น large text ที่ยอมให้ 3:1):

     --faint บนพื้นการ์ดขาว   earth  #6A8074 4.24 → #657A6E 4.60
                              ocean  #5D8296 4.12 → #57798C 4.65
                              earth2 #65816C 4.28 → #617B67 4.63
                              sweet  #8B6C9E 4.43 → #89699C 4.60
     --muted บนพื้นจอ         genesis #4A5599 2.62 → #2E345E 4.52
     --faint บนพื้นกระจก      genesis #5A66AB 4.44 → #5562A8 4.70

   1C10 · รอบสอง — คราวก่อนวัด --faint เทียบ "พื้นการ์ด" อย่างเดียว ยังไม่ได้วัดเทียบ
   "พื้นจอ" (--scr) ซึ่งเป็นที่ที่ป้ายเลขรุ่นกับข้อความรองนอกการ์ดไปตกอยู่:
     --faint บนพื้นจอ  light  #637692 4.42 → #617490 4.55
                       earth  #657A6E 4.21 → #607469 4.57
                       ocean  #57798C 4.16 → #527284 4.59
                       earth2 #617B67 4.23 → #5D7562 4.59
                       sweet  #89699C 4.16 → #826295 4.60
   ทั้งห้าค่ายังผ่านบนพื้นการ์ดและพื้นกระจกด้วย (4.76–5.12) — เลือกค่าที่ผ่านทั้งสามพื้น

   **genesis ไม่ได้แก้ด้วยวิธีนี้โดยตั้งใจ** พื้นจอของมันคือม่วงอิ่มสี #8E9BE8 ซึ่งกลาง
   เกินกว่าจะรองรับขั้น "จาง" ได้เลย · ค่าที่ผ่าน 4.5 คือ #2D345A ซึ่งเท่ากับ --muted
   ของมันเอง (#2E345E) แปลว่าขั้น muted/faint ยุบเป็นขั้นเดียว ซึ่งแย่กว่าปัญหาเดิม
   และธีม sweet ได้ --blue เข้มขึ้นนิดหนึ่งด้วย (#B247CC 4.42 → #AC39C8 4.94 บนพื้นกระจก)
   H กับ S เท่าเดิม ขยับแค่ความสว่าง — สีลิงก์ของธีมนั้นจึงยังเป็นม่วงชมพูเหมือนเดิม

   ตัวที่ตกจริงบนจอนี้คือป้ายเลขรุ่น จึงแก้ที่ตัวมัน (.app-ver ใช้ --muted แทน --faint
   ใน style.css) ได้ผลทุกธีมด้วยบรรทัดเดียว โดยไม่ต้องรื้อบันไดสีของธีมไหนเลย

   สี่ตัวแรกขยับแค่ความสว่าง (H กับ S เท่าเดิมเป๊ะ) จึงไม่มีธีมไหนเปลี่ยนโทน
   ส่วน genesis ขยับเยอะเพราะพื้นจอมันเป็นม่วงอ่อนอิ่มสี (#8E9BE8) ไม่ใช่พื้นเทา
   ตัวหนังสือจางบนพื้นนั้นวัดได้ 2.62 ซึ่งต่ำกว่าเกณฑ์ตัวใหญ่ (3:1) ด้วยซ้ำ
   ค่าใหม่ยังอ่านออกบนพื้นการ์ดของมันเอง (10.46:1) ไม่ได้เสียอีกด้านไป

   ทั้งห้าจุดเป็นคู่สีเดิมที่มีมาก่อน 1C09 ไม่ใช่ของใหม่จากการรื้อจอ "ฉัน" —
   แต่จอนั้นใช้มันถี่ที่สุด (ค่าชิดขวาเจ็ดแถว + บรรทัดใต้ชื่อบนหัวจอ) จึงเจอตอนวัด
   ============================================================ */
/* ============================================================
   ธีมเพิ่ม 4 โทน (ALT)
   ใช้ชื่อโทเคนชุดเดียวกับ style.css เป๊ะ — เพิ่มโทน = เพิ่มบล็อกเดียว
   ไม่ต้องแตะ CSS ของจอไหนเลย ตามที่ระบบเดิมออกแบบไว้
   ============================================================ */

/* ---------- โทน 5: โลก — ฟ้า + เขียว + น้ำตาล ---------- */
:root[data-theme="earth"] {
  color-scheme: light;
  --scr:#F1F6F1; --card:#FFFFFF; --card2:#E5EFE6; --surface:#E5EFE6;
  --ink:#1E2E27; --muted:#5C7267; --faint:#607469;
  --line:rgba(30,46,39,.10);
  --blue:#1F7A5C; --blue-soft:#DCEFE6; --blue-deep:#14563F; --on-accent:#FFFFFF;
  --neon:#1F7A5C;
  --alert:#B23A2B; --alert-soft:#F7E3DF;
  --warn:#8A6206;  --warn-soft:#F8EFD3;
  --good:#1C6B3B;  --good-soft:#DAEFE2; --fire:#B23A2B;
  --shadow:0 2px 6px rgba(28,58,44,.06), 0 16px 34px -14px rgba(28,58,44,.22);
  --shadow-lg:0 4px 12px rgba(28,58,44,.08), 0 32px 58px -18px rgba(28,58,44,.28);
  --shadow-brand:0 10px 26px -8px rgba(31,122,92,.42);
  --glass:rgba(241,246,241,.84); --glass-line:rgba(30,46,39,.08);
  --skel:rgba(30,46,39,.06); --skel-hi:rgba(30,46,39,.11);
  --grad-brand:linear-gradient(135deg,#2FA37A 0%,#2C7CC4 100%);
  --grad-hero:linear-gradient(150deg,#17594A 0%,#2C7CC4 100%);
  --glow-scan:0 8px 22px -6px rgba(31,122,92,.5);
  --pg:#E1EBE2; --pg-ink:#1E2E27; --pg-muted:#5C7267;
  --frame:#5A4128; /* ขอบเครื่องสีไม้ — ให้ครบทั้งฟ้า เขียว น้ำตาล */
  --r-card:22px; --r-tile:15px;
}

/* ---------- โทน 6: มหาสมุทร — ฟ้าอ่อนผิวน้ำ + น้ำเงินทะเลลึก ---------- */
:root[data-theme="ocean"] {
  color-scheme: light;
  --scr:#E9F4FB; --card:#FFFFFF; --card2:#D7EAF7; --surface:#D7EAF7;
  --ink:#0C2C3E; --muted:#4E7186; --faint:#527284;
  --line:rgba(12,44,62,.10);
  --blue:#0E6E92; --blue-soft:#D5EDF9; --blue-deep:#0A5170; --on-accent:#FFFFFF;
  --neon:#0E6E92;
  --alert:#C0392B; --alert-soft:#FBE4E0;
  --warn:#8A6206;  --warn-soft:#F8EFD3;
  --good:#0F766E;  --good-soft:#D6F0EC; --fire:#C0392B;
  --shadow:0 2px 8px rgba(10,60,86,.08), 0 18px 38px -14px rgba(10,60,86,.24);
  --shadow-lg:0 5px 16px rgba(10,60,86,.10), 0 34px 60px -18px rgba(10,60,86,.30);
  --shadow-brand:0 10px 26px -8px rgba(14,110,146,.45);
  --glass:rgba(233,244,251,.84); --glass-line:rgba(12,44,62,.09);
  --skel:rgba(12,44,62,.07); --skel-hi:rgba(12,44,62,.13);
  --grad-brand:linear-gradient(135deg,#38BDF8 0%,#0E6E92 100%);
  --grad-hero:linear-gradient(150deg,#0A4C68 0%,#0E7490 100%);
  --glow-scan:0 8px 24px -6px rgba(14,110,146,.55);
  --pg:#CDE5F3; --pg-ink:#0C2C3E; --pg-muted:#4E7186;
  --frame:#0A3348;
  --r-card:22px; --r-tile:16px;
}

/* ---------- โทน 7: เวทมนตร์ — ม่วงหมึก + ทองเทียน ---------- */
:root[data-theme="magic"] {
  color-scheme: dark;
  --scr:#150E26; --card:#20163A; --card2:#2C204E; --surface:#2C204E;
  --ink:#F1EAFF; --muted:#AA9BD4; --faint:#9C8FC6;
  --line:rgba(232,194,90,.14);
  --blue:#E8C25A; --blue-soft:rgba(232,194,90,.26); --blue-deep:#F5DC96; --on-accent:#1A1030;
  --neon:#E8C25A;
  --alert:#FF8098; --alert-soft:rgba(255,128,152,.26);
  --warn:#E8C25A;  --warn-soft:rgba(232,194,90,.26);
  --good:#69D8B5;  --good-soft:rgba(105,216,181,.26); --fire:#FF8098;
  --shadow:0 2px 8px rgba(0,0,0,.5), 0 18px 40px -14px rgba(0,0,0,.85);
  --shadow-lg:0 4px 12px rgba(0,0,0,.55), 0 36px 66px -18px rgba(0,0,0,.95);
  --shadow-brand:0 10px 28px -8px rgba(139,92,246,.6);
  --glass:rgba(21,14,38,.82); --glass-line:rgba(232,194,90,.18);
  --skel:rgba(255,255,255,.07); --skel-hi:rgba(255,255,255,.13);
  --grad-brand:linear-gradient(135deg,#8B5CF6 0%,#E8C25A 100%);
  --grad-hero:linear-gradient(150deg,#2E1C5C 0%,#160F2B 100%);
  --glow-scan:0 0 0 1px rgba(232,194,90,.45), 0 8px 26px -4px rgba(139,92,246,.7),
    0 0 34px -6px rgba(232,194,90,.35);
  --pg:#0C0718; --pg-ink:#F1EAFF; --pg-muted:#AA9BD4; --frame:#0E0820;
  --r-card:22px; --r-tile:15px;
}

/* ---------- โทน 8: กาแล็กซี — ม่วง/ชมพูเนบิวลา ---------- */
:root[data-theme="galaxy"] {
  color-scheme: dark;
  --scr:#0B0618; --card:#170D2E; --card2:#241143; --surface:#241143;
  --ink:#F0E8FF; --muted:#A796CF; --faint:#9C8BC5;
  --line:rgba(255,255,255,.10);
  --blue:#BB8CFF; --blue-soft:rgba(187,140,255,.28); --blue-deep:#DAC7FF; --on-accent:#130826;
  --neon:#FF7AD9;
  --alert:#FF6F9C; --alert-soft:rgba(255,111,156,.26);
  --warn:#FFC46B;  --warn-soft:rgba(255,196,107,.26);
  --good:#5EE7D0;  --good-soft:rgba(94,231,208,.26); --fire:#FF6F9C;
  --shadow:0 2px 8px rgba(0,0,0,.55), 0 18px 42px -14px rgba(0,0,0,.9);
  --shadow-lg:0 4px 12px rgba(0,0,0,.6), 0 36px 68px -18px rgba(0,0,0,.95);
  --shadow-brand:0 10px 30px -8px rgba(168,85,247,.65);
  --glass:rgba(11,6,24,.8); --glass-line:rgba(187,140,255,.18);
  --skel:rgba(255,255,255,.07); --skel-hi:rgba(255,255,255,.13);
  --grad-brand:linear-gradient(135deg,#A855F7 0%,#EC4899 100%);
  --grad-hero:linear-gradient(150deg,#3E1178 0%,#170D2E 100%);
  --glow-scan:0 0 0 1px rgba(255,122,217,.4), 0 8px 28px -4px rgba(168,85,247,.75),
    0 0 36px -6px rgba(236,72,153,.4);
  --pg:#070312; --pg-ink:#F0E8FF; --pg-muted:#A796CF; --frame:#050210;
  --r-card:22px; --r-tile:15px;
}

/* ============================================================
   1A6M3 — ปรับสองโทนหลักตามที่สั่ง
   สว่าง = ขาว-ฟ้า · อุ่น = ขาว-ชมพู (เปลี่ยนชื่อเป็น "ชมพู")
   เขียนทับเฉพาะโทเคนสี ไม่แตะโครงของ style.css
   ============================================================ */
:root, :root[data-theme="light"] {
  --scr:#F7FAFF; --card:#FFFFFF; --card2:#EAF2FD; --surface:#EAF2FD;
  --ink:#0F1B2D; --muted:#556884; --faint:#617490;
  --line:rgba(15,27,45,.10);
  --blue:#1566CE; --blue-soft:#E2EEFC; --blue-deep:#0D4A9B; --on-accent:#FFFFFF;
  --neon:#1566CE;
  --shadow:0 2px 6px rgba(15,40,80,.06), 0 16px 34px -14px rgba(15,40,80,.22);
  --shadow-lg:0 4px 12px rgba(15,40,80,.08), 0 32px 58px -18px rgba(15,40,80,.28);
  --shadow-brand:0 10px 26px -8px rgba(21,102,206,.42);
  --glass:rgba(247,250,255,.86); --glass-line:rgba(15,27,45,.08);
  --grad-brand:linear-gradient(135deg,#3E97F7 0%,#1566CE 100%);
  --grad-hero:linear-gradient(150deg,#0D4A9B 0%,#2F86EC 100%);
  --glow-scan:0 8px 22px -6px rgba(21,102,206,.5);
  --pg:#E4EDFA; --pg-ink:#0F1B2D; --pg-muted:#556884; --frame:#22344D;
}

:root[data-theme="warm"] {
  --scr:#FFF6FA; --card:#FFFFFF; --card2:#FCE7F1; --surface:#FCE7F1;
  --ink:#2E1420; --muted:#7A5265; --faint:#8A6072;
  --line:rgba(46,20,32,.10);
  --blue:#CE3F79; --blue-soft:#FCE1EE; --blue-deep:#A22759; --on-accent:#FFFFFF;
  --neon:#CE3F79;
  --alert:#C42B3F; --alert-soft:#FBE0E4;
  --warn:#8A6206;  --warn-soft:#F8EFD3;
  --good:#1C6B4F;  --good-soft:#DAF0E8; --fire:#C42B3F;
  --shadow:0 2px 8px rgba(90,30,60,.07), 0 18px 38px -16px rgba(90,30,60,.24);
  --shadow-lg:0 5px 16px rgba(90,30,60,.09), 0 34px 60px -18px rgba(90,30,60,.3);
  --shadow-brand:0 12px 30px -10px rgba(206,63,121,.45);
  --glass:rgba(255,246,250,.86); --glass-line:rgba(46,20,32,.08);
  --skel:rgba(46,20,32,.06); --skel-hi:rgba(46,20,32,.11);
  --grad-brand:linear-gradient(135deg,#F783B6 0%,#CE3F79 100%);
  --grad-hero:linear-gradient(150deg,#A22759 0%,#E96BA3 100%);
  --glow-scan:0 10px 26px -6px rgba(206,63,121,.5);
  --pg:#F8DCE9; --pg-ink:#2E1420; --pg-muted:#7A5265; --frame:#5A2238;
  --r-card:24px; --r-tile:17px;
}

/* ---------- โทน 12 (ลับสุดท้าย): GENESIS — ฟ้าอมม่วง + ฟ้าอมเขียวอ่อน ---------- */
/* ปลดล็อกเมื่อได้เหรียญครบทุกอันในแอป */
:root[data-theme="genesis"] {
  color-scheme: dark;
  --scr:#8E9BE8; --card:#EDF0FF; --card2:#D5DCFA; --surface:#D5DCFA;
  --ink:#1B2154; --muted:#2E345E; --faint:#5562A8;
  --line:rgba(27,33,84,.12);
  --blue:#3B49B8; --blue-soft:#DFE5FF; --blue-deep:#232C87; --on-accent:#FFFFFF;
  --neon:#B7F5FF;
  --alert:#C43B5E; --alert-soft:#FBE0E7;
  --warn:#8A6206;  --warn-soft:#F8EFD3;
  --good:#17796F;  --good-soft:#D6F2EE; --fire:#C43B5E;
  --shadow:0 2px 10px rgba(30,40,110,.14), 0 20px 42px -16px rgba(30,40,110,.4);
  --shadow-lg:0 6px 18px rgba(30,40,110,.18), 0 36px 66px -18px rgba(30,40,110,.46);
  --shadow-brand:0 12px 32px -10px rgba(120,150,255,.6);
  --glass:rgba(226,232,255,.8); --glass-line:rgba(255,255,255,.6);
  --skel:rgba(27,33,84,.07); --skel-hi:rgba(27,33,84,.13);
  --grad-brand:linear-gradient(135deg,#B7F5FF 0%,#6F7FE8 55%, #4C57C9 100%);
  --grad-hero:linear-gradient(150deg,#2C3597 0%,#7C8BF0 60%, #A9F0FF 100%);
  --glow-scan:0 0 0 1px rgba(183,245,255,.7), 0 10px 30px -6px rgba(140,170,255,.8),
    0 0 40px -6px rgba(183,245,255,.6);
  --pg:#7C8AE0; --pg-ink:#1B2154; --pg-muted:#4A5599; --frame:#3A45A8;
  --r-card:24px; --r-tile:16px;
}
/* บรรยากาศทั้งจอค่อย ๆ คลื่นไปเป็นฟ้าอมเขียวอ่อนแวบหนึ่ง แล้วจางกลับ */
:root[data-theme="genesis"] .phone {
  animation: gen-tide 17s ease-in-out infinite;
}
@keyframes gen-tide {
  0%, 62%, 100% { background: #8E9BE8; }
  72% { background: #A8CFF0; }
  78% { background: #BDEAF6; }
  86% { background: #A2C3F2; }
}

/* ---------- โทน 11 (ลับ): จักรวาลหวานแหว — พาสเทลชมพู + สายรุ้ง ---------- */
:root[data-theme="sweet"] {
  color-scheme: light;
  --scr:#FDF0F8; --card:#FFFFFF; --card2:#F8E5F6; --surface:#F8E5F6;
  --ink:#3A1F4A; --muted:#7B5B90; --faint:#826295;
  --line:rgba(58,31,74,.10);
  --blue:#AC39C8; --blue-soft:#F7E3FB; --blue-deep:#8A2FA6; --on-accent:#FFFFFF;
  --neon:#FF8FD0;
  --alert:#D1417C; --alert-soft:#FCE2EC;
  --warn:#A87516;  --warn-soft:#FBEFD6;
  --good:#2E9182;  --good-soft:#DDF2EE; --fire:#D1417C;
  --shadow:0 2px 8px rgba(110,50,130,.08), 0 18px 38px -16px rgba(110,50,130,.24);
  --shadow-lg:0 5px 16px rgba(110,50,130,.10), 0 34px 60px -18px rgba(110,50,130,.3);
  --shadow-brand:0 12px 30px -10px rgba(178,71,204,.45);
  --glass:rgba(253,240,248,.85); --glass-line:rgba(58,31,74,.09);
  --skel:rgba(58,31,74,.06); --skel-hi:rgba(58,31,74,.11);
  --grad-brand:linear-gradient(135deg,#FF9BD2 0%,#9B6BF0 100%);
  --grad-hero:linear-gradient(150deg,#8C51E0 0%,#F282C8 100%);
  --glow-scan:0 0 0 1px rgba(255,155,210,.45), 0 10px 28px -6px rgba(155,107,240,.55);
  --pg:#F4DCEF; --pg-ink:#3A1F4A; --pg-muted:#7B5B90; --frame:#4A2A5C;
  --r-card:26px; --r-tile:18px;
}

/* ---------- โทน 10 (ลับ): ต้นไม้โลก — ทุ่งหญ้ามีลม ---------- */
/* ปลดล็อกด้วยการกดปุ่มธีมโลกซ้ำ 5 ครั้ง */
:root[data-theme="earth2"] {
  color-scheme: light;
  --scr:#EFF7EE; --card:#FFFFFF; --card2:#E2EFE1; --surface:#E2EFE1;
  --ink:#1B2E20; --muted:#57735E; --faint:#5D7562;
  --line:rgba(27,46,32,.10);
  --blue:#2F7D42; --blue-soft:#DCEFDC; --blue-deep:#1E5B2E; --on-accent:#FFFFFF;
  --neon:#2F7D42;
  --alert:#B23A2B; --alert-soft:#F7E3DF;
  --warn:#8A6206;  --warn-soft:#F8EFD3;
  --good:#1C6B3B;  --good-soft:#DAEFE2; --fire:#B23A2B;
  --shadow:0 2px 6px rgba(28,58,40,.07), 0 16px 34px -14px rgba(28,58,40,.24);
  --shadow-lg:0 4px 12px rgba(28,58,40,.09), 0 32px 58px -18px rgba(28,58,40,.3);
  --shadow-brand:0 10px 26px -8px rgba(47,125,66,.42);
  --glass:rgba(239,247,238,.86); --glass-line:rgba(27,46,32,.08);
  --skel:rgba(27,46,32,.06); --skel-hi:rgba(27,46,32,.11);
  --grad-brand:linear-gradient(135deg,#5FBF6B 0%,#2F7D42 100%);
  --grad-hero:linear-gradient(150deg,#1E5B2E 0%,#4E9E5C 100%);
  --glow-scan:0 8px 22px -6px rgba(47,125,66,.5);
  --pg:#DDECDC; --pg-ink:#1B2E20; --pg-muted:#57735E;
  --frame:#5A4128;
  --r-card:22px; --r-tile:15px;
}

/* ---------- โทน 9 (ลับ): ทะเลลึก — มหาสมุทรเวอร์ชันมืด ---------- */
/* ปลดล็อกด้วยการกดปุ่มธีมมหาสมุทรซ้ำ 4 ครั้ง */
:root[data-theme="deepocean"] {
  color-scheme: dark;
  --scr:#04121F; --card:#0B2033; --card2:#132E45; --surface:#132E45;
  --ink:#DCEEF9; --muted:#8AAEC6; --faint:#7CA3BD;
  --line:rgba(160,220,255,.11);
  --blue:#38BDF8; --blue-soft:rgba(56,189,248,.26); --blue-deep:#9BDCFB; --on-accent:#04121F;
  --neon:#22D3EE;
  --alert:#FF7A94; --alert-soft:rgba(255,122,148,.26);
  --warn:#F0C05A;  --warn-soft:rgba(240,192,90,.26);
  --good:#4FD8C0;  --good-soft:rgba(79,216,192,.26); --fire:#FF7A94;
  --shadow:0 2px 8px rgba(0,10,20,.55), 0 18px 40px -14px rgba(0,8,16,.9);
  --shadow-lg:0 4px 12px rgba(0,10,20,.6), 0 36px 66px -18px rgba(0,8,16,.95);
  --shadow-brand:0 10px 28px -8px rgba(14,165,233,.55);
  --glass:rgba(4,18,31,.8); --glass-line:rgba(56,189,248,.18);
  --skel:rgba(255,255,255,.06); --skel-hi:rgba(255,255,255,.12);
  --grad-brand:linear-gradient(135deg,#22D3EE 0%,#0369A1 100%);
  --grad-hero:linear-gradient(150deg,#06304A 0%,#041B2B 100%);
  --glow-scan:0 0 0 1px rgba(34,211,238,.35), 0 8px 26px -4px rgba(14,165,233,.7),
    0 0 34px -6px rgba(34,211,238,.35);
  --pg:#020B14; --pg-ink:#DCEEF9; --pg-muted:#8AAEC6; --frame:#020A12;
  --r-card:22px; --r-tile:15px;
}

/* ป้ายความสำคัญบนโทนมืดใหม่ — พื้นโปร่ง ตัวอักษรสว่าง (เหมือนที่ dark/space ทำ) */
/* 1B98 · Metaverse กับ Glitch ถูกลืมไว้ในบล็อกนี้ตั้งแต่วันที่เพิ่มธีมทั้งสอง
   สองอันนั้นจึงยังใช้ค่าธีมสว่างอยู่ — ป้าย "ทำเลย" เป็นแดงเข้ม #A8281D บนการ์ด #0A0F16
   วัดได้ 1.7:1 ซึ่งแปลว่ามองไม่เห็นเลย ไม่ใช่แค่จาง (เจ้าของแจ้งว่า Glitch บัคเรื่องสี)

   และทั้งห้าอันยังขาด --gold-* ด้วย: ทองของธีมสว่างคือ #8A6206 บนพื้นมืด = 2:1
   ซึ่งเป็นสีของแถบเช็คอินรายวันกับชิปร้านค้า สองที่ที่ต้องเห็นชัดที่สุดในแท็บ "ฉัน" */
:root[data-theme="magic"], :root[data-theme="galaxy"], :root[data-theme="deepocean"],
:root[data-theme="meta"], :root[data-theme="glitch"] {
  --pri-red-soft:rgba(255,107,124,.28);  --pri-red-text:#FF9AA6;
  --pri-yellow-soft:rgba(240,185,10,.28); --pri-yellow-text:#F3C64B;
  --pri-green-soft:rgba(52,211,153,.28);  --pri-green-text:#5BDC93;
  --gold-soft:rgba(240,193,74,.26);       --gold-text:#F0C14A;
}

/* สวอตช์ในหน้าเลือกธีม */
.sw-earth{background:linear-gradient(135deg,#2C7CC4 34%,#2FA37A 34%,#2FA37A 68%,#5A4128 68%)}
.sw-ocean{background:linear-gradient(135deg,#BFE6F7 38%,#38BDF8 38%,#38BDF8 70%,#0A5170 70%)}
.sw-deepocean{background:linear-gradient(135deg,#04121F 40%,#0369A1 40%,#0369A1 72%,#22D3EE 72%)}
.sw-earth2{background:linear-gradient(135deg,#BFE3F7 34%,#5BAE5B 34%,#5BAE5B 68%,#6B4A2A 68%)}
.sw-sweet{background:linear-gradient(135deg,#FFD3EC 30%,#FF9BD2 30%,#FF9BD2 58%,#9B6BF0 58%,#9B6BF0 80%,#8ED4FF 80%)}
.sw-warm{background:linear-gradient(135deg,#FFF6FA 46%,#CE3F79 46%)}
.sw-light{background:linear-gradient(135deg,#FFFFFF 48%,#1566CE 48%)}

/* ประกายดาวตอนกดปุ่มธีมชมพูซ้ำ */
.egg-star {
  position: absolute;
  bottom: -24px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #fff 20%, #FFB6E1 55%, rgba(155,107,240,.2) 75%, transparent 78%);
  box-shadow: 0 0 12px 2px rgba(255,160,220,.6);
  pointer-events: none;
  z-index: 45;
  animation: egg-star-fly 1.5s ease-out forwards;
}
@keyframes egg-star-fly {
  0% { transform: translateY(0) scale(.5) rotate(0); opacity: 0; }
  14% { opacity: 1; }
  100% { transform: translateY(-88vh) translateX(-18px) scale(1.2) rotate(220deg); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .egg-star { display: none; } }
/* ปุ่มธีมลับ: โผล่เฉพาะอันที่ปลดล็อกแล้ว (แยกกันต่อธีม) */
.th-grid .th-secret { display: none; }
:root[data-deep="on"] .th-grid .th-secret[data-th="deepocean"],
:root[data-earth2="on"] .th-grid .th-secret[data-th="earth2"],
:root[data-sweet="on"] .th-grid .th-secret[data-th="sweet"],
:root[data-genesis="on"] .th-grid .th-secret[data-th="genesis"] { display: flex; }
/* ปุ่มธีม GENESIS: ชื่อใช้ฟอนต์เดียวกับคอนเซปต์ */
.th-grid .th-genesis .nm {
  font-family: 'Orbitron', 'Space Mono', monospace;
  font-weight: 800; font-size: 11px; letter-spacing: .1em;
}

/* ใบไม้ปลิวตอนกดปุ่มธีมโลกซ้ำ */
.egg-leaf {
  position: absolute;
  bottom: -24px;
  border-radius: 60% 8% 60% 8%;
  background: linear-gradient(135deg, #7CC47C, #3F8F4F);
  box-shadow: 0 2px 6px rgba(20,60,30,.25);
  pointer-events: none;
  z-index: 45;
  animation: egg-leaf-fly 1.6s ease-out forwards;
}
@keyframes egg-leaf-fly {
  0% { transform: translateY(0) rotate(0); opacity: 0; }
  12% { opacity: 1; }
  100% { transform: translateY(-86vh) translateX(30px) rotate(420deg); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .egg-leaf { display: none; } }

/* ฟองอากาศตอนกดปุ่มธีมซ้ำ (อีสเตอร์เอกก์) */
.egg-bub {
  position: absolute;
  bottom: -24px;
  border-radius: 50%;
  border: 1.5px solid rgba(190, 235, 255, .8);
  background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.6), rgba(160,220,255,.12) 60%, transparent 70%);
  pointer-events: none;
  z-index: 45;
  animation: egg-rise 1.4s ease-out forwards;
}
@keyframes egg-rise {
  0% { transform: translateY(0) scale(.6); opacity: 0; }
  15% { opacity: .95; }
  70% { opacity: .8; }
  100% { transform: translateY(-88vh) translateX(14px) scale(1.15); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .egg-bub { display: none; } }
.sw-magic{background:linear-gradient(135deg,#150E26 40%,#8B5CF6 40%,#8B5CF6 72%,#E8C25A 72%)}
.sw-galaxy{background:linear-gradient(135deg,#0B0618 38%,#A855F7 38%,#A855F7 70%,#EC4899 70%)}

/* ============================================================
   ชั้นบรรยากาศของธีม (.fx) — พื้นหลังเคลื่อนไหวหลังเนื้อหา
   ทุกชั้นอยู่ z-index:0 ใต้ .screens (z-index:1) และไม่รับคลิก
   ฉากขยับตลอดเวลาที่แอปเปิด — ขยับได้แค่ translate / rotate / scale / opacity (การ์ดจอทำเอง)
   ห้าม background-position · margin · ขนาด · เงา · blur/drop-shadow — มือถือสเปคต่ำค้างเพราะสิ่งนี้มาแล้ว (16 ต.ค. 69)
   แก้ฉากเสร็จต้องผ่าน: node alt/devtools/scene-check.cjs
   ============================================================ */
.fx { display: none; }
:root[data-theme="meta"] .fx,
:root[data-theme="glitch"] .fx,
:root[data-theme="earth"] .fx,
:root[data-theme="earth2"] .fx,
:root[data-theme="sweet"] .fx,
:root[data-theme="genesis"] .fx,
:root[data-theme="ocean"] .fx,
:root[data-theme="deepocean"] .fx,
:root[data-theme="magic"] .fx,
:root[data-theme="galaxy"] .fx,
:root[data-theme="space"] .fx {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.fx i, .fx span { position: absolute; display: block; }

/* ---------- โลก: ขอบฟ้า + เมฆลอย ---------- */
:root[data-theme="earth"] .fx-a {
  inset: 0;
  background:
    radial-gradient(130% 60% at 50% -10%, rgba(88,164,214,.30), transparent 70%),
    radial-gradient(120% 45% at 50% 108%, rgba(122,88,46,.26), transparent 72%),
    radial-gradient(90% 40% at 50% 78%, rgba(47,163,122,.22), transparent 70%);
}
:root[data-theme="earth"] .fx-b {
  inset: -6% -20% auto -20%;
  height: 42%;
  background:
    radial-gradient(38px 16px at 12% 40%, rgba(255,255,255,.75), transparent 70%),
    radial-gradient(52px 20px at 34% 62%, rgba(255,255,255,.62), transparent 72%),
    radial-gradient(30px 13px at 62% 32%, rgba(255,255,255,.55), transparent 70%),
    radial-gradient(46px 18px at 84% 56%, rgba(255,255,255,.5), transparent 72%);
  animation: fx-drift-x 120s linear infinite;
}

/* ============================================================
   GENESIS — เพชรยักษ์ · ลม · หิมะ · เส้นพุ่งขึ้นจากพื้น · คลื่นกระแทก
   ปกติเดินเบา ๆ · ทุก 99 วิ JS ติดธง data-gevent 20 วิ แล้วทุกอย่างแรงขึ้นพร้อมกัน
   ============================================================ */
:root[data-theme="genesis"] .fx-a {          /* แสงจากใจกลาง + ขอบจอเข้ม */
  inset: 0;
  background:
    radial-gradient(72% 46% at 50% 46%, rgba(233,247,255,.92), rgba(178,196,255,.5) 42%, transparent 74%),
    radial-gradient(120% 92% at 50% 108%, rgba(60,74,190,.55), transparent 70%);
  animation: gen-glow 6s ease-in-out infinite;
}
:root[data-theme="genesis"] .fx-b {          /* เพชรยักษ์กลางจอ */
  left: 50%; top: 34%;
  width: 190px; height: 250px;
  margin: -125px 0 0 -95px;
  background: no-repeat center/contain
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 190 250'><defs><linearGradient id='d' x1='0' y1='0' x2='0.6' y2='1'><stop offset='0' stop-color='%23FFFFFF'/><stop offset='0.45' stop-color='%23DCEBFF'/><stop offset='1' stop-color='%238FA6F5'/></linearGradient></defs><path d='M95 6 172 118 95 244 18 118Z' fill='url(%23d)' opacity='0.95'/><path d='M95 6 132 118 95 244 58 118Z' fill='%23FFFFFF' opacity='0.8'/><path d='M18 118h154' stroke='%23FFFFFF' stroke-width='3' opacity='0.7'/></svg>");
  filter: drop-shadow(0 0 26px rgba(190,230,255,.9));
  animation: gen-diamond 7s ease-in-out infinite;
}
:root[data-theme="genesis"] .fx-c {          /* ลมหมุนรอบเพชร */
  left: 50%; top: 34%;
  width: 460px; height: 460px;
  margin: -230px 0 0 -230px;
  border-radius: 50%;
  background:
    conic-gradient(from 0deg, transparent 0 12%, rgba(255,255,255,.5) 18%, transparent 26% 62%,
      rgba(215,240,255,.42) 70%, transparent 78%);
  mask: radial-gradient(circle, transparent 32%, #000 40%, #000 62%, transparent 70%);
  -webkit-mask: radial-gradient(circle, transparent 32%, #000 40%, #000 62%, transparent 70%);
  opacity: .8;
  animation: gen-wind 9s linear infinite;
}
:root[data-theme="genesis"] .fx-d {          /* หิมะ 2 ชั้น */
  left: 0; right: 0; top: -12%; bottom: -12%;
}
/* 16 ต.ค. 69 · เดิมเลื่อน background-position ของกล่องสูงเกินจอ = วาดใหม่ทุกเฟรม (CPU ช้า 6 เท่า: หยุดหิมะลดเธรดหลักไป 15 จุด)
   สองชั้นตกคนละทาง (ชั้นแรก: ขวา 40px ลง 640px · ชั้นสอง: ซ้าย 50px ลง 520px ต่อรอบ = ลงสองช่องลายพอดี)
   → ชั้นละ ::before/::after ยาวเกินกล่องขึ้นไปเท่าระยะที่ตก แล้วเลื่อนทั้งชั้นด้วย translate
   จุดเริ่มของลายตั้งให้ตรงของเดิม (40px 0 · 60px 0 = ตำแหน่งเดิมเมื่อนับจากมุมชั้นใหม่) · กระโดดตอนวนรอบเท่าของเดิมทุกอย่าง */
:root[data-theme="genesis"] .fx-d::before,
:root[data-theme="genesis"] .fx-d::after { content: ''; position: absolute; bottom: 0; background-repeat: repeat; animation: gen-snow-a 14s linear infinite; }
:root[data-theme="genesis"] .fx-d::before {
  left: -40px; right: 0; top: -640px;
  background-image: radial-gradient(2.2px 2.2px at 30px 40px, rgba(255,255,255,.95), transparent);
  background-size: 200px 320px; background-position: 40px 0;
}
:root[data-theme="genesis"] .fx-d::after {
  left: 0; right: -50px; top: -520px;
  background-image: radial-gradient(1.6px 1.6px at 120px 180px, rgba(226,244,255,.9), transparent);
  background-size: 150px 260px; background-position: 60px 0;
  animation-name: gen-snow-b;
}
:root[data-theme="genesis"] .fx-e {          /* เส้นตรง + สามเหลี่ยมพุ่งขึ้นจากพื้น */
  left: 0; right: 0; bottom: 0;
  height: 62%;
  opacity: 0;
  background-repeat: no-repeat;
  background-size: 3px 70px, 3px 92px, 3px 58px, 16px 16px, 12px 12px;
  background-position: 16% 100%, 42% 100%, 76% 100%, 30% 100%, 62% 100%;
  background-image:
    linear-gradient(180deg, transparent, rgba(214,244,255,.95)),
    linear-gradient(180deg, transparent, rgba(255,255,255,.95)),
    linear-gradient(180deg, transparent, rgba(190,225,255,.95)),
    conic-gradient(from 180deg at 50% 100%, transparent 0 30%, rgba(226,247,255,.95) 30% 70%, transparent 70%),
    conic-gradient(from 180deg at 50% 100%, transparent 0 30%, rgba(255,255,255,.9) 30% 70%, transparent 70%);
}
:root[data-theme="genesis"] .fx-f {          /* คลื่นกระแทกวงกว้าง */
  left: 50%; top: 52%;
  width: 300px; height: 300px;
  margin: -150px 0 0 -150px;
  border-radius: 50%;
  border: 3px solid rgba(226,247,255,.9);
  box-shadow: 0 0 40px 8px rgba(180,225,255,.5), inset 0 0 30px rgba(255,255,255,.6);
  opacity: 0;
}
:root[data-theme="genesis"] .fx-shoot {      /* สี่เหลี่ยมเล็กผุดแล้วหดหาย */
  left: 0; right: 0; top: 0; bottom: 0;
  opacity: 0;
  background-repeat: no-repeat;
  background-size: 14px 14px, 10px 10px, 18px 18px, 12px 12px;
  background-position: 22% 62%, 68% 40%, 44% 74%, 82% 66%;
  background-image:
    linear-gradient(0deg, rgba(255,255,255,.95), rgba(255,255,255,.95)),
    linear-gradient(0deg, rgba(214,244,255,.9), rgba(214,244,255,.9)),
    linear-gradient(0deg, rgba(255,255,255,.85), rgba(255,255,255,.85)),
    linear-gradient(0deg, rgba(190,225,255,.9), rgba(190,225,255,.9));
}

/* ---------- ตอนอีเวนต์ (20 วิ) ทุกอย่างแรงขึ้นพร้อมกัน ---------- */
:root[data-gevent="on"][data-theme="genesis"] .fx-b {
  animation: gen-diamond-burst 2.6s ease-in-out infinite;
}
:root[data-gevent="on"][data-theme="genesis"] .fx-c {
  animation-duration: 2.6s;                 /* ลมหมุนจัดขึ้นชัดเจน */
  opacity: 1;
}
:root[data-gevent="on"][data-theme="genesis"] .fx-d::before,
:root[data-gevent="on"][data-theme="genesis"] .fx-d::after {
  animation-duration: 3.4s;                 /* หิมะตกเร็วขึ้น */
}
:root[data-gevent="on"][data-theme="genesis"] .fx-e {
  animation: gen-rise 1.5s linear infinite;
}
:root[data-gevent="on"][data-theme="genesis"] .fx-f {
  animation: gen-shock 2.4s ease-out infinite;
}
:root[data-gevent="on"][data-theme="genesis"] .fx-shoot {
  animation: gen-cubes 1.9s ease-in-out infinite;
}
:root[data-gevent="on"][data-theme="genesis"] .fx-a {
  animation: gen-glow 1.6s ease-in-out infinite;
}

@keyframes gen-glow {
  0%, 100% { opacity: .82; }
  50% { opacity: 1; }
}
/* 16 ต.ค. 69 · เดิมเงาเรืองแสง (drop-shadow) พองยุบไปพร้อมกัน — เบลอใหม่ทุกเฟรมบนเธรดหลัก
   (CPU ช้า 6 เท่า: หยุดเพชรลดเธรดหลักไป 16 จุด · trace: "FilterRelatedPropertyMayMovePixels")
   ตอนนี้เงาเรืองแสงนิ่งที่ค่ากลาง (กฎของ .fx-b: 26px) · เพชรยังลอยขึ้นลงและขยายเท่าเดิม — ขยายแล้วเงาก็ขยายตาม แสงยังดูหายใจอยู่
   ตอนอีเวนต์ 20 วิ (gen-diamond-burst) ยังเรืองแสงแรงแบบเดิม — สั้นและนาน ๆ ครั้ง */
@keyframes gen-diamond {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-10px) scale(1.05); }
}
@keyframes gen-diamond-burst {
  0% { transform: translateY(0) scale(1.12); filter: drop-shadow(0 0 30px rgba(215,245,255,.9)); }
  38% { transform: translateY(-16px) scale(1.5); filter: drop-shadow(0 0 70px rgba(255,255,255,1)) brightness(1.5); }
  52% { transform: translateY(-10px) scale(1.28); filter: drop-shadow(0 0 44px rgba(226,247,255,1)); }
  100% { transform: translateY(0) scale(1.12); filter: drop-shadow(0 0 30px rgba(215,245,255,.9)); }
}
@keyframes gen-wind { to { transform: rotate(360deg); } }
@keyframes gen-snow-a { to { translate: 40px 640px; } }
@keyframes gen-snow-b { to { translate: -50px 520px; } }
@keyframes gen-rise {
  0% { opacity: 0; background-position: 16% 100%, 42% 100%, 76% 100%, 30% 100%, 62% 100%; }
  15% { opacity: .95; }
  100% { opacity: 0; background-position: 16% -20%, 42% -35%, 76% -10%, 30% -25%, 62% -40%; }
}
@keyframes gen-shock {
  0% { opacity: .95; transform: scale(.15); }
  70% { opacity: .35; }
  100% { opacity: 0; transform: scale(2.6); }
}
@keyframes gen-cubes {
  0% { opacity: 0; transform: scale(.2) rotate(0); }
  25% { opacity: .95; transform: scale(1) rotate(12deg); }
  70% { opacity: .8; transform: scale(.9) rotate(-8deg); }
  100% { opacity: 0; transform: scale(.1) rotate(20deg); }
}
.sw-genesis {
  background: linear-gradient(135deg, #8E9BE8 34%, #B7F5FF 34%, #B7F5FF 66%, #EDF0FF 66%);
}
@media (prefers-reduced-motion: reduce) {
  :root[data-theme="genesis"] .phone { animation: none; }
}

/* ---------- จักรวาลหวานแหว: เมฆพาสเทล + สายรุ้ง + ดาวเคราะห์มีวงแหวน + ประกาย ---------- */
:root[data-theme="sweet"] .fx-a {
  inset: -10%;
  background:
    radial-gradient(closest-side, rgba(255,170,220,.55), transparent 72%) 18% 22% / 62% 46% no-repeat,
    radial-gradient(closest-side, rgba(170,150,255,.5), transparent 72%) 78% 34% / 58% 44% no-repeat,
    radial-gradient(closest-side, rgba(150,220,255,.42), transparent 72%) 42% 74% / 66% 42% no-repeat,
    radial-gradient(closest-side, rgba(255,225,150,.34), transparent 72%) 84% 82% / 46% 34% no-repeat;
  filter: blur(12px);
  animation: fx-breathe 16s ease-in-out infinite;
}
/* สายรุ้งพาดโค้ง */
:root[data-theme="sweet"] .fx-b {
  left: -20%; right: -20%; top: 8%;
  height: 60%;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  border-top: 16px solid transparent;
  background:
    linear-gradient(180deg,
      rgba(255,120,170,.42) 0 3px, rgba(255,190,120,.4) 3px 6px, rgba(255,240,140,.38) 6px 9px,
      rgba(150,230,170,.38) 9px 12px, rgba(140,200,255,.4) 12px 15px, rgba(190,150,255,.42) 15px 18px,
      transparent 18px) top center / 100% 20px no-repeat;
  filter: blur(1.5px);
  opacity: .8;
  animation: fx-breathe 12s ease-in-out infinite;
}
/* ก้อนเมฆลอยสองชั้น */
:root[data-theme="sweet"] .fx-c,
:root[data-theme="sweet"] .fx-d {
  left: -30%; right: -30%; top: 0; bottom: 0;
  background-repeat: no-repeat;
}
:root[data-theme="sweet"] .fx-c {
  opacity: .75;
  background-size: 150px 62px, 110px 46px, 130px 54px;
  background-position: 14% 20%, 62% 40%, 34% 70%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 62'><g fill='%23FFFFFF' opacity='0.92'><ellipse cx='48' cy='40' rx='40' ry='22'/><ellipse cx='86' cy='34' rx='32' ry='24'/><ellipse cx='112' cy='44' rx='26' ry='17'/></g></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 62'><g fill='%23FDE7F6'><ellipse cx='48' cy='40' rx='40' ry='22'/><ellipse cx='86' cy='34' rx='32' ry='24'/><ellipse cx='112' cy='44' rx='26' ry='17'/></g></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 62'><g fill='%23F1E6FF'><ellipse cx='48' cy='40' rx='40' ry='22'/><ellipse cx='86' cy='34' rx='32' ry='24'/><ellipse cx='112' cy='44' rx='26' ry='17'/></g></svg>");
  animation: sea-swim-r 90s linear infinite, sea-bob 11s ease-in-out infinite;
}
/* ดาวเคราะห์มีวงแหวน */
:root[data-theme="sweet"] .fx-d {
  opacity: .58;
  background-size: 132px 92px;
  background-position: 76% 24%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 132 92'><defs><linearGradient id='p' x1='0' y1='0' x2='1' y2='1'><stop offset='0' stop-color='%23FFC2E4'/><stop offset='0.55' stop-color='%23C79BF5'/><stop offset='1' stop-color='%238ED4FF'/></linearGradient></defs><ellipse cx='66' cy='46' rx='42' ry='16' fill='none' stroke='%23FFFFFF' stroke-width='4' opacity='0.85' transform='rotate(-18 66 46)'/><circle cx='66' cy='44' r='27' fill='url(%23p)'/><ellipse cx='66' cy='46' rx='47' ry='13' fill='none' stroke='%23FFE9F6' stroke-width='3' opacity='0.75' transform='rotate(-18 66 46)'/></svg>");
  animation: sea-bob 9s ease-in-out infinite;
}
/* ประกายดาวกระพริบ */
:root[data-theme="sweet"] .fx-e,
:root[data-theme="sweet"] .fx-f {
  inset: 0;
  background-repeat: no-repeat;
}
:root[data-theme="sweet"] .fx-e {
  background-image:
    radial-gradient(2px 2px at 22% 18%, #fff, transparent),
    radial-gradient(2.6px 2.6px at 58% 28%, #FFF0FA, transparent),
    radial-gradient(2px 2px at 82% 52%, #fff, transparent),
    radial-gradient(2.4px 2.4px at 34% 62%, #F6E9FF, transparent),
    radial-gradient(2px 2px at 68% 78%, #fff, transparent);
  animation: fx-twinkle 4s ease-in-out infinite;
}
:root[data-theme="sweet"] .fx-f {
  opacity: .7;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 44%, #fff, transparent),
    radial-gradient(1.6px 1.6px at 46% 12%, #FFE6F5, transparent),
    radial-gradient(1.6px 1.6px at 90% 34%, #fff, transparent),
    radial-gradient(1.6px 1.6px at 74% 88%, #EFE2FF, transparent);
  animation: fx-twinkle 6.5s ease-in-out infinite reverse;
}
:root[data-theme="sweet"] .fx-shoot {
  left: 0; right: 0; bottom: 0; height: 100%;
  background-image:
    radial-gradient(circle, rgba(255,255,255,.95) 42%, transparent 62%),
    radial-gradient(circle, rgba(255,200,235,.85) 42%, transparent 62%),
    radial-gradient(circle, rgba(205,180,255,.85) 42%, transparent 62%);
  background-size: 6px 6px, 5px 5px, 7px 7px;
  background-repeat: no-repeat;
  background-position: 26% 100%, 58% 100%, 86% 100%;
  --bub-t: 12s;
}

/* ---------- ต้นไม้โลก: ท้องฟ้า + ลม + นกบิน + ต้นไม้กลางจอ + หญ้า ---------- */
:root[data-theme="earth2"] .fx-a {
  inset: 0;
  background:
    linear-gradient(180deg, rgba(150,205,240,.42) 0%, rgba(190,225,235,.22) 38%,
      rgba(120,180,110,.22) 78%, rgba(74,140,80,.42) 100%),
    radial-gradient(90% 40% at 78% 8%, rgba(255,246,200,.55), transparent 70%);
}
/* ลม: ริ้วโปร่ง ๆ พัดผ่านจากซ้ายไปขวา */
:root[data-theme="earth2"] .fx-b {
  inset: 0;
  background:
    linear-gradient(92deg, transparent 8%, rgba(255,255,255,.5) 12%, transparent 17%),
    linear-gradient(92deg, transparent 38%, rgba(255,255,255,.36) 42%, transparent 47%),
    linear-gradient(92deg, transparent 66%, rgba(255,255,255,.42) 70%, transparent 75%);
  background-size: 100% 12px, 100% 9px, 100% 10px;
  background-position: 0 28%, 0 44%, 0 62%;
  background-repeat: no-repeat;
  filter: blur(1px);
  animation: wind-blow 9s linear infinite;
}
/* นกบินผ่านไปมา 2 ชั้น */
:root[data-theme="earth2"] .fx-c,
:root[data-theme="earth2"] .fx-d {
  left: -30%; right: -30%; top: 0; bottom: 52%;
  background-repeat: no-repeat;
}
:root[data-theme="earth2"] .fx-c {
  opacity: .55;
  background-size: 26px 12px, 18px 9px, 22px 10px;
  background-position: 18% 24%, 44% 42%, 70% 18%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 12'><path d='M1 9c4 0 5-6 6-6s2 4 5 4 4-4 5-4 3 6 8 6' fill='none' stroke='%23375C42' stroke-width='1.6' stroke-linecap='round'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 12'><path d='M1 9c4 0 5-6 6-6s2 4 5 4 4-4 5-4 3 6 8 6' fill='none' stroke='%23486E52' stroke-width='1.6' stroke-linecap='round'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 12'><path d='M1 9c4 0 5-6 6-6s2 4 5 4 4-4 5-4 3 6 8 6' fill='none' stroke='%23375C42' stroke-width='1.6' stroke-linecap='round'/></svg>");
  animation: sea-swim-r 38s linear infinite, sea-bob 6s ease-in-out infinite;
}
:root[data-theme="earth2"] .fx-d {
  opacity: .38;
  background-size: 16px 8px, 13px 7px;
  background-position: 30% 58%, 62% 66%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 12'><path d='M1 9c4 0 5-6 6-6s2 4 5 4 4-4 5-4 3 6 8 6' fill='none' stroke='%235A7F63' stroke-width='1.8' stroke-linecap='round'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 12'><path d='M1 9c4 0 5-6 6-6s2 4 5 4 4-4 5-4 3 6 8 6' fill='none' stroke='%235A7F63' stroke-width='1.8' stroke-linecap='round'/></svg>");
  animation: sea-swim-l 52s linear infinite, sea-bob 8s ease-in-out infinite reverse;
}
/* ต้นไม้กลางจอ + หญ้าเต็มก้นจอ (ใช้ช่อง e กับ f) */
:root[data-theme="earth2"] .fx-e {
  left: 50%;
  bottom: 6%;
  width: 210px;
  height: 250px;
  margin-left: -105px;
  opacity: .3;
  transform-origin: 50% 100%;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: bottom center;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 210 250'><path d='M99 250V150c-18-6-30-14-38-26l30 10-34-30 34 8-26-30 34 16V78l14-26 14 26v20l34-16-26 30 34-8-34 30 30-10c-8 12-20 20-38 26v100z' fill='%234A7A3E'/><ellipse cx='105' cy='74' rx='72' ry='56' fill='%235B9A4C'/><ellipse cx='64' cy='96' rx='44' ry='34' fill='%234E8942'/><ellipse cx='148' cy='94' rx='42' ry='32' fill='%2367A857'/><rect x='97' y='150' width='16' height='100' rx='5' fill='%236B4A2A'/></svg>");
  animation: tree-sway 7s ease-in-out infinite;
}
/* ดวงอาทิตย์มุมบนขวา + ต้นไม้เล็กอีกต้น (ต้นไม้โลก เวอร์ชันเต็ม) */
:root[data-theme="earth2"] .fx-a::after {
  content: '';
  position: absolute;
  top: 6%; right: 10%;
  width: 76px; height: 76px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,246,190,.95) 38%, rgba(255,226,130,.45) 62%, transparent 72%);
  animation: fx-breathe 11s ease-in-out infinite;
}
:root[data-theme="earth2"] .fx-e::after {
  content: '';
  position: absolute;
  left: -118px; bottom: -6px;
  width: 108px; height: 130px;
  opacity: .8;
  transform-origin: 50% 100%;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: bottom center;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 108 130'><ellipse cx='54' cy='46' rx='40' ry='32' fill='%235B9A4C'/><ellipse cx='30' cy='62' rx='24' ry='19' fill='%234E8942'/><ellipse cx='78' cy='60' rx='23' ry='18' fill='%2367A857'/><rect x='48' y='74' width='11' height='56' rx='4' fill='%236B4A2A'/></svg>");
  animation: tree-sway 9s ease-in-out infinite reverse;
}
/* ผีเสื้อบินวนเหนือทุ่ง */
:root[data-theme="earth2"] .fx-f::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 46px;
  height: 90px;
  background-repeat: no-repeat;
  background-size: 20px 18px, 15px 13px;
  background-position: 24% 40%, 68% 74%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 18'><path d='M10 9c-3-6-9-8-9-4s5 6 9 4zM10 9c3-6 9-8 9-4s-5 6-9 4z' fill='%23F2A0C4'/><path d='M10 9c-3 6-8 7-8 3s5-5 8-3zM10 9c3 6 8 7 8 3s-5-5-8-3z' fill='%23E88AB4'/><rect x='9.2' y='4' width='1.6' height='11' rx='.8' fill='%234A3A2A'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 18'><path d='M10 9c-3-6-9-8-9-4s5 6 9 4zM10 9c3-6 9-8 9-4s-5 6-9 4z' fill='%23FFD98A'/><path d='M10 9c-3 6-8 7-8 3s5-5 8-3zM10 9c3 6 8 7 8 3s-5-5-8-3z' fill='%23F2C05F'/><rect x='9.2' y='4' width='1.6' height='11' rx='.8' fill='%234A3A2A'/></svg>");
  animation: butterfly 17s ease-in-out infinite;
}
@keyframes butterfly {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(30px, -18px); }
  55% { transform: translate(-24px, -32px); }
  80% { transform: translate(16px, -8px); }
}

:root[data-theme="earth2"] .fx-f {
  left: 0; right: 0; bottom: 0;
  height: 74px;
  opacity: .55;
  background-repeat: repeat-x;
  background-size: 96px 74px;
  background-position: bottom;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 74'><g fill='none' stroke='%234E8B45' stroke-width='4' stroke-linecap='round'><path d='M8 74C8 54 4 44 2 36'/><path d='M20 74C20 50 26 40 32 32'/><path d='M34 74C34 56 30 46 26 40'/><path d='M50 74C50 48 56 38 62 30'/><path d='M64 74C64 54 60 44 56 38'/><path d='M78 74C78 50 84 40 90 34'/><path d='M92 74C92 58 88 48 86 44'/></g></svg>");
  animation: grass-wave 6s ease-in-out infinite;
}
/* ใบไม้ปลิวขึ้น */
:root[data-theme="earth2"] .fx-shoot {
  left: 0; right: 0; bottom: 0; height: 100%;
  background-image:
    radial-gradient(circle, rgba(120,180,100,.85) 45%, transparent 62%),
    radial-gradient(circle, rgba(160,200,120,.7) 45%, transparent 62%),
    radial-gradient(circle, rgba(100,160,90,.75) 45%, transparent 62%);
  background-size: 7px 5px, 5px 4px, 6px 5px;
  background-repeat: no-repeat;
  background-position: 22% 100%, 55% 100%, 82% 100%;
  --bub-t: 15s;
}
/* 16 ต.ค. 69 · เดิมขยับ background-position แนวนอนด้วย % ด้วย — แต่ริ้วลมกว้าง 100% เท่ากล่อง (background-size: 100% …)
   ตามกติกา CSS ค่า % แนวนอนของภาพที่กว้างเท่ากล่องคิดเป็นศูนย์เสมอ ริ้วจึงไม่เคยเลื่อนจริง ตาเห็นแค่ความจางที่เปลี่ยน
   แต่เบราว์เซอร์ยังวาดชั้นเต็มจอ (เบลอ 1px) ใหม่ทุกเฟรม · ตอนนี้เหลือแค่ความจาง = ภาพเหมือนเดิมทุกพิกเซล การ์ดจอทำเอง */
@keyframes wind-blow {
  0%, 100% { opacity: .5; }
  50% { opacity: 1; }
}
@keyframes tree-sway {
  0%, 100% { transform: rotate(-1.2deg); }
  50% { transform: rotate(1.4deg); }
}
@keyframes grass-wave {
  0%, 100% { transform: skewX(-3deg); }
  50% { transform: skewX(3deg); }
}

/* ---------- มหาสมุทร: ผิวน้ำ + ลำแสงลอด + ปลาว่าย + สาหร่ายโบก ---------- */
/* น้ำลึกลงเรื่อย ๆ จากบนลงล่าง — เนื้อหาอยู่ช่วงบนที่สว่าง ตัวหนังสือจึงยังอ่านง่าย */
:root[data-theme="ocean"] .fx-a {
  inset: 0;
  background:
    linear-gradient(180deg, rgba(186,230,253,0) 0%, rgba(56,189,248,.16) 46%,
      rgba(12,110,146,.34) 78%, rgba(8,60,90,.55) 100%),
    radial-gradient(120% 50% at 50% -8%, rgba(255,255,255,.55), transparent 70%);
}
/* ลำแสงลอดผิวน้ำ เอียงจากมุมบน แกว่งช้า ๆ */
:root[data-theme="ocean"] .fx-b {
  inset: -20% -10%;
  background:
    linear-gradient(97deg, transparent 24%, rgba(255,255,255,.34) 30%, transparent 36%),
    linear-gradient(101deg, transparent 48%, rgba(255,255,255,.26) 53%, transparent 58%),
    linear-gradient(94deg, transparent 68%, rgba(255,255,255,.22) 73%, transparent 78%);
  filter: blur(5px);
  animation: sea-rays 14s ease-in-out infinite;
}
/* ฝูงปลา 2 ชั้น: ชั้นไกลตัวเล็กจาง ว่ายช้า · ชั้นใกล้ตัวใหญ่ ว่ายสวนทาง */
:root[data-theme="ocean"] .fx-c,
:root[data-theme="ocean"] .fx-d {
  left: -30%; right: -30%; top: 0; bottom: 22%;
  background-repeat: no-repeat;
}
:root[data-theme="ocean"] .fx-c {
  opacity: .5;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'><path d='M6 16c8-10 24-12 33-6 4 3 7 6 7 6s-3 3-7 6c-9 6-25 4-33-6z' fill='%230E7490'/><path d='M46 16l13-8v16z' fill='%230E7490'/><circle cx='17' cy='13.5' r='1.5' fill='%23fff'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'><path d='M6 16c8-10 24-12 33-6 4 3 7 6 7 6s-3 3-7 6c-9 6-25 4-33-6z' fill='%230891B2'/><path d='M46 16l13-8v16z' fill='%230891B2'/><circle cx='17' cy='13.5' r='1.5' fill='%23fff'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'><path d='M6 16c8-10 24-12 33-6 4 3 7 6 7 6s-3 3-7 6c-9 6-25 4-33-6z' fill='%2338BDF8'/><path d='M46 16l13-8v16z' fill='%2338BDF8'/><circle cx='17' cy='13.5' r='1.5' fill='%23fff'/></svg>");
  background-size: 34px 17px, 26px 13px, 30px 15px;
  background-position: 12% 18%, 46% 40%, 74% 26%;
  /* ปลาชุดนี้หันหน้าไปทางซ้าย → ต้องว่ายไปทางซ้าย ไม่งั้นเหมือนถอยหลัง */
  animation: sea-swim-l 46s linear infinite, sea-bob 7s ease-in-out infinite;
}
:root[data-theme="ocean"] .fx-d {
  opacity: .75;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'><path d='M58 16c-8-10-24-12-33-6-4 3-7 6-7 6s3 3 7 6c9 6 25 4 33-6z' fill='%230A5170'/><path d='M18 16L5 8v16z' fill='%230A5170'/><circle cx='47' cy='13.5' r='1.6' fill='%23fff'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32'><path d='M58 16c-8-10-24-12-33-6-4 3-7 6-7 6s3 3 7 6c9 6 25 4 33-6z' fill='%230E7490'/><path d='M18 16L5 8v16z' fill='%230E7490'/><circle cx='47' cy='13.5' r='1.6' fill='%23fff'/></svg>");
  background-size: 46px 23px, 38px 19px;
  background-position: 30% 62%, 68% 74%;
  /* ชุดนี้หันหน้าไปทางขวา → ว่ายไปทางขวา สวนทางกับชั้นบน */
  animation: sea-swim-r 34s linear infinite, sea-bob 5.5s ease-in-out infinite reverse;
}
/* สาหร่ายก้นจอ: ก้านหลักที่ตัว element + อีก 2 ก้านจาก ::before/::after */
:root[data-theme="ocean"] .fx-e,
:root[data-theme="ocean"] .fx-f {
  bottom: -8px;
  width: 20px; height: 92px;
  border-radius: 60% 60% 8px 8px / 72% 72% 8px 8px;
  background: linear-gradient(180deg, rgba(13,148,136,0) 0%, rgba(13,148,136,.5) 38%, rgba(6,78,74,.8) 100%);
  transform-origin: 50% 100%;
  animation: sea-sway 6.5s ease-in-out infinite;
}
:root[data-theme="ocean"] .fx-e { left: 5%; }
:root[data-theme="ocean"] .fx-f { right: 8%; height: 116px; animation-duration: 8s; animation-delay: -2.4s; }
:root[data-theme="ocean"] .fx-e::before,
:root[data-theme="ocean"] .fx-e::after,
:root[data-theme="ocean"] .fx-f::before,
:root[data-theme="ocean"] .fx-f::after {
  content: '';
  position: absolute;
  bottom: 0;
  width: 15px;
  border-radius: inherit;
  background: inherit;
  transform-origin: 50% 100%;
  animation: sea-sway 7.5s ease-in-out infinite;
}
:root[data-theme="ocean"] .fx-e::before { left: 20px; height: 68px; animation-delay: -1.2s; }
:root[data-theme="ocean"] .fx-e::after  { left: 38px; height: 104px; width: 12px; animation-delay: -3.4s; animation-duration: 9s; }
:root[data-theme="ocean"] .fx-f::before { right: 22px; height: 78px; animation-delay: -2.8s; }
:root[data-theme="ocean"] .fx-f::after  { right: 42px; height: 58px; width: 12px; animation-delay: -4.6s; animation-duration: 6s; }
/* ฟองอากาศลอยขึ้นจากพื้น */
:root[data-theme="ocean"] .fx-shoot {
  left: 0; right: 0; bottom: 0; height: 100%;
  background-image:
    radial-gradient(circle, rgba(255,255,255,.75) 40%, transparent 62%),
    radial-gradient(circle, rgba(255,255,255,.55) 40%, transparent 62%),
    radial-gradient(circle, rgba(255,255,255,.65) 40%, transparent 62%);
  background-size: 7px 7px, 5px 5px, 9px 9px;
  background-repeat: no-repeat;
  background-position: 14% 100%, 62% 100%, 84% 100%;
  --bub-t: 9s;
}

@keyframes sea-rays {
  0%, 100% { opacity: .55; transform: translateX(-2%); }
  50% { opacity: .95; transform: translateX(3%); }
}
@keyframes sea-swim-r { from { transform: translateX(-16%); } to { transform: translateX(16%); } }
@keyframes sea-swim-l { from { transform: translateX(16%); } to { transform: translateX(-16%); } }
/* 16 ต.ค. 69 · เดิม margin-top = จัดผังใหม่ทุกเฟรม (ปลา · ดาวเคราะห์ · ใบไม้ ใน 5 ธีม) · translate ขยับระยะเท่ากัน แต่การ์ดจอทำเอง
   translate เป็นคนละคุณสมบัติกับ transform จึงซ้อนกับท่าว่าย (sea-swim ใช้ transform) ได้โดยไม่ทับกัน */
@keyframes sea-bob {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 10px; }
}
@keyframes sea-sway {
  0%, 100% { transform: rotate(-7deg); }
  50% { transform: rotate(8deg); }
}
/* ฟองลอยจากก้นจอถึงเลยขอบบน (-106% ของความสูงกล่อง) · +6px ชดเชยขนาดฟอง (ของเดิมวัดตำแหน่งจากขอบฟอง ไม่ใช่ขอบกล่อง) */
@keyframes sea-bubble-a {
  0%   { translate: 0 0; opacity: 0; }
  10%  { opacity: .9; }
  90%  { opacity: .5; }
  100% { translate: 3.5% calc(-106% + 6px); opacity: 0; }
}
@keyframes sea-bubble-b {
  0%   { translate: 0 0; opacity: 0; }
  10%  { opacity: .9; }
  90%  { opacity: .5; }
  100% { translate: -4% calc(-106% + 6px); opacity: 0; }
}

/* ---------- ทะเลลึก: น้ำมืด + ฉลาม + หมึกยักษ์ + แพลงก์ตอนเรืองแสง ---------- */
/* น้ำลึกกว่าโทนมหาสมุทรมาก แสงเหลือน้อย เงาสัตว์จึงเป็นตัวเล่าเรื่องแทน */
:root[data-theme="deepocean"] .fx-a {
  inset: 0;
  background:
    linear-gradient(180deg, rgba(6,60,95,.55) 0%, rgba(4,32,54,.75) 45%, rgba(2,12,22,.92) 100%),
    radial-gradient(120% 44% at 50% -12%, rgba(120,210,255,.26), transparent 72%);
}
:root[data-theme="deepocean"] .fx-b {   /* ลำแสงจาง ๆ ลอดลงมาจากผิวน้ำไกล ๆ */
  inset: -20% -10%;
  background:
    linear-gradient(96deg, transparent 26%, rgba(150,220,255,.15) 31%, transparent 36%),
    linear-gradient(102deg, transparent 56%, rgba(150,220,255,.10) 60%, transparent 65%);
  filter: blur(7px);
  animation: sea-rays 18s ease-in-out infinite;
}
/* ฉลาม: เงาใหญ่ ว่ายช้า ๆ ผ่านจอ */
:root[data-theme="deepocean"] .fx-c {
  left: -40%; right: -40%; top: 0; bottom: 30%;
  /* 13 ต.ค. 69 · .5 → .26 — ว่ายผ่านหลังการ์ดงาน คำอธิบายในห้องน้องฮูก และหัวข้อส่วน จนตัวหนังสืออ่านยาก
     (การ์ดโปร่ง 74% เห็นทะลุ) · จางลงให้เป็นเงาไกล ๆ ไม่ใช่ของที่แย่งสายตาจากตัวหนังสือ */
  opacity: .26;
  background-repeat: no-repeat;
  background-size: 132px 52px;
  background-position: 22% 34%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 132 52'><path d='M6 30c12-13 34-19 58-18 12 .5 22 3 30 7l10-13-2 17 10 8-13 5-5 15-7-11c-8 4-18 6.5-30 7-24 1-46-5-58-17z' fill='%2394C9E8'/><path d='M56 12l14 8-22 2z' fill='%2394C9E8'/><path d='M64 40l8 8-16-4z' fill='%2394C9E8'/><circle cx='24' cy='27' r='2' fill='%2304121F'/></svg>");
  /* ตัวฉลามหันหน้าไปทางซ้าย → ต้องว่ายไปทางซ้ายด้วย */
  animation: sea-swim-l 62s linear infinite, sea-bob 9s ease-in-out infinite;
}
/* หมึกยักษ์: ลอยขึ้นลงช้า ๆ อีกฝั่งของจอ */
:root[data-theme="deepocean"] .fx-d {
  left: 0; right: 0; top: 0; bottom: 8%;
  opacity: .42;
  background-repeat: no-repeat;
  background-size: 70px 96px;
  background-position: 74% 58%;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 70 96'><path d='M35 4c14 0 23 12 23 26 0 9-4 16-9 21H21c-5-5-9-12-9-21C12 16 21 4 35 4z' fill='%23A7C4E8'/><path d='M22 51c-2 12-8 18-14 22 8 0 14-6 18-14zM30 53c-1 14-4 24-7 33 6-6 10-18 12-31zM40 53c1 13 4 23 7 32-6-6-9-18-11-30zM48 51c2 12 8 18 15 22-8 1-15-6-19-14z' fill='%23A7C4E8'/><circle cx='27' cy='26' r='3.4' fill='%2304121F'/><circle cx='43' cy='26' r='3.4' fill='%2304121F'/></svg>");
  animation: deep-float 26s ease-in-out infinite;
}
/* สาหร่ายก้นจอ เหมือนโทนมหาสมุทรแต่มืดกว่า */
:root[data-theme="deepocean"] .fx-e,
:root[data-theme="deepocean"] .fx-f {
  bottom: -8px;
  width: 20px; height: 100px;
  border-radius: 60% 60% 8px 8px / 72% 72% 8px 8px;
  background: linear-gradient(180deg, rgba(20,120,120,0) 0%, rgba(15,110,110,.45) 38%, rgba(4,50,52,.8) 100%);
  transform-origin: 50% 100%;
  animation: sea-sway 7s ease-in-out infinite;
}
:root[data-theme="deepocean"] .fx-e { left: 5%; }
:root[data-theme="deepocean"] .fx-f { right: 8%; height: 124px; animation-duration: 8.5s; animation-delay: -2.4s; }
:root[data-theme="deepocean"] .fx-e::before,
:root[data-theme="deepocean"] .fx-e::after,
:root[data-theme="deepocean"] .fx-f::before,
:root[data-theme="deepocean"] .fx-f::after {
  content: '';
  position: absolute;
  bottom: 0;
  width: 15px;
  border-radius: inherit;
  background: inherit;
  transform-origin: 50% 100%;
  animation: sea-sway 8s ease-in-out infinite;
}
:root[data-theme="deepocean"] .fx-e::before { left: 20px; height: 72px; animation-delay: -1.2s; }
:root[data-theme="deepocean"] .fx-e::after  { left: 38px; height: 110px; width: 12px; animation-delay: -3.4s; }
:root[data-theme="deepocean"] .fx-f::before { right: 22px; height: 84px; animation-delay: -2.8s; }
:root[data-theme="deepocean"] .fx-f::after  { right: 42px; height: 62px; width: 12px; animation-delay: -4.6s; }
/* แพลงก์ตอนเรืองแสงลอยขึ้น */
:root[data-theme="deepocean"] .fx-shoot {
  left: 0; right: 0; bottom: 0; height: 100%;
  background-image:
    radial-gradient(circle, rgba(120,240,255,.9) 40%, transparent 62%),
    radial-gradient(circle, rgba(120,240,255,.6) 40%, transparent 62%),
    radial-gradient(circle, rgba(160,255,240,.75) 40%, transparent 62%),
    radial-gradient(circle, rgba(120,240,255,.5) 40%, transparent 62%);
  background-size: 5px 5px, 3px 3px, 4px 4px, 3px 3px;
  background-repeat: no-repeat;
  background-position: 18% 100%, 44% 100%, 68% 100%, 88% 100%;
  --bub-t: 13s;
}
/* 16 ต.ค. 69 · ฟองอากาศ (ทะเล · ทะเลลึก · ต้นไม้โลก · หวานแหว) ลอยด้วยการ์ดจอ ไม่ใช่เธรดหลัก
   เจ้าของ: "โทรศัพท์สเปค(ต่ำ) เริ่มใช้ไม่นานเครื่องจะค้างและกดอะไรไม่ได้"
   เดิมขยับ background-position ของกล่องเต็มจอ = วาดทั้งจอใหม่ทุกเฟรม ตลอดเวลา + กระจกฝ้าทุกชิ้นที่ทับอยู่ต้องเบลอใหม่ตาม
   วัดจริง (Chrome · CPU ช้าลง 6 เท่าเหมือนมือถือราคาถูก · วางเครื่องนิ่ง ไม่แตะ): ธีมทะเลเธรดหลักไม่ว่าง 69% · หยุดฟองอย่างเดียวเหลือ 15%
   เธรดหลักคือตัวเดียวกับที่รับการแตะ — เต็มเมื่อไหร่ แตะแล้วต้องรอคิว = "ค้าง กดไม่ได้"
   ตอนนี้: ฟองแต่ละลูกอยู่บนชั้นของตัวเอง (::before = ลูกที่ 1 กับ 3 ซึ่งลอยเฉียงทางเดียวกัน · ::after = ลูกที่ 2)
   แล้วเลื่อนทั้งชั้นด้วย translate (การ์ดจอเลื่อนภาพที่วาดไว้แล้วเอง ไม่ต้องวาดใหม่)
   ทางลอยเท่าเดิม: วัดตำแหน่งฟองเทียบของเดิมสี่จังหวะ ต่างไม่เกิน 4px · ความจางเท่าเดิมทุกจังหวะ
   กล่องเดิมไม่วาดฟองเองแล้ว (ดันภาพพื้นหลังออกนอกกล่อง) · ภาพ ขนาด สีของฟองยังมาจากกฎของแต่ละธีมเหมือนเดิม (inherit) */
:root:is([data-theme="ocean"], [data-theme="sweet"], [data-theme="earth2"], [data-theme="deepocean"]) .fx-shoot { background-position: -99px 0; }
:root:is([data-theme="ocean"], [data-theme="sweet"], [data-theme="earth2"], [data-theme="deepocean"]) .fx-shoot::before,
:root:is([data-theme="ocean"], [data-theme="sweet"], [data-theme="earth2"], [data-theme="deepocean"]) .fx-shoot::after {
  content: ''; position: absolute; inset: 0;
  background-image: inherit; background-size: inherit; background-repeat: no-repeat;
  opacity: 0;
  animation: sea-bubble-a var(--bub-t, 9s) linear infinite;
}
/* ภาพฟองชั้นที่ 4 ของทะเลลึก ใช้ตำแหน่งชุดแรกซ้ำ (กฎการวนรายการของ CSS) = ลอยไปกับลูกที่ 1 เหมือนของเดิม */
:root:is([data-theme="ocean"], [data-theme="sweet"], [data-theme="earth2"], [data-theme="deepocean"]) .fx-shoot::before { background-position: 14% 100%, -99px 0, 84% 100%; }
:root:is([data-theme="ocean"], [data-theme="sweet"], [data-theme="earth2"], [data-theme="deepocean"]) .fx-shoot::after { background-position: -99px 0, 62% 100%, -99px 0; animation-name: sea-bubble-b; }
@keyframes deep-float {
  0%, 100% { transform: translate(0, 0); }
  30% { transform: translate(-6%, -8%); }
  65% { transform: translate(5%, 6%); }
}

/* ---------- เวทมนตร์: วงเวทหมุน + ประกายลอยขึ้น ---------- */
:root[data-theme="magic"] .fx-a {
  inset: 0;
  background:
    radial-gradient(90% 60% at 20% 8%, rgba(139,92,246,.30), transparent 68%),
    radial-gradient(80% 55% at 84% 22%, rgba(232,194,90,.16), transparent 70%),
    radial-gradient(120% 80% at 50% 116%, rgba(88,44,168,.34), transparent 72%);
  animation: fx-breathe 14s ease-in-out infinite;
}
:root[data-theme="magic"] .fx-b {   /* วงเวทเส้นทอง */
  width: 300px; height: 300px;
  left: 50%; top: 34%;
  margin: -150px 0 0 -150px;
  border-radius: 50%;
  opacity: .16;
  border: 1.5px solid rgba(232,194,90,.9);
  box-shadow: inset 0 0 0 26px rgba(232,194,90,.06), inset 0 0 0 27.5px rgba(232,194,90,.5),
    inset 0 0 0 74px rgba(232,194,90,.04), inset 0 0 0 75px rgba(232,194,90,.32);
  background:
    conic-gradient(from 0deg, transparent 0 8%, rgba(232,194,90,.5) 8% 9%, transparent 9% 25%,
      rgba(232,194,90,.5) 25% 26%, transparent 26% 50%, rgba(232,194,90,.5) 50% 51%,
      transparent 51% 75%, rgba(232,194,90,.5) 75% 76%, transparent 76%);
  animation: fx-spin 70s linear infinite;
}
:root[data-theme="magic"] .fx-c,
:root[data-theme="magic"] .fx-d {   /* ประกายลอยขึ้นสองชั้น */
  inset: 0;
  background:
    radial-gradient(2px 2px at 14% 88%, rgba(232,194,90,.95), transparent),
    radial-gradient(1.5px 1.5px at 36% 96%, rgba(196,164,255,.9), transparent),
    radial-gradient(2.4px 2.4px at 62% 92%, rgba(232,194,90,.8), transparent),
    radial-gradient(1.6px 1.6px at 82% 98%, rgba(196,164,255,.85), transparent),
    radial-gradient(1.8px 1.8px at 50% 84%, rgba(255,240,200,.8), transparent);
  animation: fx-rise 17s linear infinite, fx-twinkle 4.5s ease-in-out infinite;
}
:root[data-theme="magic"] .fx-d { animation-duration: 25s, 6.5s; animation-delay: -9s, -2s; opacity: .6; }

/* ---------- กาแล็กซี: เนบิวลาหมุน + ดาวพารัลแลกซ์ + ดาวตก ---------- */
:root[data-theme="galaxy"] .fx-a {
  inset: -30%;
  background:
    radial-gradient(closest-side, rgba(168,85,247,.42), transparent 70%) 22% 26% / 62% 52% no-repeat,
    radial-gradient(closest-side, rgba(236,72,153,.34), transparent 70%) 74% 40% / 58% 46% no-repeat,
    radial-gradient(closest-side, rgba(56,189,248,.26), transparent 70%) 44% 74% / 66% 44% no-repeat;
  filter: blur(14px);
  animation: fx-spin 120s linear infinite, fx-breathe 18s ease-in-out infinite;
}
:root[data-theme="galaxy"] .fx-b {   /* แถบทางช้างเผือกพาดเฉียง */
  inset: -20%;
  background: linear-gradient(107deg, transparent 40%, rgba(226,214,255,.16) 48%,
    rgba(255,255,255,.24) 50%, rgba(226,214,255,.16) 52%, transparent 60%);
  filter: blur(7px);
  animation: fx-breathe 22s ease-in-out infinite;
}
:root[data-theme="galaxy"] .fx-c,
:root[data-theme="galaxy"] .fx-d {
  left: 0; right: 0; top: -10%; bottom: -10%;
  background-repeat: repeat-y;
  background-size: 100% 620px;
  background-image:
    radial-gradient(1.5px 1.5px at 28px 42px, #fff 100%, transparent),
    radial-gradient(1.2px 1.2px at 118px 122px, #E9D5FF 100%, transparent),
    radial-gradient(1.6px 1.6px at 208px 208px, #fff 100%, transparent),
    radial-gradient(1.2px 1.2px at 74px 292px, #FBCFE8 100%, transparent),
    radial-gradient(1.4px 1.4px at 292px 366px, #fff 100%, transparent),
    radial-gradient(1.1px 1.1px at 158px 470px, #A5F3FC 100%, transparent),
    radial-gradient(1.5px 1.5px at 336px 548px, #fff 100%, transparent);
  animation: star-drift 80s linear infinite, fx-twinkle 5s ease-in-out infinite;
}
:root[data-theme="galaxy"] .fx-d {
  opacity: .55;
  background-size: 100% 430px;
  animation-duration: 150s, 7.5s;
  animation-delay: 0s, -3s;
}
:root[data-theme="galaxy"] .fx-shoot,
:root[data-theme="space"] .fx-shoot {
  width: 130px; height: 1.6px;
  top: 16%; left: -140px;
  border-radius: 99px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.95));
  box-shadow: 0 0 10px 1px rgba(255,255,255,.55);
  opacity: 0;
  animation: fx-shoot 11s ease-in infinite;
}
:root[data-theme="space"] .fx-shoot { animation-duration: 15s; animation-delay: 5s; top: 22%; }

/* ---------- อวกาศ: เติมเนบิวลา + ขอบมืด ให้ลึกกว่าเดิม ---------- */
:root[data-theme="space"] .fx-a {
  inset: -20%;
  background:
    radial-gradient(closest-side, rgba(124,107,240,.34), transparent 70%) 26% 18% / 66% 48% no-repeat,
    radial-gradient(closest-side, rgba(94,208,232,.18), transparent 70%) 78% 62% / 58% 44% no-repeat,
    radial-gradient(closest-side, rgba(245,230,99,.10), transparent 70%) 40% 88% / 54% 38% no-repeat;
  filter: blur(16px);
  animation: fx-breathe 20s ease-in-out infinite;
}
:root[data-theme="space"] .fx-b {
  inset: 0;
  background: radial-gradient(120% 90% at 50% 42%, transparent 52%, rgba(3,5,20,.6) 100%);
}
/* ดาวชั้นที่ 4: เม็ดเล็กจิ๋ว วิ่งช้าสุด — เพิ่มความลึกแบบพารัลแลกซ์ */
:root[data-theme="space"] .starfield i:nth-child(4) {
  opacity: .4;
  background-size: 100% 940px;
  animation-duration: 220s, 11s;
  animation-delay: 0s, -6s;
  background-image:
    radial-gradient(.9px .9px at 66px 120px,#fff 100%,transparent),
    radial-gradient(.9px .9px at 286px 300px,#C4BCFF 100%,transparent),
    radial-gradient(1px 1px at 150px 520px,#fff 100%,transparent),
    radial-gradient(.9px .9px at 320px 760px,#F5E663 100%,transparent),
    radial-gradient(.9px .9px at 40px 880px,#fff 100%,transparent);
}

@keyframes fx-drift-x { from { transform: translateX(-8%); } to { transform: translateX(8%); } }
/* 16 ต.ค. 69 · เดิมทั้งสองท่าเขียน transform — ชิ้นที่ใช้คู่กัน (เนบิวลาของกาแล็กซี) Chrome ส่งให้การ์ดจอไม่ได้
   (สองอนิเมชันแย่ง transform ตัวเดียวกัน · trace บอกเหตุผล "TargetHasIncompatibleAnimations") ทั้งคู่จึงไปวิ่งบนเธรดหลัก
   บนชั้นใหญ่ 160% ของจอที่เบลอ 14px — วัด CPU ช้า 6 เท่า ธีมกาแล็กซีเธรดหลักไม่ว่าง 34% · หยุดชั้นนี้เหลือ 12%
   แยกเป็น rotate กับ scale (คนละคุณสมบัติ ซ้อนกันได้ การ์ดจอทำเองทั้งคู่) · ทุกชิ้นที่ใช้สองท่านี้ไม่มี transform ตั้งไว้ถาวร ภาพจึงเหมือนเดิม */
@keyframes fx-spin { to { rotate: 360deg; } }
@keyframes fx-breathe { 0%, 100% { opacity: .75; scale: 1; } 50% { opacity: 1; scale: 1.07; } }
@keyframes fx-lamp { 0%, 100% { opacity: .82; } 45% { opacity: 1; } }
@keyframes fx-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50% { transform: translate3d(10px, -14px, 0); }
}
@keyframes fx-rise { from { transform: translateY(0); } to { transform: translateY(-105%); } }
@keyframes fx-twinkle { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.75); } }
@keyframes fx-shoot {
  0%      { opacity: 0; transform: translate(0, 0) rotate(16deg); }
  2%      { opacity: 1; }
  9%      { opacity: 1; }
  12%     { opacity: 0; transform: translate(620px, 190px) rotate(16deg); }
  100%    { opacity: 0; transform: translate(620px, 190px) rotate(16deg); }
}
@media (prefers-reduced-motion: reduce) {
  .fx i, .fx span { animation: none !important; }
  /* ฟองชั้นใหม่ (::before/::after) — หยุดนิ่งที่ก้นจอให้เห็นเหมือนตอนเป็นกล่องเดียว */
  .fx span::before, .fx span::after { animation: none !important; opacity: 1; }
}

/* ============================================================
   ขนาดตัวอักษร
   ดีไซน์เดิมเป็น px ล้วน → ขยับ font-size ที่รากไม่มีผล
   ใช้ zoom กับกล่องเนื้อหาแทน: ตัวอักษร ไอคอน ระยะห่าง ขยายพร้อมกัน
   กรอบเครื่อง แถบสถานะ และแถบล่างไม่โดน จะได้ไม่ล้นจอ
   ============================================================ */
:root { --fs: 1; }
.home-body, .scr-body, .sticky-head, #taskList, #timeline, .login-wrap { zoom: var(--fs); }

.fs-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; }
.fs-grid button {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  min-height: 52px; padding: 6px 4px;
  border: 1.5px solid var(--line); border-radius: var(--r-tile);
  background: var(--card2); color: var(--muted);
  font-family: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
  transition: all .16s ease;
}
.fs-grid button b { font-weight: 700; line-height: 1.1; }
.fs-grid button:active { transform: scale(.96); }
.fs-grid button.active { border-color: var(--blue); color: var(--ink); background: var(--blue-soft); }

/* ============================================================
   พื้นหลังภาพของผู้ใช้เอง
   ============================================================ */
.userbg { display: none; }
:root[data-bg="on"] .userbg {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-size: cover;
  background-position: center;
}
.userbg .ub-veil {
  position: absolute;
  inset: 0;
  display: block;
  background: var(--scr);
  opacity: var(--bg-veil, .55);
}

/* มีภาพพื้นหลัง (หรือธีมห้องสมุด) → การ์ดกึ่งโปร่ง + เบลอหลังการ์ด
   ให้เห็นภาพลอดโดยที่ตัวหนังสือยังอ่านออก */
/* หมายเหตุ: ห้ามใส่ .brief ในกลุ่มนี้ — การ์ดของ AI ใช้พื้นไล่สีเข้มกับตัวอักษรสีขาว
   ถ้าเอาสีการ์ด (ขาว) ไปทับ พื้นจะกลายเป็นขาว ตัวหนังสือขาวก็หายไปทั้งใบ */
:root[data-bg="on"] .rank-card, :root[data-bg="on"] .card,
:root[data-bg="on"] .fm-card, :root[data-bg="on"] .ob-card, :root[data-bg="on"] .pf-list,
:root[data-bg="on"] .arow, :root[data-bg="on"] .paste-card, :root[data-bg="on"] .skel-card {
  background: var(--card); /* เบราว์เซอร์เก่าที่ไม่รู้จัก color-mix ได้พื้นทึบตามเดิม */
  background: color-mix(in srgb, var(--card) 86%, transparent);
  backdrop-filter: blur(14px) saturate(135%);
  -webkit-backdrop-filter: blur(14px) saturate(135%);
}
/* ธีมมหาสมุทร: การ์ดโปร่งนิดเดียวพอให้เห็นเงาปลาว่ายผ่านหลังการ์ดราง ๆ
   ไม่โปร่งมากเพราะตัวหนังสือต้องมาก่อนความสวย */
:root[data-theme="ocean"] .rank-card,
:root[data-theme="ocean"] .card, :root[data-theme="ocean"] .fm-card,
:root[data-theme="ocean"] .ob-card, :root[data-theme="ocean"] .pf-list,
:root[data-theme="ocean"] .arow, :root[data-theme="ocean"] .paste-card {
  background: var(--card);
  background: color-mix(in srgb, var(--card) 93%, transparent);
  backdrop-filter: blur(10px) saturate(125%);
  -webkit-backdrop-filter: blur(10px) saturate(125%);
}

.bg-tools { display: flex; gap: 8px; }
.bg-pick {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; border-radius: var(--r-tile);
  border: 1.5px dashed var(--line); background: var(--card2); color: var(--muted);
  font-size: 13px; font-weight: 600; cursor: pointer;
  transition: all .16s ease;
}
.bg-pick svg { width: 16px; height: 16px; }
.bg-pick:active { transform: scale(.98); color: var(--blue); border-color: var(--blue); }
.bg-del {
  flex: none; width: 44px; min-height: 44px;
  border: 1.5px solid var(--line); border-radius: var(--r-tile);
  background: transparent; color: var(--alert); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.bg-del svg { width: 16px; height: 16px; }
.bg-del:active { transform: scale(.95); background: var(--alert-soft); }
.bg-dim { display: flex; flex-direction: column; gap: 8px; }
.bg-dim[hidden] { display: none; }
.bg-dim label { font-size: 11px; font-weight: 600; color: var(--faint); letter-spacing: .08em; text-transform: uppercase; }
.bg-dim .val { font-size: 13px; font-weight: 600; color: var(--blue); font-variant-numeric: tabular-nums; }
.bg-dim input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
  background: var(--card2); border-radius: 99px; padding: 0; min-height: 0; outline: none;
}
.bg-dim input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--card); box-shadow: 0 2px 8px rgba(15,23,42,.2), 0 0 0 2px var(--blue); cursor: pointer;
}
.bg-dim input[type=range]::-moz-range-thumb {
  width: 20px; height: 20px; border: none; border-radius: 50%;
  background: var(--card); box-shadow: 0 2px 8px rgba(15,23,42,.2), 0 0 0 2px var(--blue); cursor: pointer;
}
.bg-note { margin: 0; font-size: 11.5px; line-height: 1.6; color: var(--faint); }

/* ============================================================
   เส้นเวลา (แกนตั้ง)
   วันไหลลงตามแกน Y · แต่ละวันมีแถบรูปร่างของวันจาก context
   แถบ = พื้นว่าง + ก้อนทึบคือเวลาที่ติดเรียน/กิจวัตร + หมุดคือกำหนดส่ง
   ============================================================ */
.tl { position: relative; margin-top: 18px; padding-left: 26px; }
/* เส้นแกนตั้ง — ลากผ่านจุดกึ่งกลางของหัวข้อวันทุกใบ */
.tl::before {
  content: ''; position: absolute; left: 7px; top: 8px; bottom: 8px; width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--blue) 0%, var(--line) 42%, var(--line) 100%);
  opacity: .5;
}

.tl-day { position: relative; padding-bottom: 22px; }
.tl-day:last-child { padding-bottom: 0; }
.tl-dot {
  position: absolute; left: -26px; top: 5px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--scr); border: 2px solid var(--line); box-sizing: border-box;
}
.tl-day.today .tl-dot {
  border-color: var(--blue); background: var(--blue);
  box-shadow: 0 0 0 4px var(--blue-soft);
}
.tl-day.quiet .tl-dot { opacity: .55; }

.tl-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.tl-head b { font-size: 14.5px; font-weight: 700; letter-spacing: -.015em; color: var(--ink); }
.tl-day.today .tl-head b { color: var(--blue); }
.tl-date { font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
.tl-free {
  margin-left: auto; font-size: 11px; font-weight: 650; color: var(--good);
  background: var(--good-soft); padding: 3px 9px; border-radius: 99px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tl-free.low { color: var(--warn); background: var(--warn-soft); }

/* ---- แถบรูปร่างของวัน ---- */
/* พื้นแถบ = เวลาที่ใช้ไม่ได้ (ติดเรียน กิจวัตร หรือผ่านไปแล้ว) */
.tl-bar {
  position: relative; height: 22px; border-radius: 8px; overflow: hidden;
  background: var(--card2); margin-bottom: 9px;
}
/* ก้อนสี = ช่องว่างจริง — สิ่งเดียวบนแถบนี้ที่คนมองหา จึงเป็นสิ่งเดียวที่มีสี */
.tl-bar .f {
  position: absolute; top: 0; bottom: 0; background: var(--good); opacity: .55;
}
/* หมุดกำหนดส่ง — เส้นตั้งเต็มความสูงของแถบ เห็นชัดว่าตกตรงไหนของวัน */
.tl-bar .p {
  position: absolute; top: 0; bottom: 0; width: 3px; margin-left: -1.5px; border-radius: 2px;
}
.tl-bar .p.red { background: var(--pri-red); }
.tl-bar .p.yellow { background: var(--pri-yellow); }
.tl-bar .p.green { background: var(--pri-green); }
.tl-bar .now {
  position: absolute; top: -2px; bottom: -2px; width: 2px; margin-left: -1px;
  background: var(--blue); box-shadow: 0 0 0 1.5px var(--scr);
  transition: left .4s ease;
}

.tl-warn {
  display: flex; align-items: flex-start; gap: 7px; background: var(--warn-soft);
  border-radius: 12px; padding: 9px 11px; margin-bottom: 9px;
  font-size: 12px; line-height: 1.55; color: var(--ink);
}
.tl-warn svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--warn); }
/* วันที่ตามมา — หนี้ก้อนเดียวกัน ไม่ต้องตะโกนซ้ำ */
.tl-warn.soft { background: none; padding: 2px 2px 7px; color: var(--muted); font-size: 11.5px; }
.tl-warn.soft svg { color: var(--faint); }

/* ---- การ์ดงานใต้แถบ ---- */
.tl-task {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: var(--card); border-radius: 14px; padding: 10px 12px; margin-bottom: 7px;
  box-shadow: var(--shadow); cursor: pointer; border-left: 3px solid transparent;
}
.tl-task.red { border-left-color: var(--pri-red); }
.tl-task.yellow { border-left-color: var(--pri-yellow); }
.tl-task.green { border-left-color: var(--pri-green); }
.tl-task.over { background: var(--alert-soft); }
.tl-task:active { transform: scale(.985); }
.tt-time {
  flex: none; width: 42px; font-size: 11.5px; font-weight: 650; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.tt-ic {
  flex: none; width: 26px; height: 26px; border-radius: 9px; background: var(--card2);
  color: var(--muted); display: flex; align-items: center; justify-content: center;
}
.tt-ic svg { width: 14px; height: 14px; }
.tt-bd { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tt-nm {
  font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tt-sub { font-size: 11.5px; color: var(--faint); }
.tl-none { font-size: 12px; color: var(--faint); padding: 1px 2px 2px; }

/* ---- การ์ดงานถัดไป (บนสุด) ---- */
.tl-next {
  display: flex; align-items: center; gap: 12px; background: var(--card);
  border-radius: 20px; padding: 14px 15px; box-shadow: var(--shadow); margin-top: 4px;
}
.tl-next.late { background: var(--alert-soft); }
.tl-next .tile {
  width: 36px; height: 36px; flex: none; border-radius: 12px; background: var(--blue-soft);
  color: var(--blue); display: flex; align-items: center; justify-content: center;
}
.tl-next.late .tile { background: var(--alert); color: #fff; }
.tl-next .tile svg { width: 18px; height: 18px; }
.tl-next .bd { flex: 1; min-width: 0; }
.tl-next .lb {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 3px;
}
.tl-next.late .lb { color: var(--alert); }
.tl-next .tx {
  font-size: 13.5px; line-height: 1.5; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-next .go {
  flex: none; width: 30px; height: 30px; border-radius: 10px; background: var(--card2);
  color: var(--muted); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.tl-next .go svg { width: 15px; height: 15px; }

/* ชวนกรอกบริบท — โครงเดียวกับการ์ดในหน้าแผน */
.tl-nudge {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--blue-soft); border: 1px dashed var(--blue); border-radius: 18px;
  padding: 13px 14px; margin-top: 12px; cursor: pointer;
}
.tl-nudge:active { transform: scale(.985); }

/* รุ่นบรรทัดเดียวของคำชวนข้างบน — ใช้ในเส้นเวลา ซึ่งของหลักคือเส้น ไม่ใช่คำชวน
   ไม่มีกรอบ ไม่มีพื้นสี เพราะกรอบประให้ความรู้สึกว่า "มีอะไรผิด" ทั้งที่แค่ยังไม่ได้กรอก */
/* 1C07 · ขยายขึ้นมาเท่าหัวข้อกลุ่ม — เจ้าของวงบรรทัดนี้มาด้วย
   บรรทัดนี้คือที่เดียวบนจอที่บอกว่า AI ยังเดาเวลาว่างอยู่ แต่มันเคยเป็น
   ตัวหนังสือที่เล็กที่สุดและจางที่สุดในจอ ซึ่งอ่านเป็น "ข้อความประกอบ"
   ทั้งที่มันคือปุ่ม · nowrap ถูกถอด — ตัดท้ายประโยคทิ้งบนจอ 375
   ทำให้คำว่า "เดาเวลาว่างอยู่" หายไป ซึ่งเป็นครึ่งที่สำคัญกว่าของประโยค */
.tl-hint {
  display: flex; align-items: center; gap: 7px; width: 100%; text-align: left;
  background: transparent; border: none; padding: 2px 2px 0; margin-bottom: 14px;
  font-family: inherit; font-size: 13px; line-height: 1.45; color: var(--ink); cursor: pointer;
}
.tl-hint span { flex: 1; min-width: 0; }
.tl-hint b { flex: none; font-weight: 700; color: var(--fill); }
.tl-hint svg { width: 13px; height: 13px; flex: none; color: var(--faint); }
.tl-hint:active { opacity: .6; }

.tl-cap {
  display: flex; align-items: flex-start; gap: 7px; margin: 16px 0 0;
  font-size: 11.5px; line-height: 1.6; color: var(--muted);
}
.tl-cap svg { width: 13px; height: 13px; flex: none; margin-top: 3px; color: var(--faint); }
.tl-cap b { color: var(--ink); font-variant-numeric: tabular-nums; }

.tl-legend {
  display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; padding: 0 2px;
  font-size: 11px; color: var(--faint);
}
.tl-legend span { display: flex; align-items: center; gap: 6px; }
.tl-legend .k { width: 12px; height: 8px; border-radius: 3px; flex: none; }
.tl-legend .k.free { background: var(--good); opacity: .55; }
.tl-legend .k.busy { background: var(--card2); box-shadow: inset 0 0 0 1px var(--line); }
.tl-legend .k.red { background: var(--pri-red); width: 3px; }
.tl-legend .k.green { background: var(--pri-green); width: 3px; }

.tl-un { margin-top: 20px; }
.tl-un .lb {
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 9px;
}
.tl-un .chips { display: flex; flex-wrap: wrap; gap: 7px; }
.tl-un .chips button {
  font-size: 12.5px; padding: 8px 12px; border-radius: 12px; background: var(--card);
  border: 1px solid var(--line); color: var(--ink); cursor: pointer; font-family: inherit;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-un .chips button:active { transform: scale(.97); color: var(--blue); border-color: var(--blue); }
.tl-far { margin: 14px 2px 0; font-size: 12px; color: var(--faint); }

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

/* ============================================================
   แถวฟีเจอร์ที่ยังไม่เสร็จ (เพื่อน)
   ติ๊กค้างไว้ว่ายังไม่เสร็จ + กดไม่ได้จริง ๆ (pointer-events:none)
   ============================================================ */
.pf-row.soon { opacity: .6; pointer-events: none; user-select: none; }
.pf-row.soon .tile { background: var(--card2); color: var(--faint); }
.soon-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--warn-soft);
  color: var(--warn);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
  vertical-align: middle;
}
.soon-box {
  flex: none;
  width: 34px; height: 34px;
  border-radius: 10px;
  border: 1.5px dashed var(--line);
  color: var(--faint);
  display: flex; align-items: center; justify-content: center;
}
.soon-box svg { width: 15px; height: 15px; }

/* ============================================================
   หน้าแรก = เมนูหลัก
   ไทล์ใหญ่ กดง่าย ไม่มีข้อความอธิบาย — มีแค่ไอคอน ชื่อ และตัวเลขจริงจาก state
   ============================================================ */
/* ---------- สีประจำไทล์ ----------
   เดิมไทล์ทั้ง 4 ใบใช้ --blue ชุดเดียวกันหมด วางเรียงกันแล้วกลายเป็นกำแพงสีเดียว
   ตาต้องอ่านตัวหนังสือทุกใบก่อนถึงจะรู้ว่าอันไหนคืออะไร — จำตำแหน่งด้วยสีไม่ได้เลย
   ให้แต่ละใบมีสีของตัวเอง แต่อยู่ใน "ตระกูลน้ำเงิน" ทั้งหมด
   (แอปนี้คือขาวน้ำเงินกับดำน้ำเงิน สีที่หลุดตระกูลไปจะอ่านเป็นแอปคนละตัวทันที)

   ค่าเริ่มต้นตรงนี้คือ --blue ล้วน ๆ เท่ากับหน้าตาเดิมเป๊ะ
   ธีมไหนไม่ได้กำหนดทับข้างล่าง ก็ไม่มีอะไรเปลี่ยน ไม่ต้องไล่แก้ทั้ง 12 ธีม */
/* ค่าตั้งต้นต้องเป็นกลาง = สีเน้นของธีมนั้นเอง
   ถ้าใส่สีตายตัวตรงนี้ ธีมที่ไม่ได้ตั้งใจแตะ (ทะเลลึก · หวาน · โลก) จะได้ชิปสีน้ำเงินติดมาด้วย
   ทั้งที่ทั้งธีมเป็นเขียวหรือม่วง — ธีมไหนอยากแยกสีไทล์ ค่อยประกาศทับเอง */
:root {
  --tile-plan:  var(--fill); --tile-plan-soft:  var(--blue-soft);
  --tile-tasks: var(--fill); --tile-tasks-soft: var(--blue-soft);
  --tile-route: var(--fill); --tile-route-soft: var(--blue-soft);
  --tile-me:    var(--fill); --tile-me-soft:    var(--blue-soft);
  --tile-on:    var(--on-fill);
}
/* ขาวน้ำเงิน — ชิปวางบนการ์ดสีขาว จึงต้องเข้มพอให้ไอคอนขาวอ่านออก */
:root[data-theme="light"] {
  --tile-plan:  #1566CE; --tile-tasks: #0E7C86;
  --tile-route: #5B4BC4; --tile-me:    #1A6FA8;
  --tile-on:    #FFFFFF;
}
/* ดำน้ำเงิน — ไล่จากน้ำเงินหลักไปฟ้าและคราม ห่างกันพอให้แยกออกด้วยหางตา
   ทุกค่าต้องสว่างพอ เพราะป้ายตัวเลขใช้สีนี้เป็นพื้นแล้ววางตัวอักษรสีเข้ม (--on-accent) ทับ */
/* ธีมมืดเคยยุบสีไทล์ทั้งสี่ให้เหลือฟ้าเดียวตามกฎ 60/30/10 (สีเน้นควรมีสีเดียว)
   ผลข้างเคียงคือชิปไอคอนหกใบบนหน้าแรกกลายเป็นสี่เหลี่ยมสีเดียวกันเรียงกัน
   ตาเลยไม่มีอะไรให้เกาะ ต้องอ่านตัวหนังสือทุกใบก่อนถึงจะรู้ว่าใบไหนคืออะไร
   ซึ่งแพงกว่าที่กฎสีช่วยประหยัดไว้ — คืนสีให้ทั้งสี่ใบ แต่คุมให้อยู่ในตระกูลน้ำเงินเหมือนเดิม
   (น้ำเงิน → ฟ้าอมเขียว → ม่วงคราม → ฟ้า) ห่างกันพอให้แยกออกด้วยหางตาโดยไม่หลุดโทนแอป */
:root[data-theme="dark"] {
  --tile-plan:  #2E6BFF; --tile-plan-soft:  var(--blue-soft);
  --tile-tasks: #0E9AA0; --tile-tasks-soft: var(--blue-soft);
  --tile-route: #6D5CE0; --tile-route-soft: var(--blue-soft);
  --tile-me:    #1D86BF; --tile-me-soft:    var(--blue-soft);
  --tile-on:    #FFFFFF;
}
/* ขาวน้ำเงิน — กลับกัน ต้องเข้มพอเพราะเป็นไอคอนบนพื้นขาว และป้ายตัวเลขวางตัวอักษรขาวทับ */
:root[data-theme="ocean"] {
  --tile-plan:  #0E6E92; --tile-plan-soft:  #D5EDF9;
  --tile-tasks: #0E8AA8; --tile-tasks-soft: #D3EFF7;
  --tile-route: #4B57C4; --tile-route-soft: #E1E4FB;
  --tile-me:    #1667BF; --tile-me-soft:    #DCEAFA;
  --tile-on:    #FFFFFF;
}

/* หน้าแรกต้องจบในจอเดียว ไม่ต้องเลื่อน — ทุกระยะในหน้านี้จึงถูกบีบกว่าจอทั่วไป */
.menu-body { gap: 9px; padding-top: 10px; padding-bottom: calc(80px + var(--tabgap)); }
.menu-head .page-title { margin-top: 2px; }
.menu-head .page-sub { display: none; }
/* ชื่อผู้ใช้ในคำทักทาย — คำเดียวบนจอที่เป็นของเขาคนเดียว ให้มันมีสี */
.menu-head .page-title .pt-me { color: var(--blue); font-weight: 700; }
.menu-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
/* --mt-a / --mt-s = สีของไทล์ใบนี้ (เข้ม/อ่อน) — ทุกชิ้นข้างในอ่านจากสองตัวนี้ตัวเดียว
   เปลี่ยนสีไทล์ทั้งใบจึงแก้ที่บรรทัดเดียว ไม่ต้องไล่แก้ไอคอน ป้ายเลข และวงแสงทีละอัน */
/* --mt-on คู่มากับ --mt-a เสมอ เพราะไอคอนวางทับพื้นสีนั้นโดยตรง
   ธีมที่ไม่ได้กำหนด --tile-* ไว้ (ทะเลลึก · หวาน · โลก · เจเนซิส) จะตกมาที่ค่าตั้งต้น
   ซึ่งคือ --fill/--on-fill ของธีมนั้นเอง = หน้าตาเดิมเป๊ะ ไม่ต้องไล่แก้ทีละธีม */
.mtile { --mt-a: var(--fill); --mt-s: var(--blue-soft); --mt-on: var(--on-fill); }
.mtile.tone-plan  { --mt-a: var(--tile-plan);  --mt-s: var(--tile-plan-soft);  --mt-on: var(--tile-on, var(--on-fill)); }
.mtile.tone-tasks { --mt-a: var(--tile-tasks); --mt-s: var(--tile-tasks-soft); --mt-on: var(--tile-on, var(--on-fill)); }
.mtile.tone-route { --mt-a: var(--tile-route); --mt-s: var(--tile-route-soft); --mt-on: var(--tile-on, var(--on-fill)); }
.mtile.tone-me    { --mt-a: var(--tile-me);    --mt-s: var(--tile-me-soft);    --mt-on: var(--tile-on, var(--on-fill)); }
.mtile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 7px;
  min-height: 92px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -.015em;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: transform .16s ease, box-shadow .16s ease;
}
.mtile::after {              /* แสงจาง ๆ มุมบนขวา ให้ไทล์ไม่แบนจนเกินไป */
  content: '';
  position: absolute;
  top: -46px; right: -34px;
  width: 128px; height: 128px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--mt-s), transparent 70%);
  pointer-events: none;
}
.mtile:active { transform: scale(.975); box-shadow: var(--shadow-lg); }
.mt-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border-radius: 12px;
  /* ชิปไอคอนเป็นพื้นทึบสีเน้น ไม่ใช่พื้นจาง ๆ อีกแล้ว
     พื้นจางบนการ์ดสีเข้มแทบไม่ต่างจากตัวการ์ด ไอคอนเลยลอยอยู่เฉย ๆ ไม่มีขอบเขต
     ก้อนทึบทำให้ตาจับ "จุดเริ่มของไทล์" ได้ก่อนอ่านตัวหนังสือ และเป็นตัวเดียวกับ
     ที่กฎ 60/30/10 กันไว้ให้เป็นสีเน้น 10% */
  /* ใช้สีของไทล์ใบนั้น ไม่ใช่ --fill ก้อนเดียวทั้งหน้า
     --mt-a ถูกประกาศไว้ตั้งแต่แรกแต่ไม่เคยมีใครอ่าน ชิปทุกใบเลยฟ้าเหมือนกันหมด */
  background: var(--mt-a, var(--fill));
  color: var(--mt-on, var(--on-fill));
  position: relative;
}
.mt-ic svg { width: 18px; height: 18px; stroke-width: 2.1; }
.mt-tx { position: relative; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mt-lb { position: relative; }
/* คำอธิบายใต้ชื่อไทล์ต้องอยู่บรรทัดเดียวเสมอ — ตกบรรทัดเมื่อไหร่หน้าแรกก็ต้องเลื่อนทันที */
.mt-sub {
  font-size: var(--fs-meta);
  font-weight: 500;
  line-height: 1.4;
  color: var(--muted);
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mtile.hero .mt-sub { color: rgba(255,255,255,.72); }
/* ตัวเลขบนไทล์: เดิมใช้ card2 + muted ซึ่งบนธีมสว่างมันจางจนแทบมองไม่เห็น
   เปลี่ยนมาใช้สีเน้นของธีม อ่านออกทั้งโทนสว่างและโทนมืด */
/* ตัวเลขบนไทล์: พื้นทึบสีเน้น + ตัวอักษรสีตัดกันเต็มที่
   (เคยใช้พื้นอ่อนกับตัวอักษรอ่อน แล้วบางธีมมองแทบไม่เห็นเลย) */
.mt-ct {
  position: absolute;
  top: 13px; right: 13px;
  min-width: 24px;
  padding: 3px 8px 4px;
  border-radius: 999px;
  /* ตัวเลขบนไทล์เป็นสีกลาง ไม่ใช่สีเน้น — ตัวเลขส่วนใหญ่บนหน้าแรกเป็นแค่ "ของที่มีอยู่"
     ไม่ใช่ "ของที่ต้องทำเดี๋ยวนี้" ป้าย 0 ของกล่องเข้าเคยเด่นเท่าป้าย 5 ของงานค้าง
     ซึ่งบอกลำดับผิดตรง ๆ ตัวที่ต้องลงมือจริงจะได้สีเน้นทีละใบข้างล่าง */
  background: var(--card2);
  color: var(--ink);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: var(--fs-meta);
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  /* ต้นเหตุที่ตัวเลขจางในธีมสว่าง: .mtile::after คือวงแสงมุมบนขวา 128px
     ที่ไล่จาก var(--blue-soft) ออกไปโปร่ง — ธีมสว่างสีนั้นเป็นสีทึบ (เช่น #E2EEFC)
     และ pseudo-element เป็นลูกคนสุดท้าย จึงวาดทับป้ายที่ไม่มี z-index จนมิด
     (.mt-tx ของดีไซน์เดิมกัน position:relative ไว้แล้ว แต่ป้ายตัวเลขตกหล่นไป)
     ธีมมืดไม่เป็นเพราะสีนั้นเป็น rgba โปร่งเกือบหมด */
  z-index: 2;
  /* เงาใต้ป้าย + วงแหวนสีการ์ด ทำให้ป้ายลอยขึ้นมาจากไทล์ ไม่จมไปกับพื้นไม่ว่าธีมไหน */
  box-shadow: 0 0 0 2px var(--card), 0 3px 8px rgba(0,0,0,.3);
  /* เงาใต้ตัวเลขอีกชั้น เผื่อธีมที่สีป้ายกับสีตัวอักษรใกล้กันกว่าที่ควร */
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
  /* กันไม่ให้ความโปร่งของกล่องแม่ (ธีมที่การ์ดกึ่งโปร่ง / มีภาพพื้นหลัง) ลามมาที่ตัวเลข */
  opacity: 1;
}
.mt-ct.hot {
  background: var(--pri-red);
  color: #fff;
  box-shadow: 0 0 0 2px var(--card), 0 3px 8px rgba(0,0,0,.3);
}
/* ไทล์เดียวบนหน้าแรกที่ตัวเลขแปลว่า "งานที่ยังไม่ได้ทำ" คือตารางงาน
   มันจึงเป็นตัวเลขตัวเดียวที่ได้สีเน้น ที่เหลือเป็นสีกลางหมด */
.mtile.tone-plan .mt-ct { background: var(--fill); color: var(--on-fill); }
.mtile.hero .mt-ct {
  background: #fff;
  color: var(--blue-deep);
  text-shadow: none;                       /* พื้นขาวตัวน้ำเงินเข้ม ไม่ต้องมีเงาช่วย */
  box-shadow: 0 0 0 2px rgba(0,0,0,.14), 0 3px 8px rgba(0,0,0,.26);
}
/* ไทล์เด่น: เพิ่มงานใหม่ — กว้างเต็มแถวและใช้สีแบรนด์ */
/* ไทล์เด่นครึ่งแถว — วางคู่กับ "งานทั้งหมด" ให้ปุ่มที่ต้องกดบ่อยที่สุดได้สีเน้น
   ส่วนปุ่มที่แค่พาไปดูของเก่าอยู่ข้าง ๆ ด้วยสีกลาง ขนาดเท่ากันแต่น้ำหนักไม่เท่ากัน
   ธีมมืดลด --grad-hero ลงเป็นสีการ์ดทั้งแอป (กฎ 60/30/10 ท้ายไฟล์) ซึ่งถูกสำหรับ
   "กล่องใหญ่ที่แค่แสดงผล" แต่ใบนี้คือปุ่มลงมือของทั้งหน้า มันต้องเป็นสีเน้นจริง ๆ
   จึงบังคับ --fill กลับมาเฉพาะใบนี้ใบเดียว ไม่แตะ .mtile.hero ใบอื่น */
.mtile.hero.half {
  grid-column: span 1;
  min-height: 108px;
  font-size: var(--fs-body);
  background: var(--fill);
  color: var(--on-fill);
}
/* กรอบไอคอนเดิมเป็นขาว 22% + ไอคอนขาว บนพื้นน้ำเงิน = ขาวจาง ๆ บนน้ำเงิน แล้วขาวทึบบนขาวจาง
   สองชั้นนั้นต่างกันน้อยเกินกว่าจะเห็นเป็นรูปกล้อง มันเลยละลายหายไปกับพื้น
   ทางออกคือทำกรอบให้ "เข้มกว่า" พื้นแทนที่จะสว่างกว่า ไอคอนขาวจึงลอยขึ้นมาชัด
   ใช้ดำโปร่งไม่ใช่สีน้ำเงินเจาะจง เพราะไทล์นี้เปลี่ยนสีตามธีมทั้ง 15 ตัว
   ดำโปร่งทำให้มันเข้มกว่าพื้นเสมอไม่ว่าพื้นจะเป็นสีอะไร */
.mtile.hero.half .mt-ic { background: rgba(0,0,0,.22); color: #fff; }
.mtile.hero.half .mt-sub { color: rgba(255,255,255,.78); }
.mtile.hero.half .mt-go { top: 12px; right: 12px; bottom: auto; color: var(--on-fill); opacity: .8; }

.mtile.hero {
  grid-column: span 2;
  min-height: 78px;
  background: var(--grad-hero);
  border: none;
  color: #fff;
  box-shadow: var(--shadow-brand);
  font-size: 17px;
}
.mtile.hero .mt-ic { background: rgba(255,255,255,.18); color: #fff; }
.mtile.hero::after { background: radial-gradient(circle, rgba(255,255,255,.22), transparent 70%); }
/* ไทล์แนวนอน: ต้องสั่ง flex-start ด้วย ไม่งั้นค่า flex-end ที่ตั้งไว้ให้แนวตั้ง
   (แปลว่า "ชิดล่าง") จะกลายเป็น "ชิดขวา" แล้วหลุดแนวจากไทล์อื่นทั้งกริด */
.mtile.wide {
  grid-column: span 2;
  min-height: 66px;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 13px;
}
.mtile.wide .mt-ic { width: 38px; height: 38px; }

/* ---------- ลูกศร "กดแล้วไปต่อ" ----------
   จาง ๆ พอ ไม่ใช่ของที่ต้องอ่าน แค่ต้องเห็นตอนกวาดตาว่าไทล์นี้พาไปที่อื่นได้ */
.mt-go {
  position: absolute;
  right: 12px; bottom: 11px;
  display: flex;
  color: var(--mt-a);
  opacity: .5;
  pointer-events: none;
  z-index: 2;
}
.mt-go svg { width: 15px; height: 15px; }
/* ไทล์แนวนอน: ลูกศรไปอยู่กลางแนวตั้งสุดขวา แล้วดันป้ายตัวเลขเข้ามาให้พ้นกัน */
.mtile.wide .mt-go { top: 50%; bottom: auto; transform: translateY(-50%); right: 13px; }
.mtile.wide .mt-ct { top: 50%; right: 36px; transform: translateY(-50%); }
/* ไทล์เด่นพื้นสีเข้ม ลูกศรต้องเป็นสีขาวถึงจะเห็น */
.mtile.hero .mt-go {
  top: 50%; bottom: auto; transform: translateY(-50%); right: 14px;
  color: #fff; opacity: .75;
}
.mtile.hero .mt-go svg { width: 17px; height: 17px; }
/* ไทล์เล็ก 4 ใบ: กันที่มุมล่างขวาไว้ให้ลูกศร ไม่งั้นคำอธิบายยาว ๆ วิ่งไปทับ */
.mtile:not(.hero):not(.wide) .mt-tx { padding-right: 18px; }

/* จอกว้าง (แถบซ้าย) วางได้ 3 คอลัมน์สบาย ๆ */
:root[data-nav="side"] .menu-grid { grid-template-columns: repeat(3, 1fr); }
:root[data-nav="side"] .mtile.hero { grid-column: span 3; }
:root[data-nav="side"] .mtile.wide { grid-column: span 3; }

/* ============================================================
   วิดเจ็ตบนหน้าแรก (1A6M2) — เลือกได้ 4 แบบในแท็บ "ฉัน"
   ============================================================ */
.wg {
  position: relative;
  border-radius: calc(var(--r-card) + 2px);
  padding: 14px 15px 13px;
  box-shadow: var(--shadow);
  overflow: hidden;
  min-height: 104px;
  display: flex;
  flex-direction: column;
}
.wg-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  opacity: .85;
}
.wg-head svg { width: 14px; height: 14px; }
.wg-pill {
  margin-left: auto;
  padding: 3px 9px 4px;
  border-radius: 999px;
  background: rgba(255,255,255,.18);
  font-size: var(--fs-meta);
  letter-spacing: 0;
  text-transform: none;
}
.wg-title {
  margin-top: 6px;
  font-size: var(--fs-title);
  font-weight: 700;
  line-height: 1.32;
  letter-spacing: -.028em;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* บีบให้จบบรรทัดเดียว — หน้าแรกต้องไม่ยาวจนต้องเลื่อน */
.wg-meta {
  margin-top: 4px;
  font-size: 11.5px;
  line-height: 1.5;
  opacity: .82;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wg-cta {
  margin-top: auto;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* 44px คือขนาดนิ้วขั้นต่ำที่ทั้ง iOS และ Android กำหนด — เดิม 34px ทำให้กดพลาดบนมือถือจริง */
  min-height: 44px;
  padding: 0 16px;
  border: none;
  border-radius: 999px;
  background: rgba(255,255,255,.95);
  color: #10233A;
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 700;
  cursor: pointer;
}
.wg-cta svg { width: 14px; height: 14px; }
.wg-cta:active { transform: scale(.97); }

/* 1) งานด่วนที่สุด
   เดิมทั้งใบเป็นพื้นแดง/เหลืองไล่เฉดตามระดับความด่วน — ก้อนที่ใหญ่ที่สุดบนหน้าแรก
   จึงกลายเป็นสีเตือน ซึ่งกลับหัวกฎ 60/30/10 (สีเตือนควรเป็นของน้อยที่สุดบนจอ)
   ตอนนี้ตัววิดเจ็ตเป็นการ์ดสีเดียวกับไทล์อื่น แล้วย้ายความด่วนไปไว้ที่ชิปใบเล็ก
   ข้อดีอีกอย่าง: ผู้ใช้สลับวิดเจ็ตได้ 4 แบบ ทุกแบบจึงมีน้ำหนักบนจอเท่ากันแล้ว
   ไม่ใช่ว่าเลือก "ควรทำก่อน" ทีหน้าแรกเปลี่ยนสีทั้งหน้า */
.wg-urgent { background: var(--card); color: var(--ink); border: 1px solid var(--line); }
.wg-urgent.red, .wg-urgent.yellow, .wg-urgent.clear { background: var(--card); }
.wg-urgent .wg-head { color: var(--muted); }
.wg-urgent .wg-pill { background: var(--card2); color: var(--muted); }
.wg-urgent .wg-cta { margin-top: 10px; background: var(--fill); color: var(--on-fill); }
/* หัวข้อวิดเจ็ต: ไอคอนอยู่ในชิปทึบชุดเดียวกับไทล์ ไม่ใช่ไอคอนเปล่า ๆ ลอย ๆ */
.wg-urgent .wg-head > svg:first-child {
  box-sizing: content-box;
  width: 13px; height: 13px;
  padding: 5px;
  border-radius: 7px;
  background: var(--fill);
  color: var(--on-fill);
}

/* ---------- ชิปบอกสถานะใต้ชื่องาน ----------
   ของเดิมเป็นข้อความยาวบรรทัดเดียวคั่นด้วยจุด: กำหนดส่ง เวลาที่ใช้ คะแนน และเหตุผล
   ต่อกันหมด ตัวหนังสือขนาดเท่ากันทุกคำ เลยไม่มีทางรู้ว่าคำไหนคือคำที่ต้องอ่านก่อน
   (แถมยาวเกินจนโดนตัดกลางคัน) แยกเป็นก้อน ๆ แล้วให้สีเฉพาะก้อนที่เป็นข่าวร้ายจริง */
.wg-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.wg-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  border-radius: 999px;
  background: var(--card2);
  color: var(--muted);
  font-size: var(--fs-meta);
  font-weight: 600;
  letter-spacing: 0;
  white-space: nowrap;
}
.wg-chip svg { width: 13px; height: 13px; }
.wg-chip.late { background: var(--pri-red-soft); color: var(--pri-red-text); }
.wg-chip.soon { background: var(--pri-yellow-soft); color: var(--pri-yellow-text); }

/* ---------- ลิสต์งานในการ์ด "ควรทำก่อน" ----------
   เดิมการ์ดนี้โชว์งานใบเดียว และทำอะไรกับมันจากหน้าแรกไม่ได้เลยนอกจากกดเข้าไปอีกจอ
   ตอนนี้เป็นลิสต์ 3 ใบที่ติ๊กเสร็จได้ในที่ — และทั้งสามใบเป็นการ์ดของตัวเองขนาดเท่ากัน
   ความด่วนบอกด้วยสีของกำหนดส่งอย่างเดียว ไม่ใช่ด้วยขนาดของก้อน
   ระยะห่าง 12px · มุมโค้ง 12px ตามไฟล์ดีไซน์ */
.wg-list { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.wg-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--card2);
  cursor: pointer;
  transition: transform .14s ease, border-color .14s ease;
}
.wg-item:active { transform: scale(.985); }
/* แถบสีวิชา — ใช้ --sj จากคลาส sj-* ชุดเดียวกับที่หน้ารายการงานใช้อยู่
   งานคณิตสองใบจึงเป็นสีเดียวกันเสมอ แยกจากวิชาอื่นได้โดยไม่ต้องอ่านชื่อ */
.wg-item-bar { flex: none; width: 3px; align-self: stretch; border-radius: 2px; background: var(--sj, var(--muted)); }
.wg-item-tx { flex: 1; min-width: 0; }
/* ชื่องานได้สองบรรทัด — เดิมล็อกไว้บรรทัดเดียว "คณิตศาสตร์ · 2 ข้อ ส่ง…" จึงตัด
   ส่วนที่บอกว่าเป็นงานอะไรทิ้งไปหมด งานคนละใบเลยเหลือข้อความเหมือนกันเป๊ะ */
.wg-item-ttl {
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: 1.4;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* กำหนดส่งคือตัวเดียวในแถวที่มีสี — เวลาที่ใช้ต่อท้ายด้วยสีกลาง
   เดิม "~30 นาที" นั่งคอลัมน์ขวาถาวร บีบความกว้างของชื่องานทั้งที่สำคัญน้อยกว่า */
.wg-item-meta { margin-top: 3px; font-size: var(--fs-meta); font-weight: 600; color: var(--muted); }
.wg-item-due.hot  { color: var(--pri-red-text); }
.wg-item-due.warm { color: var(--pri-yellow-text); }
.wg-item-due.far  { color: var(--pri-green-text); }
.wg-item-go { flex: none; display: flex; margin-top: 3px; color: var(--muted); opacity: .55; }
.wg-item-go svg { width: 15px; height: 15px; }

/* ทางไปงานที่เหลือ — คนที่มีงานค้าง 28 ใบต้องรู้ว่าลิสต์นี้แสดงแค่ 3 ใบแรก
   ไม่งั้น "ควรทำก่อน" จะอ่านได้ว่า "มีอยู่แค่นี้" ซึ่งเป็นคำโกหกที่ทำให้วางแผนผิด */
.wg-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 100%;
  margin-top: 8px;
  min-height: 34px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: var(--fs-meta);
  font-weight: 600;
  cursor: pointer;
}
.wg-more svg { width: 14px; height: 14px; }
.wg-more:active { background: var(--card2); }

/* ป้ายความด่วนบนหัวการ์ด — แดงจริงเมื่อด่วนจริง ป้ายสีเทาทุกระดับก็ไม่ต้องมีก็ได้ */
.wg-pill.red    { background: var(--pri-red);    color: #fff; font-weight: 700; }
.wg-pill.yellow { background: var(--pri-yellow); color: #2A1D02; font-weight: 700; }

/* วงกลมติ๊ก — 28px แต่กรอบกดจริง 44px ตามขนาดนิ้วขั้นต่ำของ iOS/Android
   (ปุ่ม "เปิดงานนี้" เดิมสูง 34px ซึ่งต่ำกว่าเกณฑ์ ดู .wg-cta ข้างล่าง) */
.wg-tick {
  flex: none;
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* --line เป็นเส้นแบ่งจาง ๆ (ขาว 7%) ซึ่งจางเกินไปสำหรับของที่ต้อง "เห็นแล้วรู้ว่ากดได้"
     วงกลมนี้คือปุ่มหลักของทั้งลิสต์ มันต้องดูเหมือนปุ่มตั้งแต่ยังไม่ได้กด */
  border: 2px solid var(--muted);
  background: transparent;
  color: transparent;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  transition: background .16s, border-color .16s, color .16s, transform .12s;
}
.wg-tick::after {
  content: '';
  position: absolute;
  inset: -8px;
}
.wg-tick svg { width: 16px; height: 16px; }
.wg-tick:active { transform: scale(.9); }
.wg-tick.on {
  background: var(--fill);
  border-color: var(--fill);
  color: var(--on-fill);
}

/* 2) โน้ต */
.wg-note { background: var(--card); border: 1px solid var(--line); color: var(--ink); }
.wg-note .wg-head { color: var(--blue); opacity: 1; }
.wg-note-in {
  flex: 1;
  margin-top: 10px;
  width: 100%;
  border: none;
  background: transparent;
  resize: none;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
}
.wg-note-in:focus { outline: none; }

/* 3) เวลา */
.wg-clock {
  background: var(--grad-hero);
  color: #fff;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.wg-time { font-size: 46px; font-weight: 700; line-height: 1.05; letter-spacing: -.03em; }
.wg-date { margin-top: 4px; font-size: 12.5px; opacity: .8; }
.wg-next {
  margin-top: 12px;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(255,255,255,.16);
  font-size: 12px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 4) ภาพของฉัน */
/* 158px กินพื้นที่เกือบเท่างานหนึ่งใบครึ่ง บนจอที่ต้องใส่ลิสต์งาน + ทางเข้าอีกสามอัน
   ให้พอดีจอเดียว รูปยังเป็นแถบกว้างที่เห็นเนื้อภาพครบ แค่เตี้ยลง */
.wg-photo {
  background-size: cover;
  background-position: center;
  justify-content: flex-end;
  min-height: 120px;
  color: #fff;
}
.wg-photo .wg-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.05) 40%, rgba(0,0,0,.6) 100%);
}
.wg-photo-tx {
  position: relative;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.02em;
  text-shadow: 0 2px 10px rgba(0,0,0,.5);
}
.wg-photo.empty {
  background: var(--card2);
  border: 1.5px dashed var(--line);
  align-items: center;
  justify-content: center;
  box-shadow: none;
}
.wg-pick {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.wg-pick svg { width: 17px; height: 17px; }

.wg-grid button { flex-direction: column; gap: 3px; font-size: 11px; }
.wg-grid button svg { width: 17px; height: 17px; }
.wg-extra { margin-top: 2px; }
.wg-extra textarea {
  width: 100%;
  border: none;
  border-radius: 12px;
  background: var(--card2);
  padding: 11px 12px;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink);
  resize: vertical;
}
.wg-extra textarea:focus { outline: 2px solid var(--blue); outline-offset: -2px; }

/* ============================================================
   หน้าเพื่อน (1A6M2)
   ============================================================ */
.fr-body { gap: 16px; padding-top: 22px; }
/* ---------- แถบค้นหา ----------
   ทรงมาตรฐาน: แคปซูลมีแว่นขยายอยู่ข้างใน ไม่มีป้ายกำกับลอยข้างบน
   ป้ายกำกับมีไว้สำหรับฟอร์มหลายช่อง ไม่ใช่ช่องเดียวบนสุดของจอ */
.fr-search {
  display: flex; align-items: center; gap: 10px;
  background: var(--card2); border-radius: 999px; padding: 0 14px;
  min-height: 46px;
}
.fr-search > svg { width: 18px; height: 18px; flex: none; color: var(--faint); }
.fr-search input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  font-family: inherit; font-size: 15px; color: var(--ink);
}
.fr-search input::placeholder { color: var(--faint); }
.fr-search:focus-within { outline: 2px solid var(--blue); outline-offset: -2px; }
.fr-clear {
  flex: none; width: 24px; height: 24px; border: none; border-radius: 50%;
  background: var(--line); color: var(--ink); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.fr-clear svg { width: 13px; height: 13px; }
.fr-clear[hidden] { display: none; }

/* ---------- หัวข้อกลุ่ม ---------- */
.fr-sec {
  display: flex; align-items: center; gap: 7px;
  margin: 4px 2px 9px; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
}
.fr-sec i { font-style: normal; opacity: .75; }
/* ถัง "เลยกำหนด" ต้องอ่านต่างจากถังอื่นตั้งแต่ยังไม่ทันอ่านคำ — มันคือถังเดียว
   ในจอที่แปลว่า "สายแล้ว" ส่วนที่เหลือแปลว่า "ยังทัน" */
.fr-sec.hot { color: var(--alert); }

/* ช่องค้นหางาน — ทรงเดียวกับช่องค้นหาเพื่อนเป๊ะ ต่างแค่ระยะห่างรอบตัว
   เพราะจอนี้มีหัวจอเต็มรูปแบบอยู่ข้างบน ส่วนจอเพื่อนไม่มี */
.tk-search { margin: 14px 0 4px; }

/* 1B93 · สวิตช์สองโหมดบนหัวจองาน (สัปดาห์ / รายการ)

   แถวเดียวสูง ~34px รวมระยะห่าง — นี่คือเพดานที่ตั้งไว้เอง เพราะเหตุผลที่สวิตช์
   สามช่องเดิมถูกถอดออกตอน 1B47 คือมันกินจอเกือบครึ่งก่อนเห็นงานใบแรก
   สองช่องกว้างเท่ากันแบบ 1fr 1fr ไม่ใช่ auto — ป้ายยาวไม่เท่ากัน ("สัปดาห์" 7 ตัว
   "รายการ" 7 ตัว) แต่ช่องต้องเท่ากัน ไม่งั้นตัวที่ถูกเลือกจะขยับความกว้างตอนสลับ */
/* 1B94 · จำนวนช่องไม่ถูกล็อกไว้ที่สองอีกแล้ว
   ของเดิมเขียน grid-template-columns: 1fr 1fr ตายตัว พอเพิ่มโหมด "วันนี้" เข้ามา
   ช่องที่สามตกไปบรรทัดสอง กลายเป็นแถบสองชั้นที่ช่องล่างกว้างครึ่งเดียว
   (เห็นบนจอจริงเท่านั้น — DOM ยังบอกว่ามีปุ่มครบสามปุ่ม จึงไม่มีเทสไหนจับได้)
   grid-auto-flow: column ปล่อยให้จำนวนช่องเป็นไปตามจำนวนปุ่มที่วาดจริง */
.tk-modes {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px;
  margin: 10px 0 2px; padding: 3px;
  background: var(--surface); border-radius: 12px;
}
.tk-mode {
  padding: 7px 10px; border: none; border-radius: 9px; cursor: pointer;
  background: transparent; color: var(--faint);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  transition: background .14s ease, color .14s ease;
}
/* 1B95 · ตัวที่เลือกอยู่เป็นน้ำเงินทึบ ไม่ใช่การ์ดขาวบนพื้นเทา
   เจ้าของสั่งเอง: "อยากให้ selected state เป็นสีฟ้า เพราะจะช่วยให้เห็น active state ชัดขึ้น"
   ของเดิมขาวบนพื้นเทาอ่อน ต่างกันแค่เงาบาง ๆ — กลางแดดแยกไม่ออกว่าอยู่โหมดไหน

   เส้นแบ่งที่ห้ามข้าม: ฟ้าบนจอนี้มีสามจุดเท่านั้น — ปุ่มโหมดที่เลือก · การ์ดควรทำก่อน ·
   เส้นหน้าชื่องาน · พื้นหลังยังขาว-ฟ้าจางเหมือนเดิมทั้งหน้า และตัวเลขสรุปเป็นสีหมึกธรรมดา
   ฟ้าแปลว่า "กดได้ / สำคัญ" ไม่ใช่สีตกแต่ง (คำสั่งเดิม: "อย่าใช้ฟ้าทั้งหน้าจอ")

   ไม่ใส่เงาสีให้ปุ่ม — ปุ่มกว้าง ~100px สูง 30px เงาฟุ้งใต้ของเล็กขนาดนี้อ่านเป็นรอยเปื้อน
   ไม่ใช่ความสูง · พื้นทึบกับพื้นโปร่งต่างกันมากพออยู่แล้ว */
.tk-mode.on { background: var(--fill); color: var(--on-fill); }

/* 1B93 · เส้นคั่นก่อนของที่ยังไม่เสร็จ (ร้านค้า · Pro) ในลิสต์แท็บ "ฉัน"

   แทนหัวข้อกลุ่ม "เร็ว ๆ นี้" ที่ถูกยุบทิ้ง — ได้ขอบเขตเดิมกลับมาในราคา 1px
   แทน 31px · เส้นเข้มกว่าเส้นคั่นระหว่างแถวปกติเล็กน้อยและมีระยะห่างรอบตัว
   ไม่งั้นมันอ่านเหมือนเส้นคั่นแถวธรรมดาแล้วไม่ได้แบ่งอะไรเลย */
.pe-split {
  height: 1px; margin: 9px 14px; background: var(--line);
  opacity: .9;
}

/* หัวข้อกลุ่มในแท็บ "ฉัน" — ทรงเดียวกับ .fr-sec แต่ต้องมีระยะบนของตัวเอง
   เพราะมันคั่นระหว่างกล่องรายการ ไม่ได้อยู่ในกล่องเหมือนจอเพื่อน
   1B93 · ไม่มีที่ไหนใช้แล้วหลังยุบสี่กลุ่มเหลือก้อนเดียว — เก็บไว้เพราะ .fr-sec
   ฝั่งจอเพื่อนยังใช้ทรงเดียวกัน และคลาสนี้เป็นตัวอ้างอิงของทรงนั้น */
.pf-sec {
  margin: 22px 4px 9px; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
}
.pf-sec:first-of-type { margin-top: 4px; }
/* หัวข้อจัดระยะบนให้แล้ว กล่องที่ตามมาจึงไม่ต้องเว้นซ้ำอีกชั้น */
.pf-sec + .pf-entry { margin-top: 0; }



/* ---------- แถวชื่อผู้ใช้ของฉัน — ล่างสุด ----------
   ของที่ตั้งครั้งเดียวแล้วแทบไม่กลับมาแก้ ไม่ควรกินพื้นที่บนสุดของจอที่เปิดทุกวัน */
.fr-me2 {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-radius: var(--r-card);
  background: var(--card2); font-size: 14px;
}
.fr-me2-lb { color: var(--faint); font-size: 12.5px; }
.fr-me2 b { font-weight: 700; letter-spacing: -.01em; }
.fr-me2 .fr-ic { margin-left: auto; }
.fr-me2 .fr-ic + .fr-ic { margin-left: 0; }
.fr-ic {
  flex: none; width: 32px; height: 32px; border: none; border-radius: 50%;
  background: transparent; color: var(--muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.fr-ic svg { width: 16px; height: 16px; }
.fr-ic:active { background: var(--line); }
.fr-me2.edit { gap: 6px; }
.fr-me2 .fr-at { font-size: 15px; font-weight: 700; color: var(--faint); }
.fr-me2 input {
  flex: 1; min-width: 0; border: none; border-radius: 9px;
  background: var(--card); padding: 9px 11px;
  font-family: inherit; font-size: 15px; font-weight: 600; color: var(--ink);
}
.fr-me2 input:focus { outline: 2px solid var(--blue); outline-offset: -2px; }
.fr-fine { margin: 7px 4px 0; font-size: 11.5px; color: var(--faint); }

/* ---------- จอว่าง ----------
   ไอคอน + ประโยคเดียว + ปุ่มหนึ่งปุ่ม · ย่อหน้าสีเทาคือจอที่ไม่มีใครอ่านจบ
   คนที่มาถึงจอว่างคือคนที่ยังไม่รู้ว่าต้องทำอะไรต่อ จึงต้องมีของให้กด */
.fr-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 8px; padding: 34px 22px;
}
.fr-empty > svg { width: 30px; height: 30px; color: var(--faint); opacity: .7; }
.fr-empty b { font-size: 15.5px; font-weight: 700; }
.fr-empty p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--muted); max-width: 28ch; }
.fr-empty-go {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 6px; min-height: 40px; padding: 0 18px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink);
  font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
}
.fr-empty-go svg { width: 15px; height: 15px; }
.fr-empty-go:active { transform: scale(.97); }

.fr-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow); padding: 13px 14px; margin-bottom: 9px;
}
.fr-av {
  width: 40px; height: 40px; flex: none; border-radius: 50%;
  background: var(--grad-brand); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; font-weight: 700;
}
.fr-bd { flex: 1; min-width: 0; }
.fr-nm { display: flex; align-items: center; gap: 7px; font-size: 15px; font-weight: 600; letter-spacing: -.015em; }
.fr-tag { padding: 2px 7px; border-radius: 999px; background: var(--blue); color: var(--on-accent);
  font-size: 9.5px; font-weight: 700; }
.fr-st { margin-top: 3px; font-size: 12px; color: var(--muted); }
.fr-st b { color: var(--ink); }
.fr-del {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  border: none; background: transparent; color: var(--faint); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.fr-del svg { width: 15px; height: 15px; }
.fr-del:active { color: var(--alert); }
.fr-note { margin: 4px 2px 0; font-size: 12px; line-height: 1.7; color: var(--faint); }
/* ประตูล็อกอินของแท็บ "เพื่อนฉัน" — แทนที่ทั้งจอ ไม่ใช่แถบเตือนเหนือช่องที่กรอกไม่ได้
   ช่องที่กรอกได้แต่บันทึกไม่ได้ แย่กว่าไม่มีช่องเลย */
.fr-gate {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 10px; padding: 30px 22px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
}
.fr-gate svg { width: 26px; height: 26px; color: var(--blue); }
.fr-gate b { font-size: 16px; font-weight: 700; }
.fr-gate p { margin: 0; font-size: 13px; line-height: 1.7; color: var(--muted); max-width: 30ch; }
.fr-gate-go {
  margin-top: 4px; min-height: 44px; padding: 0 26px; border: none; border-radius: 999px;
  background: var(--blue); color: var(--on-accent);
  font-family: inherit; font-size: 14.5px; font-weight: 700; cursor: pointer;
  box-shadow: var(--shadow-brand);
}
.fr-gate-go:active { transform: scale(.97); }
.fr-card.req { border-color: var(--blue); background: var(--blue-soft); }
.fr-av img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.fr-nm { flex-wrap: wrap; }
.fr-hd { margin-top: 2px; font-size: 12px; color: var(--faint); }
/* ป้ายสถานะในผลค้นหาต้องไม่หน้าตาเหมือนปุ่ม — พื้นน้ำเงินข้างปุ่ม "เพิ่ม" สีเดียวกัน
   คือการสอนให้คนกด "เพื่อนแล้ว" แล้วงงว่าทำไมไม่มีอะไรเกิดขึ้น */
#frHits .fr-tag { background: transparent; border: 1px solid var(--line); color: var(--faint);
  min-height: 30px; display: inline-flex; align-items: center; padding: 0 11px; }
.fr-tag.wait { background: var(--card2); color: var(--muted); }
.fr-go {
  flex: none; min-height: 36px; padding: 0 15px; border: none; border-radius: 999px;
  background: var(--blue); color: var(--on-accent);
  font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
}
.fr-go:active { transform: scale(.97); }
/* ปุ่มปฏิเสธต้องอ่านออกว่าเป็นคนละน้ำหนักกับปุ่มรับ — สองปุ่มหน้าตาเท่ากันคือกดผิดตัว */
/* ปฏิเสธเป็น ✕ เล็ก ไม่ใช่ปุ่มขนาดเท่า "รับ" — สองปุ่มน้ำหนักเท่ากันแปลว่าจอกำลัง
   บอกว่าสองทางนี้มีค่าเท่ากัน ซึ่งไม่จริง คนกดเข้ามาที่นี่มาเพื่อกดรับ */
.fr-x {
  flex: none; width: 32px; height: 32px; border: none; border-radius: 50%;
  background: transparent; color: var(--faint); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.fr-x svg { width: 15px; height: 15px; }
.fr-x:active { background: var(--line); color: var(--alert); }
.pf-go { flex: none; color: var(--faint); display: flex; }
.pf-go svg { width: 16px; height: 16px; }

/* ============================================================
   ป้ายเตือนบนแถบเมนู
   ============================================================ */
.tab .ic-wrap { position: relative; display: block; }
.tab-badge {
  position: absolute;
  top: -5px;
  right: -8px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--pri-red);
  color: #fff;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--glass);
  animation: badge-pop .28s cubic-bezier(.2,.9,.3,1.5);
}
.tab-badge[hidden] { display: none; }
@keyframes badge-pop { from { transform: scale(.4); } to { transform: none; } }

/* จุดแดงไม่มีตัวเลข — ใช้กับของที่มีได้แค่ชิ้นเดียว (ของรางวัลรายวันบนแท็บ "ฉัน")
   ตัวเลข "1" บนป้ายแบบนั้นไม่ได้บอกอะไรเพิ่มจากการที่ป้ายมันโผล่ขึ้นมาเฉย ๆ */
.tab-dot {
  position: absolute;
  top: -3px;
  right: -5px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--pri-red);
  box-shadow: 0 0 0 2px var(--glass);
  animation: badge-pop .28s cubic-bezier(.2,.9,.3,1.5);
}
.tab-dot[hidden] { display: none; }

/* ============================================================
   ผลของฉัน (แท็บ "ฉัน")
   ============================================================ */
/* การ์ดสรุปผลเป็นทอง — มันคือ "สิ่งที่ทำสำเร็จไปแล้ว" ซึ่งเป็นความหมายเดียวกับ
   ไทล์ทองกับเหรียญในจอวิเคราะห์ · ของที่หมายความเหมือนกันต้องหน้าตาเหมือนกัน
   ไม่ใช้ --grad-hero เพราะธีมมืดแบนมันเป็นสีเดียว การ์ดนี้เลยกลายเป็นการ์ดธรรมดา
   ทองเป็นความหมาย ไม่ใช่รสนิยม จึงคงที่ทุกธีมเหมือน --pri-* */
.st-hero {
  display: flex;
  align-items: stretch;
  background: var(--grad-gold);
  color: var(--on-gold);
  border-radius: var(--r-card);
  padding: 14px 10px;
  box-shadow: var(--shadow-gold);
}
.st-hero > div { flex: 1; text-align: center; }
.st-hero .sep { flex: none; width: 1px; background: rgba(92,65,4,.22); }
.st-hero .v { font-family: 'Space Mono', ui-monospace, monospace; font-size: 23px; font-weight: 700; }
.st-hero .v .u { font-size: 12px; margin-left: 2px; opacity: .8; }
.st-hero .k { margin-top: 3px; font-size: 11px; opacity: .78; font-weight: 600; }

.st-card {
  margin-top: 8px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: 13px 13px 12px;
}
.st-card.soft { box-shadow: none; background: var(--card2); border: none; }
/* 1C08 · บั๊กเดียวกับ .sec-label ใน 1C07 — letter-spacing .07em คู่กับ uppercase
   เป็นสูตรของหัวข้ออังกฤษตัวใหญ่ พอใช้กับ "งานที่ติ๊กเสร็จ 7 วันล่าสุด" ที่ 11px
   สระกับวรรณยุกต์หลุดจากพยัญชนะ · uppercase ไม่มีผลกับไทยอยู่แล้วแต่ยังคงไว้
   เพราะบางที่ใช้คลาสนี้กับข้อความอังกฤษ */
.st-h {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}
/* block ไม่ใช่ flex — ประโยคมี <b> ตัวเลขอยู่กลางประโยค flex หั่นข้อความเป็นสามคอลัมน์
   (เลขลอยอยู่กลาง ข้อความสองฝั่งตัดบรรทัดแยกกัน) ทันทีที่ประโยคยาวเกินหนึ่งบรรทัด */
.st-line { display: block; font-size: 13.5px; line-height: 1.5; color: var(--ink); }
.st-line svg { width: 15px; height: 15px; color: var(--muted); vertical-align: -2px; margin-right: 7px; }
.st-line b { color: var(--blue); }
.st-track {
  margin-top: 10px;
  height: 7px;
  border-radius: 999px;
  background: var(--card2);
  overflow: hidden;
}
.st-track i { display: block; height: 100%; border-radius: 999px; background: var(--grad-brand); }

.st-bars { display: flex; align-items: flex-end; gap: 7px; height: 88px; }
.st-bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  gap: 4px;
}
.st-bar .bar {
  width: 100%;
  min-height: 4px;
  border-radius: 7px 7px 3px 3px;
  background: var(--card2);
}
.st-bar.now .bar { background: var(--grad-brand); }
.st-bar .n { font-size: 10px; color: var(--muted); min-height: 12px; }
.st-bar .d { font-size: 10.5px; color: var(--faint); }
.st-bar.now .d { color: var(--blue); font-weight: 700; }

.st-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
  font-size: 13.5px;
}
.st-row:first-of-type { border-top: none; }
.st-row .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-row .ct { flex: none; font-size: 12px; color: var(--muted); }

/* ============================================================
   ปุ่มเพิ่มงานตรงกลางแถบล่าง — ใหญ่ขึ้นและยกลอยเหนือแถบ (1A6M)
   ของเดิมสูงเท่าไอคอนอื่นเป๊ะเพื่อไม่ให้แถบสูงขึ้น แต่พอเป็นปุ่มที่ใช้บ่อยที่สุด
   มันเด่นไม่พอ — ยกขึ้นด้วย margin ลบแทน แถบจึงยังสูงเท่าเดิม
   ============================================================ */
/* กุญแจสำคัญ: ปุ่มต้องกินพื้นที่ในผังเท่าไอคอนเดิม (22px) เป๊ะ ๆ
   56 − 34 = 22 → แถบล่างสูงเท่าเดิม และฐานตัวอักษรทุกปุ่มยังตรงแนวกัน
   ส่วนที่เกินขึ้นไปเป็นการล้นออกนอกผัง ไม่ดันอะไรทั้งนั้น */
.tab.scan .scan-dot {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  margin-top: -34px;
  box-shadow: var(--glow-scan), 0 10px 24px -8px rgba(0, 0, 0, .45);
  outline: 4px solid var(--scr);   /* วงแหวนสีพื้นจอ ตัดปุ่มออกจากแถบให้เห็นเป็นก้อนลอย */
  transition: transform .16s cubic-bezier(.2, .9, .3, 1.3);
}
.tab.scan .scan-dot svg { width: 26px; height: 26px; stroke-width: 2.1; }
.tab.scan:active .scan-dot { transform: scale(.9); }
.tab.scan.active .scan-dot { transform: translateY(-2px); }
.tab.scan.active { background: none; }   /* ปุ่มมีพื้นของตัวเองอยู่แล้ว ไม่ต้องมีกล่องซ้อน */

/* ============================================================
   แถบเมนูด้านซ้าย — โหมดจอกว้าง (iPad / แท็บเล็ต / PC)
   จอกว้างแล้ววางแถบไว้ล่างสุดคือเสียพื้นที่แนวตั้งฟรี ๆ
   ย้ายเป็นแถบตั้งด้านซ้าย เนื้อหาได้ความสูงคืนเต็ม ๆ
   ============================================================ */
/* เมนูซ้าย = เต็มหน้าต่างเสมอ ไม่ต้องมีกรอบเครื่องจำลอง
   เดิมเต็มจอเฉพาะหน้าต่างกว้างไม่เกิน 1120px (แท็บเล็ต/ไอแพด) · กว้างกว่านั้น (แล็ปท็อป · จอคอม) กลับไปเป็นกรอบเครื่องจำลอง
   ของ style.css: กว้างแค่ 928px (ติดเพดาน .stage 960px) ขอบหนามุมมน · แถบสถานะปลอม (นาฬิกา · สัญญาณ · แบต)
   · ข้อความใต้กรอบล้นจนทั้งหน้าเว็บเลื่อนได้และโดนตัดครึ่ง (1280×800: เลื่อนได้ 78px)
   17 ต.ค. 69 · เจ้าของ: "ตอนที่ปุ่มอยู่ฝั่งซ้าย … หน้าไม่เต็มจอ" → ใช้กฎชุดเดียวกับแท็บเล็ตทุกขนาด
   เนื้อหายังเป็นคอลัมน์กว้างสุด 720px อยู่กลาง (กฎข้างล่าง) จอใหญ่จึงได้พื้นหลังเต็มจอ ไม่ใช่บรรทัดยาวเกินอ่าน */
:root[data-nav="side"] .stage { padding: 0; gap: 0; max-width: none; }
:root[data-nav="side"] .stage-note { display: none; }
:root[data-nav="side"] .phone {
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-width: none;
  border-radius: 0;
  border: none;
  box-shadow: none;
}
:root[data-nav="side"] .statusbar { display: none; }
:root[data-nav="side"] .tabbar { top: calc(14px + env(safe-area-inset-top)); }
:root[data-nav="side"] .tabbar {
  top: 14px;
  bottom: 14px;
  left: 14px;
  right: auto;
  width: 92px;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 12px 8px;
  border-radius: 26px;
}
:root[data-nav="side"] .tab {
  flex: none;
  width: 100%;
  min-height: 60px;
  border-radius: 18px;
}
/* ในแถบตั้ง ปุ่มเพิ่มงานไม่ต้องยกลอยแล้ว — วางเต็มก้อนกลางแถบได้เลย */
:root[data-nav="side"] .tab.scan .scan-dot {
  margin: 0 0 3px;
  outline: none;
  width: 50px;
  height: 50px;
}
:root[data-nav="side"] .tab.scan { min-height: 78px; }
/* เนื้อหาเลื่อนมาพ้นแถบ และไม่ต้องเผื่อที่ว่างด้านล่างให้แถบอีก */
:root[data-nav="side"] .screens { margin-left: 106px; }
:root[data-nav="side"] .statusbar { padding-left: 120px; }
:root[data-nav="side"] .screen { padding-bottom: 28px; }
/* หัวจอย่อยอยู่ในคอลัมน์ flex + margin auto (กฎคุมความกว้างข้างล่าง) จึงหดเหลือเท่าปุ่มแล้วไปกลางจอ
   ปุ่มกลับของจอสุ่มสกิน/ร้านค้า ฯลฯ เลยลอยอยู่กลางบน — เจ้าของ: "ปุ่มออกอยู่ฝั่งซ้าย"
   เต็มความกว้างของคอลัมน์ ปุ่มกลับกลับไปชิดซ้ายเหมือนบนมือถือ */
:root[data-nav="side"] .sticky-head { width: 100%; }
:root[data-nav="side"] .home-body,
:root[data-nav="side"] .scr-body {
  padding-bottom: 28px;
}
/* จอกว้างแล้วบรรทัดยาวเกินอ่านยาก — คุมความกว้างคอลัมน์ไว้ */
:root[data-nav="side"] .home-body,
:root[data-nav="side"] .scr-body,
:root[data-nav="side"] .sticky-head,
:root[data-nav="side"] #taskList,
:root[data-nav="side"] #timeline {
  max-width: 720px;
  margin-inline: auto;
}
/* toast กับแผ่นแนะนำติดตั้ง ต้องไม่ไปทับแถบซ้าย */
:root[data-nav="side"] .toast { left: 120px; }
:root[data-nav="side"] .particle { z-index: 40; }

.nav-grid { grid-template-columns: repeat(3, 1fr); }
.nav-grid button { min-height: 44px; font-size: 12.5px; }

/* ---------- OCR: คำแนะนำตอนถ่าย + ป้ายเตือนตอนอ่านได้ไม่ชัด ---------- */
.scan-tip {
  margin: 10px 2px 0;
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--faint);
}
/* ป้ายผลการอ่าน: เปลี่ยนเป็นโทนเตือนเมื่อ OCR ความมั่นใจต่ำ */
.fm-ok.shaky {
  background: var(--warn-soft);
  color: var(--warn);
}

/* ช่องที่ค่ามาจากคำที่ OCR ไม่มั่นใจ — ตีกรอบไว้ให้สายตาไปหยุดตรงนั้นก่อน */
.fld.unsure > label::after,
.fld.unsure .fld-head label::after {
  content: ' · ไม่ค่อยชัด';
  color: var(--warn);
  font-weight: 700;
}
.fld.unsure input[type=text],
.fld.unsure textarea,
.fld.unsure select {
  box-shadow: inset 0 0 0 1.5px var(--warn);
  background: var(--warn-soft);
}
/* 1C15 · โครงใหม่ของจอเพิ่มงาน: ช่องที่ OCR ไม่มั่นใจอาจเป็นบล็อกวิชา
   (ไม่มี input ให้ตีกรอบ) หรือแถวสรุปที่พับไว้ — ต้องมีที่เกาะป้ายทั้งสามแบบ
   ช่องวันที่เป็น input[type=date] ซึ่งกฎเดิมไม่ครอบถึง */
.fld.unsure input[type=date],
.fld.unsure input[type=number] {
  box-shadow: inset 0 0 0 1.5px var(--warn);
  background: var(--warn-soft);
}
.fld.unsure::before {
  content: 'อ่านได้ไม่ชัด — ตรวจอีกทีหน่อย';
  font-size: 11.5px; font-weight: 700; color: var(--warn);
}
.fm-sec.unsure { box-shadow: var(--shadow), inset 0 0 0 1.5px var(--warn); }
.fm-sec.unsure .fs-h::after,
.fm-row.unsure > summary .rw-l::after {
  content: ' · ไม่ค่อยชัด';
  color: var(--warn); font-weight: 700; font-size: 11.5px;
}

/* ---------- หน้าครอบกรอบก่อนอ่าน ---------- */
.crop-body { gap: 16px; padding-top: 22px; }
.crop-p { margin: 8px 0 0; font-size: 13px; line-height: 1.6; color: var(--muted); }
.crop-stage {
  position: relative;
  width: 100%;
  max-height: 400px;
  border-radius: var(--r-card);
  overflow: hidden;
  background: #000;
  touch-action: none;      /* ลากกรอบได้โดยจอไม่เลื่อนตาม */
  user-select: none;
  cursor: crosshair;
}
.crop-stage img { width: 100%; height: 100%; display: block; object-fit: contain; }
.crop-shade {
  position: absolute; inset: 0;
  background: rgba(4, 8, 20, .62);
  pointer-events: none;
}
.crop-box {
  position: absolute;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .5), 0 6px 22px rgba(0, 0, 0, .45);
  pointer-events: none;
}
.crop-box .h {
  position: absolute;
  width: 16px; height: 16px;
  border: 3px solid #fff;
  border-radius: 3px;
  background: rgba(0, 0, 0, .35);
}
/* มุมซ้ายบนใช้คลาส .tl ชนกับ .tl ของเส้นเวลา (margin-top 18px · padding-left 26px · เส้นแกนตั้ง ::before)
   มุมนี้เลยหลุดลงมาจากมุมกรอบและกว้างกว่าอีกสามมุม — ล้างของเส้นเวลาทิ้งให้ทั้งสี่มุมหน้าตาเดียวกัน */
.crop-box .h { margin: 0; padding: 0; }
.crop-box .h::before { content: none; }
.crop-box .tl { left: -9px; top: -9px; border-right: none; border-bottom: none; }
.crop-box .tr { right: -9px; top: -9px; border-left: none; border-bottom: none; }
.crop-box .bl { left: -9px; bottom: -9px; border-right: none; border-top: none; }
.crop-box .br { right: -9px; bottom: -9px; border-left: none; border-top: none; }
.crop-hint {
  margin: 0 2px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10.5px;
  line-height: 1.6;
  color: var(--faint);
}
.crop-act { display: flex; flex-direction: column; gap: 8px; }

/* ============================================================
   1A6M3 — ลำดับสายตา + ความอ่านง่าย
   ปรับ 3 อย่าง: ขนาดหัวข้อไล่ลำดับชัดขึ้น · ตัวอักษรรองไม่จางเกิน ·
   ตัวเลขทุกที่ใช้ฟอนต์ตัวเลขที่ความกว้างเท่ากัน อ่านเป็นข้อมูลไม่ใช่ข้อความ
   ============================================================ */
/* ฟอนต์เนื้อความ = Sarabun (ภาษาไทยแบบ "มีหัว") — หัวตัวอักษรช่วยให้สายตาจับตัวอักษรได้เร็ว
   อ่านยาว ๆ สบายกว่าแบบไม่มีหัว · ตั้งที่ body + ช่องกรอก เพราะช่องกรอกไม่สืบทอดฟอนต์เอง */
body,
input, textarea, select, button {
  font-family: 'Sarabun', 'Leelawadee UI', sans-serif;
}
body { line-height: 1.7; letter-spacing: 0; }

/* style.css (ห้ามแก้) มีอีก 5 กฎที่ตั้งฟอนต์เป็น "Space Mono","IBM Plex Sans Thai"
   ตัวเลขได้ Space Mono ถูกแล้ว แต่ตัวไทยในกล่องพวกนี้จะตกไปเป็นแบบไม่มีหัว
   จึงต้องเปลี่ยนตัวสำรองเป็น Sarabun ให้ครบทุกอัน (ไล่จาก grep "font-family" ในไฟล์นั้น)
   ตัวเลขไม่กระทบ เพราะ Space Mono ยังอยู่หน้าสุดเหมือนเดิม */
.mono,
.rank,
.seg3 .ct,
.day-label .ct,
.tltime {
  font-family: 'Space Mono', 'Sarabun', ui-monospace, monospace;
}

/* หัวข้อ: ภาษาอังกฤษกับตัวเลขยังเป็น IBM Plex เหมือนเดิม แต่ภาษาไทยต้องเป็นแบบ "มีหัว"
   วิธี: ใส่ 'IBM Plex Sans' (ตัวละติน ไม่มีสระ/พยัญชนะไทยอยู่ในฟอนต์) ไว้หน้าสุด
   เบราว์เซอร์เลือกฟอนต์ทีละตัวอักษร ตัวอังกฤษกับเลขจึงได้ IBM Plex เหมือนเดิมทุกประการ
   ส่วนตัวไทยหาไม่เจอในฟอนต์นั้น เลยตกไปใช้ Sarabun ซึ่งมีหัวโดยอัตโนมัติ
   (ของเดิมใส่ 'IBM Plex Sans Thai' ซึ่งมีตัวไทยอยู่ด้วย ตัวไทยเลยไม่มีหัวทั้งหน้า) */
.page-title, .sh-title, .big-title, .fm-h, .ob-h, .obw-name, .empty-h,
.wg-title, .wg-time, .mt-lb, .pe-tx b, .st-hero .v, .fr-nm, .bg-nm,
.sec-label, .eyebrow {
  font-family: 'IBM Plex Sans', 'Sarabun', 'Leelawadee UI', sans-serif;
}

/* ---------- สเกลตัวอักษร ----------
   หน้าแรกเคยมีตัวอักษร 8 ขนาดในจอเดียว: 10.5 · 11 · 12.5 · 13 · 15 · 16 · 17 · 24
   คู่ที่ห่างกันครึ่งพิกเซล (10.5 กับ 11) หรือสองพิกเซล (15/16/17) ตาแยกไม่ออกอยู่แล้ว
   แต่มันทำให้จังหวะการอ่านสะดุด เพราะไม่มีขนาดไหนแปลว่าอะไรแน่นอนสักขนาด
   เหลือ 4 ขั้น แต่ละขั้นมีหน้าที่ของตัวเอง — ขนาดกลายเป็นข้อมูล ไม่ใช่การตกแต่ง
   (ยังไม่ได้ไล่ทั้งแอป — จอแผน/จอรายการงานยังมีสเกลของตัวเองอยู่ ดู .sh-title .rc-title) */
:root {
  --fs-meta:  12px;   /* วันที่ · ชิป · คำอธิบายใต้ชื่อ · ตัวเลขบนไทล์ */
  --fs-body:  14px;   /* ชื่อไทล์ · งานใบรอง · ปุ่มในการ์ด */
  --fs-title: 17px;   /* ชื่องานใบแรก — ของชิ้นเดียวบนจอที่ต้องอ่านก่อนเพื่อน */
  --fs-page:  24px;   /* คำทักทาย */
}

.page-title { font-size: var(--fs-page); line-height: 1.24; letter-spacing: -.034em; }
.page-sub { font-size: 13px; line-height: 1.65; color: var(--muted); }
.sh-title { font-size: 21px; letter-spacing: -.03em; }
/* 1C07 · หัวข้อกลุ่มขยายและเข้มขึ้น — เจ้าของวงมาสามจุด "ขยายกับเพิ่มความชัด"
   ตัวการไม่ใช่ขนาดอย่างเดียว แต่เป็น letter-spacing .08–.09em ที่ติดมากับ
   .sec-label ตั้งแต่ style.css · การถ่างตัวอักษรเป็นสูตรของหัวข้อภาษาอังกฤษตัวใหญ่
   ซึ่งได้ผลเพราะตัวพิมพ์ใหญ่ทุกตัวสูงเท่ากันและไม่มีอะไรลอยอยู่ข้างบนข้างล่าง
   ภาษาไทยตรงข้าม: สระบนล่างกับวรรณยุกต์ต้องเกาะพยัญชนะของมัน พอถ่างออก
   คำเลยแตกเป็นตัว ๆ และที่ 11.5px ตาต้องประกอบคำเองทุกคำ
   เหลือ .01em ไว้พอไม่ให้ตัวชนกัน · สีขึ้นจาก --muted เป็น --ink เพราะมันคือ
   หัวข้อที่บอกว่ากลุ่มข้างล่างคืออะไร ไม่ใช่คำอธิบายประกอบ */
.sec-label {
  font-size: 13.5px; font-weight: 700; letter-spacing: .01em;
  color: var(--ink); margin-top: 20px;
}
.eyebrow { font-size: var(--fs-meta); letter-spacing: .04em; }
/* ตัวหนังสือรองเดิมจางจนอ่านยากบนธีมสว่าง — ยกน้ำหนักขึ้นนิดหนึ่ง */
.rc-meta, .am, .mt-sub, .st-row .ct, .fr-st { font-weight: 500; }
.rc-title, .at { font-size: 15.5px; line-height: 1.45; }
.brief-body { font-size: 14px; line-height: 1.7; color: rgba(255,255,255,.9); }
.mono, .st-hero .v, .wg-time { font-variant-numeric: tabular-nums; }

/* ============================================================
   หน้าฉัน: ปุ่มทางเข้าใหญ่ 3 ปุ่ม (1A6M3)
   ============================================================ */
/* ============================================================
   1C09 · ลิสต์ทางเข้าเป็น "การ์ดใบเดียวมีเส้นคั่น" ไม่ใช่การ์ดลอยเจ็ดใบ
   ============================================================
   เจ้าของสั่ง (18 ก.ย. 2569): "ไม่ทำให้ทุก card ดูเหมือนปุ่ม · ลด border และ
   decoration ที่ไม่จำเป็น · card hierarchy ชัด"

   ของเดิมให้เจ็ดแถวได้ขอบ + เงา + มุมโค้งของตัวเองคนละใบ ซึ่งแปลว่าทุกแถว
   ประกาศตัวว่า "ฉันเป็นวัตถุแยกชิ้น" เท่ากันหมด รวมถึงเท่ากับการ์ดผลงานข้างบน
   ที่เป็นของหลักจริง ๆ ด้วย · เมื่อทุกอย่างลอยเท่ากัน ก็ไม่มีอะไรลอย

   ใบเดียวมีเส้นคั่นให้ผลสามอย่างพร้อมกัน: ลำดับชั้นกลับมา (การ์ดผลงานลอย
   ลิสต์ไม่ลอย) · เงาเจ็ดชั้นเหลือชั้นเดียว · และสูงลดลง ~54px จากช่องว่าง
   ระหว่างใบที่ไม่ต้องมีอีก (gap 9px × 6)

   :active เปลี่ยนจากย่อทั้งใบเป็นพื้นสว่างขึ้น — ย่อแถวเดียวในกล่องที่ overflow
   ซ่อนอยู่ ทำให้ขอบแถวข้างเคียงกระตุกตาม */
.pf-entry {
  display: flex;
  flex-direction: column;
  margin-top: 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  /* หมายเหตุ: บล็อก "พื้นแบบกระจก" ท้ายไฟล์ (.card, .st-card, .pf-entry, …)
     มาทีหลังและความจำเพาะเท่ากัน จึงทับสองบรรทัดนี้ด้วย --soft-card/--soft-shadow
     ตั้งใจให้เป็นแบบนั้น — ลิสต์จะได้เป็นพื้นชุดเดียวกับการ์ดอื่นทั้งแอป
     สองบรรทัดนี้คือค่าสำรองเผื่อบล็อกนั้นถูกจำกัดขอบเขตในอนาคต */
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.pe {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 15px;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .16s ease;
}
.pe + .pe { border-top: 1px solid var(--line); }
/* พื้นตอนกดใช้ --press ตัวเดียวกับแถวในการ์ดสัปดาห์ (.wk-card .wc) และแถวราง
   ของจอวันนี้ (.dr-row) — เทากลาง 7% เข้มขึ้นบนพื้นสว่าง สว่างขึ้นบนพื้นมืด
   จึงเห็นครบทุกธีมโดยไม่ต้องเขียนทีละธีม และไม่ดึงคอนทราสต์ของค่าชิดขวาลง
   (ถ้าใช้ --card2 แทน ค่าจาง 12px จะตกไปเหลือ 3.76:1 ในธีมทะเล) */
.pe:active { background: var(--press, rgba(127,127,127,.07)); }
/* ไอคอนเป็นพื้นทึบสีฟ้า ไม่ใช่พื้นจาง 15%
   ของเดิมใช้ var(--blue-soft) ซึ่งบนธีมมืดคือฟ้าที่ opacity .15 บนพื้นการ์ดเข้ม —
   ออกมาเป็นเทาอมฟ้าที่แทบแยกไม่ออกจากพื้น ทั้งแถวเลยดูเป็นสี่เหลี่ยมเทาเรียงกัน
   ใช้คู่สีเดียวกับปุ่มที่ถูกเลือกบนแถบล่าง (--fill / --on-fill) แถวนี้จะได้พูดภาษาเดียวกับ
   แถบเมนู: ฟ้าทึบ = ของที่กดได้และกำลังชี้ไปหา */
.pe-ic {
  width: 40px; height: 40px; flex: none;
  border-radius: 14px;
  background: var(--fill);
  color: var(--on-fill);
  display: flex; align-items: center; justify-content: center;
}
.pe-ic svg { stroke-width: 2.1; }
.pe-ic svg { width: 19px; height: 19px; }
.pe-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pe-tx b { font-size: 15.5px; font-weight: 600; letter-spacing: -.015em; }
.pe-tx i { font-style: normal; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.pe-go { width: 16px; height: 16px; flex: none; color: var(--faint); }
.pe[hidden] { display: none; }

/* คำชวนตั้งบริบทในหน้าโปรไฟล์ (1A9g) — ใช้ .tl-hint ตัวเดิม แค่ขยับระยะให้เข้าที่
   เคยทำเป็นการ์ดขอบฟ้าพร้อมไอคอนทึบมาก่อน — มันดังกว่ากราฟ 7 วันที่อยู่ใต้มัน
   ทั้งที่กราฟคือของหลักของจอ ส่วนคำชวนเป็นแค่งานค้างที่พูดเบา ๆ ว่ายังไม่ได้ทำ */
/* 1C10 · .pf-hint ไม่มีใครใช้แล้ว — มันเป็นของแถบ "รู้จักคุณแล้ว %" ที่ถูกถอดออก */

/* ============================================================
   หน้าเหรียญตรา (1A6M3)
   ============================================================ */
.bg-body { gap: 10px; padding-top: 22px; }
.bg-row {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  opacity: .62;
}
.bg-row.on { opacity: 1; }
.bg-mark {
  width: 52px; height: 52px; flex: none;
  border-radius: 50%;
  background: var(--card2);
  color: var(--faint);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 20px; font-weight: 700;
  box-shadow: inset 0 0 0 2px var(--line);
}
.bg-row.on .bg-mark { color: #fff; box-shadow: none; }
.bg-row.on.b1 .bg-mark { background: linear-gradient(140deg,#94A3B8,#64748B); }
.bg-row.on.b2 .bg-mark { background: linear-gradient(140deg,#60A5FA,#2563EB); }
.bg-row.on.b3 .bg-mark { background: linear-gradient(140deg,#C084FC,#7C3AED); }
.bg-row.on.b4 .bg-mark { background: linear-gradient(140deg,#FB7185,#E11D48); }
.bg-row.on.b5 .bg-mark { background: linear-gradient(140deg,#FBBF24,#D97706); }
.bg-row.on.sea .bg-mark { background: linear-gradient(140deg,#22D3EE,#0369A1); }
.bg-row.on.tree .bg-mark { background: linear-gradient(140deg,#86EFAC,#15803D); }
.bg-row.on.sweet .bg-mark { background: linear-gradient(140deg,#FF9BD2,#9B6BF0); }
.bg-bd { flex: 1; min-width: 0; }
.bg-nm { font-size: 14.5px; font-weight: 700; line-height: 1.4; letter-spacing: -.015em; }
/* ชื่อเหรียญพิเศษใช้ฟอนต์ตามคอนเซปต์ของแต่ละอัน */
.bg-row.sea .bg-nm.fancy {
  font-family: 'Orbitron', 'Space Mono', ui-monospace, monospace;
  font-weight: 800; font-size: 14px; letter-spacing: .06em; text-transform: uppercase;
}
.bg-row.tree .bg-nm.fancy {
  font-family: 'Cinzel', Georgia, serif;
  font-weight: 700; font-size: 16px; letter-spacing: .04em;
}
.bg-row.sweet .bg-nm.fancy {
  font-family: 'Cinzel Decorative', 'Cinzel', Georgia, serif;
  font-weight: 700; font-size: 17px; letter-spacing: .05em;
}
.bg-row.on.sea .bg-nm.fancy { color: #0E7BA8; }
.bg-row.on.tree .bg-nm.fancy { color: #1E7A3C; }
.bg-row.on.sweet .bg-nm.fancy {
  background: linear-gradient(96deg, #C349D8, #FF6FB5 45%, #8A5BF0);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- ขอบไฮไลต์เคลื่อนไหว: เป็น "กรอบ" ของการ์ดเท่านั้น ----------
   ของเดิมเอา conic-gradient ทั้งแผ่นมาสั่ง rotate() — การ์ดเป็นทรงยาว
   พอหมุน มุมทั้งสี่จึงเหวี่ยงออกไปไกลกว่าตัวการ์ดมาก กลายเป็นแผ่นสีพาดทับการ์ดใบอื่น
   ของใหม่: ไล่สีแนวนอนเลื่อนไปทางเดียว แล้วเจาะไส้กลางทิ้งด้วย mask
   เหลือเป็นกรอบหนา 2px ทาบขอบการ์ดพอดี ไม่มีอะไรออกไปนอกกรอบได้เลย
   โผล่เฉพาะเหรียญที่ปลดล็อกแล้ว (.on) */
.bg-row { position: relative; isolation: isolate; }
.bg-row.on.sea, .bg-row.on.tree, .bg-row.on.sweet, .bg-row.on.genesis {
  border-color: transparent;
}
.bg-row.on.sea::before,
.bg-row.on.tree::before,
.bg-row.on.sweet::before,
.bg-row.on.genesis::before {
  content: '';
  position: absolute;
  /* กล่องลอยอิงจาก padding box — ถอย 1px ออกไปจึงพอดีขอบนอกสุดของการ์ด
     (ทับเส้น border 1px ที่ทำใสไว้ข้างบน) */
  inset: -1px;
  z-index: 2;
  pointer-events: none;
  border-radius: var(--r-card);
  padding: 2px;                 /* = ความหนาของกรอบ */
  /* กว้าง 2 เท่าของการ์ด → เลื่อน 200% พอดี 1 รอบ รอยต่อจึงไม่กระตุก */
  background-size: 200% 100%;
  animation: bd-slide 4.5s linear infinite;
  /* ชั้นในคลุม content box ชั้นนอกคลุมทั้งกล่อง แล้วหักลบกัน = เหลือเฉพาะขอบ */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
}
/* ไล่สีต้องเริ่มและจบด้วยสีเดียวกัน ตอนวนกลับมาจะได้ต่อกันสนิท */
.bg-row.on.sea::before {
  background-image: linear-gradient(90deg, #38BDF8, #1E3A8A 25%, #22D3EE 50%, #1D4ED8 75%, #38BDF8);
}
.bg-row.on.tree::before {
  background-image: linear-gradient(90deg, #86EFAC, #14532D 25%, #4ADE80 50%, #166534 75%, #86EFAC);
  animation-duration: 6s;
}
.bg-row.on.sweet::before {
  background-image: linear-gradient(90deg, #FF5FC8, #A855F7 25%, #FF8AE2 50%, #7C3AED 75%, #FF5FC8);
  animation-duration: 3.2s;
}
.bg-row.on.genesis::before {
  background-image: linear-gradient(90deg, #B7F5FF, #3B49B8 25%, #FFFFFF 50%, #6F7FE8 75%, #B7F5FF);
  animation-duration: 5s;
}
@keyframes bd-slide { to { background-position: 200% 0; } }

/* เบราว์เซอร์ที่เจาะไส้กลางไม่ได้ ให้เหลือเป็นขอบสีเรียบไปเลย
   ดีกว่าปล่อยให้ไล่สีทั้งแผ่นทับเนื้อการ์ดจนอ่านไม่ออก */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .bg-row.on.sea::before,
  .bg-row.on.tree::before,
  .bg-row.on.sweet::before,
  .bg-row.on.genesis::before { display: none; }
  .bg-row.on.sea     { border-color: #22D3EE; }
  .bg-row.on.tree    { border-color: #4ADE80; }
  .bg-row.on.sweet   { border-color: #FF8AE2; }
  .bg-row.on.genesis { border-color: #8E9BE8; }
}
@media (prefers-reduced-motion: reduce) {
  .bg-row.on.sea::before,
  .bg-row.on.tree::before,
  .bg-row.on.sweet::before,
  .bg-row.on.genesis::before { animation: none; }
}
/* เหรียญ GENESIS: วงกลม + ชื่อ */
.bg-row.on.genesis .bg-mark { background: linear-gradient(140deg,#B7F5FF,#4C57C9); }
.bg-row.genesis .bg-nm.fancy {
  font-family: 'Orbitron', 'Space Mono', monospace;
  font-weight: 800; font-size: 15px; letter-spacing: .12em;
}
.bg-row.on.genesis .bg-nm.fancy {
  background: linear-gradient(96deg, #2C3597, #6F7FE8 40%, #37B9D6);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- ขอบวงในของเหรียญ (เสริมจากขอบแถว) ---------- */
.bg-row .bg-mark { position: relative; overflow: hidden; }
.bg-row.on.sea .bg-mark::before,
.bg-row.on.tree .bg-mark::before,
.bg-row.on.sweet .bg-mark::before,
.bg-row.on.genesis .bg-mark::before {
  content: '';
  position: absolute;
  inset: -55%;
  border-radius: 50%;
  animation: mark-spin 3.4s linear infinite;
}
.bg-row.on.sea .bg-mark::before {
  background: conic-gradient(from 0deg, #0EA5E9, #1E3A8A 25%, #22D3EE 50%, #1D4ED8 75%, #0EA5E9);
}
.bg-row.on.tree .bg-mark::before {
  background: conic-gradient(from 0deg, #86EFAC, #14532D 28%, #4ADE80 52%, #166534 78%, #86EFAC);
  animation-duration: 4.6s;
}
.bg-row.on.sweet .bg-mark::before {
  background: conic-gradient(from 0deg, #FF5FC8, #A855F7 22%, #FF8AE2 48%, #7C3AED 72%, #FF5FC8);
  animation-duration: 2.6s;
  filter: saturate(1.5) brightness(1.12);
}
/* วงในทึบ — เหลือให้เห็นเป็น "ขอบ" กว้าง 3px */
.bg-row.on.genesis .bg-mark::before {
  background: conic-gradient(from 0deg, #B7F5FF, #3B49B8 24%, #FFFFFF 48%, #6F7FE8 72%, #B7F5FF);
  animation-duration: 3.8s;
}
.bg-row.on.sea .bg-mark::after,
.bg-row.on.tree .bg-mark::after,
.bg-row.on.sweet .bg-mark::after,
.bg-row.on.genesis .bg-mark::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: inherit;
}
.bg-row.on.sea .bg-mark span,
.bg-row.on.tree .bg-mark span,
.bg-row.on.sweet .bg-mark span,
.bg-row.on.genesis .bg-mark span { position: relative; z-index: 2; }
/* ใบไม้ลอยอยู่ในวงของ World Tree (ตัดขอบด้วย overflow ของตัววง) */
.bg-row.on.tree .bg-mark span::before,
.bg-row.on.tree .bg-mark span::after {
  content: '';
  position: absolute;
  width: 9px; height: 9px;
  border-radius: 62% 8% 62% 8%;
  background: #BBF7D0;
  box-shadow: 0 0 0 1px rgba(20,83,45,.25);
  animation: mark-leaf 5s ease-in-out infinite;
}
.bg-row.on.tree .bg-mark span::before { left: -15px; top: -12px; }
.bg-row.on.tree .bg-mark span::after { right: -14px; top: 6px; animation-delay: -2.4s; width: 7px; height: 7px; }
@keyframes mark-spin { to { transform: rotate(360deg); } }
@keyframes mark-leaf {
  0%, 100% { transform: translate(0, 0) rotate(0); opacity: .95; }
  50% { transform: translate(6px, 9px) rotate(140deg); opacity: .65; }
}
@media (prefers-reduced-motion: reduce) {
  .bg-mark::before, .bg-mark span::before, .bg-mark span::after { animation: none !important; }
}
.bg-ds { margin-top: 3px; font-size: 12px; line-height: 1.55; color: var(--muted); }
.bg-pg { margin-top: 8px; height: 5px; border-radius: 999px; background: var(--card2); overflow: hidden; }
.bg-pg i { display: block; height: 100%; border-radius: 999px; background: var(--grad-brand); }
.bg-ct { margin-top: 4px; font-size: 10.5px; color: var(--faint); }
.bg-ok { flex: none; color: var(--good); }
.bg-ok svg { width: 18px; height: 18px; }

/* ============================================================
   หน้าเพิ่ม/แก้งาน — จัดกลุ่มให้อ่านง่ายขึ้น (1A6M3)
   ============================================================ */
.fm-card { gap: 20px; padding: 18px 17px 20px; }
/* 1C14 · กับดักเดิมคลาสที่สาม — .08em + uppercase คือสูตรหัวข้ออังกฤษตัวพิมพ์ใหญ่
   พอเนื้อหาเป็นไทย 11px คำแตกเป็นตัว ๆ เพราะสระบนล่างหลุดจากพยัญชนะที่มันเกาะ
   ("ซ้ำ อี ก ไห ม" · "ไ ด้ ค ะ แ น น เ ท่ า ไ ห ร่") แก้เหมือน .sec-label กับ .st-h
   ใน 1C07–1C08 เป๊ะ: ถอดเฉพาะการถ่าง เหลือ .01em พอไม่ให้ตัวชนกัน
   uppercase ไม่ต้องถอด — ไม่มีผลกับไทย และป้ายบางใบในฟอร์มเป็นอังกฤษ */
.fm-card .fld > label,
.fm-card .fld-head label {
  font-size: 12px;
  letter-spacing: .01em;
  color: var(--muted);
}
.fm-card input[type=text],
.fm-card input[type=number],
.fm-card input[type=date],
.fm-card input[type=time],
.fm-card textarea,
.fm-card select {
  min-height: 48px;
  border-radius: 14px;
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 15px;
}
.fm-card input:focus, .fm-card textarea:focus, .fm-card select:focus { box-shadow: none; }

/* ช่อง "งานที่ต้องทำ" — ยืดลงล่างแทนที่จะเลื่อนออกข้าง
   style.css จัดหน้าตาให้เฉพาะ input/select (แก้ไม่ได้) จึงต้องเขียนของ textarea เองทั้งชุด
   ตัวเลข padding/มุม/ขนาดตัวอักษร ลอกจากช่องอื่นให้เท่ากันเป๊ะ ไม่งั้นฟอร์มจะดูไม่เป็นชุดเดียวกัน */
.fm-card textarea {
  background: var(--card2);
  border: none;
  padding: 12px 13px;
  font-family: inherit;
  font-weight: 500;
  color: var(--ink);
  width: 100%;
  line-height: 1.65;
  display: block;                /* ไม่งั้น inline-block ทิ้งช่องว่างใต้กล่องจากเส้นฐานตัวอักษร */
  resize: none;                  /* ความสูงคุมด้วย autoGrow() — ที่จับลากมุมจะขัดกัน */
  overflow: hidden;              /* ไม่มีแถบเลื่อนใน เพราะกล่องสูงเท่าเนื้อหาอยู่แล้ว */
  -webkit-appearance: none; appearance: none;
}
.fm-card textarea:focus { outline: 2px solid var(--blue); outline-offset: -2px; }
/* ปุ่มเลือกประเภท: ให้ตัวที่เลือกอยู่เด่นชัดกว่าเดิมมาก */
.type-pick { gap: 10px; }
.tp { min-height: 50px; border-radius: 15px; font-size: 14px; box-shadow: inset 0 0 0 1px var(--line); }
.tp svg { width: 17px; height: 17px; }
.tp.on, .tp.active {
  background: var(--blue);
  color: var(--on-accent);
  box-shadow: var(--shadow-brand);
}
/* แถวดาวความสำคัญ: ให้เป็นแถวเดียวเลื่อนได้ ไม่ตกบรรทัดจนดูรก */
.star-pick {
  display: flex;
  gap: 7px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.star-pick::-webkit-scrollbar { display: none; }
.star-pick .sp { flex: none; min-height: 40px; border-radius: 12px; padding: 0 13px; }
.fm-h { font-size: 23px; letter-spacing: -.03em; }
.fm-save { min-height: 54px; font-size: 15.5px; border-radius: 17px; }

/* หมายเหตุใต้ตัวเครื่อง (เห็นเฉพาะตอนเปิดบนจอคอม) */
.stage-note .alt-tag {
  display: inline-block;
  padding: 2px 7px;
  margin-right: 4px;
  border-radius: 5px;
  background: #FACC15;
  color: #0B1220;
  font-weight: 700;
  letter-spacing: .02em;
}
.stage-note code {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: .92em;
}

/* ============================================================
   ALT 1A6M3: ช่องใส่โค้ดในหน้าตั้งค่า
   ไม่มีที่ไหนในแอปบอกว่ามีโค้ดอะไรอยู่บ้าง — คนที่ได้โค้ดมาเท่านั้นถึงจะรู้
   ============================================================ */
.code-tools { display: flex; align-items: center; gap: 8px; }
/* .pf-row input ของดีไซน์เดิมถูกบังคับกว้าง 120px และชิดขวา ช่องนี้ต้องยาวเต็มแถว
   1C40 · แถวนี้ย้ายจาก .pf-row ไปอยู่ใน .set-row ตอนจัดจอตั้งค่าใหม่ กฎนี้จึงไม่ติดอีก
   ช่องพิมพ์โดน .set-row input (แคบ ชิดขวา) ทับ เหลือ 116px ข้างปุ่ม — ครอบทั้งสองแบบแถว */
.pf-row .code-tools input[type=text],
.set-row .code-tools input[type=text] {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  text-align: left;
  min-height: 42px;
  padding: 0 12px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 13.5px;
  letter-spacing: .02em;
}
.code-tools .btn { flex: none; width: auto; min-height: 42px; padding: 0 18px; }
/* ช่องพิมพ์ยาวเต็มแถวตั้งแต่ขอบซ้ายของการ์ดถึงปุ่ม "ใช้" ที่ชิดขวาสุด
   (รอบแรกเยื้องเข้าไปตรงแนวชื่อแถว — เจ้าของขอให้ยาวเต็มช่อง จึงไม่เยื้องแล้ว) */
.set-row .code-tools { width: 100%; }
.code-msg { margin: 0; }
.code-msg.bad { color: var(--alert); }
.code-msg[hidden] { display: none; }

/* ---------- ฉากปิดจอตอนโค้ดล้างแอป ----------
   ปิดทึบไว้ก่อน ไม่ให้เห็นข้อมูลค่อย ๆ หายทีละส่วนระหว่างรอโหลดใหม่ */
.wipe-curtain {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 15px;
  background: #070B14;
  color: #C8D4FF;
  animation: wipe-in .4s ease both;
}
.wipe-mark {
  font-size: 46px;
  line-height: 1;
  animation: wipe-pulse 1.5s ease-in-out infinite;
}
.wipe-tx {
  font-size: 14px;
  letter-spacing: .05em;
}
@keyframes wipe-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes wipe-pulse {
  0%, 100% { opacity: .5;  transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .wipe-mark { animation: none; }
}

/* ============================================================
   ALT: อนิเมชันเปลี่ยนจอ + จังหวะตอนกด
   ของเดิมมีแค่ rise เดียวใช้กับทุกการเปลี่ยนจอ ไม่ว่าจะเข้า ถอย หรือสลับแท็บ
   แยกเป็น 3 ทิศให้ตรงกับสิ่งที่เพิ่งกด (ทิศตั้งใน go() ที่ body[data-godir])
   .screens มี overflow:hidden อยู่แล้ว การเลื่อนแนวนอนจึงไม่ทำให้จอเลื่อนได้
   ============================================================ */
body[data-godir="fwd"] .screen.on  { animation: scr-fwd  .34s cubic-bezier(.22,.9,.28,1) both; }
body[data-godir="back"] .screen.on { animation: scr-back .32s cubic-bezier(.22,.9,.28,1) both; }
body[data-godir="lat"] .screen.on  { animation: scr-lat  .28s cubic-bezier(.25,.85,.3,1) both; }

@keyframes scr-fwd {
  from { opacity: 0; transform: translate3d(26px, 0, 0); }
  to   { opacity: 1; transform: none; }
}
@keyframes scr-back {
  from { opacity: 0; transform: translate3d(-22px, 0, 0); }
  to   { opacity: 1; transform: none; }
}
@keyframes scr-lat {
  from { opacity: 0; transform: translate3d(0, 8px, 0) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* เนื้อหาไล่ขึ้นทีละชิ้นแทนที่จะโผล่พร้อมกันทั้งจอ — สายตาได้ไล่จากบนลงล่าง
   จำกัดที่ 6 ชิ้นแรกพอ ที่เหลือขึ้นพร้อมกัน ไม่งั้นชิ้นท้าย ๆ รอนานจนรู้สึกแอปช้า */
.screen.on.just-in .menu-grid > *,
.screen.on.just-in .rank-card,
.screen.on.just-in .pf-entry > *,
.screen.on.just-in .bg-row,
.screen.on.just-in .pf-list > .pf-row {
  animation: item-in .3s cubic-bezier(.22,.9,.28,1) both;
}
.screen.on.just-in .menu-grid > :nth-child(1),
.screen.on.just-in .pf-list > .pf-row:nth-child(1) { animation-delay: .02s; }
.screen.on.just-in .menu-grid > :nth-child(2),
.screen.on.just-in .rank-card:nth-child(2),
.screen.on.just-in .pf-entry > :nth-child(2),
.screen.on.just-in .bg-row:nth-child(2),
.screen.on.just-in .pf-list > .pf-row:nth-child(2) { animation-delay: .05s; }
.screen.on.just-in .menu-grid > :nth-child(3),
.screen.on.just-in .rank-card:nth-child(3),
.screen.on.just-in .pf-entry > :nth-child(3),
.screen.on.just-in .bg-row:nth-child(3),
.screen.on.just-in .pf-list > .pf-row:nth-child(3) { animation-delay: .08s; }
.screen.on.just-in .menu-grid > :nth-child(4),
.screen.on.just-in .bg-row:nth-child(4),
.screen.on.just-in .pf-list > .pf-row:nth-child(4) { animation-delay: .11s; }
.screen.on.just-in .menu-grid > :nth-child(5),
.screen.on.just-in .bg-row:nth-child(5),
.screen.on.just-in .pf-list > .pf-row:nth-child(5) { animation-delay: .14s; }
.screen.on.just-in .menu-grid > :nth-child(n+6),
.screen.on.just-in .bg-row:nth-child(n+6),
.screen.on.just-in .pf-list > .pf-row:nth-child(n+6) { animation-delay: .17s; }

@keyframes item-in {
  from { opacity: 0; transform: translate3d(0, 9px, 0); }
  to   { opacity: 1; transform: none; }
}

/* ---------- จังหวะตอนกด ----------
   กดแล้วยุบลงทันที ปล่อยแล้วเด้งกลับ — บอกว่าแอปรับคำสั่งแล้วก่อนจอจะเปลี่ยน */
/* 1C09 · .pe หลุดจากสองกฎนี้ — แถวในลิสต์ไม่ได้เป็นการ์ดลอยของตัวเองแล้ว
   จึงย่อทั้งใบไม่ได้ (ดูหมายเหตุ .pf-entry) · มันใช้พื้นสว่างขึ้นแทน */
.mtile, .pf-row, .tl-task, .rank-card, .bg-pick, .empty-cta {
  transition: transform .13s cubic-bezier(.3,.8,.4,1), box-shadow .13s ease;
}
.pf-row:active, .rank-card:active { transform: scale(.982); }
.tl-task:active { transform: scale(.97); }
.empty-cta:active { transform: scale(.96); }

/* ปุ่มบนแถบเมนู: ไอคอนเด้งขึ้นตอนกลายเป็นแท็บที่เลือกอยู่ */
.tab.active .ic { animation: tab-pop .32s cubic-bezier(.2,.9,.3,1.5); }
@keyframes tab-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.22) translateY(-2px); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  body[data-godir] .screen.on,
  .screen.on.just-in .menu-grid > *,
  .screen.on.just-in .rank-card,
  .screen.on.just-in .pf-entry > *,
  .screen.on.just-in .bg-row,
  .screen.on.just-in .pf-list > .pf-row,
  .tab.active .ic { animation: none; }
  .mtile, .pe, .pf-row, .tl-task, .rank-card, .bg-pick, .empty-cta { transition: none; }
}

/* ---------- ALT: รูปโปรไฟล์ตั้งเองได้ ---------- */
.pf-av-btn {
  position: relative;
  flex: none;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  line-height: 0;
  border-radius: 20px;
  transition: transform .13s cubic-bezier(.3,.8,.4,1);
}
.pf-av-btn:active { transform: scale(.94); }
.pf-av-btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* ป้ายกล้องมุมขวาล่าง บอกว่ารูปนี้แตะเปลี่ยนได้ ไม่ใช่แค่รูปแสดงผล */
.pf-av-cam {
  position: absolute;
  right: -3px; bottom: -3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #fff;
  color: var(--blue-deep);
  box-shadow: 0 2px 6px rgba(0,0,0,.28);
  display: flex; align-items: center; justify-content: center;
}
.pf-av-cam svg { width: 12px; height: 12px; }
/* ตั้งรูปแล้วไม่ต้องมีพื้นกับขอบของกรอบตัวอักษรอีก ปล่อยให้เห็นรูปเต็ม ๆ */
.pf-av.has-img { background: none; border-color: rgba(255,255,255,.45); }
@media (prefers-reduced-motion: reduce) { .pf-av-btn { transition: none; } }

/* ฉากประจำธีมบนหน้าเส้นทางถูกถอดออกทั้งหมดแล้ว (ทะเลลึก/ต้นไม้โลก/หวานแหว/Crystal)
   หน้าเส้นทางมีข้อมูลแน่นอยู่แล้ว ฉากหลังถนนไปแย่งสายตากับป้ายจอด
   บรรยากาศของธีมยังอยู่ครบที่พื้นหลัง (.fx) ซึ่งเห็นได้ทุกจออยู่แล้ว */
/* ---------- GENESIS: 2 ชั้นบรรยากาศเพิ่ม (ทุกจอ) ----------
   ฉากบนหน้าเส้นทางถูกถอดออกแล้ว น้ำหนักของธีมย้ายมาอยู่ที่พื้นหลังแทน
   .fx เป็นพี่น้องกับ .screens อยู่ใน .phone จึงอยู่หลังทุกจอโดยอัตโนมัติ

   คุมความ "รก" ไว้ตามที่รีวิวมา: ทั้งสองชั้นเป็นผืนใหญ่เคลื่อนช้า ความทึบต่ำ
   ไม่มีของเล็ก ๆ วิ่งตัดสายตา ให้รู้สึกเป็นบรรยากาศ ไม่ใช่ของที่ต้องมอง */

/* แสงเหนือ 2 ผืนไหลสวนทางกัน — วิ่งกลับไปกลับมา จึงไม่มีรอยต่อตอนวนซ้ำ */
/* 16 ต.ค. 69 · เดิมเลื่อน background-position ของกล่องเต็มจอ = วาดใหม่ทุกเฟรม (CPU ช้า 6 เท่า: หยุดชั้นนี้ลดเธรดหลักไป 13 จุด)
   ผืนละชั้น กว้างเท่าภาพเดิม (220% · 280% ของจอ) แล้วเลื่อนทั้งผืนด้วย translate
   ระยะเท่าของเดิม: ผืนแรก 0 → −120% ของจอ (= −54.545% ของความกว้างตัวเอง) · ผืนสอง −180% → 0 (= −64.286%) */
:root[data-theme="genesis"] .fx-g { inset: 0; }
:root[data-theme="genesis"] .fx-g::before,
:root[data-theme="genesis"] .fx-g::after {
  content: ''; position: absolute; left: 0; top: 0; height: 100%;
  animation: gen-aurora-a 26s ease-in-out infinite alternate;
}
:root[data-theme="genesis"] .fx-g::before {
  width: 220%;
  background: linear-gradient(102deg, transparent 26%, rgba(183,245,255,.16) 42%, rgba(255,255,255,.10) 50%, transparent 66%);
}
:root[data-theme="genesis"] .fx-g::after {
  width: 280%;
  background: linear-gradient(76deg, transparent 50%, rgba(142,155,232,.18) 66%, transparent 84%);
  animation-name: gen-aurora-b;
}

/* ชั้นหมู่ดาวถูกถอดออกแล้ว — radial ที่ตั้ง stop ไว้ 18% บนไทล์ 168×112
   ให้วงกลมกว้างราว 36px ซึ่งใหญ่เกินจนอ่านเป็น "จุดเต็มจอ" ไม่ใช่ดาว
   ธีมนี้ควรสะอาด เหลือเพชร ลม แสงเหนือ และหิมะเม็ดเล็ก ๆ ก็พอ */
:root[data-theme="genesis"] .fx-h { display: none; }

@keyframes gen-aurora-a { from { translate: 0 0; } to { translate: -54.545% 0; } }
@keyframes gen-aurora-b { from { translate: -64.286% 0; } to { translate: 0 0; } }

/* ตอนอีเวนต์ 99 วิ ชั้นนี้เร่งขึ้นพร้อมของเดิม */
:root[data-gevent="on"][data-theme="genesis"] .fx-g::before,
:root[data-gevent="on"][data-theme="genesis"] .fx-g::after { animation-duration: 7s; }   /* :is() ใส่ ::before ไม่ได้ จึงแยกบรรทัด */

@media (prefers-reduced-motion: reduce) {
  :root[data-theme="genesis"] .fx-g, :root[data-theme="genesis"] .fx-g::before, :root[data-theme="genesis"] .fx-g::after,
  :root[data-theme="genesis"] .fx-d::before, :root[data-theme="genesis"] .fx-d::after { animation: none; }
}

/* ============================================================
   ALT 1A6M3: ร้านค้า + โทเคน (ยังสร้างไม่เสร็จ)
   ปุ่มติดป้าย "กำลังทำ" ไว้ชัด ๆ แต่ยังกดเข้าไปดูยอดได้จริง
   ไม่ทำเป็นปุ่มตาย เพราะโทเคนเดินจริงแล้วตั้งแต่ตอนนี้
   ============================================================ */
.pe-wip {
  display: inline-block;
  margin-left: 7px;
  padding: 2px 7px 3px;
  border-radius: 999px;
  background: var(--pri-yellow);
  color: var(--pri-yellow-text);
  font-family: 'IBM Plex Sans', 'Sarabun', sans-serif;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .01em;
  vertical-align: 2px;
}
.pe-shop .pe-ic { background: var(--pri-yellow); color: var(--pri-yellow-text); }

/* ---------- เหรียญโทเคน ----------
   ขนาดมาจาก width/height ใน coin() ไม่ใช่จาก CSS — เหรียญที่ 16px กับ 52px
   ใช้ symbol คนละตัว การปล่อยให้ CSS ยืดตัวเดียวจะได้ขอบหยักที่กลายเป็นรอยเปื้อน */
.tok { display: block; flex: none; }

/* ---------- ยอดโทเคน ----------
   เดิมเป็นแผ่นไล่สีน้ำเงินเต็มความกว้าง ซึ่งทำให้ "กล่องยอด" เป็นของสว่างที่สุดในจอ
   ทั้งที่มันเป็นแค่ตัวเลข · ตอนนี้พื้นเป็นสีการ์ดปกติ แล้วปล่อยให้ **เหรียญ** เป็น
   ของสว่างชิ้นเดียว — ตาจะได้ไปหยุดที่ของสะสม ไม่ใช่ที่พื้นหลัง */
.tk-hero {
  position: relative;
  overflow: hidden;
  padding: 18px 17px 15px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  margin-bottom: 11px;
}
/* แสงทองใต้เหรียญ — ให้เหรียญดูเหมือนวางอยู่บนการ์ด ไม่ใช่ถูกแปะทับลงไป */
.tk-aura {
  position: absolute;
  left: -34px; top: -66px;
  width: 220px; height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(233,169,60,.26), rgba(233,169,60,0) 62%);
  pointer-events: none;
}
.tk-glint {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(115deg, rgba(255,255,255,.02) 0 1px, transparent 1px 10px);
  pointer-events: none;
}
.tk-top { position: relative; display: flex; align-items: center; gap: 15px; }
.tk-top .tok { flex: none; }
.tk-bal {
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.038em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.tk-unit {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--muted); margin-top: 6px;
}
/* ชิปเดียวต่อการ์ด — สองชิปเมื่อไหร่ ตาจะเริ่มไล่อ่านแทนที่จะเห็นยอดก่อน */
.tk-pill {
  font-size: 10.5px; font-weight: 700;
  padding: 3px 8px;
  border-radius: 99px;
}
.tk-pill.up   { background: var(--good-soft); color: var(--good); }
.tk-pill.free { background: rgba(233,169,60,.16); color: #E9A93C; }
/* แถบระยะถึง "สุ่ม 10 ใบ" — ยอดลอย ๆ ไม่ได้บอกว่ามันพอทำอะไรหรือยัง */
.tk-track {
  position: relative;
  height: 5px;
  margin-top: 15px;
  border-radius: 99px;
  background: var(--skel);
  overflow: hidden;
}
.tk-track i {
  position: absolute; left: 0; top: 0; bottom: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, #C8850F, #FFD87A);
}
.tk-goal { position: relative; margin-top: 8px; font-size: 11px; color: var(--muted); }
.tk-goal b { color: #E9A93C; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ชิปยอดมุมขวาบนของจอสุ่ม */
.tk-chip {
  display: inline-flex; align-items: center; gap: 5px;
  flex: none;
  padding: 7px 11px;
  border-radius: 99px;
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 13px; font-weight: 700;
}
.tk-chip b { font-variant-numeric: tabular-nums; }

/* ---------- สถิติการเปิดแอป ---------- */
.tk-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 9px;
  margin-bottom: 11px;
}
.tk-stats > div {
  padding: 13px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  text-align: center;
}
.tk-stats .v {
  font-size: 21px;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.tk-stats .k { font-size: 11px; color: var(--muted); margin-top: 5px; font-weight: 500; }

/* ---------- อธิบายวิธีได้โทเคน ---------- */
.tk-note {
  display: flex;
  gap: 12px;
  padding: 14px 15px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  margin-bottom: 11px;
}
.tk-note .tile {
  width: 34px; height: 34px;
  flex: none;
  border-radius: 11px;
  background: var(--blue-soft);
  color: var(--blue);
  display: flex; align-items: center; justify-content: center;
}
.tk-note .tile svg { width: 16px; height: 16px; }
.tk-note .lb { font-size: 13.5px; font-weight: 700; margin-bottom: 3px; }
.tk-note .tx { font-size: 12.5px; line-height: 1.6; color: var(--muted); }
.tk-note .tx b { color: var(--blue); font-variant-numeric: tabular-nums; }

/* ---------- กล่องบอกว่ายังไม่เปิด ----------
   ขอบประบอกว่า "ยังไม่ใช่ของจริง" ได้ตรงกว่าข้อความอย่างเดียว */
.tk-soon {
  padding: 16px 16px 17px;
  border: 1.5px dashed var(--line);
  border-radius: var(--r-card);
  background: var(--card2);
  text-align: center;
}
.tk-soon .lb {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 5px;
}
.tk-soon p {
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--muted);
  margin: 0;
}

/* ============================================================
   ตราแบรนด์ไปอยู่ตรงไหนได้บ้าง (1A9k) — เลิกยัดลงช่องไอคอน
   ------------------------------------------------------------
   1A6M4 เอาตราแบรนด์ไปแทนไอคอนดาวทุกช่อง แล้วต้องรองพื้นขาวทุกช่องตามไปด้วย
   เพราะตราเป็นรูปหลายสีบนพื้นใส สั่ง color ให้เปลี่ยนตามธีมไม่ได้
   1A6M4b เห็นว่าแผ่นรองเต็มไปหมดเลยลบทิ้ง — เหลือตราลอยจมพื้นทุกช่อง
   สองรุ่นนั้นแก้กันคนละทาง เพราะโจทย์จริงไม่ใช่ "มีแผ่นรองหรือไม่มี"

   โจทย์จริงคือตราเป็นภาพแรสเตอร์ ย่อลงช่อง 15–22px แล้วขอบแตก อ่านไม่ออกว่า
   เป็นรูปอะไร ต่อให้รองพื้นขาวก็ยังเป็นก้อนเบลอ ๆ อยู่ดี และมันไม่ได้สื่ออะไรด้วย —
   ตราบอกว่า "นี่คือแอปอะไร" ซึ่งคนที่เปิดแอปอยู่รู้อยู่แล้ว ช่องไอคอนต้องการคำว่า
   "ตรงนี้คือ AI" ซึ่งไอคอนประกายบอกได้ตรงกว่าตราแบรนด์

   จึงแบ่งตามขนาดแทน:
     ช่องใหญ่ 44px ขึ้นไป  ตราอยู่ได้ ใส่แผ่นรองขาวให้ (ดูบล็อกข้างล่าง)
     ช่องเล็กกว่านั้น       ไอคอนเส้น #lu-sparkles คมทุกขนาด เปลี่ยนสีตามธีมได้
                            และได้พื้นเดิมของช่องใน style.css คืนมาโดยไม่ต้องทับ
   ============================================================ */

/* วงต้อนรับตอนเปิดแอปครั้งแรก — 96px ตราเต็มวงพอดี เป็นช่องใหญ่ที่ตราอยู่ได้ */
.obw-ring { background: #fff; }
.obw-ring svg { width: 62px; height: 62px; }

/* ปุ่ม "ให้ AI อ่าน" (1A9g)
   ------------------------------------------------------------
   เดิมปุ่มนี้เอาตราแบรนด์ (ไฟล์ .png) มาย่อลงเหลือ 19px แล้ววางบนพื้นฟ้าอ่อน
   ตราเป็นภาพแรสเตอร์ ย่อขนาดนั้นบนจอมือถือแล้วขอบแตก อ่านไม่ออกว่าเป็นรูปอะไร
   และมันไม่ได้สื่ออะไรเลยด้วย — ตราแบรนด์บอกว่า "นี่คือแอปอะไร" ไม่ได้บอกว่า
   "กดแล้วจะเกิดอะไร" ทั้งที่นี่คือปุ่มหลักของการ์ดนี้

   จึงเปลี่ยนสองอย่างพร้อมกัน:
     1) ไอคอน → ประกาย (#lu-sparkles) เป็นเส้นเวกเตอร์เหมือนไอคอนอื่นทั้งแอป
        คมทุกขนาด และเป็นภาษาเดียวกับที่คนอ่านออกว่าหมายถึง AI
     2) พื้น → สีเน้นทึบ (--fill) แทนฟ้าอ่อน เพราะการ์ดนี้มีปุ่มเดียว
        มันคือปุ่มหลัก ไม่ใช่ปุ่มรอง — เดิมมันจมจนดูเหมือนป้ายมากกว่าปุ่ม
   ============================================================ */
.ai-read {
  background: var(--fill);
  color: var(--on-fill);
  box-shadow: var(--shadow-brand);
}
.ai-read svg { width: 18px; height: 18px; }

/* ---------- หน้าล็อกอิน: แผ่นรองโลโก้ ---------- */
/* 1C14 · .login-plate / .login-mark ถูกถอด — จอล็อกอินไม่มีแผ่นรอง 112px แล้ว
   ตราย้ายเข้าไปอยู่บนหัวใบพระเอก ขนาด 34px คู่กับชื่อแบรนด์บรรทัดเดียว (.lg-mark ใน style.css)
   แผ่นรองขาวยังอยู่ — ตราวาดมาสำหรับพื้นขาว และใบพระเอกก็เป็นไล่สีเข้มเหมือนเดิม */

/* ============================================================
   ตรามาร์ค: เอากรอบสีออกให้หมด (1A6M4b)
   ------------------------------------------------------------
   เดิมทุกที่ที่วางโลโก้จะมีกล่องรองสีแบรนด์/พื้นขาวอยู่ข้างหลัง — มันมาจากยุคที่
   โลโก้เก่ามีพื้นเข้มติดมาในรูปอยู่แล้ว กล่องพวกนั้นเลยกลายเป็นของส่วนเกิน

   ปัญหาคือตราใหม่เป็นสันหนังสือกรมท่าเข้ม วางบนพื้นมืดตรง ๆ แล้วหายไป 47%
   (วัดด้วยอัตราส่วนความสว่างจริง ไม่ได้กะเอา) จึงทำตราไว้สองไฟล์:
     logo-splash.png        ตราเข้ม  ใช้บนพื้นสว่าง
     logo-splash-light.png  ตราสว่าง ใช้บนพื้นมืด  (จมหายเหลือ 14% เท่ากันพอดี)
   แล้วให้ CSS สลับให้ตามธีม — ได้ทั้ง "ไม่มีกรอบ" และ "ไม่จมหาย" พร้อมกัน
   ============================================================ */

/* ค่าเริ่มต้น = ธีมสว่าง จึงโชว์ตราเข้ม */
.brand-dark { display: none; }
.brand-light { display: inline; }
/* ธีมพื้นมืดทั้งหมด สลับไปใช้ตราสว่าง */
:root[data-theme="dark"] .brand-light,
:root[data-theme="space"] .brand-light,
:root[data-theme="magic"] .brand-light,
:root[data-theme="galaxy"] .brand-light,
:root[data-theme="genesis"] .brand-light { display: none; }
:root[data-theme="dark"] .brand-dark,
:root[data-theme="space"] .brand-dark,
:root[data-theme="magic"] .brand-dark,
:root[data-theme="galaxy"] .brand-dark,
:root[data-theme="genesis"] .brand-dark { display: inline; }

/* ---------- เอากล่องรองออกให้หมด ---------- */
/* 1A9k: .brief-mark · .pr-dot · .obw-ring · .tl-note .tile · .brain-hd เคยถูกลบพื้นตรงนี้
   ทั้งห้าช่องเปลี่ยนไปใช้ไอคอนประกายแล้ว จึงได้พื้นเดิมของตัวเองใน style.css คืนไป
   (ฟ้าทึบ · ขาวจาง · ฟ้าอ่อน) ซึ่งเป็นพื้นที่ออกแบบมาให้ไอคอนเส้นอยู่ตั้งแต่แรก */
/* หน้าล็อกอิน: แผ่นรองขาวกลับมาแล้ว (1A9j)
   ------------------------------------------------------------
   กฎที่เคยอยู่ตรงนี้ลบแผ่นรองทิ้ง โดยให้เหตุผลว่า "ตราสว่างอ่านออกเองบนพื้นกรมท่า"
   ตอนที่เขียนมันจริง — logo-splash-light.png เป็นตราสีฟ้าอ่อน
   แต่ ca2694b เปลี่ยนไฟล์นั้นเป็นตรากรมท่าเข้ม (ตราใหม่วาดมาสำหรับพื้นขาว
   ส่วนตัวหนังสือในโลโก้ทำเป็นสีอ่อนไม่ได้ เพราะมันคือกรมท่าหลายร้อยเฉด)
   ชื่อไฟล์เดิม กฎนี้จึงไม่มีอะไรมาเตือน แล้วตราก็จมหายไปกับพื้นตั้งแต่วันนั้น

   ตราวาดมาสำหรับพื้นขาว ก็ให้พื้นขาวมันไป — แผ่นรองอยู่ใน .login-plate
   ข้างบนอยู่แล้ว แค่เลิกลบทิ้ง ไม่ต้องเขียนใหม่
   ============================================================ */
/* หน้าต้อนรับ · คู่มือติดตั้ง · แจ้งเตือนในแอป — ช่องใหญ่ที่ตราแบรนด์ยังอยู่
   แผ่นรองขาวอยู่ที่ตัว <img> เลย ไม่ต้องมี <div> ห่ออีกชั้นเหมือนหน้าล็อกอิน */
.ob-mark, .ig-icon img, .toast .tav {
  background: #fff;
  object-fit: contain;
}
.ob-mark { width: 62px; height: 62px; border-radius: 17px; padding: 7px; }
.ig-icon img { border-radius: 20px; padding: 7px; }
.toast .tav { width: 44px; height: 44px; border-radius: 14px; padding: 5px; }


/* ---------- แถบความคืบหน้าหน้าต้อนรับ (1A9m) ----------
   สี่ขั้นแล้วไม่บอกว่าอยู่ขั้นไหน = คนไม่รู้ว่าอีกนานแค่ไหนถึงจะได้ใช้แอป
   ซึ่งเป็นความไม่รู้ที่ทำให้คนกดข้ามทั้งที่เหลืออีกข้อเดียว
   แถบนี้เขียนตายตัวในแต่ละขั้น ไม่ต้องมี JS มาคอยอัปเดต — ขั้นไหนก็ขีดของขั้นนั้น */
.ob-prog { display: flex; gap: 5px; width: 100%; max-width: 300px; margin: 0 auto; }
.ob-prog i {
  flex: 1; height: 3px; border-radius: 2px;
  background: var(--line);
  transition: background .2s ease;
}
.ob-prog i.on { background: var(--fill); }

/* ตัวเลือกที่มีแต่คำสั้น ๆ — เรียงเป็นตารางสองคอลัมน์ให้กดโดนง่ายกว่าชิปลอยเรียงกัน
   (.ob-chips เดิมเป็น flex-wrap ซึ่งเหมาะกับคำยาวไม่เท่ากันอย่างเวลาเลิกเรียน) */
.ob-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 0;
}
.ob-grid .ob-chip { padding: 13px 8px; text-align: center; }

/* ============================================================
   ALT 1A7: เช็คอินรายวัน + วงล้อสุ่มสกิน
   ============================================================ */
:root {
  --r-common: #7C8AA5;
  --r-rare: #3B82F6;
  --r-legend: #F59E0B;
}

/* ---------- หน้าต่างเช็คอิน ---------- */
#checkin {
  position: absolute;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(6,10,22,.62);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  animation: ck-fade .22s ease both;
}
#checkin[hidden] { display: none; }
.ck-sheet {
  width: 100%;
  max-width: 330px;
  padding: 20px 18px 16px;
  border-radius: 24px;
  background: var(--card);
  box-shadow: 0 26px 60px rgba(0,0,0,.45);
  text-align: center;
  animation: ck-rise .34s cubic-bezier(.2,.9,.3,1.1) both;
}
.ck-ttl { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.ck-sub { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* ---------- เส้นทาง 6 วัน ----------
   ตาราง 3×3 เดิมทุกช่องหน้าตาเท่ากันหมด มันอ่านว่า "ตารางของรางวัล"
   ทั้งที่สิ่งที่ต้องสื่อคือ "รอบที่เดินหน้าไปทีละวัน" — เส้นเชื่อมทำให้เห็นความต่อเนื่อง
   ที่ตัวเลขในตารางไม่เคยบอกได้ */
.ck-track {
  display: flex;
  align-items: center;
  margin: 16px 2px 0;
}
.ck-node {
  flex: 1;
  display: flex; flex-direction: column; align-items: center;
  gap: 5px;
}
.ck-bub {
  width: 33px; height: 33px;
  border-radius: 11px;
  background: var(--card2);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--faint);
}
.ck-bub b { font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.ck-bub svg { width: 17px; height: 17px; }
.ck-node em { font-style: normal; font-size: 9px; color: var(--faint); }
.ck-node.done .ck-bub {
  background: var(--good-soft);
  border-color: color-mix(in srgb, var(--good) 32%, transparent);
  color: var(--good);
}
/* วันนี้ — ทองทึบ ไม่มีเงาเรือง · เงาเรืองมีได้ก้อนเดียวต่อแผ่นและมันเป็นของปุ่มรับ */
.ck-node.now .ck-bub {
  background: #FFD87A;
  border-color: #FFE9A8;
  color: #4A2E02;
}
.ck-node.now em { color: #E9A93C; font-weight: 700; }
.ck-line {
  flex: 0 0 9px;
  height: 2px;
  margin-bottom: 16px;
  border-radius: 2px;
  background: var(--line);
}
.ck-line.on { background: color-mix(in srgb, var(--good) 38%, transparent); }
/* ของวันนี้ได้เท่าไหร่ — เดิมต้องไปไล่หาช่องที่เรืองอยู่ในตารางแล้วอ่านเลขในนั้นเอง */
.ck-today {
  display: flex; align-items: center; justify-content: center;
  gap: 9px;
  margin-top: 16px;
}
.ck-today b { font-size: 30px; font-weight: 700; line-height: 1; letter-spacing: -.03em; }
.ck-today span { font-size: 12.5px; color: var(--muted); align-self: flex-end; padding-bottom: 3px; }
.ck-tspin { width: 28px; height: 28px; color: #E9A93C; }
/* วันที่ 7 — เคยเป็นแผ่นสีเน้นเต็มแถวที่ดังกว่าปุ่มรับ ทั้งที่ยังกดไม่ได้ */
.ck-d7 {
  display: flex; align-items: center; gap: 9px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  text-align: left;
  opacity: .62;
}
.ck-d7 .tok.off { filter: grayscale(1); opacity: .55; }
.ck-d7b { flex: 1; min-width: 0; }
.ck-d7b b { display: block; font-size: 12px; font-weight: 700; }
.ck-d7b i { font-style: normal; font-size: 10.5px; color: var(--faint); }
.ck-rem { flex: none; font-size: 10.5px; font-weight: 700; color: var(--faint); }
/* ปุ่มรับเป็นก้อนทองที่เรืองก้อนเดียวของแผ่นนี้ — ช่องวันนี้ในแถวข้างบนจึงเป็นทองทึบ
   ไม่มีเงา ทองสองก้อนที่เรืองพร้อมกันแปลว่าไม่มีก้อนไหนเรียกสายตาได้จริง */
.ck-cta {
  width: 100%;
  min-height: 52px;
  margin-top: 13px;
  border: none;
  border-radius: 16px;
  background: linear-gradient(135deg, #C8850F, #FFD87A);
  color: #3A2404;
  font-family: inherit;
  font-size: 15.5px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 13px 30px -10px rgba(233,169,60,.8);
}
.ck-cta:active { transform: scale(.98); }
.ck-done { font-size: 12.5px; color: var(--muted); margin: 6px 0 2px; }
.ck-close {
  width: 100%;
  min-height: 40px;
  margin-top: 6px;
  border: none;
  background: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
@keyframes ck-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ck-rise { from { opacity: 0; transform: translateY(18px) scale(.96); } to { opacity: 1; transform: none; } }

/* ============================================================
   ALT 1A7: การ์ดสุ่มสกิน 3D (แทนวงล้อเดิม)
   1C40: จากแถบเลื่อนเอียง ๆ เป็นวงทรงกระบอก (แบบ ThreeDPhotoCarousel)
   JS เซ็ต --a (มุมของแต่ละใบ) --r (รัศมี) --rot (มุมของวง) · ลาก/ปัดหมุนวงได้ ดู ringBind() ใน app.js
   ============================================================ */
/* ---------- ตารางอัตรา ----------
   ย้ายลงมาอยู่ใต้ปุ่มแล้ว: มันเป็นข้อมูลอ้างอิง ไม่ใช่ของที่ต้องอ่านก่อนกด
   แถบสัดส่วนบอก "Common กินเกือบทั้งแถบ" ได้ในพริบตา ซึ่งตัวเลข 83% ไม่เคยทำได้ */
.gc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.gc-odds { margin-top: 14px; }
.gc-obar {
  display: flex;
  gap: 2px;
  height: 4px;
  border-radius: 99px;
  overflow: hidden;
}
.gc-obar i { display: block; }
.gc-obar .r-legendary { background: var(--r-legend); }
.gc-obar .r-rare      { background: var(--r-rare); }
.gc-obar .r-common    { background: var(--r-common); flex: 1; opacity: .5; }
.gc-olb {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-size: 10px;
  font-weight: 600;
  opacity: .75;
}
.r-legendary { color: var(--r-legend); }
.r-rare { color: var(--r-rare); }
.r-common { color: var(--r-common); }

/* ---------- สำรับก่อนสุ่มครั้งแรก ----------
   เดิมตรงนี้เป็นที่ว่างที่มีประกายจาง ๆ กับข้อความบอกให้ไปกดปุ่มข้างล่าง —
   จอที่ควรน่าตื่นเต้นที่สุดในแอปกลับเป็นจอที่ไม่มีอะไรให้อยากแตะเลย
   สูงเท่าแถบการ์ดจริงเหมือนเดิม จอจะได้ไม่กระโดดตอนการ์ดโผล่ */
.gc-empty { min-height: 250px; display: flex; align-items: center; justify-content: center; }
.gc-fan {
  position: relative;
  width: 154px; height: 206px;
  padding: 0; border: none; background: none;
  cursor: pointer;
  animation: gc-float 4.5s ease-in-out infinite;
}
.gc-fc {
  position: absolute;
  left: 20px; top: 8px;
  width: 114px; height: 166px;
  border-radius: 15px;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.038) 0 2px, transparent 2px 7px),
    linear-gradient(150deg, var(--blue), var(--blue-deep));
  border: 1.5px solid rgba(255,255,255,.16);
  box-shadow: 0 16px 30px -12px rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
:root[data-theme="dark"] .gc-fc {
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.038) 0 2px, transparent 2px 7px),
    linear-gradient(150deg, #3E63AE, #1A2748);
}
/* ลายรัศมีบนหลังการ์ด — ลายทแยงเดิมอ่านว่า "พื้นผิวเปล่า" ไม่ใช่ "หลังการ์ด" */
.gc-fc .tok { position: relative; z-index: 2; }
.gc-fc.a { transform: rotate(-13deg) translate(-31px, 10px) scale(.94); opacity: .55; }
.gc-fc.b { transform: rotate(13deg) translate(31px, 10px) scale(.94); opacity: .55; }
.gc-fh {
  position: absolute;
  bottom: -6px; left: 0; right: 0;
  font-size: 11.5px;
  color: var(--muted);
}
.gc-fan:active { transform: scale(.97); }
@keyframes gc-float {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(-6px); }
}

/* ---------- วงการ์ด ----------
   สูงเท่าสำรับก่อนสุ่ม (.gc-empty 250px) จอจะได้ไม่กระโดดตอนการ์ดโผล่
   กว้างชนขอบจอ (margin ติดลบเท่า padding ของจอ) ใบข้าง ๆ จึงหายเข้าขอบจอ ไม่ใช่โดนตัดกลางจอ
   touch-action: pan-y = ลากขึ้นลงยังเลื่อนจอได้ตามปกติ แนวนอนเป็นของวง */
.gc-ring {
  position: relative;
  height: 250px;
  margin: 0 -20px;
  overflow: hidden;
  perspective: 1000px;
  touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
  animation: gc-ring-in .45s ease-out both;
}
.gc-ring.multi { cursor: grab; }
.gc-ring.multi:active { cursor: grabbing; }
.gc-cyl {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: translateZ(calc(-1 * var(--r, 0px))) rotateY(var(--rot, 0deg));
}
@keyframes gc-ring-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

.gc {
  position: absolute;
  left: 50%; top: 50%;
  width: 132px;
  height: 190px;
  margin: -95px 0 0 -66px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  transform-style: preserve-3d;
  transform: rotateY(var(--a, 0deg)) translateZ(var(--r, 0px));
  -webkit-tap-highlight-color: transparent;
}
.gc-ring.multi .gc { cursor: inherit; }

.gc-in {
  /* ต้องมี display:block — ตัวนี้เป็น <span> ซึ่งเป็น inline โดยปริยาย
     inline ไม่รับ width/height กล่องจึงยุบเป็น 0x0 และหน้า/หลังการ์ดที่ใช้ inset:0
     อ้างอิงกล่องนี้ ก็เลยเป็น 0x0 ตามไปด้วย (การ์ดขึ้นครบแต่มองไม่เห็นอะไรเลย) */
  display: block;
  position: relative;
  width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform .72s cubic-bezier(.3,.9,.28,1.05);
}
.gc.open .gc-in { transform: rotateY(180deg); }

.gc-back, .gc-face {
  position: absolute;
  inset: 0;
  border-radius: 17px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* ---------- หลังการ์ด ----------
   หน้าตาต้องเป็นใบเดียวกับสำรับที่แผ่อยู่ก่อนกด (.gc-fc) — ลายกับสีต่างกันเมื่อไหร่
   มันอ่านว่าการ์ดถูกสลับไปแล้วระหว่างทาง ไม่ใช่ใบเดิมที่เพิ่งหยิบขึ้นมา

   **อย่าพึ่ง backface-visibility กับกล่องที่มีพื้นลาย** — พื้นแบบ repeating-gradient
   (ทั้ง linear และ conic) ถูกเบราว์เซอร์ยกไปวาดเป็นเลเยอร์ของตัวเอง เลเยอร์นั้นไม่โดน
   backface-visibility ของกล่องแม่ ผลคือ *หงายการ์ดแล้วยังเห็นหลังการ์ดทับหน้าอยู่*
   ของเดิมใช้ลายทแยง repeating-linear-gradient จึงมีอาการนี้มาตั้งแต่ก่อนแก้รอบนี้
   ทางที่เชื่อถือได้คือบังด้วย opacity ตรง ๆ (ดู .gc.open .gc-back ข้างล่าง) */
.gc-back {
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.038) 0 2px, transparent 2px 7px),
    linear-gradient(150deg, var(--blue), var(--blue-deep));
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.16), 0 12px 26px -10px rgba(0,0,0,.6);
  color: rgba(255,255,255,.9);
  /* หน่วงเท่าครึ่งหนึ่งของเวลาพลิก (.72s) — หลังการ์ดหายตอนการ์ดหันข้างพอดี
     ถ้าหายทันทีจะเห็นหน้าการ์ดกลับด้านตั้งแต่ยังไม่ทันหมุน */
  transition: opacity 0s linear .36s;
}
.gc.open .gc-back { opacity: 0; }
:root[data-theme="dark"] .gc-back {
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.038) 0 2px, transparent 2px 7px),
    linear-gradient(150deg, #3E63AE, #1A2748);
}

/* เหรียญวางบนหลังการ์ดตรง ๆ — จานขาวรอบเหรียญทำให้มันดูเป็นไอคอนที่ถูกแปะทับ
   ไม่ใช่ตราที่ปั๊มอยู่บนการ์ด */
.gc-mark {
  position: relative;
  z-index: 2;
  display: flex; align-items: center; justify-content: center;
}
.gc-mark svg { width: 24px; height: 24px; }
.gc-mark .tok { width: 44px; height: 44px; }
.gc-face .gc-tok { margin-bottom: 2px; }

/* หน้าการ์ด — พลิกไว้ 180 องศาตั้งแต่ต้น พอ .open พลิกทั้งใบมันจึงหันมาพอดี */
.gc-face {
  transform: rotateY(180deg);
  color: #fff;
  text-align: center;
  padding: 10px;
  gap: 2px;
}
.gc-face.r-common { background: linear-gradient(160deg, #94A3B8, #55637A); }
.gc-face.r-rare {
  background: linear-gradient(160deg, #60A5FA, #1D4ED8);
  box-shadow: inset 0 0 0 2px rgba(191,219,254,.7), 0 0 20px -4px rgba(59,130,246,.9);
}
.gc-face.r-legendary {
  background: linear-gradient(160deg, #FDE68A, #D97706);
  box-shadow: inset 0 0 0 2px rgba(255,247,214,.85), 0 0 28px -3px rgba(245,158,11,.95);
  animation: gc-shine 1.7s ease-in-out infinite;
}
.gc-rar {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .07em;
  opacity: .95;
  margin-bottom: 4px;
}
.gc-face b { font-size: 20px; font-weight: 700; line-height: 1.15; }
.gc-face .mono { font-size: 30px; }
.gc-face span { font-size: 11px; opacity: .92; }
@keyframes gc-shine {
  0%,100% { box-shadow: inset 0 0 0 2px rgba(255,247,214,.85), 0 0 28px -3px rgba(245,158,11,.95); }
  50%     { box-shadow: inset 0 0 0 2px #FFFBEB, 0 0 40px 2px rgba(252,211,77,1); }
}

/* ---------- ปุ่ม ---------- */
.gc-all {
  width: 100%;
  min-height: 44px;
  margin-bottom: 12px;
  border: 1.5px dashed var(--line);
  border-radius: 15px;
  background: var(--card2);
  color: var(--muted);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.gc-all:active { transform: scale(.985); }
.gc-sum {
  padding: 12px 14px;
  margin-bottom: 12px;
  border-radius: 15px;
  background: var(--card2);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--muted);
  text-align: center;
}
.gc-sum b { color: var(--ink); font-variant-numeric: tabular-nums; }

.gc-btns { display: flex; gap: 9px; }
/* ปุ่มนำ = ปุ่มที่คุ้มที่สุด "ตอนนี้" ไม่ใช่ปุ่มที่แพงที่สุดเสมอ —
   เดิมปุ่ม 10 ใบเป็นทองตายตัว ทั้งที่บางทีสิทธิ์ฟรีนอนอยู่ในมือแล้ว
   ตอนนี้ทองย้ายตามปุ่มที่ควรกดก่อน (ดู refreshDrawHead) และมีได้ปุ่มเดียว */
.gc-go {
  flex: 1;
  min-height: 62px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card2);
  color: var(--muted);
  font-family: inherit;
  cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  transition: transform .13s ease;
}
.gc-go.lead {
  background: linear-gradient(135deg, #C8850F, #FFD87A);
  border-color: transparent;
  color: #3A2404;
  box-shadow: 0 13px 30px -10px rgba(233,169,60,.8);
}
.gc-go.lead i { color: #5C3A05; opacity: 1; }
.gc-go b { font-size: 14.5px; font-weight: 700; }
.gc-go i { font-size: 11px; font-style: normal; opacity: .85; }
.gc-go:active { transform: scale(.97); }
.gc-go:disabled { opacity: .45; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .gc-ring { animation: none; }
  .gc-in { transition: none; }
  .gc-face.r-legendary { animation: none; }
  .gc-fan { animation: none; }
}

/* ---------- ปุ่มใหญ่ในร้าน + ตู้สกิน ---------- */
.tk-cta {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 15px;
  margin-bottom: 9px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  color: var(--ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform .13s ease;
}
.tk-cta:active { transform: scale(.985); }
.tk-cta .tile {
  width: 42px; height: 42px; flex: none;
  border-radius: 13px;
  background: var(--pri-yellow); color: var(--pri-yellow-text);
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
/* ---------- ไทล์เช็คอินที่ยังไม่ได้กดรับ ----------
   สีแดงในจอนี้มีที่เดียว: ของที่รอให้กดอยู่ตอนนี้
   ถ้าไทล์อื่นได้สีเน้นด้วย จุดแดงจะกลายเป็นแค่สีอีกสีในกอง */
.tk-cta.live { border-color: color-mix(in srgb, var(--alert) 30%, transparent); }
.tk-cta.live .tile.cal {
  background: var(--alert-soft);
  color: var(--alert);
}
.tk-cta .tile.cal { background: var(--blue-soft); color: var(--blue); }
.tk-live {
  flex: none;
  font-size: 10.5px; font-weight: 700;
  padding: 5px 10px;
  border-radius: 99px;
  background: var(--alert);
  color: var(--on-accent);
}
/* สำรับย่อบนไทล์สุ่ม — ไอคอนประกายเดิมบอกได้แค่ "มีอะไรวิบวับ"
   สามใบซ้อนบอกว่าข้างในเป็นการ์ดที่เปิดได้ ซึ่งตรงกับสิ่งที่เจอเมื่อกดเข้าไป */
.tk-cta .tile.deck { background: none; }
.tk-cta .tile.deck i {
  position: absolute;
  left: 8px; top: 3px;
  width: 25px; height: 35px;
  border-radius: 7px;
  border: 1px solid rgba(255,255,255,.2);
  background: linear-gradient(150deg, var(--blue), var(--blue-deep));
}
:root[data-theme="dark"] .tk-cta .tile.deck i { background: linear-gradient(150deg, #3E63AE, #20305C); }
.tk-cta .tile.deck i:nth-child(1) { transform: rotate(-16deg) translateX(-5px); opacity: .5; }
.tk-cta .tile.deck i:nth-child(2) { transform: rotate(9deg) translateX(5px); opacity: .72; }
.tk-cta .tile.deck i:nth-child(3) {
  transform: none;
  box-shadow: 0 4px 12px -4px rgba(0,0,0,.55);
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,.09) 0 3px, transparent 3px 6px),
    linear-gradient(150deg, var(--blue), var(--blue-deep));
}
:root[data-theme="dark"] .tk-cta .tile.deck i:nth-child(3) {
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,.09) 0 3px, transparent 3px 6px),
    linear-gradient(150deg, #3E63AE, #20305C);
}
.tk-cta .tile svg { width: 18px; height: 18px; }
.tk-cta .bd { flex: 1; min-width: 0; }
.tk-cta b { display: block; font-size: 14.5px; font-weight: 700; }
.tk-cta i { display: block; font-size: 11.5px; font-style: normal; color: var(--muted); margin-top: 2px; }
.tk-cta > svg { width: 18px; height: 18px; color: var(--faint); flex: none; }

.tk-skins { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 11px; }
.tk-skin {
  padding: 12px 11px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  opacity: .55;
}
.tk-skin.got { opacity: 1; }
.tk-skin.got.r-rare { border-color: var(--r-rare); }
.tk-skin.got.r-legendary { border-color: var(--r-legend); box-shadow: 0 0 14px -5px var(--r-legend), var(--shadow); }
.ts-rar { font-size: 9px; font-weight: 800; letter-spacing: .05em; }
.tk-skin.r-rare .ts-rar { color: var(--r-rare); }
.tk-skin.r-legendary .ts-rar { color: var(--r-legend); }
.ts-nm { font-size: 14px; font-weight: 700; margin-top: 3px; }
.ts-ct { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

@media (prefers-reduced-motion: reduce) {
  #checkin, .ck-sheet, .ck-cell.now { animation: none; }
}

/* ============================================================
   ALT 1A7 (แก้): ไอคอนบนพื้นทอง · ล็อกจอตอนสุ่ม · ตกแต่งหน้าสุ่ม · ร้านขายธีม
   ============================================================ */

/* ---------- ไอคอนบนพื้นทอง ----------
   ของเดิมใช้ var(--pri-yellow-text) เป็นสีไอคอนบนพื้น var(--pri-yellow)
   โทเคนตัวนั้นเป็นเหลืองอ่อน (ตั้งใจไว้ให้เป็นตัวหนังสือบนชิปสีจาง ไม่ใช่บนพื้นทองทึบ)
   ผลคือเหลืองบนเหลือง วัดได้ contrast 1.21 เท่ากันทุกธีม มองไม่เห็นทั้งแอป
   เปลี่ยนเป็นสีเข้มคงที่ ซึ่งอ่านออกบนทองในทุกธีมเพราะพื้นทองไม่เปลี่ยนตามธีมอยู่แล้ว */
.pe-shop .pe-ic,
.tk-cta .tile,
.pe-wip {
  color: #33230A;
}
.pe-shop .pe-ic svg, .tk-cta .tile svg { stroke-width: 2.1; }

/* ---------- ระหว่างหงายการ์ด ----------
   เดิมซ่อนแถบเมนูกับปุ่มกลับ บังคับให้ดูจนจบ — เจ้าของ: "ให้ปุ่มเมนูมาด้วย" จึงไม่ซ่อนแล้ว
   ออกกลางคันได้ ของในใบที่ยังคว่ำเข้ากระเป๋าให้เอง (drawSettle ใน app.js) */

/* ---------- เวทีของหน้าสุ่ม ----------
   แสงไล่สีหลังแถบการ์ด ทำให้การ์ดดูลอยอยู่บนเวที ไม่ใช่วางบนพื้นเปล่า */
.gc-stage {
  position: absolute;
  left: -20px; right: -20px;
  top: 0;
  height: 250px;
  pointer-events: none;
  z-index: 0;
  /* เงาพื้นดำใต้การ์ด (วงรีดำ 28% ที่ก้นเวที) ถูกถอดออก — เจ้าของ: "มีขอบดำ ๆ จาง ๆ ข้างล่างใต้การ์ด เอาออก"
     วงรีจุดศูนย์กลางอยู่ที่ 96% ของความสูง ครึ่งล่างล้นกล่องจึงโดนตัดเป็นขอบตรง เห็นเป็นแถบเทาขอบแข็งใต้การ์ด */
  background:
    radial-gradient(60% 52% at 50% 46%, rgba(120,160,255,.22), transparent 72%);
}
.gc-stage.idle { animation: gc-breathe 5s ease-in-out infinite; }
@keyframes gc-breathe { 0%,100% { opacity: .6; } 50% { opacity: 1; } }
/* แสงวูบตอนเปิดได้ของหายาก — สีตามระดับ · คลุมทั้งจอ (ดู gcFlash ใน app.js)
   เดิมอยู่บน .gc-stage สูง 250px เห็นเป็นกล่องฟ้าขอบแข็งกลางจอ — เจ้าของ: "ให้มันรอบหน้าจอเลย"
   เรืองจากขอบจอทุกด้านเข้ามา (เงาด้านใน) + พื้นจอติดสีจาง ๆ ตรงกลาง แล้วจางหาย
   อนิเมตแค่ opacity — เงาก้อนใหญ่ขนาดนี้ถ้าอนิเมตขนาดเงาเองจะวาดใหม่ทุกเฟรมบนมือถือ */
.gc-flash {
  position: absolute; inset: 0; z-index: 60; pointer-events: none;
  opacity: 0;
  animation: gc-flash 1.1s ease-out forwards;
}
.gc-flash.rare {
  background: radial-gradient(130% 90% at 50% 42%, rgba(59,130,246,.2), transparent 70%);
  box-shadow: inset 0 0 90px 24px rgba(96,165,250,.8), inset 0 0 0 2px rgba(147,197,253,.7);
}
.gc-flash.legendary {
  animation-duration: 1.45s;
  background: radial-gradient(130% 90% at 50% 42%, rgba(245,158,11,.26), transparent 70%);
  box-shadow: inset 0 0 120px 34px rgba(252,211,77,.85), inset 0 0 0 2px rgba(253,230,138,.8);
}
@keyframes gc-flash { 0% { opacity: 0; } 14% { opacity: 1; } 100% { opacity: 0; } }
.gc-flash.secret {
  animation-duration: 1.45s;
  background: radial-gradient(130% 90% at 50% 42%, rgba(217,70,239,.24), transparent 70%);
  box-shadow: inset 0 0 120px 34px rgba(232,121,249,.8), inset 0 0 0 2px rgba(245,208,254,.8);
}
/* แสงขอบจอที่ค้างอยู่ตลอดที่การ์ดของหายากใบนั้นอยู่ข้างหน้า (ดู gcAuraSync ใน app.js)
   เบากว่าจังหวะวูบ เพราะต้องอยู่ร่วมกับจอไปนาน ๆ · หายใจช้า ๆ ให้รู้ว่ายังมีชีวิต
   เปลี่ยนสี/เปิด/ปิด ไล่ 0.4 วิ — หมุนผ่านหลายใบเร็ว ๆ แสงจะไหลตาม ไม่กะพริบ */
.gc-aura {
  position: absolute; inset: 0; z-index: 59; pointer-events: none;
  opacity: 0; transition: opacity .4s ease, box-shadow .4s ease;
}
.gc-aura.on { opacity: 1; animation: gc-aura 2.8s ease-in-out .5s infinite alternate; }
.gc-aura.rare {
  box-shadow: inset 0 0 85px 18px rgba(96,165,250,.75), inset 0 0 0 1.5px rgba(147,197,253,.7);
}
.gc-aura.legendary {
  box-shadow: inset 0 0 90px 18px rgba(252,211,77,.65), inset 0 0 0 1.5px rgba(253,230,138,.7);
}
.gc-aura.secret {
  box-shadow: inset 0 0 90px 18px rgba(232,121,249,.6), inset 0 0 0 1.5px rgba(245,208,254,.65);
}
@keyframes gc-aura { from { opacity: 1; } to { opacity: .62; } }
@media (prefers-reduced-motion: reduce) { .gc-aura.on { animation: none; } }
#gcArea { position: relative; }

/* หัวจอมีไล่สีทองนิดหนึ่ง ให้รู้ว่าจอนี้ไม่ใช่จอข้อมูลธรรมดา */
.gc-title {
  background: linear-gradient(96deg, var(--ink) 30%, #F59E0B);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* แสงวิ่งผ่านหลังการ์ดที่ยังคว่ำ — บอกว่ายังไม่เปิด ยังกดได้ */
.gc-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(104deg, transparent 38%, rgba(255,255,255,.3) 48%, transparent 58%);
  background-size: 260% 100%;
  animation: gc-sweep 2.6s linear infinite;
}
@keyframes gc-sweep { to { background-position: -260% 0; } }
.gc.open .gc-shine { display: none; }
/* การ์ดที่เปิดแล้วเรืองแสงค้างไว้ตามระดับ */
.gc.lit-rare { filter: drop-shadow(0 0 12px rgba(59,130,246,.55)); }
.gc.lit-legendary { filter: drop-shadow(0 0 18px rgba(245,158,11,.75)); }

/* ---------- ร้าน: ธีมที่ซื้อได้ ---------- */
.tk-buy {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 11px;
}
.tb-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}
.tb-row:last-child { border-bottom: none; }
.tb-sw {
  width: 34px; height: 34px; flex: none;
  border-radius: 11px;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.16);
}
.tb-bd { flex: 1; min-width: 0; }
.tb-bd b { display: block; font-size: 14px; font-weight: 700; }
.tb-bd i { display: block; font-size: 11.5px; font-style: normal; color: var(--muted); margin-top: 2px; }
.tb-go {
  flex: none;
  min-height: 36px;
  padding: 0 16px;
  border: none;
  border-radius: 11px;
  background: linear-gradient(135deg, var(--blue-deep), var(--blue));
  color: #fff;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.tb-go.poor { opacity: .45; }
.tb-go:active { transform: scale(.96); }
.tb-ok { color: #16A34A; display: flex; }
.tb-ok svg { width: 20px; height: 20px; }
.tb-row.own .tb-bd i { color: #16A34A; font-weight: 600; }

/* ป้ายบนปุ่มธีมที่ยังใช้อยู่แต่ยังไม่ได้เป็นเจ้าของ */
.th-grid .th-grace { position: relative; }
.th-grid .th-grace::after {
  content: 'ใช้อยู่';
  position: absolute;
  top: 3px; right: 5px;
  padding: 1px 5px 2px;
  border-radius: 999px;
  background: var(--pri-yellow);
  color: #33230A;
  font-size: 8.5px;
  font-weight: 800;
}

@media (prefers-reduced-motion: reduce) {
  .gc-stage, .gc-shine { animation: none; }
}
/* ปุ่มธีมที่ยังไม่ได้เป็นเจ้าของต้องหายจริง
   style.css ตั้ง .th-grid button { display:flex } ไว้ ซึ่งชนะกฎ [hidden]{display:none}
   ของเบราว์เซอร์ (กฎผู้เขียนชนะกฎ UA เสมอ) การตั้ง el.hidden = true จึงไม่มีผลเลย
   ต้องเขียนกฎผู้เขียนของเราเองมาทับ */
.th-grid button[hidden] { display: none; }

/* ============================================================
   ALT 1A7V: ธีมระดับลับ 2 โทน — Metaverse · Glitch
   ออกจากการสุ่มเท่านั้น และ **แอปไม่บอกว่ามีระดับนี้อยู่**
   ไม่โผล่ในตารางอัตรา ไม่โผล่ในตู้สะสม จนกว่าจะได้จริง
   ============================================================ */

/* ---------- Metaverse: โดมนีออนกลางความมืด ---------- */
:root[data-theme="meta"] {
  color-scheme: dark;
  --scr:#050A16; --card:#0C1526; --card2:#132038; --surface:#132038;
  --ink:#E6F0FF; --muted:#8FA8CC; --faint:#7A93B8;
  --line:rgba(120,190,255,.14);
  --blue:#3FA9FF; --blue-soft:rgba(63,169,255,.26); --blue-deep:#9CD4FF; --on-accent:#03101F;
  --neon:#5FD0FF;
  --alert:#FF6B8A; --alert-soft:rgba(255,107,138,.26);
  --warn:#FFC46B;  --warn-soft:rgba(255,196,107,.26);
  --good:#4FE0C0;  --good-soft:rgba(79,224,192,.26); --fire:#FF6B8A;
  --shadow:0 2px 8px rgba(0,0,0,.6), 0 18px 42px -14px rgba(0,0,0,.92);
  --shadow-lg:0 4px 12px rgba(0,0,0,.65), 0 36px 68px -18px rgba(0,0,0,.95);
  --shadow-brand:0 10px 30px -8px rgba(63,169,255,.6);
  --glass:rgba(5,10,22,.82); --glass-line:rgba(120,190,255,.2);
  --skel:rgba(255,255,255,.06); --skel-hi:rgba(255,255,255,.12);
  --grad-brand:linear-gradient(135deg,#1E6FD9 0%,#3FA9FF 100%);
  --grad-hero:linear-gradient(150deg,#0E2A52 0%,#0C1526 100%);
  --glow-scan:0 0 0 1px rgba(95,208,255,.4), 0 8px 28px -4px rgba(63,169,255,.7);
  --pg:#030711; --pg-ink:#E6F0FF; --pg-muted:#8FA8CC; --frame:#020509;
  --r-card:22px; --r-tile:15px;
}
/* พื้นลึก + แสงจากขอบฟ้า */
:root[data-theme="meta"] .fx-a {
  inset: 0;
  background:
    radial-gradient(120% 60% at 50% 108%, rgba(30,111,217,.42), transparent 70%),
    radial-gradient(90% 50% at 50% -10%, rgba(63,169,255,.18), transparent 72%);
}
/* โดมสามเหลี่ยม — เส้นนีออนสามชุดตัดกันเป็นตาข่ายทรงโดม
   ใช้ไล่สีเป็นเส้นแทนการวาดทีละเส้น จอไหนก็ต่อกันได้ไม่มีรอยตัด */
:root[data-theme="meta"] .fx-b {
  inset: -14% -20% auto -20%;
  height: 78%;
  background-image:
    repeating-linear-gradient(60deg, transparent 0 46px, rgba(120,200,255,.5) 46px 47.2px),
    repeating-linear-gradient(-60deg, transparent 0 46px, rgba(120,200,255,.5) 46px 47.2px),
    repeating-linear-gradient(0deg, transparent 0 40px, rgba(120,200,255,.34) 40px 41.2px);
  -webkit-mask-image: radial-gradient(70% 100% at 50% 100%, #000 26%, transparent 78%);
          mask-image: radial-gradient(70% 100% at 50% 100%, #000 26%, transparent 78%);
  opacity: .5;
  animation: mv-dome 22s ease-in-out infinite alternate;
}
/* จุดตัดของตาข่ายสว่างวาบเป็นจังหวะ — "ลูกเล่นพิเศษ" ของธีมนี้ */
:root[data-theme="meta"] .fx-c {
  inset: -14% -20% auto -20%;
  height: 78%;
  background-image: radial-gradient(circle, rgba(180,235,255,.9) 1.4px, transparent 2px);
  background-size: 94px 81px;
  -webkit-mask-image: radial-gradient(70% 100% at 50% 100%, #000 20%, transparent 74%);
          mask-image: radial-gradient(70% 100% at 50% 100%, #000 20%, transparent 74%);
  animation: mv-nodes 3.6s ease-in-out infinite;
}
/* ลำแสงกวาดขึ้นจากพื้น เหมือนกำลังสแกนพื้นที่ */
:root[data-theme="meta"] .fx-d {
  left: 0; right: 0; bottom: 0;
  height: 62%;
  background: linear-gradient(0deg, rgba(63,169,255,.3), transparent 70%);
  animation: mv-scan 7.5s ease-in-out infinite;
}
/* เส้นขอบฟ้าเรืองแสง */
:root[data-theme="meta"] .fx-e {
  left: -10%; right: -10%; bottom: 26%;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(140,215,255,.8) 30%, rgba(255,255,255,.7) 50%, rgba(140,215,255,.8) 70%, transparent);
  filter: blur(1.4px);
  animation: mv-horizon 6s ease-in-out infinite alternate;
}
/* ผงข้อมูลลอยขึ้นช้า ๆ */
/* 16 ต.ค. 69 · เดิมเลื่อน background-position ของกล่องเต็มจอ = วาดทั้งจอใหม่ทุกเฟรม (CPU ช้า 6 เท่า: เธรดหลักไม่ว่าง 43% · หยุดชั้นนี้เหลือ 12%)
   สองชั้นลอยคนละความเร็ว (ขึ้นหนึ่งช่องลายต่อรอบ: 300px กับ 260px) → แยกเป็น ::before/::after ยาวเกินกล่องลงไปหนึ่งช่องลาย
   แล้วเลื่อนทั้งชั้นขึ้นด้วย translate · ลายซ้ำทุก 300/260px พอดี วนรอบจึงต่อกันสนิทเหมือนเดิม */
:root[data-theme="meta"] .fx-f { inset: 0; }
:root[data-theme="meta"] .fx-f::before,
:root[data-theme="meta"] .fx-f::after { content: ''; position: absolute; left: 0; right: 0; top: 0; }
:root[data-theme="meta"] .fx-f::before {
  bottom: -300px;
  background-image: radial-gradient(1.6px 1.6px at 40px 60px, rgba(160,220,255,.8), transparent);
  background-size: 220px 300px;
  animation: mv-rise-a 26s linear infinite;
}
:root[data-theme="meta"] .fx-f::after {
  bottom: -260px;
  background-image: radial-gradient(1.2px 1.2px at 150px 200px, rgba(120,200,255,.6), transparent);
  background-size: 170px 260px;
  animation: mv-rise-b 26s linear infinite;
}
@keyframes mv-dome    { from { transform: translateY(-8px) scale(1); } to { transform: translateY(4px) scale(1.03); } }
@keyframes mv-nodes   { 0%,100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes mv-scan    { 0%,100% { opacity: .35; transform: translateY(10%); } 50% { opacity: .9; transform: translateY(0); } }
@keyframes mv-horizon { from { opacity: .45; } to { opacity: 1; } }
@keyframes mv-rise-a  { to { translate: 0 -300px; } }
@keyframes mv-rise-b  { to { translate: 0 -260px; } }

/* ---------- Glitch: สัญญาณเสีย ---------- */
:root[data-theme="glitch"] {
  color-scheme: dark;
  --scr:#04060A; --card:#0A0F16; --card2:#101822; --surface:#101822;
  --ink:#DFF7FF; --muted:#7FA6B4; --faint:#6B909D;
  --line:rgba(90,230,255,.16);
  --blue:#27E0F5; --blue-soft:rgba(39,224,245,.26); --blue-deep:#9DF3FF; --on-accent:#01161B;
  --neon:#FF2E88;
  --alert:#FF3B5C; --alert-soft:rgba(255,59,92,.28);
  --warn:#FFD166;  --warn-soft:rgba(255,209,102,.26);
  --good:#3DF5C0;  --good-soft:rgba(61,245,192,.26); --fire:#FF3B5C;
  --shadow:0 2px 8px rgba(0,0,0,.7), 0 18px 42px -14px rgba(0,0,0,.95);
  --shadow-lg:0 4px 12px rgba(0,0,0,.75), 0 36px 68px -18px rgba(0,0,0,.98);
  --shadow-brand:0 10px 30px -8px rgba(39,224,245,.55);
  --glass:rgba(4,6,10,.86); --glass-line:rgba(90,230,255,.22);
  --skel:rgba(255,255,255,.05); --skel-hi:rgba(255,255,255,.11);
  --grad-brand:linear-gradient(135deg,#0E8FA6 0%,#27E0F5 100%);
  --grad-hero:linear-gradient(150deg,#08313A 0%,#0A0F16 100%);
  --glow-scan:0 0 0 1px rgba(39,224,245,.45), 0 8px 28px -4px rgba(39,224,245,.6);
  --pg:#020407; --pg-ink:#DFF7FF; --pg-muted:#7FA6B4; --frame:#010203;
  --r-card:22px; --r-tile:15px;
}
:root[data-theme="glitch"] .fx-a {
  inset: 0;
  background:
    radial-gradient(80% 50% at 22% 34%, rgba(39,224,245,.16), transparent 68%),
    radial-gradient(70% 46% at 80% 62%, rgba(120,60,220,.14), transparent 70%);
}
/* ก้อนสัญญาณเสียลอยอยู่ในความมืด — เลื่อนกระตุกเป็นช่วง ไม่ไหลลื่น */
/* 16 ต.ค. 69 · เดิมสามก้อนอยู่บนพื้นหลังของกล่องเดียว แล้วกระโดดด้วย background-position (steps 6 ครั้ง)
   เธรดหลักยังต้องคิดสไตล์ชั้นเต็มจอนี้ทุกเฟรม (CPU ช้า 6 เท่า: 32% · หยุดชั้นนี้เหลือ 18%)
   ตอนนี้ก้อนละชิ้น (.fx-b · .fx-g · .fx-h — สองช่องหลังธีมนี้ไม่เคยใช้) กระโดดด้วย translate จังหวะ steps เดิม
   ระยะกระโดด = (ความกว้างจอ − ความกว้างก้อน) × ระยะ % ที่เดิมเลื่อน — สูตรเดียวกับที่ background-position คิด ภาพจึงตรงทุกขนาดจอ
   เส้นสแกน/สัญญาณรบกวน (c–f) ยกขึ้นเหนือก้อนเหมือนเดิม — g/h อยู่ท้ายใน HTML ถ้าไม่ยกจะวาดทับเส้นสแกน */
:root[data-theme="glitch"] :is(.fx-b, .fx-g, .fx-h) {
  inset: 0;
  background-repeat: no-repeat;
  animation: gl-slide 5.2s steps(6, end) infinite;
}
:root[data-theme="glitch"] .fx-b {
  background-image: linear-gradient(90deg, rgba(39,224,245,.5) 0 34px, transparent 34px 100%);
  background-size: 340px 16px; background-position: 12% 26%;
  --gl-dx: calc((100% - 340px) * .66);
}
:root[data-theme="glitch"] .fx-g {
  background-image: linear-gradient(90deg, rgba(157,243,255,.36) 0 60px, transparent 60px 100%);
  background-size: 260px 9px; background-position: 68% 44%;
  --gl-dx: calc((100% - 260px) * -.6);
}
:root[data-theme="glitch"] .fx-h {
  background-image: linear-gradient(90deg, rgba(255,46,136,.28) 0 22px, transparent 22px 100%);
  background-size: 420px 6px; background-position: 34% 68%;
  --gl-dx: calc((100% - 420px) * .42);
}
:root[data-theme="glitch"] :is(.fx-c, .fx-d, .fx-e, .fx-f) { z-index: 1; }
/* เส้นสแกนแนวนอนทั้งจอ */
:root[data-theme="glitch"] .fx-c {
  inset: 0;
  background-image: repeating-linear-gradient(180deg, rgba(255,255,255,.05) 0 1px, transparent 1px 4px);
  opacity: .7;
}
/* แถบสัญญาณกวาดลงจากบนลงล่าง */
:root[data-theme="glitch"] .fx-d {
  left: 0; right: 0; top: -30%;
  height: 26%;
  background: linear-gradient(180deg, transparent, rgba(39,224,245,.18) 45%, rgba(255,255,255,.12) 55%, transparent);
  animation: gl-sweep 6.5s linear infinite;
}
/* สัญญาณรบกวนเม็ดหยาบ */
:root[data-theme="glitch"] .fx-e {
  inset: 0;
  background-image:
    radial-gradient(1px 1px at 20px 30px, rgba(200,255,255,.5), transparent),
    radial-gradient(1px 1px at 120px 90px, rgba(255,46,136,.4), transparent),
    radial-gradient(1px 1px at 70px 160px, rgba(157,243,255,.45), transparent);
  background-size: 180px 210px, 140px 170px, 200px 240px;
  animation: gl-noise .28s steps(3, end) infinite;
  opacity: .5;
}
:root[data-theme="glitch"] .fx-f {
  inset: 0;
  background: repeating-linear-gradient(90deg, transparent 0 3px, rgba(255,46,136,.05) 3px 4px);
}
@keyframes gl-slide { to { translate: var(--gl-dx) 0; } }
@keyframes gl-sweep { to { transform: translateY(520%); } }
@keyframes gl-noise { 0% { transform: translate(0,0); } 33% { transform: translate(-2px,1px); } 66% { transform: translate(2px,-1px); } }

/* ---------- ลูกเล่นของ Glitch: จอสั่นบัคสั้น ๆ ----------
   ติดธง data-gfx ที่ <html> จาก JS แล้วปล่อยทิ้งใน ~380ms
   แยกชั้นสีแดง/ฟ้าออกจากกันด้วยเงาข้อความ + ขยับกล่องทั้งจอ */
/* ชุดอาการสั่นย้ายไปอยู่ท้ายไฟล์ (รุ่นแรงขึ้น) */

@keyframes gl-shake {
  0%   { transform: translate(0,0); }
  20%  { transform: translate(-3px,1px) skewX(.6deg); }
  40%  { transform: translate(3px,-1px) skewX(-.6deg); }
  60%  { transform: translate(-2px,0); }
  80%  { transform: translate(2px,1px); }
  100% { transform: translate(0,0); }
}

/* ---------- ลูกเล่นของ Glitch: ป้ายแจ้งข้อผิดพลาดสีแดง ---------- */
.gl-err {
  position: absolute;
  left: 14px; right: 14px;
  top: 64px;
  z-index: 65;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border: 1.5px solid #FF2A2A;
  border-radius: 6px;
  background:
    repeating-linear-gradient(135deg, rgba(255,42,42,.16) 0 9px, transparent 9px 18px),
    #170203;
  box-shadow: 0 0 18px -2px rgba(255,42,42,.8), inset 0 0 24px rgba(255,42,42,.22);
  color: #FF6060;
  font-family: 'Space Mono', ui-monospace, monospace;
  pointer-events: none;
  animation: gl-err-in .16s steps(2, end) both, gl-err-out .3s 1.5s steps(2, end) forwards;
}
.gl-err i {
  flex: none;
  width: 26px; height: 26px;
  border: 1.5px solid #FF2A2A;
  border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px;
  font-style: normal;
  color: #FF4040;
}
.gl-err .b { flex: 1; min-width: 0; }
.gl-err .h {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .16em;
  color: #FF3B3B;
  text-shadow: 0 0 8px rgba(255,42,42,.9);
}
.gl-err .m {
  font-size: 9.5px;
  line-height: 1.35;
  color: #E06A6A;
  word-break: break-all;
  opacity: .9;
  margin-top: 2px;
}
@keyframes gl-err-in  { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
@keyframes gl-err-out { to { opacity: 0; transform: translateX(5px); } }

@media (prefers-reduced-motion: reduce) {
  :root[data-theme="meta"] .fx-b,
  :root[data-theme="meta"] .fx-c,
  :root[data-theme="meta"] .fx-d,
  :root[data-theme="meta"] .fx-e,
  :root[data-theme="meta"] .fx-f,
  :root[data-theme="meta"] .fx-f::before,
  :root[data-theme="meta"] .fx-f::after,
  :root[data-theme="glitch"] .fx-b,
  :root[data-theme="glitch"] .fx-g,
  :root[data-theme="glitch"] .fx-h,
  :root[data-theme="glitch"] .fx-d,
  :root[data-theme="glitch"] .fx-e { animation: none; }
  :root[data-gfx="on"] .phone { animation: none; }
  .gl-err { animation: gl-err-out .3s 1.5s steps(2,end) forwards; }
}

/* ตัวอย่างสีบนปุ่มเลือกธีม */
.sw-meta { background: linear-gradient(135deg,#050A16 40%,#1E6FD9 40%,#1E6FD9 70%,#5FD0FF 70%); }
.sw-glitch { background: linear-gradient(135deg,#04060A 34%,#27E0F5 34%,#27E0F5 60%,#FF2E88 60%); }
/* ชื่อธีมลับใช้ฟอนต์ให้เข้ากับคอนเซปต์ */
.th-grid .th-meta .nm { font-family: 'Orbitron', 'Space Mono', monospace; font-weight: 800; font-size: 10.5px; letter-spacing: .08em; }
.th-grid .th-glitch .nm { font-family: 'Space Mono', ui-monospace, monospace; font-weight: 700; font-size: 11px; letter-spacing: .06em; }

/* ============================================================
   ALT 1A7V (แก้): อาการบัคของ Glitch แรงขึ้นและลงมาบน UI จริง
   ทุกอย่างเป็นชั้นภาพล้วน ๆ — ไม่มีอันไหนไปหยุดการทำงานหรือบล็อกการกดจริง
   ============================================================ */

/* จังหวะสั่นปกติ */
:root[data-gfx="on"] .phone { animation: gl-shake .4s steps(2, end); }
/* จังหวะสั่นแรง — ขยับมากขึ้น เอียงมากขึ้น และมีกระตุกซ้อน */
:root[data-gfx="hard"] .phone { animation: gl-shake-hard .62s steps(3, end); }

/* แยกสีตัวหนังสือทั้งจอ (แดง/ฟ้า) ตอนสั่น */
:root[data-gfx] .screen.on {
  text-shadow: 1.5px 0 rgba(255,46,136,.75), -1.5px 0 rgba(39,224,245,.75);
}
:root[data-gfx="hard"] .screen.on {
  text-shadow: 3px 0 rgba(255,46,136,.9), -3px 0 rgba(39,224,245,.9);
}
/* การ์ดกับไทล์ขยับคนละจังหวะกับตัวเครื่อง ให้เห็นว่า UI เองก็รวน ไม่ใช่แค่กล้องสั่น */
:root[data-gfx="hard"] .mtile:nth-child(odd),
:root[data-gfx="hard"] .rank-card:nth-child(even) {
  animation: gl-jolt .3s steps(2, end);
}
/* แถบเมนูกับหัวจอเลื่อนหลุดแนวแวบหนึ่ง */
:root[data-gfx="hard"] .tabbar { animation: gl-slip .34s steps(2, end); }
:root[data-gfx="hard"] .page-title { animation: gl-slip-x .28s steps(2, end); }

@keyframes gl-shake {
  0%   { transform: translate(0,0); }
  20%  { transform: translate(-3px,1px) skewX(.6deg); }
  40%  { transform: translate(3px,-1px) skewX(-.6deg); }
  60%  { transform: translate(-2px,0); }
  80%  { transform: translate(2px,1px); }
  100% { transform: translate(0,0); }
}
@keyframes gl-shake-hard {
  0%   { transform: translate(0,0) skewX(0); }
  12%  { transform: translate(-7px,3px) skewX(1.6deg); }
  26%  { transform: translate(6px,-4px) skewX(-1.4deg); }
  40%  { transform: translate(-5px,-2px) skewY(.8deg); }
  55%  { transform: translate(5px,3px) skewX(1deg); }
  70%  { transform: translate(-3px,1px); }
  85%  { transform: translate(3px,-1px); }
  100% { transform: translate(0,0) skewX(0); }
}
@keyframes gl-jolt {
  0%,100% { transform: none; }
  35%     { transform: translateX(-5px) skewX(1.2deg); filter: hue-rotate(40deg); }
  70%     { transform: translateX(4px); }
}
@keyframes gl-slip {
  0%,100% { transform: none; }
  40%     { transform: translateY(5px); opacity: .6; }
  75%     { transform: translateY(-3px); }
}
@keyframes gl-slip-x {
  0%,100% { transform: none; }
  45%     { transform: translateX(9px); letter-spacing: .05em; }
}

/* ---------- ระบบสะดุด ----------
   หน่วงภาพทั้งจอสั้น ๆ ให้เหมือนเครื่องค้าง เป็นชั้นภาพล้วน
   pointer-events ไม่ถูกปิด ระหว่างนี้ยังกดใช้งานได้จริงทุกอย่าง */
:root[data-gstut="on"] .screens {
  filter: contrast(1.25) saturate(1.4);
  animation: gl-freeze .26s steps(1, end);
}
:root[data-gstut="on"] .screen.on {
  clip-path: polygon(0 0, 100% 0, 100% 42%, 0 42%, 0 44%, 100% 44%, 100% 100%, 0 100%);
}
@keyframes gl-freeze {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-6px); }
  100% { transform: translateY(0); }
}

/* ตัวหนังสือที่กำลังเพี้ยนอยู่ */
[data-glx="1"] {
  color: var(--neon) !important;
  text-shadow: 2px 0 rgba(255,46,136,.8), -2px 0 rgba(39,224,245,.8);
  animation: gl-txt .16s steps(2, end) infinite;
}
@keyframes gl-txt {
  0%,100% { transform: translateX(0); }
  50%     { transform: translateX(-1.5px); }
}

/* ---------- เหรียญตราของธีมระดับลับ ---------- */
.bg-row.on.meta .bg-mark { background: linear-gradient(140deg,#3FA9FF,#0B2E63); }
.bg-row.on.glitch .bg-mark { background: linear-gradient(140deg,#27E0F5,#8A1046); }
.bg-row.meta .bg-nm.fancy {
  font-family: 'Orbitron', 'Space Mono', monospace;
  font-weight: 800; font-size: 14px; letter-spacing: .08em;
}
.bg-row.glitch .bg-nm.fancy {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-weight: 700; font-size: 15px; letter-spacing: .04em;
}
.bg-row.on.meta .bg-nm.fancy { color: #2C8BD8; }
.bg-row.on.glitch .bg-nm.fancy {
  background: linear-gradient(96deg, #E0197A, #17B6C9 55%, #7C3AED);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* ขอบไล่สีเลื่อน — ใช้กลไกเดียวกับเหรียญพิเศษอื่น (เจาะไส้กลางด้วย mask เหลือแค่กรอบ) */
.bg-row.on.meta, .bg-row.on.glitch { border-color: transparent; }
.bg-row.on.meta::before,
.bg-row.on.glitch::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: 2;
  pointer-events: none;
  border-radius: var(--r-card);
  padding: 2px;
  background-size: 200% 100%;
  animation: bd-slide 4.5s linear infinite;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
}
.bg-row.on.meta::before {
  background-image: linear-gradient(90deg, #3FA9FF, #0B2E63 25%, #9CD4FF 50%, #1E6FD9 75%, #3FA9FF);
  animation-duration: 5.5s;
}
.bg-row.on.glitch::before {
  background-image: linear-gradient(90deg, #27E0F5, #FF2E88 25%, #9DF3FF 50%, #7C3AED 75%, #27E0F5);
  animation-duration: 2.4s;   /* เร็วที่สุดในบรรดาเหรียญ — ให้เข้ากับคอนเซปต์สัญญาณเสีย */
}
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .bg-row.on.meta::before, .bg-row.on.glitch::before { display: none; }
  .bg-row.on.meta    { border-color: #3FA9FF; }
  .bg-row.on.glitch  { border-color: #27E0F5; }
}

/* ตัวอย่างสีของธีมคราฟบนแถวร้านค้า (ใช้ swatch เดิมของแต่ละธีม) */
.tb-sw.sw-deepocean, .tb-sw.sw-earth2, .tb-sw.sw-sweet { background-size: cover; }

@media (prefers-reduced-motion: reduce) {
  :root[data-gfx] .phone,
  :root[data-gfx="hard"] .mtile,
  :root[data-gfx="hard"] .rank-card,
  :root[data-gfx="hard"] .tabbar,
  :root[data-gfx="hard"] .page-title,
  :root[data-gstut="on"] .screens,
  [data-glx="1"] { animation: none; }
  :root[data-gstut="on"] .screen.on { clip-path: none; }
  .bg-row.on.meta::before, .bg-row.on.glitch::before { animation: none; }
}

/* ============================================================
   ALT 1A7V hotfix: การ์ดระดับลับแต่งตามธีม · เหรียญ Erorr 404 กระตุก
                    · ธีม Metaverse ทันสมัยขึ้น · ป้ายโชคเพิ่ม
   ============================================================ */

/* ---------- การ์ดของระดับลับ — หน้าตาเป็นแนวของธีมนั้นเอง ----------
   ระดับอื่นใช้ไล่สีตามระดับ แต่ระดับลับควรบอกได้ตั้งแต่แรกเห็นว่าเป็น "ของอีกโลกหนึ่ง" */
.gc-face.p-meta {
  background:
    repeating-linear-gradient(60deg, transparent 0 15px, rgba(120,200,255,.4) 15px 16px),
    repeating-linear-gradient(-60deg, transparent 0 15px, rgba(120,200,255,.4) 15px 16px),
    linear-gradient(165deg, #0E2A52, #050A16);
  box-shadow: inset 0 0 0 2px rgba(156,212,255,.85), 0 0 26px -2px rgba(63,169,255,.95);
  color: #DCF0FF;
  animation: p-meta-pulse 2.4s ease-in-out infinite;
}
.gc-face.p-meta .gc-rar,
.gc-face.p-meta b { text-shadow: 0 0 10px rgba(120,200,255,.9); }
@keyframes p-meta-pulse {
  0%,100% { box-shadow: inset 0 0 0 2px rgba(156,212,255,.85), 0 0 26px -2px rgba(63,169,255,.95); }
  50%     { box-shadow: inset 0 0 0 2px #DCF0FF, 0 0 40px 2px rgba(63,169,255,1); }
}

.gc-face.p-glitch {
  background:
    repeating-linear-gradient(180deg, rgba(255,255,255,.07) 0 1px, transparent 1px 4px),
    linear-gradient(90deg, rgba(255,46,136,.5) 0 8px, transparent 8px 100%),
    linear-gradient(165deg, #08313A, #04060A);
  background-size: auto, 100% 22px, auto;
  background-position: 0 0, 0 62%, 0 0;
  background-repeat: repeat, no-repeat, no-repeat;
  box-shadow: inset 0 0 0 2px rgba(39,224,245,.85), 0 0 26px -2px rgba(39,224,245,.9);
  color: #DFF7FF;
  animation: p-glitch-jump .5s steps(3, end) infinite;
}
.gc-face.p-glitch .gc-rar,
.gc-face.p-glitch b { text-shadow: 2px 0 rgba(255,46,136,.9), -2px 0 rgba(39,224,245,.9); }
@keyframes p-glitch-jump {
  0%, 60%, 100% { background-position: 0 0, 0 62%, 0 0; transform: none; }
  70%  { background-position: 0 0, 0 30%, 0 0; transform: translateX(-2px); }
  85%  { background-position: 0 0, 0 78%, 0 0; transform: translateX(2px); }
}

/* ---------- เหรียญ Erorr 404: กระตุกช็อคเป็นระยะ ----------
   ผูกกับ .on เท่านั้น — คนที่ยังไม่ปลดล็อกเห็นแค่แถวเปล่า ๆ กับ "— — —" เหมือนเดิม
   กระตุกสั้น ๆ ทุก 6 วิ ไม่ได้ขยับตลอดเวลา จะได้ไม่กวนตอนเลื่อนอ่านเหรียญอื่น */
.bg-row.on.glitch { animation: bg-shock 6s steps(2, end) infinite; }
.bg-row.on.glitch .bg-mark { animation: bg-shock-mark 6s steps(2, end) infinite; }
.bg-row.on.glitch .bg-nm.fancy { animation: bg-shock-txt 6s steps(2, end) infinite; }
@keyframes bg-shock {
  0%, 86%, 100% { transform: none; }
  88%  { transform: translateX(-5px) skewX(1.6deg); }
  91%  { transform: translateX(5px) skewX(-1.2deg); }
  94%  { transform: translateX(-2px); }
  97%  { transform: translateX(1px); }
}
@keyframes bg-shock-mark {
  0%, 86%, 100% { filter: none; }
  89%  { filter: hue-rotate(120deg) saturate(2); }
  95%  { filter: hue-rotate(-60deg); }
}
@keyframes bg-shock-txt {
  0%, 86%, 100% { opacity: 1; letter-spacing: .04em; }
  88%  { opacity: .55; letter-spacing: .14em; }
  92%  { opacity: 1; letter-spacing: 0; }
}

/* ---------- Metaverse: ทำให้แอปดู "ทันสมัย" ขึ้นทั้งชุด ----------
   ตัวอังกฤษกับตัวเลขของหัวข้อเปลี่ยนเป็น Orbitron (ฟอนต์แนวเทค)
   **Orbitron เป็นฟอนต์ละตินล้วน ไม่มีตัวไทย** ตัวไทยจึงตกไปใช้ Sarabun เหมือนเดิม
   กฎ "ตัวไทยต้องมีหัว" ยังอยู่ครบ ไม่ได้ถูกละเมิด */
:root[data-theme="meta"] .page-title,
:root[data-theme="meta"] .sh-title,
:root[data-theme="meta"] .big-title,
:root[data-theme="meta"] .mt-lb,
:root[data-theme="meta"] .eyebrow,
:root[data-theme="meta"] .sec-label,
:root[data-theme="meta"] .pe-tx b,
:root[data-theme="meta"] .fm-h {
  font-family: 'Orbitron', 'Sarabun', 'Leelawadee UI', sans-serif;
  letter-spacing: .01em;
}
/* มุมคมขึ้น = อ่านเป็นงานเทคมากกว่างานนุ่ม ๆ */
:root[data-theme="meta"] {
  --r-card: 12px;
  --r-tile: 9px;
}
/* เส้นนีออนบางบนขอบบนของการ์ด — รายละเอียดเล็ก ๆ ที่ทำให้ดูเป็นแผงข้อมูล */
:root[data-theme="meta"] .mtile,
:root[data-theme="meta"] .rank-card,
:root[data-theme="meta"] .pe,
:root[data-theme="meta"] .pf-list,
:root[data-theme="meta"] .tk-cta {
  position: relative;
  overflow: hidden;
}
:root[data-theme="meta"] .mtile::before,
:root[data-theme="meta"] .pe::before,
:root[data-theme="meta"] .tk-cta::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(95,208,255,.85), transparent);
}
/* ไอคอนบนแถบเมนูที่เลือกอยู่ มีแสงเรืองรอบตัว */
:root[data-theme="meta"] .tab.active .ic { filter: drop-shadow(0 0 6px rgba(63,169,255,.9)); }
/* จังหวะเปลี่ยนจอคมและเร็วกว่าธีมอื่น */
:root[data-theme="meta"] body[data-godir] .screen.on,
body[data-godir] :root[data-theme="meta"] .screen.on { animation-duration: .24s; }
:root[data-theme="meta"] .mtile,
:root[data-theme="meta"] .pe,
:root[data-theme="meta"] .tk-cta { transition: transform .1s cubic-bezier(.2,.9,.3,1), box-shadow .1s ease; }
:root[data-theme="meta"] .mtile:active { transform: scale(.965); box-shadow: 0 0 0 1px rgba(95,208,255,.7), var(--shadow-lg); }

/* ---------- ป้ายโชคเพิ่มบนตารางอัตรา ---------- */
.gc-luck {
  padding: 1px 8px 2px;
  border-radius: 999px;
  background: var(--pri-yellow);
  color: #33230A;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .03em;
}
.gc-odds.lucky .r-legendary,
.gc-odds.lucky .r-rare { text-shadow: 0 0 8px currentColor; }

@media (prefers-reduced-motion: reduce) {
  .gc-face.p-meta, .gc-face.p-glitch,
  .bg-row.on.glitch,
  .bg-row.on.glitch .bg-mark,
  .bg-row.on.glitch .bg-nm.fancy { animation: none; }
}

/* ============================================================
   60 / 30 / 10 — ระเบียบสีของธีมมืด (ALT 1A7W)
   ------------------------------------------------------------
   60%  --scr    #0B1120  พื้นจอ ไม่มีอะไรวางทับนอกจากการ์ด
   30%  --card   #18233C  การ์ด ไทล์ วิดเจ็ต แถบเมนู — ทุกกล่องบนจอใช้สีนี้
        --card2  #22304F  ชั้นในของกล่อง (ชิป ป้ายตัวเลข แถบพื้นหลังกราฟ)
   10%  --fill   #2E6BFF  เฉพาะของที่ "กดแล้วเกิดอะไรขึ้น" กับของที่ต้องเห็นก่อนเพื่อน

   ปัญหาเดิมไม่ใช่ว่าสีไม่สวย แต่คือทุกอย่างบนจอสำคัญเท่ากันหมด: การ์ด AI เป็นพื้นน้ำเงิน
   ไล่เฉด การ์ดโปรไฟล์เป็นพื้นน้ำเงินไล่เฉด วิดเจ็ตงานด่วนเป็นพื้นแดงเต็มใบ ไทล์สี่ใบสี่สี
   พอทุกอย่างตะโกน ก็ไม่มีอะไรถูกได้ยิน — บล็อกนี้ลดทุกกล่องลงมาเป็นชั้น 30% เท่ากันหมด
   แล้วคืนสีเน้นให้เฉพาะปุ่มกับตำแหน่งปัจจุบัน

   วิธีทำคือเปลี่ยนความหมายของสองโทเคนที่ทั้งแอปใช้ร่วมกันอยู่แล้ว ไม่ใช่ไล่แก้ทีละจอ:
     --grad-hero  = พื้นของ "กล่องใหญ่" → กลายเป็น --card (ชั้น 30%)
     --grad-brand = พื้นของ "ปุ่มหลัก"  → กลายเป็น --fill (ชั้น 10%)
   จอไหนที่ยังไม่ได้เขียนตอนนี้ ถ้าใช้สองโทเคนนี้ก็เข้าระเบียบเองอัตโนมัติ
   ธีมอีก 11 ตัวไม่ถูกแตะเลย เพราะทุกกฎในบล็อกนี้ล็อกด้วย [data-theme="dark"]
   ============================================================ */
:root[data-theme="dark"] {
  --grad-hero: var(--card);
  --grad-brand: var(--fill);
  /* กล่องพวกนี้ไม่ใช่สีแบรนด์แล้ว เงาเรืองสีน้ำเงินใต้กล่องจึงไม่มีที่มา */
  --shadow-brand: var(--shadow);
  --glow-scan: 0 8px 22px -6px rgba(46,107,255,.55);
}

/* ---------- กล่องใหญ่ที่เคยเป็นพื้นสีเน้น ----------
   พื้นเปลี่ยนเป็นสีการ์ดแล้ว ของข้างในที่เคยเป็น "สีขาวโปร่ง" ต้องเปลี่ยนตาม
   ไม่งั้นจะได้ชิปสีเทาจาง ๆ บนพื้นเข้ม ซึ่งจมหายไปทั้งอัน */
:root[data-theme="dark"] .mtile.hero,
:root[data-theme="dark"] .brief,
:root[data-theme="dark"] .pf-hero,
:root[data-theme="dark"] .st-hero,
:root[data-theme="dark"] .mtile.hero .mt-ic,
:root[data-theme="dark"] .brief-mark {
  background: var(--fill);
  border-color: transparent;
  color: var(--on-fill);
}
:root[data-theme="dark"] .brief-mark svg { color: var(--on-fill); }
:root[data-theme="dark"] .mtile.hero .mt-ct { background: var(--fill); color: var(--on-fill); }
/* ...ยกเว้นไทล์ครึ่งแถว ซึ่งพื้นเป็น --fill อยู่แล้ว กฎข้างบนจึงให้ไอคอนสีเดียวกับพื้นเป๊ะ
   = กล้องหายไปกับพื้นทั้งดวง กรอบต้องเข้มกว่าพื้น ไอคอนขาวถึงจะลอยขึ้นมา
   (กฎนี้ต้องอยู่หลังกฎข้างบน — น้ำหนักตัวเลือกเท่ากัน ตัวที่มาทีหลังจึงชนะ) */
:root[data-theme="dark"] .mtile.hero.half .mt-ic { background: rgba(0,0,0,.22); color: #fff; }
:root[data-theme="dark"] .mtile.hero.half .mt-go { color: var(--on-fill); opacity: .8; }
:root[data-theme="dark"] .mtile.hero .mt-go { color: var(--blue); opacity: .85; }
/* ปุ่มในการ์ด AI: เดิมเป็นพื้นขาวเต็มความกว้าง = ของที่สว่างที่สุดบนจอตารางงาน
   ทั้งที่มันเป็นทางเลือกเสริม ส่วนการ์ดงานจริงที่ต้องอ่านกลับหม่นกว่า
   ให้มันเป็นปุ่มสีเน้นขนาดปกติแทน สว่างพอให้เห็นว่ากดได้ แต่ไม่แย่งซีนงานจริง */
:root[data-theme="dark"] .brief-cta {
  background: var(--fill);
  color: var(--on-fill);
  box-shadow: none;
}

/* ---------- ลูกศร "ไปต่อ" บนไทล์ ----------
   เป็นของประกอบ ไม่ใช่ของที่ต้องอ่าน จึงเป็นสีกลาง ไม่ใช่สีเน้น */
:root[data-theme="dark"] .mtile:not(.hero) .mt-go { color: var(--muted); opacity: .7; }

/* ---------- กราฟ 7 วันในแท็บ "ฉัน" ----------
   แท่งที่มีค่ากับแท่งที่เป็นศูนย์เคยใช้สีเดียวกัน (--card2) ต่างกันแค่ความสูง
   บนพื้นการ์ดสีใกล้กันจึงมองไม่ออกว่าวันไหนทำงานเสร็จบ้าง — ตอนนี้แท่งที่มีค่าเป็นสีเน้น */
.st-bar .bar { background: var(--card2); }
.st-bar.has .bar { background: var(--fill); }
.st-bar.now .d { color: var(--blue); }

/* ---------- ระยะปลอดภัยเหนือแถบเมนู ----------
   ปุ่มสแกนกลม ๆ ลอยขึ้นเหนือแถบ 34px แต่ padding ล่างของทุกจอเผื่อไว้แค่ความสูงแถบ
   ปุ่มสุดท้ายของหน้า (เช่น "ดูงานที่เหลืออีก 2 งาน") จึงถูกปุ่มสแกนทับจนกดไม่ได้ */
/* 1B98 · 100 ไม่ใช่ 118 — ตัวเลข 118 อิงกับปุ่มกลมที่โผล่พ้นแถบ 22px
   ตอนนี้มันโผล่ 13px และตัวแถบเองเตี้ยลง 6px ระยะเผื่อจึงต้องลดตาม
   ไม่งั้นที่ประหยัดได้จากแถบจะกลายเป็นที่ว่างเปล่าท้ายหน้าแทน ซึ่งไม่ได้อะไรคืนเลย */
.home-body, .scr-body { padding-bottom: calc(100px + var(--tabgap)); }
/* หน้าแรกเผื่อน้อยกว่าจอ์อื่น 20px — วัดจากของจริง: ปุ่มสแกนเริ่มที่ 756px จากขอบบน
   เผื่อ 88 + 5 = 93 ทำให้เนื้อหาจบที่ 751 ซึ่งพ้นปุ่มสแกนพอดีโดยไม่เหลือที่ว่างเปล่า
   20px ที่ประหยัดได้คือส่วนหนึ่งของ 72px ที่ทำให้หน้าแรกล้นจอ */
.menu-body { padding-bottom: calc(88px + var(--tabgap)); }

/* ---------- ระยะปลอดภัยใต้แถบบน ----------
   ป้ายเลขรุ่นกับปุ่มเพื่อนลอยอยู่เหนือทุกจอ จอที่ขึ้นต้นด้วยการ์ดเต็มความกว้าง
   (แท็บ "ฉัน") จึงมีของมาทับหัวการ์ดพอดี จอที่ขึ้นต้นด้วยหัวข้อไม่เป็น เพราะบรรทัด
   วันที่ตัวเล็กรับแรงชนไว้ให้อยู่แล้ว */
/* 1B95 · 42px นั้นเคยเป็นที่ว่างที่กันไว้ให้ปุ่มเฟืองลอยมุมขวาบนโดยเฉพาะ
   เฟืองย้ายเข้าไปอยู่ในหัวโปรไฟล์แล้ว ที่ว่างก้อนนี้จึงไม่มีอะไรมาอยู่อีก —
   ถ้าไม่ถอดออก หน้าจะเปิดมาด้วยช่องว่างเปล่าสูงเท่านิ้วหัวแม่มือ
   เหลือ 6px ไว้พอไม่ให้แถว @ชื่อผู้ใช้ชนขอบบนของพื้นที่เลื่อน */
.pf-body { padding-top: 6px; }

/* ก้อนที่ไม่มีเนื้อในต้องไม่กินระยะห่าง — #pfPriv ว่างตั้งแต่ 1B95 (ตัวเลขย้ายไปรวมกับกราฟ)
   ส่วน #showBox ว่างได้ตามสถานะของผู้ใช้ · <div> เปล่าที่ยังมี margin
   คือช่องว่างลึกลับกลางหน้าที่หาต้นตอไม่เจอ */
#pfPriv:empty, #showBox:empty { display: none; }

/* ---------- การ์ดงานในตารางงาน ----------
   หนึ่งใบเคยพูดว่า "ด่วน" สามครั้ง: เลขลำดับพื้นแดง ป้ายคำว่าด่วนมากพื้นแดง
   และเวลาส่งตัวหนังสือแดง พอวางเรียงสามใบ ทั้งหน้าจึงเป็นสีเตือน
   เก็บสีไว้ที่ป้ายคำอย่างเดียว เพราะมันคือที่เดียวที่บอก "ระดับ" ได้จริง
   เลขลำดับกลับไปเป็นตัวเลขเฉย ๆ — มันบอกแค่ลำดับ ไม่ได้บอกความด่วน */
:root[data-theme="dark"] .rank.red,
:root[data-theme="dark"] .rank.yellow,
:root[data-theme="dark"] .rank.green {
  background: var(--card2);
  color: var(--ink);
}
/* ใบแรกยังต้องต่างจากใบอื่น — ใช้สีเน้น ไม่ใช่สีเตือน เพราะมันแปลว่า "เริ่มที่นี่" */
:root[data-theme="dark"] .rank.first { background: var(--fill); color: var(--on-fill); }

/* ปุ่มของการ์ด AI ไม่ต้องเต็มความกว้าง — ปุ่มเต็มแถบอ่านเป็น "ปุ่มหลักของทั้งหน้า"
   ทั้งที่หน้านี้มีหน้าที่หลักคือให้กดการ์ดงาน ไม่ใช่กดวางแผน */
:root[data-theme="dark"] .brief-cta { width: auto; padding: 0 18px; }

/* ---------- การ์ดโปรไฟล์ ----------
   วงกลมตกแต่งสองวงเคยเป็นสีขาวโปร่งบนพื้นน้ำเงินเข้ม พอพื้นเป็นสีการ์ดแล้ว
   มันกลายเป็นก้อนเทาใหญ่กลางการ์ด ดูเหมือนภาพโหลดไม่ขึ้นมากกว่าลายตกแต่ง */
:root[data-theme="dark"] .pf-hero .b1 { background: rgba(255,255,255,.035); }
:root[data-theme="dark"] .pf-hero .b2 { background: rgba(255,255,255,.025); }
:root[data-theme="dark"] .pf-av { background: var(--fill); color: var(--on-fill); }
/* วงแสงมุมบนขวาของไทล์เด่น — พื้นไม่ใช่สีเน้นแล้ว แสงสีขาวจึงไม่มีที่มาเหมือนกัน */
:root[data-theme="dark"] .mtile.hero::after { background: none; }

/* ปุ่มเพื่อนมุมขวาบนหลบให้ปุ่มย้อนกลับของจอชั้นใน (ดู TABBED_SCREENS ใน app.js) */
body.deep-scr .top-friends { display: none; }

/* ชิปไอคอนของทางเข้าหลักในจอ "เพิ่มงานใหม่" ใช้กฎเดียวกับไทล์หน้าแรก — พื้นทึบ
   (ชิปในลิสต์ยาว ๆ เช่นแถวตั้งค่า ยังเป็นพื้นจางเหมือนเดิม ไม่งั้นสีเน้นจะเกินโควตา
   ทันทีที่ลิสต์ยาวขึ้น — กฎคือ "ทางเข้า" ได้พื้นทึบ ส่วน "รายการ" ไม่ได้) */
:root[data-theme="dark"] .scan-tile .tile { background: var(--fill); color: var(--on-fill); }

/* ============================================================
   จอ "บริบทของฉัน"
   ------------------------------------------------------------
   ลำดับบนจอตั้งใจกลับหัวกับฟอร์มทั่วไป: ผลลัพธ์อยู่บนสุด ฟอร์มอยู่ล่าง
   เพราะสิ่งที่ต้องขายให้ผู้ใช้เชื่อคือ "กรอกแล้วได้อะไร" ไม่ใช่ "กรอกยังไง"
   แก้เวลาไหนก็ตาม การ์ดบนสุดขยับให้เห็นทันทีในจังหวะเดียวกัน
   ============================================================ */
.ctx-sum {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  padding: 15px 16px 14px;
  margin-bottom: 4px;
}
.ctx-sum-h {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted);
}
.ctx-sum-h svg {
  box-sizing: content-box;
  width: 13px; height: 13px; padding: 5px;
  border-radius: 7px; background: var(--fill); color: var(--on-fill);
}
.ctx-sum-v { margin-top: 9px; font-size: 27px; font-weight: 700; letter-spacing: -.03em; }
.ctx-slots { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ctx-slot {
  padding: 5px 10px; border-radius: 999px;
  background: var(--card2); color: var(--ink);
  font-size: 11.5px; font-weight: 700;
}
.ctx-none { font-size: 12px; color: var(--muted); }
.ctx-sum-p { margin-top: 11px; font-size: 11px; line-height: 1.7; color: var(--faint); }

.ctx-list { display: flex; flex-direction: column; gap: 7px; }
.ctx-item {
  display: flex; align-items: center; gap: 11px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-tile); padding: 10px 11px;
}
.ctx-ic {
  width: 32px; height: 32px; flex: none; border-radius: 10px;
  background: var(--card2); color: var(--blue);
  display: flex; align-items: center; justify-content: center;
}
.ctx-ic svg { width: 16px; height: 16px; }
.ctx-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ctx-bd b { font-size: 13.5px; font-weight: 600; letter-spacing: -.015em; }
.ctx-bd i { font-size: 11px; font-style: normal; color: var(--muted); }
.ctx-del {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  border: none; background: transparent; color: var(--faint); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ctx-del svg { width: 15px; height: 15px; }
.ctx-del:active { color: var(--alert); background: var(--alert-soft); }
.ctx-empty { font-size: 11.5px; line-height: 1.7; color: var(--faint); padding: 2px 2px 4px; }

/* ---- ตารางเรียนพับเป็นวันละแถว ----
   ของเดิมเรียงคาบทั้งสัปดาห์ตามเวลาในรายการเดียว จันทร์กับศุกร์เลยนอนติดกัน
   ต่างกันแค่ "จ." กับ "ศ." ตัวจิ๋วข้างเวลา — สามสิบห้าแถวที่ตอบไม่ได้ว่าวันไหนเรียนอะไร */
.ctx-week { display: flex; flex-direction: column; gap: 7px; }
.ctx-weeksum { margin: 0 2px 1px; font-size: 11px; color: var(--faint); }
.ctx-dayblk {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-tile); overflow: hidden;
}
.ctx-dayblk.on { border-color: var(--fill); }
.ctx-dayh {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  border: none; background: transparent; padding: 11px 11px 9px;
  font-family: inherit; text-align: left; cursor: pointer; color: var(--ink);
}
.ctx-dayh b { flex: 1; font-size: 13.5px; font-weight: 600; letter-spacing: -.015em; color: var(--ink); }
.ctx-dayh i { font-style: normal; font-size: 11px; color: var(--muted); }
.ctx-dayh u { text-decoration: none; font-size: 11px; color: var(--faint); white-space: nowrap; }
.ctx-dayx { flex: none; align-self: center; display: flex; color: var(--faint); }
.ctx-dayx svg { width: 15px; height: 15px; transform: rotate(90deg); transition: transform .18s ease; }
.ctx-dayblk.on .ctx-dayx svg { transform: rotate(-90deg); }
/* พับอยู่ = ชื่อวิชาเรียงเดียว บอกว่าวันนั้นหน้าตายังไงโดยไม่ต้องกาง */
.ctx-daysum { margin: 0; padding: 2px 11px 8px; line-height: 1.5; }
/* ชิปชื่อวิชา — ใช้ทั้งในสรุปวันที่พับอยู่และในก้อนคาบเรียนของเส้นเวลา
   สีมาจากชื่อวิชา วิชาเดียวกันจึงเป็นสีเดียวกันทุกจอ */
.ctx-chip {
  display: inline-block; margin: 0 4px 4px 0; padding: 3px 8px; border-radius: 6px;
  background: var(--sj); color: var(--sj-on); font-size: 11px; font-weight: 600;
}
.ctx-pers { border-top: 1px solid var(--line); padding: 3px 5px 5px 11px; }
.ctx-per { display: flex; align-items: center; gap: 10px; min-height: 38px; }
.ctx-per + .ctx-per { border-top: 1px solid var(--line); }
.ctx-per i { flex: none; font-style: normal; font-size: 11px; color: var(--muted); }
/* เลขคาบ — ตารางเรียนที่โรงเรียนแจกนับคาบเสมอ คนจึงพูดกันว่า "คาบ 5" ไม่ใช่ "13:00" */
.ctx-per-n {
  flex: none; width: 20px; height: 20px; border-radius: 6px;
  background: var(--sj); color: var(--sj-on);
  font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.ctx-per b { flex: 1; min-width: 0; font-size: 13px; font-weight: 500; letter-spacing: -.01em; }
/* คาบที่เรียนหลายวันเป็นรายการเดียว ลบทีเดียวหายทุกวัน — ป้ายนี้คือคำเตือนก่อนกดถังขยะ */
.ctx-per u {
  flex: none; text-decoration: none; font-size: 10px; color: var(--faint);
  background: var(--card2); border-radius: 999px; padding: 3px 7px;
}
.ctx-per .ctx-del { width: 30px; height: 30px; }

.ctx-add {
  min-height: 42px; border-radius: var(--r-tile);
  border: 1.5px dashed var(--line); background: transparent;
  color: var(--blue); font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.ctx-add:active { transform: scale(.99); background: var(--card2); }

.ctx-form {
  display: flex; flex-direction: column; gap: 9px;
  background: var(--card2); border-radius: var(--r-tile); padding: 12px;
}
.ctx-form input[type=text] {
  width: 100%; min-height: 42px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--ink);
  font-family: inherit; font-size: 14px;
}
/* ปุ่มวันเรียงเจ็ดช่องเท่ากัน — แตะพลาดวันข้าง ๆ แล้วตารางทั้งสัปดาห์เพี้ยน
   จึงต้องกว้างพอและมีระยะห่างจริง ไม่ใช่ตัวหนังสือเจ็ดตัวชิดกัน */
.ctx-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.ctx-day {
  min-height: 38px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--muted); font-family: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.ctx-day.on { background: var(--fill); color: var(--on-fill); border-color: transparent; }
.ctx-kinds { display: flex; flex-wrap: wrap; gap: 5px; }
.ctx-kind {
  padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--muted); font-family: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.ctx-kind.on { background: var(--fill); color: var(--on-fill); border-color: transparent; }
.ctx-times { display: flex; align-items: center; gap: 9px; }
.ctx-times input[type=time] {
  flex: 1; min-height: 42px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--ink);
  font-family: 'Space Mono', ui-monospace, monospace; font-size: 14px;
}
.ctx-times span { font-size: 12px; color: var(--muted); }
.ctx-form-act { display: flex; gap: 8px; }
.ctx-form-act .btn { flex: 1; }
.ctx-err { font-size: 11.5px; color: var(--alert); }
.ctx-err[hidden] { display: none; }

.ctx-wipe {
  margin-top: 18px; min-height: 44px; width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--line); border-radius: var(--r-tile);
  background: transparent; color: var(--alert);
  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.ctx-wipe svg { width: 15px; height: 15px; }
.ctx-wipe:active { background: var(--alert-soft); }
.ctx-note { margin: 10px 2px 0; font-size: 11px; line-height: 1.75; color: var(--faint); }

/* ช่องเวลาในแถวตั้งค่า — ของเดิมกว้าง 80px ซึ่งพอดีเป๊ะกับ "06:00" แบบ 24 ชั่วโมง
   แต่เครื่องที่ตั้งภาษาอังกฤษเรนเดอร์เป็น "06:00 AM" พร้อมไอคอนนาฬิกา แล้วตัวเลขโดนตัด
   รูปแบบเวลาเป็นของระบบ บังคับไม่ได้ จึงต้องเผื่อความกว้างไว้ให้พอทั้งสองแบบ */
.pf-row input[type=time] { width: 132px; text-align: left; padding: 0 8px; }

/* ตัวเลขสรุปเวลาว่าง — เป็นตัวไทยปนตัวเลข ใช้ Space Mono ทั้งก้อนไม่ได้
   (ตัวไทยในฟอนต์ mono จะกลายเป็นแบบไม่มีหัวและถ่างจนอ่านยาก — กฎข้อ 9 ของโปรเจกต์)
   เอาเฉพาะคุณสมบัติที่ต้องการจริงคือความกว้างตัวเลขเท่ากันทุกตัว */
.ctx-sum-v { font-family: inherit; font-variant-numeric: tabular-nums; }

/* ---------- ALT 1A7V: ปุ่มอ่านให้แม่นขึ้นด้วยเซิร์ฟเวอร์ ----------
   จงใจให้ดูเป็น "ทางเลือกที่สอง" ไม่ใช่ปุ่มหลัก — พื้นจาง ขอบบาง ไม่มีสีเน้น
   เพราะการอ่านในเครื่องต้องเป็นค่าเริ่มต้นที่คนใช้ก่อนเสมอ */
.cloud-ocr {
  margin: 14px 2px 0; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--r-tile);
  background: var(--card-soft, transparent);
}
.cloud-ocr[hidden] { display: none; }
.cloud-ocr .co-h { margin: 0; font-size: 13.5px; font-weight: 700; }
.cloud-ocr .co-s { margin: 4px 0 0; font-size: 12px; line-height: 1.7; color: var(--muted); }
.cloud-ocr .co-btn {
  margin-top: 11px; min-height: 44px; width: 100%;
  border: 1px solid var(--line); border-radius: var(--r-tile);
  background: transparent; color: inherit;
  font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
}
.cloud-ocr .co-btn:active:not(:disabled) { background: var(--alert-soft, rgba(0,0,0,.05)); }
.cloud-ocr .co-btn:disabled { opacity: .45; cursor: default; }
.cloud-ocr .co-why { margin: 8px 0 0; font-size: 11.5px; color: var(--alert); }
.cloud-ocr .co-why[hidden] { display: none; }
/* คำเตือนเรื่องรูปออกจากเครื่อง — ต้องอ่านออกเสมอ ห้ามจางจนมองข้าม
   ผู้ใช้ตัดสินใจเรื่องความเป็นส่วนตัวจากบรรทัดนี้บรรทัดเดียว */
.cloud-ocr .co-warn { margin: 9px 0 0; font-size: 11px; line-height: 1.7; color: var(--muted); }

/* ══════════════════════════════════════════════════════════════════
   จอ "งานทั้งหมด" — การ์ดงาน · ชิปสถานะ · แถบเลือกวัน
   ------------------------------------------------------------------
   60 พื้นจอ (--scr) · 30 การ์ด (--card) · 10 ฟ้า (--fill) เฉพาะของที่กดได้
   สีความหมาย (แดง/ส้ม/เขียว) อยู่ในชิปกลมเล็กเท่านั้น ห้ามกินพื้นที่ใหญ่
   ══════════════════════════════════════════════════════════════════ */

/* ---- แถบเลือกวัน ---- */
.daystrip {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 5px; margin: 0 0 14px;
}
.ds {
  border: none; background: var(--card); border-radius: 12px;
  padding: 8px 2px 7px; font-family: inherit; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  transition: background .16s ease;
}
.ds .ds-d { font-style: normal; font-size: 10.5px; color: var(--muted); }
.ds .ds-n { font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -.01em; }
.ds .ds-dot { height: 4px; width: 4px; border-radius: 999px; background: var(--muted); margin-top: 1px; }
.ds .ds-dot.hot  { background: var(--alert); }
.ds .ds-dot.warm { background: var(--warn); }
.ds .ds-dot.off  { background: transparent; }
.ds:active { transform: scale(.96); }
/* วันที่เลือกอยู่ = ของที่กดได้และกำลังทำงาน จึงได้สีเน้นก้อนเดียวของแถบนี้ */
.ds.on { background: var(--fill); }
/* 1C40 · ตัวหนังสือบนช่องวันที่เลือกใช้คู่สีของธีม (--on-fill) ไม่ใช่ขาวตายตัว
   ธีมที่สีเน้นสว่าง (เวทมนตร์ ทอง · กาแล็กซี · อวกาศ · Metaverse · Astral Black เงิน)
   ได้ขาวบนพื้นสว่าง วัดได้ 1.2:1 = มองไม่เห็นวันที่เลือกอยู่เลย */
.ds.on .ds-d { color: color-mix(in srgb, var(--on-fill) 72%, transparent); }
.ds.on .ds-n { color: var(--on-fill); }
.ds.on .ds-dot { background: color-mix(in srgb, var(--on-fill) 90%, transparent); }

/* ---- การ์ดงาน ---- */
.tk {
  position: relative; background: var(--card); border-radius: 14px;
  padding: 14px 46px 14px 15px; margin-bottom: 9px; cursor: pointer;
  transition: transform .14s ease;
}
.tk:active { transform: scale(.99); }
/* แถบฟ้าได้ใบเดียว — ใบที่ควรลงมือ ให้ทุกใบมีก็เท่ากับไม่มีใบไหนมี */
.tk-focus { border-left: 3px solid var(--fill); padding-left: 12px; }

.tk-sub { font-size: 11px; color: var(--muted); margin-bottom: 5px; }
.tk-ttl {
  font-size: 15px; font-weight: 600; line-height: 1.45;
  letter-spacing: -.01em; color: var(--ink);
}
.tk-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.tk-sp { flex: 1; }
.tk-min { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ชิปสถานะ — กลมเล็ก พื้นจาง ตัวอักษรสีเดียวกับความหมาย */
.tk-chip {
  font-size: 11px; line-height: 1.5; padding: 4px 9px; border-radius: 999px;
  background: var(--card2); color: var(--muted); white-space: nowrap;
}
.tk-chip.hot  { background: var(--alert-soft); color: var(--alert); }
.tk-chip.warm { background: var(--warn-soft);  color: var(--warn); }
.tk-chip.ok   { background: var(--good-soft);  color: var(--good); }

/* ปุ่มติ๊กเสร็จ — มุมขวาบน ไม่แทรกกลางกองข้อความ
   เอาไว้ซ้ายแบบ to-do list ทั่วไปไม่ได้ เพราะจะดันชื่องานเข้าไปข้างในจนอ่านยาก */
.tk-tick {
  position: absolute; top: 12px; right: 12px;
  width: 24px; height: 24px; border-radius: 50%;
  border: 1.5px solid var(--line); background: transparent;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; transition: all .16s ease;
}
.tk-tick svg { width: 13px; height: 13px; color: transparent; }
.tk-tick:active { transform: scale(.9); }
.tk-tick.on { border-color: transparent; background: var(--good-soft); }
.tk-tick.on svg { color: var(--good); }

/* งานที่เสร็จแล้ว = บันทึก ไม่ใช่สิ่งที่ต้องตัดสินใจ จึงจมลงไปกับพื้น */
.tk-done { display: flex; align-items: center; gap: 12px; padding: 12px 12px 12px 15px; opacity: .6; }
.tk-done .tk-tick { position: static; flex: none; }
.tk-done .tk-bd { flex: 1; min-width: 0; }
.tk-done .tk-sub { margin-bottom: 2px; }
.tk-done .tk-ttl { font-size: 14px; }
.tk-done .tk-go { width: 15px; height: 15px; color: var(--faint); flex: none; }

/* ปุ่มล้างตัวกรองวัน — โผล่เฉพาะตอนกรองอยู่ เพื่อให้แถบวันไม่ต้องเสียช่องให้ปุ่ม "ทุกวัน" */
.dayclear {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: var(--fill-soft, var(--card2)); border: none; border-radius: 12px;
  padding: 10px 12px; margin: -4px 0 14px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; color: var(--ink); text-align: left;
}
.dayclear span { margin-left: auto; color: var(--muted); font-size: 11.5px; }
.dayclear svg { width: 14px; height: 14px; color: var(--muted); flex: none; }
.dayclear:active { transform: scale(.99); }

/* ══════════════════════════════════════════════════════════════════
   เส้นเวลา: ตื่นจนหลับ
   เส้นแนวตั้งเส้นเดียว คอลัมน์เวลากว้างคงที่ จุดตรงกันทุกแถว
   ของเดิมแต่ละแถวโครงสร้างต่างกัน คอลัมน์เวลาเลยขยับขึ้นลงตามความสูงของแถว
   ตาต้องไล่หาใหม่ทุกบรรทัด ซึ่งเป็นสาเหตุหลักที่มันอ่านยาก
   ══════════════════════════════════════════════════════════════════ */
.dayrail { position: relative; padding-left: 68px; margin-top: 4px; }
.dayrail::before {
  content: ''; position: absolute; left: 50px; top: 8px; bottom: 8px;
  width: 1px; background: var(--line);
}
.dayrow { position: relative; margin-bottom: 18px; min-height: 20px; cursor: pointer; }
.dayrow:last-child { margin-bottom: 0; }
.dayrow-t {
  position: absolute; left: -68px; top: 0; width: 38px; text-align: right;
  font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.dayrow-dot {
  position: absolute; left: -19px; top: 6px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--card2);
}
/* จุดสีเน้นมีจุดเดียวทั้งเส้น = งานถัดไปที่ต้องลงมือ */
.dayrow-dot.on { left: -20px; top: 20px; width: 9px; height: 9px; background: var(--fill); }
.dayrow-dot.flag { background: var(--alert); }
.dayrow-l { font-size: 13px; color: var(--muted); }
.dayrow-l i { font-style: normal; margin-left: 8px; color: var(--faint); font-size: 11.5px; }
/* ธุระที่กินเวลาจริงเข้มกว่าหมุดบอกช่วงวัน — เส้นที่ทุกแถวสีเดียวกันคือเส้นที่ตาไม่รู้จะเกาะตรงไหน */
.dayrow-l.solid { color: var(--ink); font-weight: 500; }

/* ---- ก้อนคาบเรียนที่ยุบรวม ----
   หนึ่งก้อน = ครึ่งวันที่ติดเรียน แทนแถวเทาแปดแถวที่หน้าตาเหมือนกันหมด
   รายคาบไม่ได้หายไป — อยู่ในแผ่นรายละเอียดที่กดแล้วขึ้น */
.dayblk { background: var(--card); border-radius: 12px; padding: 10px 12px; }
.dayblk-h { display: flex; align-items: baseline; gap: 8px; }
.dayblk-h b { flex: 1; font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; color: var(--ink); }
.dayblk-h span { flex: none; font-size: 11px; color: var(--muted); }
/* ชื่อวิชาเป็นบริบท ไม่ใช่ของที่ต้องอ่านครบ — สองบรรทัดพอ ที่เหลือรอตอนกด */
.dayblk-p {
  margin: 7px 0 -4px; line-height: 1.5;
  max-height: 48px; overflow: hidden;
}

/* ---- สลับ รายวัน / ทั้งสัปดาห์ ---- */
/* จำนวนช่องต้องตามจำนวนปุ่มเอง — ตอนเพิ่มโหมดที่สามเข้ามา ค่าเดิมที่ตรึงไว้ 2 ช่อง
   ทำให้ปุ่มที่สามตกไปห้อยบรรทัดล่างเป็นแท่งยาวเต็มความกว้าง */
.tlmode {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px;
  background: var(--card); border-radius: 12px; padding: 3px; margin: 0 0 12px;
}
.tlm {
  border: none; background: transparent; border-radius: 9px; padding: 8px 4px;
  font-family: inherit; font-size: 12.5px; font-weight: 600; color: var(--muted); cursor: pointer;
  transition: background .16s ease, color .16s ease;
}
.tlm.on { background: var(--fill); color: var(--on-fill); }

/* ══════════════════════════════════════════════════════════════════
   แผนราคา (ยังไม่เปิดขาย)
   ------------------------------------------------------------------
   การ์ดสองใบเลือกได้จริง เพราะรายการของแต่ละแผนเปลี่ยนตามที่เลือก —
   ถ้าโชว์รายการรวมของทั้งสองแผนไว้ก้อนเดียว คนอ่านจะไม่รู้ว่าจ่าย 49 ได้อะไรบ้าง
   ══════════════════════════════════════════════════════════════════ */
.pro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-top: 6px; }
.pro-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 13px; text-align: left; cursor: pointer;
  font-family: inherit; color: var(--ink);
  transition: border-color .16s ease, background .16s ease;
}
/* ใบที่เลือกได้ขอบสีเน้น 2px — เป็นข้อยกเว้นเดียวของกฎเส้น 1px ในไฟล์นี้
   เพราะมันคือสถานะ "เลือกอยู่" ที่ต้องเห็นจากระยะกวาดตา ไม่ใช่ตอนจ้อง */
.pro-card.on { border: 2px solid var(--blue); background: var(--blue-soft); padding: 11px 12px; }
.pro-top { display: flex; align-items: center; gap: 6px; width: 100%; }
.pro-name {
  font-size: var(--fs-meta); font-weight: 700; letter-spacing: .04em;
  background: var(--card2); color: var(--muted); border-radius: 999px; padding: 3px 9px;
}
.pro-card.on .pro-name { background: var(--fill); color: var(--on-fill); }
.pro-tag {
  margin-left: auto; font-size: 10.5px; font-weight: 700;
  background: var(--good); color: #04180C; border-radius: 999px; padding: 3px 8px;
}
.pro-price { display: flex; align-items: baseline; gap: 4px; }
.pro-price b { font-size: 23px; font-weight: 700; letter-spacing: -.03em; }
.pro-price i { font-style: normal; font-size: var(--fs-meta); color: var(--muted); }
.pro-line { font-size: var(--fs-meta); line-height: 1.45; color: var(--muted); }

.pro-feats { display: flex; flex-direction: column; gap: 2px; margin-top: 14px; }
.pro-f {
  display: flex; align-items: flex-start; gap: 9px; padding: 10px 0;
  border-top: 1px solid var(--line); font-size: var(--fs-body); line-height: 1.5;
}
.pro-f:first-child { border-top: none; }
.pro-f svg { width: 15px; height: 15px; flex: none; margin-top: 3px; color: var(--good); }

.pro-cta {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: 50px; margin-top: 16px;
  border: none; border-radius: 14px; background: var(--fill); color: var(--on-fill);
  font-family: inherit; font-size: var(--fs-body); font-weight: 700; cursor: pointer;
}
.pro-cta svg { width: 17px; height: 17px; }
.pro-cta:active { transform: scale(.98); }
.pro-cta.done { background: var(--card2); color: var(--muted); }
.pro-note { margin: 12px 0 0; font-size: var(--fs-meta); line-height: 1.7; color: var(--muted); }
.pro-note b { color: var(--ink); }

/* ══════════════════════════════════════════════════════════════════
   ถามน้องไซ
   ------------------------------------------------------------------
   จอนี้มีแชทจริงแล้ว แต่ยังคงสองรายการท้ายจอไว้ — ทำอะไรให้ และจะไม่ทำอะไร
   สองรายการหนักเท่ากัน ไม่ใช่รายการดี ๆ ยาว ๆ แล้วต่อท้ายด้วยตัวหนังสือจาง
   ══════════════════════════════════════════════════════════════════ */

/* แถบบอกว่าน้องไซเห็นอะไร — กดได้ ไม่ใช่ข้อความประดับ
   คำสัญญาเรื่องข้อมูลที่ตรวจสอบไม่ได้ ก็ไม่ต่างจากไม่ได้สัญญา
   ปุ่มนี้เปิดข้อความก้อนจริงที่ถูกส่งขึ้นเซิร์ฟเวอร์ ให้เทียบกับที่เขียนไว้ได้เอง */
.ai-priv {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: var(--blue-soft); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 12px; margin-top: 4px; cursor: pointer;
  font-family: inherit; color: var(--ink);
}
.ai-priv-ic { display: flex; color: var(--blue); flex: none; }
.ai-priv-ic svg { width: 15px; height: 15px; }
.ai-priv-tx { flex: 1; min-width: 0; font-size: var(--fs-meta); line-height: 1.45; }
.ai-priv-go { flex: none; font-size: var(--fs-meta); font-weight: 700; color: var(--blue); }

.ai-thread { display: flex; flex-direction: column; gap: 9px; margin-top: 12px; }
.ai-thread.empty {
  align-items: flex-start; gap: 3px;
  background: var(--card); border: 1px dashed var(--line); border-radius: 14px; padding: 14px 15px;
}
.ai-thread.empty b { font-size: var(--fs-body); font-weight: 700; }
.ai-thread.empty p { margin: 0; font-size: var(--fs-meta); line-height: 1.6; color: var(--muted); }

.ai-msg { display: flex; gap: 8px; align-items: flex-end; }
.ai-msg.me { justify-content: flex-end; }
.ai-av {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--fill); color: var(--on-fill);
  display: grid; place-items: center; margin-bottom: 2px;
}
.ai-av svg { width: 14px; height: 14px; }
.ai-bub {
  max-width: 84%; padding: 9px 12px; font-size: var(--fs-body); line-height: 1.6;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.ai-msg.me .ai-bub {
  background: var(--fill); color: var(--on-fill); border-radius: 14px 14px 4px 14px;
}
.ai-msg.sai .ai-bub {
  background: var(--card2); border: 1px solid var(--line); border-radius: 14px 14px 14px 4px;
}
/* ข้อความที่เป็นความผิดพลาดต้องหน้าตาไม่เหมือนคำตอบ ไม่งั้นผู้ใช้จะอ่านว่าน้องไซพูดอย่างนั้นจริง */
.ai-msg.sai .ai-bub.err {
  background: var(--pri-red-soft); border-color: transparent; color: var(--pri-red-text);
}
.ai-typing { display: flex; gap: 5px; align-items: center; }
.ai-typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); animation: ai-blink 1.1s infinite; }
.ai-typing i:nth-child(2) { animation-delay: .18s; }
.ai-typing i:nth-child(3) { animation-delay: .36s; }
@keyframes ai-blink { 0%, 60%, 100% { opacity: .28; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ai-typing i { animation: none; opacity: .6; } }

/* คำถามสำเร็จรูป — ขึ้นเฉพาะตอนยังไม่เคยคุย
   ช่องพิมพ์เปล่าบนจอเปล่าคือจุดที่คนส่วนใหญ่ปิดทิ้ง เพราะไม่รู้ว่าถามอะไรได้ */
.ai-seeds { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.ai-seeds button {
  border: 1px solid var(--blue); background: transparent; color: var(--blue);
  border-radius: 999px; padding: 7px 12px; min-height: 34px;
  font-family: inherit; font-size: var(--fs-meta); font-weight: 600; cursor: pointer;
}
.ai-seeds button:active { transform: scale(.97); }

.ai-bar { display: flex; align-items: flex-end; gap: 8px; margin-top: 11px; }
.ai-in {
  flex: 1; min-height: 44px; max-height: 140px; resize: none;
  background: var(--card2); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 13px; font-family: inherit; font-size: var(--fs-body); line-height: 1.5;
  color: var(--ink);
}
.ai-in:focus { outline: 2px solid var(--blue); outline-offset: -2px; }
.ai-in:disabled { opacity: .55; }
.ai-send {
  flex: none; width: 44px; height: 44px; border-radius: 50%; border: none;
  background: var(--fill); color: var(--on-fill);
  display: grid; place-items: center; cursor: pointer;
}
.ai-send svg { width: 18px; height: 18px; transform: rotate(-90deg); }
.ai-send:disabled { opacity: .5; }
.ai-send:active { transform: scale(.94); }
.ai-foot { margin: 9px 0 0; font-size: var(--fs-meta); line-height: 1.6; color: var(--muted); text-align: center; }
.ai-wipe {
  border: none; background: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: inherit; color: var(--blue); font-weight: 600;
}
.ai-soon {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  background: var(--card); border: 1px dashed var(--line); border-radius: 14px;
  padding: 14px 15px; margin-top: 4px;
}
.ai-soon-ic {
  display: flex; width: 30px; height: 30px; border-radius: 9px; margin-bottom: 5px;
  background: var(--fill); color: var(--on-fill); align-items: center; justify-content: center;
}
.ai-soon-ic svg { width: 16px; height: 16px; }
.ai-soon b { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.ai-soon p { margin: 0; font-size: 12px; line-height: 1.6; color: var(--muted); }

.ai-list { display: flex; flex-direction: column; gap: 2px; }
.ai-row { display: flex; gap: 11px; padding: 10px 0; border-top: 1px solid var(--line); }
.ai-row:first-child { border-top: none; }
.ai-ic {
  flex: none; width: 24px; height: 24px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
}
.ai-ic svg { width: 13px; height: 13px; }
.ai-ic.ok { background: var(--good-soft); color: var(--good); }
.ai-ic.no { background: var(--alert-soft); color: var(--alert); }
.ai-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ai-bd b { font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; }
.ai-bd span { font-size: 11.5px; line-height: 1.6; color: var(--muted); }
.ai-note { margin: 18px 2px 0; font-size: 11px; line-height: 1.7; color: var(--faint); }

/* ---- ปฏิทินเดือน ----
   ภาชนะที่ถูกกับคำถาม "เดือนนี้มีอะไรรออยู่" — สอบกลางภาคไม่ได้อยู่ใน 7 วันข้างหน้า
   และมันใช้ได้ตั้งแต่ยังไม่กรอกตารางเรียน เพราะเส้นตายมาจากงานที่สแกนเข้ามาแล้ว */
.calbar { display: flex; align-items: center; gap: 8px; margin: 2px 0 10px; }
.calbar b { flex: 1; text-align: center; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.calbar button {
  width: 34px; height: 34px; border: none; border-radius: 50%;
  background: var(--card); color: var(--muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.calbar button svg { width: 16px; height: 16px; }
.calbar button:first-child svg { transform: rotate(180deg); }
.calbar button:active { background: var(--card2); }

.calwd { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 4px; }
.calwd span { text-align: center; font-size: 10.5px; color: var(--faint); }

.calgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
/* aspect-ratio: 1 ทำให้ช่องสูงเท่าความกว้างเสมอ — บนจอแคบได้ 48px ซึ่งพอดี
   แต่บนจอกว้าง คอลัมน์กว้างขึ้นช่องก็สูงตามไปถึง 100px+ ทั้งที่ในช่องมีแค่เลขวัน
   ผลคือขีดคาบเรียน (.cal-sch ที่เกาะขอบล่าง) กับแถบหมุด (.cal-marks ที่เกาะขอบบน)
   ลอยห่างจากเลขวันของตัวเองไปคนละมุมช่อง จนอ่านเหมือนเป็นของวันที่อยู่แถวถัดไป
   คุมเพดานไว้ ช่องจึงยังเป็นจัตุรัสบนมือถือ และไม่ยืดจนเสียความหมายบนจอกว้าง */
.cal-c {
  position: relative; aspect-ratio: 1; max-height: 58px; border: none; background: transparent;
  border-radius: 10px; font-family: inherit; cursor: pointer; padding: 4px 0 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--ink);
}
.cal-c.off { pointer-events: none; }
.cal-c b { font-size: 13px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
/* วันนี้ได้วงกลม ส่วนวันที่เลือกได้พื้น — สองสถานะนี้เกิดพร้อมกันได้ จึงต้องแยกกันคนละที่ */
.cal-c.today b {
  background: var(--fill); color: var(--on-fill);
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.cal-c.on { background: var(--card); }
.cal-c.on b { font-weight: 700; }
.cal-c.hot b { color: var(--alert); }
.cal-c.today.hot b { color: var(--on-fill); }
.cal-dots { display: flex; align-items: center; justify-content: center; gap: 2px; min-height: 6px; }
.cal-more { font-style: normal; font-size: 9px; line-height: 1; color: var(--faint); }
/* ขีดบางใต้วัน = วันนั้นมีคาบเรียน · บางพอที่จะไม่แย่งจุดเส้นตาย */
.cal-sch {
  position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%);
  width: 12px; height: 2px; border-radius: 1px; background: var(--line);
}
.cal-c.on .cal-sch { background: var(--muted); opacity: .5; }

/* แผ่นของวันที่เลือก — ปฏิทินที่กดวันแล้วไม่มีอะไรขึ้นคือปฏิทินที่อ่านได้อย่างเดียว */
.cal-day { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.cal-day-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.cal-day-h b { font-size: 15px; font-weight: 600; letter-spacing: -.015em; }
.cal-day-h i { font-style: normal; font-size: 11.5px; color: var(--faint); }
.cal-day-h u { margin-left: auto; text-decoration: none; font-size: 11.5px; color: var(--muted); }
.cal-day-cls {
  display: flex; align-items: center; gap: 7px; margin-bottom: 9px;
  font-size: 12px; color: var(--muted);
}
.cal-day-cls svg { width: 13px; height: 13px; flex: none; }
.cal-day-0 { margin: 0; font-size: 12px; color: var(--faint); }

.cal-t {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  border: none; background: var(--card); border-radius: 12px;
  padding: 9px 11px; margin-bottom: 6px; font-family: inherit; color: var(--ink); cursor: pointer;
}
.cal-t:active { transform: scale(.995); }
.cal-t-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cal-t-b b {
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-t-b i { font-style: normal; font-size: 11px; color: var(--muted); }

/* ---- หมุดปฏิทิน ----
   ของที่ผู้ใช้ปักเอง ต่างจากเส้นตายที่ระบบรู้มาจากใบงาน — จึงเป็นแถบสี ไม่ใช่จุด
   "สำคัญมาก" ระบายทั้งช่องในปฏิทิน เพราะหน้าที่ของมันคือถูกเห็นตั้งแต่ยังไม่ตั้งใจมอง */
.cal-marks { display: flex; gap: 2px; width: 100%; padding: 0 5px; }
.cal-marks i { flex: 1; height: 3px; border-radius: 2px; background: var(--sj); }
.cal-c.big { background: color-mix(in srgb, var(--sj) 22%, transparent); }
.cal-c.big .cal-marks i { background: var(--sj); }

.cal-m {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  border: none; background: var(--card); border-radius: 12px;
  padding: 9px 11px; margin-bottom: 6px; font-family: inherit; color: var(--ink); cursor: pointer;
}
.cal-m.big { background: color-mix(in srgb, var(--sj) 16%, var(--card)); }
.cal-m-bar { width: 3px; align-self: stretch; border-radius: 2px; background: var(--sj); flex: none; }
.cal-m-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cal-m-b b {
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-m-b i { font-style: normal; font-size: 11px; color: var(--muted); }
.cal-m svg { width: 14px; height: 14px; color: var(--faint); flex: none; }
.cal-m:active { transform: scale(.995); }

.cal-add {
  width: 100%; min-height: 40px; border-radius: 12px;
  border: 1.5px dashed var(--line); background: transparent;
  color: var(--blue); font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.cal-add:active { background: var(--card2); }

.cal-form {
  display: flex; flex-direction: column; gap: 9px;
  background: var(--card2); border-radius: 12px; padding: 12px;
}
.cal-form input[type=text] {
  width: 100%; min-height: 42px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); color: var(--ink); font-family: inherit; font-size: 14px;
}
/* จานสีสองแถว ปุ่มละ 28px — เล็กกว่านี้แตะพลาดสีข้าง ๆ แล้วต้องแก้ใหม่ */
.cal-sw { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.cal-sw button {
  height: 28px; border-radius: 8px; border: 2px solid transparent;
  background: var(--sj); cursor: pointer; padding: 0;
}
.cal-sw button.on { border-color: var(--ink); }
.cal-big {
  display: flex; align-items: center; gap: 8px; width: 100%;
  border: 1px solid var(--line); border-radius: 10px; background: var(--card);
  padding: 9px 11px; font-family: inherit; font-size: 12px; color: var(--ink);
  text-align: left; cursor: pointer;
}
.cal-big span { flex: 1; }
.cal-big svg { width: 14px; height: 14px; flex: none; color: var(--muted); }
.cal-big.on { border-color: var(--alert); color: var(--alert); }
.cal-big.on svg { color: var(--alert); }
.cal-big-x { display: flex; }
.cal-form-a { display: flex; align-items: center; gap: 8px; }

/* หมุดในจอรายวัน — อยู่เหนือเส้น ไม่ใช่ในเส้น เพราะหมุดไม่มีเวลาของตัวเอง */
.tl-mark {
  display: flex; align-items: center; gap: 9px;
  background: var(--card); border-radius: 12px; padding: 10px 12px; margin-bottom: 8px;
}
.tl-mark.big { background: color-mix(in srgb, var(--sj) 16%, var(--card)); }
.tl-mark b { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; letter-spacing: -.01em; }
.tl-mark i { font-style: normal; font-size: 11px; color: var(--muted); flex: none; }

.cal-go {
  display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%;
  min-height: 42px; margin-top: 10px; border: 1px solid var(--line); border-radius: 12px;
  background: transparent; font-family: inherit; font-size: 13px; font-weight: 600;
  color: var(--ink); cursor: pointer;
}
.cal-go svg { width: 15px; height: 15px; color: var(--muted); }
.cal-go:active { background: var(--card2); }
.dayrow-due {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--alert);
}
.dayrow-due svg { width: 13px; height: 13px; }
/* เวลาที่ผ่านไปแล้วยังอยู่ครบ แต่จางลง — ลบทิ้งแล้วเส้นจะสั้นลงเรื่อย ๆ จนหาที่ยืนไม่เจอ */
.dayrow.past { opacity: .42; }

.dayrow-card { margin: 0; }
.dayrow .dayrow-t { top: 0; }
.dayrow:has(.dayrow-card) .dayrow-t { top: 16px; }
.dayrow-go {
  width: 100%; margin-top: 12px; border: none; border-radius: 10px;
  background: var(--fill); color: var(--on-fill);
  font-family: inherit; font-size: 13px; font-weight: 600; padding: 11px;
  display: flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer;
}
.dayrow-go svg { width: 15px; height: 15px; }
.dayrow-go:active { transform: scale(.98); }

/* ---- คำตัดสินบนสุด ----
   การ์ดนี้อยู่เหนือเส้นเวลา ทุกพิกเซลที่มันสูงขึ้นคือพิกเซลที่เส้นเวลาหายไปจากจอแรก
   หัวบรรทัดจึงต้องพอตัดสินใจได้เอง ส่วนบรรทัดล่างเป็นรายละเอียดที่ตัดท้ายได้ */
.dayvd { background: var(--card); border-radius: 14px; padding: 11px 13px; margin-bottom: 12px; }
.dayvd-h { display: flex; align-items: center; gap: 8px; }
.dayvd-h b { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.dayvd p {
  margin: 3px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* ข่าวร้ายเท่านั้นที่ได้พื้นสี — ถ้าทุกสถานะมีสี ก็ไม่มีสถานะไหนสะดุดตา */
.dayvd.bad { background: var(--alert-soft); }
.dayvd.bad p { color: var(--ink); }

/* ---- แผ่นรายละเอียด ---- */
#tlSheet { position: absolute; inset: 0; z-index: 72; }
#tlSheet[hidden] { display: none; }
.daysheet-back { position: absolute; inset: 0; background: rgba(6,10,22,.62); }
.daysheet {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--card); border-radius: 20px 20px 0 0; padding: 12px 16px 18px;
  box-shadow: 0 -8px 32px rgba(0,0,0,.55);
  animation: tls-up .22s cubic-bezier(.2,.9,.3,1);
}
@keyframes tls-up { from { transform: translateY(18px); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .daysheet { animation: none; } }
/* ---------- แผ่นนี้เคยเป็นสีเทาทั้งใบ ----------
   ป้ายหมวดเทา · ชิปเทา · กล่องเหตุผลใช้สีพื้นจอซึ่งเข้มกว่าตัวแผ่น จึงอ่านเป็น "รูโหว่"
   และปุ่มทั้งสองใบเป็น .ghost ทั้งคู่ — ไม่มีปุ่มไหนเป็นสีเน้นเลย ทั้งแผ่นจึงไม่มีสีสักจุด
   แก้สามที่: ป้ายหมวดได้สีน้ำเงิน · กล่องเหตุผลเป็นพื้นน้ำเงินจางแบบยกขึ้น (ไม่ใช่จมลง)
   · ปุ่มหลักกลับไปเป็นปุ่มทึบตามที่ .daysheet-go ตั้งใจไว้แต่แรก เหลือ "ปิด" เป็น ghost ใบเดียว */
.daysheet-grip {
  display: block; width: 36px; height: 4px; border-radius: 2px;
  background: var(--muted); opacity: .45; margin: 0 auto 14px;
}
.daysheet-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--blue); margin-bottom: 5px;
}
.daysheet-h { font-size: 19px; font-weight: 600; line-height: 1.4; letter-spacing: -.015em; }
.daysheet-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }
.daysheet-why {
  background: var(--blue-soft);
  border: 1px solid var(--line);
  border-radius: 12px; padding: 12px; margin-top: 14px;
}
.daysheet-why b { display: block; font-size: 11px; font-weight: 700; color: var(--blue); margin-bottom: 4px; }
.daysheet-why p { margin: 0; font-size: 13px; line-height: 1.65; white-space: pre-line; }
.daysheet-act { display: flex; gap: 8px; margin-top: 14px; }
.daysheet-go {
  flex: 1; min-height: 46px; border: none; border-radius: 12px;
  background: var(--fill); color: var(--on-fill);
  font-family: inherit; font-size: 13px; font-weight: 600;
  display: flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer;
}
.daysheet-go svg { width: 15px; height: 15px; }
.daysheet-go.ghost { background: transparent; border: 1px solid var(--line); color: var(--ink); flex: 0 0 88px; }
.daysheet-go:active { transform: scale(.98); }

/* ============================================================
   จอตั้งค่า — ทางลัดสี่ช่อง + การ์ดแยกกลุ่ม
   ------------------------------------------------------------
   ทุกค่าสีมาจากตัวแปรของธีมล้วน ๆ (--card --card2 --line --ink --muted)
   ห้ามใส่สีตรง ๆ ที่นี่ — ธีมในแอปมี 16 อัน ตัวไหนพลาดจะพังเฉพาะบางธีม
   ซึ่งเป็นบั๊กที่หาเจอยากที่สุด เพราะสองธีมแรกที่เปิดดูมักจะดูปกติ
   ============================================================ */
.set-quick {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 20px;
}
.set-quick button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 13px 4px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-tile);
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  cursor: pointer;
  transition: transform .16s ease;
}
.set-quick button:active { transform: scale(.96); }
.set-quick svg { width: 21px; height: 21px; stroke-width: 2.1; color: var(--blue); }
.set-quick span { font-size: 11px; font-weight: 600; letter-spacing: -.01em; text-align: center; }

.set-card {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 20px;
}
/* 1C40 · จอตั้งค่าไม่มีหัวข้อกลุ่มแล้ว — การ์ดชิดกันขึ้น (เจ้าของ: "เอาให้มันใกล้ ๆ กันหน่อย")
   ระยะเดิม 42px = gap ของ .pf-body 22 + margin ล่างของการ์ด 20 ซึ่งมีไว้กันการ์ดชนหัวข้อกลุ่มถัดไป
   ไม่มีหัวข้อแล้วจึงเหลือ gap อย่างเดียว 12px · จำกัดที่จอนี้ — .set-card ใช้ในจอย่อยอื่นด้วย */
#scr-settings .pf-body { gap: 12px; }
#scr-settings :is(.set-me, .set-quick, .set-card) { margin-bottom: 0; }
.set-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: inherit;
  text-align: left;
}
.set-row + .set-row { border-top: 1px solid var(--line); }
.set-row.go { cursor: pointer; transition: background .14s ease; }
.set-row.go:active { background: var(--card2); }
.set-row[hidden] { display: none; }
/* 31 ต.ค. 69 · "ออกจากระบบ" เป็นแถวสุดท้ายของการ์ด และแถวข้างบนมันซ่อนได้หมด (ยังไม่ล็อกอิน) — .set-row + .set-row นับแถวที่ซ่อนด้วย
   เส้นคั่นบนจึงโผล่ทั้งที่เป็นแถวเดียวในการ์ด · ให้มีเส้นเฉพาะเมื่อมีแถวที่เห็นอยู่ข้างบน */
#setOutRow { border-top: 0; }
.set-card > .set-row:not([hidden]) ~ #setOutRow { border-top: 1px solid var(--line); }
/* หน้าย่อยเอฟเฟกต์ตอนงานเสร็จ (31 ต.ค. 69) — เส้นคั่นบนของ .fx-sec มีไว้แยกจากตารางธีมตอนอยู่หน้าเดียวกัน แยกหน้าแล้วไม่ต้องมี */
#setBlkFx .fx-sec { margin-top: 4px; padding-top: 0; border-top: 0; }

/* ชิปไอคอน — พื้นเรียบ ไม่ใช่สีเน้นทึบแบบ .pe-ic
   จอนี้มีสิบกว่าแถว ถ้าทุกแถวมีชิปสีเน้น สายตาจะไม่รู้ว่าควรมองอันไหนก่อน */
.set-ic {
  width: 34px; height: 34px; flex: none;
  border-radius: 11px;
  background: var(--card2);
  color: var(--muted);
  display: flex; align-items: center; justify-content: center;
}
.set-ic svg { width: 18px; height: 18px; stroke-width: 2.1; }
.set-lb {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
  font-size: 15px; font-weight: 600; letter-spacing: -.015em;
}
.set-lb i {
  font-style: normal;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
}
.set-val {
  flex: none;
  max-width: 42%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
}
.set-go { width: 16px; height: 16px; flex: none; color: var(--faint); }
/* 26 ต.ค. 69 · เจ้าของ (ภาพจอตั้งค่า ธีม Halloween): "ให้มันมองดูออกกว่านี้ ตรงธีมให้เห็นเป็นสีธีมและชื่อที่ใช้เลย"
   ค่าท้ายแถวเป็น --muted 13px น้ำหนักปกติ บนฉากมืดเลยจางจนต้องเพ่ง → หมึกหลัก 78% หนาขึ้น · ลูกศรชัดขึ้นเล็กน้อย
   แถวธีม = ป้ายเม็ดยาสีธีม: ช่องสีของธีมจริง (.shw-sw .sw-* ชุดเดียวกับตารางเลือกธีม) + ชื่อธีมตัวหนา
   ป้ายย้อม --fill จาง ๆ ไม่ใช่ทึบ — มันคือ "ค่าที่ตั้งอยู่" ไม่ใช่ปุ่มหลักของจอ */
.set-row .set-val { font-size: 13.5px; font-weight: 600; color: color-mix(in srgb, var(--ink) 78%, transparent); }
.set-row .set-go { color: color-mix(in srgb, var(--ink) 45%, transparent); }
.set-row .set-val.set-val-theme {
  display: inline-flex; align-items: center; gap: 7px; max-width: 52%;
  padding: 4px 11px 4px 4px; border-radius: 999px;
  background: color-mix(in srgb, var(--fill) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 45%, transparent);
  color: var(--ink);
}
.set-val-theme .shw-sw {
  flex: none; width: 22px; height: 22px; margin: 0; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--card), 0 0 10px -2px var(--fill);
}
.set-val-theme b { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 700; }
.set-row.danger .set-lb { color: var(--alert); }
.set-row.danger .set-ic { background: var(--alert-soft); color: var(--alert); }

/* ช่องกรอกในแถว — ยกหน้าตาเดิมจาก .pf-row input มาทั้งชุด
   ไม่งั้นช่องพวกนี้จะกลายเป็น input เปล่าของเบราว์เซอร์ที่ไม่เข้ากับธีมไหนเลย */
.set-row input[type=text], .set-row input[type=number] {
  flex: none;
  width: 116px;
  text-align: right;
  border: none;
  border-radius: 10px;
  background: var(--card2);
  color: var(--ink);
  padding: 8px 10px;
  min-height: 36px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
}
.set-row input[type=number] { width: 78px; }
/* 1C40 · ช่องชื่อเล่นยาวเต็มแถว (เจ้าของ: "ตรงคำว่า เช่น Nado ด้วย" — ต่อจากช่องใส่โค้ด)
   ชื่อแถวหดเท่าตัวหนังสือ ช่องกรอกกินที่ที่เหลือถึงขอบขวา พิมพ์จากซ้ายแบบช่องพิมพ์ทั่วไป
   (116px ชิดขวาเหมาะกับตัวเลขสั้น ๆ ไม่ใช่ชื่อคน — ชื่อยาวโดนตัดตั้งแต่ตัวที่สิบ) */
.set-row:has(#pName) .set-lb { flex: none; }
.set-row #pName { flex: 1 1 auto; width: auto; min-width: 0; text-align: left; }
.set-row input:focus { outline: 2px solid var(--blue); outline-offset: -2px; }

/* ปุ่มเลือก/ลบรูป — ของเดิมสูง 44px และกินพื้นที่เต็มแถว เพราะเคยอยู่ในแถวแบบ col
   ที่มันได้อยู่คนเดียวทั้งบรรทัด ตอนนี้มันมาแชร์บรรทัดกับป้ายชื่อแล้ว */
.set-row .bg-tools { flex: none; margin: 0; gap: 6px; }
.set-row .bg-pick { flex: none; min-height: 36px; padding: 0 12px; font-size: 12.5px; border-radius: 10px; }
.set-row .bg-del { width: 36px; min-height: 36px; border-radius: 10px; }
.set-row .bg-pick svg, .set-row .bg-del svg { width: 15px; height: 15px; }

/* แถวที่ของข้างในวางเรียงลงล่าง (ช่องใส่โค้ด) */
.set-row.col { flex-direction: column; align-items: stretch; gap: 10px; }
.set-hd { display: flex; align-items: center; gap: 12px; }

/* หน้าย่อยของตั้งค่า — บล็อกที่ย้ายเข้ามาเป็นการ์ดเดี่ยวอยู่แล้ว
   จอนี้จึงไม่ต้องมีกรอบซ้อนอีกชั้น */
#scr-setopt .pf-list { padding-top: 4px; }

/* ============================================================
   1A9c — แถบล่างติดขอบจอ · หัวจอพ้นนาฬิกาเครื่อง (เฉพาะมือถือจริง)
   ============================================================
   เจอตอนเปิดบนเครื่องจริง ไม่ใช่ในกรอบจำลองบนจอคอม กรอบจำลองมีขอบดำรอบด้าน
   ปัญหาสองข้อล่างจึงมองไม่เห็นเลยจนกว่าจะเปิดบนมือถือ

   1A9l · เพิ่มขาที่สอง (display-mode: standalone) — นี่คือตัวแก้อาการ "บางรอบก็ดี บางรอบไม่"
   ถ้าบล็อกนี้ไม่ทำงาน แถบจะตกกลับไปใช้กฎฐานใน style.css ซึ่งเป็นแคปซูลลอย
   (position:absolute · เว้นซ้ายขวา 14px · มุมมน 20px) = อาการ "ไม่อยู่ขอบจอ" ทุกด้าน
   ไม่ใช่แค่ด้านล่าง · เงื่อนไขเดิมมีขาเดียวคือความกว้าง ซึ่งบนแอปที่ติดตั้งแล้ว
   iOS รายงานผิดได้ตอนเปิดเย็น (คืนค่า viewport เริ่มต้น 980px ก่อนอ่าน meta viewport)
   รอบไหนที่มันรายงานผิด รอบนั้นได้แคปซูล — จึงเป็นอาการที่มาบ้างไม่มาบ้าง
   "ติดตั้งเป็นแอปแล้ว" เป็นข้อเท็จจริงที่ไม่ขึ้นกับความกว้างที่รายงานมา
   ขาไหนจริงก็พอ แถบจึงติดขอบเสมอไม่ว่าความกว้างจะเพี้ยนหรือไม่ */
@media (max-width: 768px), (display-mode: standalone) {
  /* 1 · แถบล่างเคยเป็นแคปซูลลอย (left/right 14px · bottom var(--tabgap))
     บนกรอบจำลองมันดูเป็นของลอยสวย ๆ · บนเครื่องจริงมันคือแถบที่ "ยังไม่ถึงขอบ"
     แล้วเหลือแถบสีพื้นจอคาอยู่ใต้มันเหนือเส้น home indicator ซึ่งอ่านว่าเลย์เอาต์หลุด
     ติดขอบไปเลย แล้วให้ env(safe-area-inset-bottom) เป็นตัวเว้นระยะให้เส้น home indicator */
  /* ต้นเหตุจริงของช่องว่างใต้แถบ: `position: absolute` วัดจาก .phone ไม่ใช่จากจอ
     .phone สูง 100dvh ซึ่งบนเครื่องจริงจบเหนือแถบ home indicator — แถบเลยไปนั่งที่ขอบล่าง
     ของ .phone ซึ่งไม่ใช่ขอบล่างของจอ · เหลือพื้นสีเพจ (--pg) คาอยู่ใต้มันประมาณ 34pt
     สองรุ่นก่อนหน้าไล่ลด padding ซึ่งแก้ผิดที่ เพราะ padding ไม่เคยเป็นต้นเหตุ
     `position: fixed` วัดจาก viewport ตรง ๆ — แถบจึงถึงขอบล่างจริงเสมอ
     (.phone มี overflow:hidden แต่ไม่มี transform จึงไม่ตัด fixed ทิ้ง) */
  /* 1A9n · เลิกใช้ position: fixed — แถบเป็นลูกคนสุดท้ายของ .phone ในผังปกติ
     .phone เป็น flex column สูง 100dvh อยู่แล้ว ลูกคนสุดท้ายจึงไปนั่งก้นกล่องเอง
     ไม่ต้องบอกพิกัดสักตัว · fixed บน iOS ในแอปที่ติดตั้งแล้วไม่ลงขอบล่างจริงเสมอไป
     (ไล่ ancestor ทุกตัวแล้วไม่มีอันไหนสร้าง containing block เลย แต่มันก็ยังลอยสูงกว่าขอบ
      ~34px อยู่ดี) · static ไม่มีอะไรให้เพี้ยน เพราะไม่ได้ไปอ้างอิงขอบจอตั้งแต่แรก
     ผลพลอยได้: .screens หดให้เองเพราะแถบกินที่ในผัง เนื้อหาจึงไม่มีทางถูกแถบทับอีก */
  :root:not([data-nav="side"]) .tabbar {
    position: static;
    flex: none;
    /* 1A9o · กลับมาเป็นแคปซูลลอยตามที่เลือก — แต่คราวนี้เป็นแคปซูลที่ "อยู่ในผัง"
       ระยะห่างจากขอบจอมาจาก margin ไม่ใช่ bottom/left/right ของของลอย
       ต่างกันตรงที่ margin ไม่ต้องรู้ว่าขอบจออยู่ไหน มันแค่เว้นจากก้นกล่องพ่อ
       ซึ่งเป็นเหตุผลเดียวกับที่ทิ้ง fixed ไปใน 1A9n — ไม่มีตัวแปรที่ iOS ตีความต่างได้
       margin ล่างใช้ max() กับ safe area: มีแถบ home indicator ก็เว้นเท่ามัน ไม่มีก็ 8px */
    /* 1A9q · บีบช่องรอบแคปซูลให้แคบที่สุดเท่าที่ยังใช้งานได้จริง
       ข้าง 8px — ต่ำกว่านี้มุมมน 20px จะไปแตะขอบจอจนอ่านเป็นแถบที่ตัดมุมผิด ไม่ใช่ก้อนลอย
       ล่าง safe-area − 18 → ~16pt บนไอโฟน · ตัวเลขนี้มีเพดานของมันเอง:
       ขอบล่างแคปซูล 16 + padding ในแคปซูล 5 = ก้นปุ่มอยู่ที่ ~21pt จากขอบจอ
       ซึ่งเป็นระยะขั้นต่ำที่ iOS กันไว้ให้ท่าปัดขึ้นออกจากแอป ต่ำกว่านี้นิ้วที่ปัดออก
       จะไปโดนปุ่มแถวล่างแทน · จึงบีบได้แค่นี้ ไม่ใช่เพราะเลือกไว้เผื่อ */
    margin: 0 8px max(6px, calc(env(safe-area-inset-bottom) - 18px));
    border-radius: 20px; border-width: 1px;
    /* max() ไม่ใช่ + : ถ้าเครื่องมีแถบ home indicator ก็ใช้ระยะของมัน ถ้าไม่มีก็ 8px
       บวกกันคือที่มาของ "แผ่นเปล่าซ้อนสองชั้น" ที่เห็นในรุ่นก่อน */
    /* 1A9f · ความสูงแถบ = 49px + safe area เท่าแถบล่างของ iOS เป๊ะ
       (1 ขอบ + 4 padding + 44 ปุ่ม) ของเดิม 6 + 48 = 55 ซึ่งเกินมา 6px
       44 คือขนาดปุ่มขั้นต่ำที่นิ้วกดติด จึงลดต่ำกว่านี้ไม่ได้ */
    /* 3px ไม่ใช่ 5px — ปุ่มยังสูง 44 เท่าเดิม (ต่ำกว่านี้นิ้วกดไม่ติด) แต่ท้องแถบ
       ไม่ต้องกว้างตามไปด้วย · 4px ที่ประหยัดได้ตกเป็นของบทสนทนาซึ่งขาดที่จริง ๆ */
    /* 1B98 · 2px ไม่ใช่ 3px — เจ้าของบอกว่าแถบล่าง "ใหญ่ กินพื้นที่ด้านบนมากไป"
       ท้องแถบไม่ได้ทำงานอะไรเลยนอกจากกันปุ่มไม่ให้ชนขอบ ลดได้ก่อนเพื่อน */
    padding: 2px 4px;
    /* พื้นเป็นสีการ์ด ไม่ใช่สีพื้นจอ — สีเดียวกับพื้นจอทำให้แถบไม่มีขอบบน
       สายตาจึงอ่านที่ว่างทั้งก้อนล่างจอเป็นแถบเดียวกัน แล้วรู้สึกว่าแถบสูงกว่าจริง */
    background: var(--card);
    backdrop-filter: none; -webkit-backdrop-filter: none;
    /* 1A9k · เส้นบนต้องเห็นชัดกว่า --line ปกติ มันคือสิ่งเดียวที่บอกว่า "แถบเริ่มตรงนี้"
       ถ้ามันจาง ท้องแถบช่วง safe-area จะถูกอ่านเป็นช่องว่างหลุดเลย์เอาต์ ไม่ใช่ส่วนของแถบ */
    box-shadow: 0 -1px 0 var(--line), 0 -8px 20px -12px rgba(0, 0, 0, .5);
  }
  /* 1C32 · หน้าเว็บสั้นกว่าจอจริง (บั๊ก iOS 26 · app.js checkShortVP ติดธงให้)
     ขอบล่างของหน้าเว็บอยู่เหนือเส้น home indicator อยู่แล้ว ~47pt
     ระยะเว้นข้างบนเลยซ้ำกับที่ว่างของ iOS กลายเป็นช่องเปล่า ~64pt ใต้แถบ (ผู้ใช้ส่งภาพมา 24 ก.ย.) */
  :root[data-vpshort]:not([data-nav="side"]) .tabbar { margin-bottom: 4px; }
  /* ทุกปุ่มสูง 44px เท่ากัน (22 ไอคอน + 3 ช่อง + 13 ตัวหนังสือ + 6 padding)
     ของเดิม padding 4px ทำให้เป็น 46 ซึ่งดันแถบให้สูงเกินโดยไม่ได้อะไรกลับมา */
  /* 1B98 · 42 ไม่ใช่ 44 · 44 คือขนาดปุ่มขั้นต่ำที่นิ้วกดติด "บนพื้นที่กดที่เป็นก้อนเดี่ยว"
     แต่ปุ่มพวกนี้กว้างเต็มช่อง ~70px และเรียงกันโดยไม่มีช่องว่างระหว่างกัน
     พื้นที่กดจริงจึงเป็น 70×42 ซึ่งกว้างกว่าเป้าขั้นต่ำมากในแกนที่พลาดง่ายกว่า
     บวก padding ของแถบอีก 2px บน-ล่างที่ยังรับนิ้วที่เลยขอบปุ่มไปได้ */
  :root:not([data-nav="side"]) .tab { min-height: 42px; padding: 2px 2px; gap: 3px; }

  /* 1A9k · แท็บที่เลือกอยู่ = เปลี่ยนสี ไม่ใช่ก้อนสีทึบ
     ก้อนทึบทำให้ปุ่มห้าปุ่มไม่ใช่ของชนิดเดียวกันอีกต่อไป — หนึ่งในนั้นกลายเป็นการ์ด
     แถบล่างของแอปที่คนใช้ทุกวัน (Grab/LINE/iOS) ไม่มีอันไหนทำแบบนั้นเลย
     สีกับไอคอนทึบบอก "อยู่หน้านี้" ได้ครบอยู่แล้ว โดยไม่ต้องเพิ่มรูปทรงใหม่เข้ามาในแถบ */
  :root:not([data-nav="side"]) .tab.active { background: none; color: var(--blue); }
  :root:not([data-nav="side"]) .tab .ic { width: 21px; height: 21px; }
  /* วงแหวนรอบแบดจ์ต้องเป็นสีพื้นแถบจริง — บนมือถือแถบไม่ใช่ glass แล้วตั้งแต่ 1A9c */
  .tab-badge, .tab-dot { box-shadow: 0 0 0 2px var(--card); }
  /* กันไว้อีกชั้น: ถ้ามีอะไรโผล่ใต้ .phone ขึ้นมาอีก มันต้องเป็นสีเดียวกับพื้นแอป
     ไม่ใช่สีเพจสีดำที่อ่านออกมาว่า "แอปจบตรงนี้แล้ว" */
  /* กันชั้นสุดท้าย: ถ้า .phone สูงไม่ถึงขอบจอจริงบนเครื่องไหน แถบสีที่โผล่ใต้มัน
     ต้องเป็นสีเดียวกับพื้นแถบ ไม่ใช่สีพื้นจอ — สีพื้นจออ่านออกมาว่า "เลย์เอาต์หลุด"
     สีเดียวกับแถบอ่านออกมาว่า "แถบมันสูงเท่านี้" ซึ่งไม่มีใครสงสัย */
  html, body { background: var(--scr); }
  /* 1A9k · ปุ่ม + ไม่ลอยเหนือแถบอีกแล้ว
     ก้อนกลมสีแบรนด์ที่โผล่ขึ้นมาพร้อมวงแหวนสีพื้นแถบ คือของที่ต้องกินพื้นที่นอกแถบ
     พอแถบมาติดขอบจอจริง (1A9c) ส่วนที่โผล่ขึ้นไปก็ไปนั่งทับการ์ดใบล่างสุดตลอดเวลา
     และวงแหวนรอบปุ่มก็อ่านเป็น "รอยขาดบนแถบ" ไม่ใช่ปุ่มลอย
     ปุ่มนี้จึงกลายเป็นแท็บธรรมดาแท็บที่สาม เท่าอีกสี่ปุ่มเป๊ะ — แถบล่างมีของชนิดเดียว
     (การเพิ่มงานยังเข้าถึงได้จากปุ่มในหน้า "งาน" และแผ่นเลื่อนขึ้นตัวเดิมทุกประการ) */
  /* 1A9o · ปุ่ม + กลับมาเป็นก้อนกลมลอยเหนือแถบ
     46 − 24 = 22 เท่าไอคอนปุ่มอื่นเป๊ะ แถบจึงไม่สูงขึ้นเพราะปุ่มนี้ ส่วนที่เกินคือการล้น
     ออกนอกผัง ไม่ดันอะไรทั้งนั้น · วงแหวนต้องเป็นสีพื้นแคปซูล ไม่ใช่สีพื้นจอ */
  :root:not([data-nav="side"]) .tab.scan .scan-dot {
    width: 46px; height: 46px; margin-top: -24px;
    border-radius: 50%; background: var(--grad-brand); color: #fff;
    outline: 3px solid var(--card);
    box-shadow: var(--glow-scan), 0 8px 20px -8px rgba(0, 0, 0, .45); }
  .tab.scan .scan-dot svg { width: 22px; height: 22px; stroke-width: 2.1; }
  .tab.scan { color: var(--blue-deep); }
  .tab.scan:active .scan-dot { transform: scale(.9); }

  /* 1B38b · กฎระยะหลบแถบล่างของ toast ถูกถอนออก — toast ขึ้นไปอยู่ด้านบนแล้ว
     (ดูหมายเหตุยาวใน style.css) ด้านบนไม่มีของที่ขยับตำแหน่งได้ จึงไม่ต้องมีกฎที่นี่อีก */

  /* ระยะเผื่อท้ายหน้า — 1A9k แถบสูง 6 + 44 + safe = 50 + safe แล้วไม่มีปุ่มโผล่เหนือแถบอีก
     เผื่อ 62 = ความสูงแถบ + ช่องหายใจ 12px ใต้การ์ดใบล่างสุด
     ตัวเลข 84 ของเดิมอิงกับปุ่ม + ที่โผล่ขึ้นมา 19px ซึ่งไม่มีแล้ว */
  /* แถบไม่ทับเนื้อหาแล้ว จึงไม่ต้องเผื่อความสูงแถบท้ายหน้าอีก เหลือแค่ช่องหายใจ
     ตัวเลขชุดเดิม (62 + safe) กลายเป็นที่ว่างเปล่าคาอยู่ใต้การ์ดใบล่างสุดทันทีที่แถบเป็น static */
  /* ช่องบนแคปซูล = เผื่อเฉพาะส่วนที่ปุ่ม + ล้นขึ้นมา (15px) + 7 กันชน
     .screens จบที่ขอบบนแคปซูลอยู่แล้ว จึงไม่ต้องเผื่อความสูงแถบอีกแม้แต่พิกเซลเดียว */
  :root:not([data-nav="side"]) .screen, :root:not([data-nav="side"]) .home-body,
  :root:not([data-nav="side"]) .scr-body, :root:not([data-nav="side"]) .menu-body {
    padding-bottom: 22px;
  }
  /* จอน้องไซตั้ง padding เองใน today.css (74px) ซึ่งเป็นเลขของยุคที่แถบทับเนื้อหา
     พอแถบเข้ามาอยู่ในผัง 74 กลายเป็นช่องว่างเปล่าคั่นช่องพิมพ์กับแคปซูลทันที */
  :root:not([data-nav="side"]) #aiBody.scr-body { padding-bottom: 22px; }

  /* แถบจับเวลาต้องลอยเหนือแถบล่างเสมอ — ของเดิมวัดจาก .phone ด้วย bottom คงที่ 77px
     ซึ่งเคยพอดีกับแถบทรงเก่า พอแถบเป็น fixed + safe-area มันจะไปนั่งใต้แถบแล้วหายไป
     วัดจาก viewport เหมือนแถบล่าง แล้วบวกความสูงแถบจริง (50 + safe) + ช่อง 8px */
  :root:not([data-nav="side"]) .runbar {
    position: absolute;
    left: 10px; right: 10px;
    bottom: calc(58px + env(safe-area-inset-bottom));
  }

  /* 2 · จอที่เป็น flush คุม padding เอง จึงไม่ได้รับ padding-top ที่กัน notch
     ไว้ให้ใน .screen — หัวจอเลยไปนั่งใต้นาฬิกากับแบตของเครื่อง
     กันที่ตรงนี้ทีเดียว ครอบทุกจอที่วาดหัวของตัวเอง */
  /* #aiBody ตั้ง padding เองใน today.css แบบย่อ (ทับกฎนี้) — safe-area ของมันอยู่ที่นั่น */
  .menu-body { padding-top: calc(10px + env(safe-area-inset-top)); }
  .screen.flush > .sticky-head { padding-top: calc(12px + env(safe-area-inset-top)); }

  /* 1C14 · แท็บ "ฉัน" ตกสำรวจมาตั้งแต่ 1B95 — #scr-profile เป็น .screen.flush
     แต่ไม่ได้ใช้ .sticky-head มันวาดหัวเอง (.ig-top จาก profileHeadHTML)
     กฎสองบรรทัดข้างบนจึงไม่ครอบถึง แล้ว .pf-body ตั้ง padding-top: 6px เปล่า ๆ
     ผลคือแถว "@ชื่อผู้ใช้ · เฟือง" ไปนั่งทับนาฬิกากับแบตของเครื่องพอดี
     — เห็นเป็น "กดเฟืองไม่ติด" เพราะนิ้วไปโดนแถบสถานะของ iOS ไม่ใช่ปุ่ม
     (ผู้ใช้ส่งภาพมา 20 ก.ย. 2569 · บนคอมไม่มีนอตช์จึงไม่มีใครจับได้อีกครั้ง)

     ต้องเขียนหลังกฎ .pf-body ของบรรทัด 5182 — ความจำเพาะเท่ากัน (0,1,0)
     ตัวที่อยู่ล่างกว่าในไฟล์เดียวกันเท่านั้นที่ชนะ · feed.css โหลดทีหลังก็จริง
     แต่ไม่ได้ประกาศ padding-top ของ .pf-body ไว้ กฎนี้จึงไม่ถูกล้าง */
  .pf-body { padding-top: calc(6px + env(safe-area-inset-top)); }

  /* 1B95 · หัวจอตระกูลแชทไม่เคยได้ safe-area เลย
     ------------------------------------------------------------
     กฎบรรทัดบนแจกให้เฉพาะจอที่ใช้ `.sticky-head` · ส่วนห้องคุย กล่องข้อความ
     ห้องการบ้าน และหัวข้อ วาดหัวของตัวเองด้วย JS ทั้งใบ (.ch-top/.hw-top/.tp-top)
     ทั้งสี่จึงตกสำรวจมาตลอด แล้วปุ่มย้อนกลับไปนั่งทับนาฬิกากับแบตของเครื่องพอดี
     — เห็นบนเครื่องจริงเท่านั้น บนคอมไม่มีนอตช์จึงไม่มีใครจับได้ (ผู้ใช้ส่งภาพมา 14 ก.ย. 2569)

     **ต้องเขียน `.screen` นำหน้า** — social.css / hw.css / topic.css โหลดทีหลัง alt.css
     และประกาศ `padding` แบบย่อไว้ทั้งคู่ (`padding: 10px 12px`) ถ้าเขียนแค่ `.ch-top`
     ความจำเพาะเท่ากัน ไฟล์ที่โหลดทีหลังชนะ แล้ว padding-top ตรงนี้จะถูกล้างทิ้งเงียบ ๆ
     `.screen .ch-top` = (0,2,0) ชนะ (0,1,0) เสมอไม่ว่าลำดับโหลดจะเป็นยังไง

     ตั้งแค่ด้านบนด้านเดียว ซ้าย/ขวา/ล่างปล่อยให้ไฟล์เจ้าของคุมต่อไปเหมือนเดิม

     (ไม่ต้อง sticky — ทั้งสี่จอวางหัวเป็นพี่น้อง flex ของตัวเลื่อนข้างใน
      .ch-list/.dm-list อยู่แล้ว หัวจึงอยู่กับที่ด้วยผังเอง ไม่ได้เลื่อนไปกับเนื้อหา) */
  .screen .ch-top, .screen .hw-top, .screen .tp-top {
    padding-top: calc(10px + env(safe-area-inset-top));
  }

  /* ปุ่มเพื่อนลอยมุมขวาบนก็โดนอาการเดียวกับปุ่มเฟืองใน 1A9e — top: 8px วัดจากขอบจอ
     บนเครื่องจริงขอบจอคือขอบบนของนาฬิกากับแบต ปุ่มจึงไปนั่งทับแบตพอดี (บนคอมไม่เห็น)
     กันนอตช์ด้วย safe-area แล้วบวก 26 ให้ตัวปุ่มเสมอกับบรรทัดหัวเรื่องของหน้าจอ
     ไม่ใช่แค่ "พ้นแบต" เฉย ๆ — ของที่ลอยต้องเกาะบรรทัดใดบรรทัดหนึ่งถึงจะดูตั้งใจ */
  /* 1B94 · เฟืองอยู่ช่องเดียวกับปุ่มเพื่อน จึงต้องขยับพร้อมกันเสมอ
     แยกบรรทัดเมื่อไหร่ ปุ่มสองตัวจะไม่อยู่ระดับเดียวกันบนเครื่องที่มีนอตช์ */
  .top-friends, .top-set { top: calc(26px + env(safe-area-inset-top)); }
}

/* ---------- ปุ่มเฟืองในการ์ดโปรไฟล์ (1A9e) ---------- */
/* เคยลอยอยู่มุมขวาบนของจอ แล้วไปทับนาฬิกากับแบตของเครื่องพอดี (เห็นบนเครื่องจริงเท่านั้น)
   ย้ายเข้ามาอยู่ในการ์ด ฝั่งขวาของแถวชื่อ — มันเป็นของของโปรไฟล์นี้อยู่แล้ว
   พื้นโปร่งขาวจาง ๆ เพราะการ์ดเป็นพื้นสีเน้น ปุ่มพื้นทึบจะกลายเป็นรูบนการ์ด */
.pf-set {
  flex: none; align-self: flex-start;
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .16); color: #fff;
  cursor: pointer;
}
.pf-set svg { width: 18px; height: 18px; }
.pf-set:active { background: rgba(255, 255, 255, .28); transform: scale(.92); }
/* ปุ่มเพื่อนยังหลบหน้า "ฉัน" เหมือนเดิม — แถว "เพื่อน" อยู่ในลิสต์ข้างล่างอยู่แล้ว */
.me-scr .top-friends { display: none; }

/* ---------- ปุ่มตั้งค่ามุมขวาบน (1B94) ----------
   ยืมทรงจาก .top-friends ทั้งก้อน เพราะทั้งสองปุ่มคือ "ช่องมุมขวาบน" ช่องเดียวกัน
   ที่สลับเนื้อในตามหน้า ไม่ใช่ปุ่มสองปุ่มที่บังเอิญอยู่ใกล้กัน — ถ้าขนาดหรือเงาไม่ตรงกัน
   มันจะกระตุกตอนสลับหน้า ทั้งที่ผู้ใช้ไม่ได้รู้สึกว่ามีอะไรถูกสลับ

   ค่าเริ่มต้นคือซ่อน แล้วโผล่เฉพาะ .me-scr — ไม่ใช่ตรงข้าม เพราะจอที่ควรมีเฟือง
   มีจอเดียว ส่วนจอที่ไม่ควรมีคือทุกจอที่เหลือ กฎที่สั้นกว่าคือกฎที่พังยากกว่า */
.top-set {
  position: absolute;
  top: 8px;
  right: 10px;
  z-index: 91;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform .16s ease;
}
.top-set svg { width: 18px; height: 18px; }
.top-set:active { transform: scale(.9); }
.me-scr .top-set { display: flex; }
/* จอที่มีปุ่มย้อนกลับของตัวเองมุมขวาบน (deep-scr) ต้องไม่มีเฟืองมาทับ —
   ตัวหน้า "ฉัน" อยู่บนแถบล่างจึงไม่เคยเป็น deep-scr แต่เขียนกันไว้เหมือนปุ่มเพื่อน */
.login-mode .top-set, .deep-scr .top-set { display: none; }

/* ---------- หัวจอตั้งค่า + การ์ดตัวตน (1A9d) ---------- */
.set-top {
  position: relative; display: flex; align-items: center;
  min-height: 40px; margin-bottom: 14px;
}
.set-back {
  position: absolute; left: -8px; width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; background: none; color: var(--ink); cursor: pointer;
}
.set-back svg { width: 20px; height: 20px; transform: rotate(180deg); }
.set-back:active { background: var(--card2); }
.set-title {
  flex: 1; margin: 0; text-align: center;
  font-size: 17px; font-weight: 700; color: var(--ink);
}
.set-me {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 14px; margin-bottom: 20px;
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); box-shadow: var(--shadow);
  font: inherit; text-align: left; cursor: pointer;
}
.set-me:active { background: var(--card2); }
.set-me-av {
  flex: none; width: 48px; height: 48px; display: grid; place-items: center;
  border-radius: 50%; background: var(--blue-soft); color: var(--blue);
  font-size: 19px; font-weight: 700; overflow: hidden;
}
.set-me-av img { width: 100%; height: 100%; object-fit: cover; }
.set-me-tx { flex: 1; min-width: 0; }
.set-me-tx b {
  display: block; font-size: 16px; font-weight: 700; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.set-me-tx i {
  display: block; margin-top: 2px; font-style: normal; font-size: 12.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.set-me .set-go { flex: none; width: 17px; height: 17px; color: var(--faint); }

/* ---------- ผลของฉัน: หัวข้อกดได้ + ทางเข้าฉบับเต็ม (1A9d) ---------- */
.st-open {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 0; border: 0; background: none; font: inherit; text-align: left; cursor: pointer;
}
/* 1C09 · .st-open-bare ไม่มีใครใช้แล้ว — ลิงก์ "ดูแบบที่เพื่อนเห็น" เหนือแถบโชว์
   ถูกถอดเพราะซ้ำกับปุ่มบนหัวจอ (ดู renderShowcase) · เก็บกฎไว้ไม่ได้ช่วยอะไร */

/* 1C08 · การ์ดใบเดียวที่รวม "ยังไม่รู้อะไร" กับ "รู้แล้วเท่าไหร่" ไว้ด้วยกัน
   กรอบกับพื้นย้ายมาอยู่ที่ใบนอก .st-card ข้างในจึงต้องถอดของพวกนั้นออก
   ไม่งั้นได้กล่องในกล่องที่ขอบห่างกัน 13px ซึ่งอ่านเป็นความผิดพลาด ไม่ใช่ลำดับชั้น */
.pf-me {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.pf-me .st-card {
  margin-top: 0; background: none; border: 0; border-radius: 0; box-shadow: none;
}
/* 1C10 · กฎของแถบ "รู้จักคุณแล้ว %" (.pf-me .tl-hint) ถูกถอดไปพร้อมกับตัวแถบ
   .tl-hint ตัวแม่ยังอยู่ ยังถูกใช้ในเส้นเวลา — ที่ถอดคือกฎเฉพาะของการ์ดใบนี้เท่านั้น */
/* ว่างเปล่าได้ถ้าวันหนึ่งกราฟไม่มีข้อมูล — ไม่ให้เหลือกล่องเปล่าที่ไม่ได้ครอบอะไร */
.pf-me > div:empty { display: none; }

/* หัวกราฟรับ "ดูทั้งหมด" เข้ามาอยู่บรรทัดเดียวกัน แทนที่จะมีแถวของตัวเอง */
.st-h-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.st-h-row > span { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.st-h-row svg { width: 12px; height: 12px; flex: none; }
.st-h-row .st-open-go { letter-spacing: 0; text-transform: none; }
.st-open .sec-label { flex: 1; margin-top: 0; }
/* 1C07 · ตามหัวข้อกลุ่มขึ้นมาหนึ่งขั้น — ลิงก์ที่เล็กกว่าหัวข้อมากเกินไป
   อ่านเป็นของที่ไม่ได้ตั้งใจให้กด */
/* 1C08 · สีลิงก์จางลง 10% ตามที่เจ้าของสั่ง — ผสมเข้าหาพื้นการ์ด ไม่ใช่ตั้งค่าสีใหม่
   ผสมกับ --card ทำให้ "จางลง 10%" แปลว่าเดียวกันในทุกธีม: ธีมสว่างจางไปทางขาว
   ธีมมืดจางไปทางกรมท่า · ถ้าตั้งเป็นค่าสีตายตัวก็ต้องไล่เขียนทั้ง 14 ธีม
   บรรทัด color แรกเป็นตัวสำรองให้เบราว์เซอร์ที่ยังไม่รู้จัก color-mix */
.st-open-go {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 0; border: 0; background: none; font-family: inherit; cursor: pointer;
  font-size: 13px; font-weight: 700; color: var(--blue);
  color: color-mix(in srgb, var(--blue) 90%, var(--card));
}
.st-open-go svg { width: 14px; height: 14px; }
/* ============================================================
   จอ "ผลของฉัน" ฉบับวิเคราะห์ (1A9e)
   ============================================================
   สีทองใช้ได้เฉพาะของที่ทำสำเร็จแล้วเท่านั้น — สถิติต่อเนื่องกับเหรียญที่ได้
   ประมาณ 10% ของจอ · ถ้าทองไปโผล่บนของที่ยังไม่ได้ทำ มันก็เลิกแปลว่าสำเร็จ */
.an-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.an-tile {
  padding: 12px 10px; border: 1px solid var(--line); border-radius: 15px;
  background: var(--card); text-align: center;
}
.at-ic { display: block; color: var(--muted); }
.at-ic svg { width: 18px; height: 18px; }
.at-v {
  display: block; margin-top: 6px; font-size: 21px; font-weight: 700;
  line-height: 1.1; color: var(--ink);
}
.at-v i { font-style: normal; font-size: 12px; font-weight: 600; margin-left: 1px; }
.at-k { display: block; margin-top: 3px; font-size: 10.5px; line-height: 1.35; color: var(--muted); }
/* ทอง — ของที่ทำสำเร็จแล้วเท่านั้น */
.an-tile.gold { border-color: var(--gold); background: var(--gold-soft); }
.an-tile.gold .at-ic, .an-tile.gold .at-v { color: var(--gold-text); }
.an-tile.gold .at-k { color: var(--gold-text); opacity: .85; }
.an-tile.up .at-ic, .an-tile.up .at-v { color: var(--pri-green-text); }
.an-tile.down .at-ic { color: var(--muted); }

/* หัวการ์ดที่มีตัวเลขรวมชิดขวา */
.st-h-v { float: right; font-weight: 700; color: var(--ink); }
.st-foot { margin: 8px 0 0; font-size: 11px; color: var(--faint); }

/* แยกตามวิชา: แถบซ้าย + โดนัทขวา */
.an-split { display: flex; align-items: center; gap: 14px; }
.an-legend { flex: 1; min-width: 0; display: grid; gap: 9px; }
.an-lg { display: grid; grid-template-columns: 9px 1fr 46px 30px; align-items: center; gap: 7px; }
.lg-dot { width: 9px; height: 9px; border-radius: 3px; background: var(--sj, var(--muted)); }
.lg-nm {
  font-size: 12.5px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lg-bar { height: 5px; border-radius: 999px; background: var(--surface); overflow: hidden; }
.lg-bar i { display: block; height: 100%; border-radius: 999px; background: var(--sj, var(--blue)); }
.lg-pct { font-size: 11.5px; color: var(--muted); text-align: right; }
.an-donut { position: relative; flex: none; width: 96px; height: 96px; }
.an-donut svg { width: 96px; height: 96px; transform: rotate(-90deg); }
.an-donut circle { fill: none; stroke-width: 11; }
.dn-bg { stroke: var(--surface); }
.an-donut circle:not(.dn-bg) { stroke: var(--sj, var(--blue)); }
.dn-mid {
  position: absolute; inset: 0; display: grid; place-content: center; text-align: center;
}
.dn-mid i { display: block; font-style: normal; font-size: 9.5px; color: var(--faint); }
.dn-mid b { display: block; font-size: 17px; font-weight: 700; color: var(--ink); line-height: 1.15; }

/* น้องไซวิเคราะห์ */
.an-ai {
  margin-top: 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: linear-gradient(158deg, var(--blue-soft) 0%, transparent 70%), var(--card);
}
.an-ai-h {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; color: var(--blue);
}
.an-ai-h svg { width: 16px; height: 16px; }
.an-ai ul { margin: 10px 0 0; padding-left: 18px; display: grid; gap: 7px; }
.an-ai li { font-size: 12.5px; line-height: 1.55; color: var(--ink); }
.an-ai-note { margin: 10px 0 0; font-size: 11px; line-height: 1.5; color: var(--faint); }

/* เหรียญ */
.an-grp {
  display: flex; align-items: baseline; gap: 8px; margin: 20px 0 9px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; color: var(--muted);
}
.an-grp button {
  margin-left: auto; display: inline-flex; align-items: center; gap: 2px;
  border: 0; background: none; color: var(--blue);
  font: inherit; font-size: 12px; font-weight: 600; letter-spacing: 0; cursor: pointer;
}
.an-grp button svg { width: 14px; height: 14px; }
.an-badges { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.an-bd {
  padding: 11px 6px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card); text-align: center;
}
.ab-mark {
  display: grid; place-items: center; width: 34px; height: 34px; margin: 0 auto;
  border-radius: 11px; background: var(--surface); color: var(--faint);
  font-size: 15px; font-weight: 700;
}
.ab-mark svg { width: 15px; height: 15px; }
.ab-nm {
  display: block; margin-top: 7px; font-size: 10.5px; font-weight: 600; line-height: 1.3;
  color: var(--muted); overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.ab-ds { display: block; margin-top: 2px; font-size: 9.5px; color: var(--faint); }
/* ได้แล้ว = ทอง · ยังไม่ได้ = เทา ไม่มีข้อยกเว้น */
.an-bd.got { border-color: var(--gold); background: var(--gold-soft); }
.an-bd.got .ab-mark { background: var(--gold); color: var(--on-gold); }
.an-bd.got .ab-nm { color: var(--gold-text); }
.an-bd.got .ab-ds { color: var(--gold-text); opacity: .8; }

/* 1C08 · กฎทองถูกถอด — คอมเมนต์เดิมบอกว่าตั้งใจให้เฉพาะหัวข้อ "ผลของฉัน"
   แต่ selector ไม่ได้เจาะจงจอหรือบล็อกไหนเลย มันจึงทาทองทับ .st-open-go ทุกใบ
   รวมถึง "ดูแบบที่เพื่อนเห็น" ในแถบโชว์ด้วย · ผลคือลิงก์สามอันในช่วงเดียวกัน
   เป็นทองสอง น้ำเงินหนึ่ง ซึ่งอ่านเป็นสีมั่ว ไม่ใช่รหัสสี — เจ้าของเห็นแล้ววงมา
   ทองในโปรเจกต์นี้แปลว่า "ของที่ได้มาจริง" (โทเคน · เหรียญ) ไม่ใช่ "กดเข้าไปดูได้" */

/* ธีมมืดแบน --grad-hero เป็นสีเดียวไว้ (ดูบล็อก :root[data-theme="dark"])
   แต่การ์ดทองใช้ token ของตัวเอง จึงไม่โดนแบนไปด้วย — เขียนกำกับไว้กันแก้ผิดที่ */
:root[data-theme="dark"] .st-hero,
:root[data-theme="space"] .st-hero { background: var(--grad-gold); border-color: transparent; }

/* ============================================================
   บริบทของฉัน — แท่งวัน · แถบรู้จัก · ตัวช่วยทำความรู้จัก (1A9h)
   ============================================================ */

/* ---------- แท่ง "วันของคุณ" ---------- */
/* ช่องว่างใช้สีเน้น (ฟ้า/สีของธีม) ไม่ใช่ทอง — ทองในแอปนี้แปลว่า "ทำสำเร็จแล้ว"
   (สถิติต่อเนื่อง · เหรียญที่ได้) เวลาว่างยังไม่ได้ทำอะไรสักหน่อย ถ้าทองไปโผล่ตรงนี้
   มันก็เลิกแปลว่าสำเร็จทันที · เวลาที่ถูกจองไปแล้วเป็นเทา เพราะวางแผนอะไรกับมันไม่ได้ */
.ctx-bar {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); box-shadow: var(--shadow);
  padding: 13px 14px; margin-bottom: 10px;
}
.cb-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700; color: var(--ink); }
.cb-h svg { width: 15px; height: 15px; color: var(--blue); flex: none; }
.cb-h span { flex: 1; min-width: 0; }
.cb-pick {
  flex: none; border: 1px solid var(--line); border-radius: 999px;
  background: var(--card2); color: var(--muted);
  font: inherit; font-size: 11px; padding: 3px 7px;
}
.cb-bar {
  display: flex; height: 30px; margin-top: 10px;
  border-radius: 9px; overflow: hidden; background: var(--card2);
}
.cb-bar i {
  display: flex; align-items: center; justify-content: center; min-width: 0;
  font-style: normal; font-size: 9.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden;
}
.cb-busy { background: var(--card2); color: var(--muted); box-shadow: inset 0 0 0 1px var(--scr); }
/* ชนิดของกิจกรรมแยกด้วยน้ำหนักของเทา ไม่ใช่สีรุ้ง — สีในแอปนี้มีความหมายจองไว้แล้ว
   (ฟ้า = กดได้ · ทอง = สำเร็จแล้ว) เวลาที่ถูกจองไม่ใช่ทั้งสองอย่าง มันแค่ไม่ว่าง */
.cb-of-class  { background: var(--line); }
.cb-of-travel { background: var(--card2); opacity: .62; }
.cb-of-meal   { background: var(--card2); opacity: .8; }
.cb-free { background: var(--fill); color: var(--on-fill); }
/* ช่องที่สั้นเกินกว่าจะนั่งลงทำอะไรได้ ต้องดูไม่เหมือนเวลาว่าง ไม่งั้นแท่งสัญญาเกินจริง */
.cb-gap { background: repeating-linear-gradient(135deg,
  var(--card2) 0 4px, transparent 4px 8px); }
.cb-axis { display: flex; justify-content: space-between; margin-top: 5px; font-size: 10px; color: var(--faint); }
.cb-p { margin: 8px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.cb-p b { color: var(--ink); font-weight: 700; }

/* ---------- แถบรู้จัก ---------- */
.ctx-know {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); box-shadow: var(--shadow);
  padding: 13px 14px; margin-bottom: 10px;
}
.ck-h { display: flex; align-items: baseline; gap: 8px; font-size: 13px; font-weight: 700; color: var(--ink); }
.ck-h span { flex: 1; }
.ck-h b { font-size: 11px; font-weight: 600; color: var(--faint); }
.ck-bar { height: 5px; border-radius: 999px; background: var(--card2); overflow: hidden; margin-top: 8px; }
.ck-bar span { display: block; height: 100%; border-radius: 999px; background: var(--blue); transition: width .3s ease; }
.ck-list { display: flex; flex-direction: column; gap: 9px; margin-top: 12px; }
/* 1C06 · แต่ละช่องที่ยังไม่รู้เป็นปุ่มของตัวเอง ไม่ใช่รายการเฉย ๆ ใต้ปุ่มรวมอันเดียว
   ต้องมีขอบกับลูกศร ไม่งั้นมันดูเหมือนรายการเดิมทุกประการแล้วไม่มีใครรู้ว่ากดได้
   ขอบเป็น --line เส้นเดียว ไม่ใช่พื้นทึบ — การ์ดนี้อยู่บนพื้นการ์ดอยู่แล้ว
   ซ้อนพื้นทึบอีกชั้นจะได้กล่องในกล่องในกล่อง */
.ck-gap {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 10px; border: 1px solid var(--line); border-radius: 11px;
  background: none; font-family: inherit; text-align: left; cursor: pointer;
  transition: transform .14s ease;
}
.ck-gap:active { transform: scale(.985); background: var(--card2); }
.ck-gap > svg:last-child { width: 15px; height: 15px; flex: none; color: var(--faint); }
.ck-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--blue); flex: none; }
.ck-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ck-tx b { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.ck-tx i { font-style: normal; font-size: 11px; line-height: 1.45; color: var(--muted); }
.ck-done {
  display: flex; align-items: center; gap: 7px; margin: 10px 0 0;
  font-size: 11.5px; line-height: 1.5; color: var(--muted);
}
.ck-done svg { width: 15px; height: 15px; flex: none; color: var(--blue); }

/* ---------- ข้อสังเกตจากพฤติกรรมจริง ---------- */
.ctx-learn {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card2); padding: 13px 14px; margin-bottom: 10px;
}
.cl-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700; color: var(--ink); }
.cl-h svg { width: 15px; height: 15px; color: var(--blue); flex: none; }
.cl-p { margin: 8px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted); }
.cl-act { display: flex; gap: 8px; margin-top: 12px; }
.cl-act .btn { flex: 1; }

/* ---------- ตัวช่วยทำความรู้จัก ---------- */
.wiz-body { display: flex; flex-direction: column; min-height: 100%; padding-top: 10px; }
.wz-top { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.wz-dots { display: flex; gap: 5px; flex: 1; }
.wz-dots span { flex: 1; height: 3px; border-radius: 999px; background: var(--card2); }
.wz-dots span.past { background: var(--blue-soft); }
.wz-dots span.on { background: var(--blue); }
.wz-main { flex: 1; }
.wz-q { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.02em; line-height: 1.3; color: var(--ink); }
.wz-sb { margin: 7px 0 18px; font-size: 12.5px; line-height: 1.55; color: var(--muted); }

.wz-chips { display: flex; gap: 7px; }
.wz-chips.wrap { flex-wrap: wrap; }
.wz-chips:not(.wrap) { flex-wrap: wrap; }
.wz-chip {
  padding: 9px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.wz-chip.on { border-color: var(--blue); background: var(--blue-soft); color: var(--blue); }

.wz-row {
  display: flex; align-items: center; gap: 10px; margin-top: 18px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-tile); background: var(--card);
}
.wz-lb { flex: 1; font-size: 13px; font-weight: 600; color: var(--ink); }
.wz-note {
  display: flex; align-items: flex-start; gap: 7px; margin: 18px 0 0;
  font-size: 11.5px; line-height: 1.55; color: var(--faint);
}
.wz-note svg { width: 14px; height: 14px; flex: none; margin-top: 2px; }

.wz-list { display: flex; flex-direction: column; gap: 8px; }
.wz-rt {
  padding: 10px 11px; border: 1px solid var(--line); border-radius: var(--r-tile); background: var(--card);
}
.wz-rt-h { display: flex; align-items: center; gap: 9px; }
.wz-rt.off { opacity: .42; }
.wz-ic {
  width: 28px; height: 28px; flex: none; border-radius: 9px;
  background: var(--blue-soft); color: var(--blue);
  display: flex; align-items: center; justify-content: center;
}
.wz-ic svg { width: 15px; height: 15px; }
.wz-tx { flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.wz-times input[type=time] {
  flex: 1; min-width: 0; max-width: 110px; padding: 6px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--card2); color: var(--ink); font: inherit; font-size: 11.5px;
}
.wz-x {
  width: 28px; height: 28px; flex: none; border: 0; border-radius: 9px;
  background: none; color: var(--faint); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.wz-x svg { width: 15px; height: 15px; }

.wz-slot { padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--r-tile); background: var(--card); }
.wz-slot-h { display: flex; align-items: center; gap: 8px; }
.wz-slot-h b { flex: 1; font-size: 13px; font-weight: 700; color: var(--ink); }
.wz-days { display: flex; gap: 4px; margin-top: 9px; }
.wz-day {
  flex: 1; padding: 6px 0; border: 1px solid var(--line); border-radius: 8px;
  background: var(--card2); color: var(--faint);
  font: inherit; font-size: 10.5px; font-weight: 600; cursor: pointer;
}
.wz-day.on { border-color: var(--blue); background: var(--blue-soft); color: var(--blue); }
.wz-times { display: flex; align-items: center; gap: 8px; margin-top: 9px; }
.wz-times span { font-size: 11.5px; color: var(--faint); }
.wz-bad { margin: 8px 0 0; font-size: 11px; color: var(--pri-red-text, var(--muted)); }
.wz-warn {
  display: flex; align-items: flex-start; gap: 6px; margin: 8px 0 0;
  font-size: 11px; line-height: 1.5; color: var(--faint);
}
.wz-warn svg { width: 13px; height: 13px; flex: none; margin-top: 2px; }

/* ปุ่มท้ายจอเกาะขอบล่าง — จอนี้ไม่มีแถบเมนู ปุ่มไปต่อจึงต้องอยู่ที่เดียวตลอดทั้งห้าขั้น
   ปุ่มที่ขยับตำแหน่งตามความยาวเนื้อหา คือปุ่มที่ต้องมองหาใหม่ทุกครั้ง */
.wz-act {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; gap: 9px; padding: 14px 0 calc(14px + env(safe-area-inset-bottom));
  margin-top: 22px; background: linear-gradient(to top, var(--scr) 72%, transparent);
}
.wz-act .btn { flex: 1; }

/* ---------- หน้าน้องไซบนฟองแชท ---------- */
/* รูปกับไอคอนสำรองถูกวาดซ้อนกันไว้ทั้งคู่ · onerror เป็นคนตัดรูปทิ้งถ้าโหลดไม่ขึ้น
   แล้วคลาส no-face เป็นตัวเปิดไอคอนสำรองแทน — ฟองแชทจึงไม่มีวันว่างเป็นวงกลมเปล่า */
.ai-av { overflow: hidden; position: relative; }
.ai-av img {
  width: 100%; height: 100%; object-fit: cover;
  display: block; border-radius: inherit;
}
/* วงแหวนบาง ๆ กันหน้าจมหายไปกับพื้นหลังตอนธีมมืด — รูปนี้ขอบบนเป็นสีเข้มเกือบดำ */
.ai-av::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--glass-line); pointer-events: none;
}
.ai-av .ai-av-fb { display: none; }
.ai-av.no-face { background: var(--fill); color: var(--on-fill); }
.ai-av.no-face .ai-av-fb { display: grid; place-items: center; width: 100%; height: 100%; }

/* หน้าใหญ่บนหัวจอ — ที่นี่คือที่เดียวที่ตัวละครได้พื้นที่พอให้เห็นว่าเป็นใคร
   ฟองแชทเล็กเกินกว่าจะอ่านหน้าออก มันทำหน้าที่แค่บอกว่า "ฝั่งนี้คือน้องไซ" */
.ai-av.big {
  width: 46px; height: 46px; border-radius: 15px; margin-bottom: 0;
}
.ai-av.big .ai-av-fb svg { width: 22px; height: 22px; }

/* ============================================================
   แถบล่าง 6 ช่อง — ปุ่ม + เลิกลอย
   ------------------------------------------------------------
   ประวัติของปุ่มนี้: 1A9k ทำให้แบน · 1A9o เอาก้อนกลมลอยกลับมา
   ตอนนั้นถูกทั้งคู่ เพราะแถบมี 5 ช่อง ปุ่มจึงเป็นช่องที่ 3 = กึ่งกลางเป๊ะ
   ก้อนที่โผล่พ้นแถบตรงกึ่งกลางอ่านเป็น "หมุด" ได้

   พอเพิ่ม "เพื่อน" เป็น 6 ช่อง ตำแหน่งกึ่งกลางหายไป (จำนวนคู่ไม่มีช่องกลาง)
   ก้อนที่โผล่พ้นแถบแต่เยื้องซ้ายครึ่งช่อง อ่านเป็น "วางผิด" ไม่ใช่ "หมุด"
   ปุ่มจึงกลับไปแบนตามเหตุผลของ 1A9k — แถบล่างมีของชนิดเดียว ทั้งหกช่องเท่ากันเป๊ะ
   ยังเด่นกว่าเพื่อนด้วยพื้นสีแบรนด์ + เงาเรือง ซึ่งพอแล้วสำหรับปุ่มที่ใช้บ่อยที่สุด

   อยากได้ก้อนลอยกลับ: ลบทั้งบล็อกนี้ แล้วของเดิมที่บรรทัด ~5734 จะกลับมาทำงานเอง
   (แต่ต้องยอมรับว่ามันจะเยื้องซ้ายครึ่งช่อง ตราบใดที่แถบยังมีจำนวนช่องคู่)
   ============================================================ */
.tabbar .tab { flex: 1 1 0; min-width: 0; }

/* 1B41 · บล็อกนี้หมดอายุตามเงื่อนไขที่มันเขียนไว้เอง
   ข้อความข้างบนบอกว่า "อยากได้ก้อนลอยกลับ ต้องยอมรับว่ามันจะเยื้องซ้ายครึ่งช่อง
   ตราบใดที่แถบยังมีจำนวนช่องคู่" — ตอนนี้แถบเป็นห้าช่องแล้ว เงื่อนไขนั้นจึงหมดไป
   ปุ่มเป็นช่องที่ 3 จาก 5 = กึ่งกลางเป๊ะ เหมือนตอน 1A9o ทุกประการ
   กฎชุดที่ทำให้มันแบนถูกถอดออก ของเดิมที่บรรทัด ~5734 กลับมาทำงานเอง
   แล้วบล็อก 1B41 ท้ายไฟล์ปรับสีให้เข้ากับแถบที่เงียบลงตั้งแต่ 1B39 */

/* ป้ายบนแท็บห้ามตัดบรรทัด — หกช่องบนจอ 320px เหลือช่องละ ~46px
   "น้องไซ" กว้าง 28px ยังพอดี แต่ถ้าปล่อยให้ตัดบรรทัด แถบจะสูงขึ้นทั้งแถบ
   เพราะช่องเดียวมีสองบรรทัดแล้วลากที่เหลือขึ้นตาม */
.tabbar .tab > span:last-child { white-space: nowrap; }

/* ============================================================
   1B38 — แถบล่างเงียบลง · กฎ 60/30/10 กลับมาตั้งตรง
   ============================================================
   ก่อนหน้านี้จอ "วันนี้" มีของสีเน้นอยู่สี่ที่พร้อมกัน: การ์ด "ตอนนี้" (พื้นฟ้าทึบ) ·
   ไทล์แปดก้อนพื้นแบรนด์สองแถว · แท็บที่เลือกเป็นสีฟ้า · ปุ่ม + พื้นไล่สีแบรนด์ + เงาเรือง
   รวมกันแล้วสีเน้นกินพื้นที่มากกว่า 10% หลายเท่า ซึ่งแปลว่าไม่มีอะไรเน้นเลย —
   สายตาไม่รู้จะลงที่ไหนก่อน จอเลยอ่านว่า "รก" ทั้งที่แต่ละชิ้นออกแบบมาดี

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

   สิ่งที่ไม่แตะ: พื้นแถบยังเป็น --card เหมือนเดิม (ชั้น 30% ของกฎ) — 1A9k เคยลอง
   ใช้สีพื้นจอแล้วแถบไม่มีขอบบน สายตาอ่านที่ว่างทั้งก้อนล่างจอเป็นแถบเดียวกัน
   ============================================================ */

/* แท็บที่เลือก: หมึกเต็ม ไม่ใช่ฟ้า — บอก "อยู่หน้านี้" ได้เท่ากันด้วยน้ำหนักตัวอักษร
   กับไอคอนทึบที่มีอยู่แล้ว โดยไม่ต้องยืมสีเน้นมาใช้เป็นครั้งที่สี่บนจอเดียว */
:root:not([data-nav="side"]) .tab.active { background: none; color: var(--ink); }
:root:not([data-nav="side"]) .tab { color: var(--faint); }

/* ปุ่ม + : ก้อนกลมทึบลอยเหนือแถบ ตรงกึ่งกลางพอดี
   1B39 เคยทำให้มันจางลงเป็นทินต์อ่อนตามหลัก 60/30/10 ซึ่งถูกในตอนนั้น
   เพราะปุ่มไม่ได้อยู่กลาง มันจึงเป็นแค่ "แท็บที่สีต่างจากเพื่อน" ซึ่งไม่คุ้มที่จะเด่น
   ตอนนี้มันอยู่กึ่งกลางแถบและเป็นของชนิดเดียวในแถบที่ไม่ใช่แท็บ (แท็บพาไปจอ
   ปุ่มนี้เปิดแผ่น) — ของที่ทำงานคนละอย่างกับเพื่อนควรหน้าตาไม่เหมือนเพื่อน
   สีเน้นในแถบล่างจึงมีที่เดียวคือก้อนนี้ ส่วนแท็บทั้งสี่ยังเงียบเหมือน 1B39
   ทึบแต่ไม่มีเงาเรือง — glow เป็นของที่แข่งกับการ์ดคำสั่งบนหน้าแรกโดยตรง */
:root:not([data-nav="side"]) .tab.scan .scan-dot {
  /* 1B98 · ก้อนกลมเคยโผล่พ้นแถบ 22px ซึ่งเท่ากับครึ่งก้อนพอดี
     ส่วนที่โผล่ขึ้นไปนั่งทับเนื้อหาของจอเสมอ และเป็นเหตุผลที่ .scr-body ต้องเผื่อ
     ระยะท้ายหน้าถึง 118px — รวมแล้วแถบล่างกินพื้นที่จอไปมากกว่าความสูงของมันเอง
     42px โผล่ 13px ยังอ่านเป็น "หมุด" ที่ลอยเหนือแถบ แต่คืนพื้นที่ให้เนื้อหา ~15px */
  width: 42px; height: 42px;
  /* margin ล่างติดลบด้วย ไม่ใช่แค่บน — ไม่งั้นก้อนนี้จะเป็นตัวกำหนดความสูงของ *ทั้งแถบ*
     42 − 13 = 29 ซึ่งสูงกว่าไอคอนของปุ่มอื่น (21) อยู่ 8px แถบจึงสูงตามช่องเดียวนี้
     (วัดจากของจริง: ลดปุ่มลงแล้วแถบกลับ "สูงขึ้น" 1px เพราะเหตุนี้)
     −13 บน −8 ล่าง = กินที่ในผัง 21px เท่าไอคอนอื่นเป๊ะ ส่วนที่เหลือคือการล้นออกนอกผัง
     ซึ่งไม่ดันอะไรทั้งนั้น — แถบจึงเตี้ยลงจริงทั้งแถบ ไม่ใช่แค่ปุ่มเล็กลง */
  margin-top: -13px; margin-bottom: -8px;
  border-radius: 50%;
  background: var(--fill);
  color: var(--on-fill);
  outline: 3px solid var(--card);
  box-shadow: 0 6px 16px -6px rgba(0, 0, 0, .5);
}
:root:not([data-nav="side"]) .tab.scan .scan-dot svg { width: 21px; height: 21px; stroke-width: 2.2; }
:root:not([data-nav="side"]) .tab.scan { color: var(--faint); }
:root:not([data-nav="side"]) .tab.scan.active { color: var(--ink); }
:root:not([data-nav="side"]) .tab.scan.active .scan-dot { transform: none; }
:root:not([data-nav="side"]) .tab.scan:active .scan-dot { transform: scale(.92); }

/* แบดจ์ยังแดงอยู่ — มันคือสัญญาณจริง ไม่ใช่ของประดับ แต่เล็กลงและไม่มีวงแหวนหนา
   แถบไม่ได้เป็น glass แล้วบนมือถือ วงแหวนสี --glass จึงเป็นเส้นสีผิดมาตั้งแต่ 1A9c */
.tab-badge { min-width: 15px; height: 15px; line-height: 15px; font-size: 9px;
  top: -4px; right: -7px; box-shadow: none; }
.tab-dot { box-shadow: none; }

/* ============================================================
   1B39 — ปุ่มเพิ่มงานบนหัวจอ "งาน"
   ============================================================
   ย้ายมาจากช่องกลางของแถบล่างที่ถูกถอดออก · ขนาด 44px คือขนาดขั้นต่ำที่นิ้วกดติด
   สีเน้นทึบเพราะมันคือปุ่มเดียวบนหัวจอนี้ และเป็นของที่กดบ่อยที่สุดในจอนี้
   (จอ "วันนี้" ยังมีการ์ดสีเน้นของมันอยู่ใบเดียวเหมือนเดิม — คนละจอกัน ไม่ชนกฎ 60/30/10) */
/* 1B41 · .tlrow / .ph-add ถูกถอดออกพร้อมกับปุ่มเพิ่มข้างสวิตช์สามโหมด
   มันมีอยู่เพราะ 1B39 เอาปุ่ม + ออกจากแถบล่าง พอปุ่มกลับมาอยู่กลางแถบแล้ว
   ปุ่มสองใบที่เปิดแผ่นเดียวกันห่างกันไม่ถึงนิ้ว คือของที่ต้องอ่านสองรอบเปล่า ๆ
   กฎ .tlrow / .ph-add ถูกลบทิ้ง สวิตช์กลับไปเต็มความกว้างเหมือนเดิม */

/* ============================================================
   1B43 · F2 งานย่อย · F4 นับถอยหลังสอบ · F5 คะแนนที่ได้
   ============================================================ */
/* ชิปสองโทนที่เพิ่มมา — ใช้โทเคนชุด --pri-* เดียวกับชิปเดิมทุกตัว
   ห้ามใช้ --sig-* ตรงนี้ เพราะชิปเหล่านี้วางบนพื้นการ์ดที่พลิกตามธีม */
.tk-chip.warn { background: var(--pri-yellow-soft); color: var(--pri-yellow-text); }
.tk-chip.good { background: var(--good-soft); color: var(--good); }

/* ---- งานย่อยในการ์ด ---- */
/* เยื้องเข้ามาเท่าปุ่มติ๊กของใบใหญ่ เพื่อให้อ่านว่า "อยู่ใต้ใบนี้" ไม่ใช่ "อีกรายการหนึ่ง"
   ไม่มีเส้นคั่นด้านบน — เส้นจะทำให้มันกลายเป็นอีกก้อนในการ์ดเดียว ซึ่งเป็นของที่
   ต้องอ่านสองรอบ · ระยะห่างพอบอกได้แล้วว่าคนละชั้นกัน */
.tk-subs { display: flex; flex-direction: column; gap: 2px; margin: 9px 0 0 34px; }
.tk-sb {
  display: flex; align-items: flex-start; gap: 9px; width: 100%;
  padding: 5px 2px; background: none; border: none; cursor: pointer;
  font-family: inherit; text-align: left; color: var(--ink);
}
.sb-box {
  flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 6px;
  border: 1.5px solid var(--line); display: grid; place-items: center;
  color: transparent; transition: background .14s ease, border-color .14s ease;
}
.sb-box svg { width: 12px; height: 12px; stroke-width: 3; }
.sb-tx { font-size: 13px; line-height: 1.4; }
.tk-sb.on .sb-box { background: var(--good); border-color: var(--good); color: #fff; }
.tk-sb.on .sb-tx { color: var(--muted); text-decoration: line-through; }
.tk-sb:active { opacity: .6; }

/* ---- ช่องคู่ในฟอร์ม (คะแนนที่ได้ / เต็ม) ---- */
.row-2 { display: flex; gap: 9px; }
.row-2 > input { flex: 1; min-width: 0; }

/* คะแนนที่ได้บนใบที่เสร็จแล้ว — ตัวเลขชิดขวา อ่านได้โดยไม่ต้องเข้าไปในใบ
   ตัวเต็มเล็กกว่าและจางกว่า เพราะคนสแกนหาตัวหน้า ไม่ได้หาตัวหาร */
.tk-got {
  flex: none; margin-left: auto; padding-left: 8px;
  font-size: 15px; font-weight: 700; color: var(--good);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.tk-got i { font-style: normal; font-size: 11px; font-weight: 600; opacity: .7; }

/* ============================================================
   1C14 · บล็อก 1B44 ("แผ่นรับปุ่มบนจอล็อกอิน") ถูกถอดทั้งก้อน
   ============================================================
   แผ่นโปร่งที่เป็น "สว่างกว่าพื้นเล็กน้อย" มีหน้าที่แยกครึ่งบนกับครึ่งล่างบนพื้นกรมท่า
   พอพื้นจอกลายเป็นพื้นแอปตามปกติ การ์ดขาวกับพื้นขาวก็เลิกแยกจากกัน — งานแยกชั้น
   ย้ายไปอยู่ที่ .lg-hero แทน (style.css) ซึ่งเป็นใบเดียวที่มีสีบนจอ ตามกฎ 1C13 */

/* ============================================================
   1B45 · F7 — ตารางสลับสัปดาห์
   ============================================================ */
/* สวิตช์ · ชื่อคลาสมี ctx- นำหน้าเพราะ style.css มี .th-grid .sw อยู่แล้วคนละความหมาย
   (อันนั้นคือช่องสีในตัวเลือกธีม) ชื่อชนกันเมื่อไหร่จะหาสาเหตุยากมาก */
.ctx-sw {
  flex: none; width: 46px; height: 28px; padding: 3px; cursor: pointer;
  border: none; border-radius: 999px; background: var(--card2);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background .18s ease;
}
.ctx-sw i {
  display: block; width: 22px; height: 22px; border-radius: 50%;
  background: var(--muted); transition: transform .18s cubic-bezier(.2,.9,.3,1.2), background .18s ease;
}
.ctx-sw.on { background: var(--fill); box-shadow: none; }
.ctx-sw.on i { background: #fff; transform: translateX(18px); }
@media (prefers-reduced-motion: reduce) { .ctx-sw i { transition: none; } }

.ab-pick { align-items: flex-start; }
.ab-btns { display: flex; gap: 7px; flex: none; margin-left: auto; }
.ab-btns .ab {
  width: 46px; min-height: 40px; border-radius: 12px; cursor: pointer;
  border: 1.5px solid var(--line); background: var(--card2); color: var(--muted);
  font-family: inherit; font-size: 15px; font-weight: 700; letter-spacing: .02em;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.ab-btns .ab.on {
  background: var(--fill); border-color: var(--fill); color: var(--on-fill);
}
.ab-btns .ab:active { transform: scale(.94); }
/* คำอธิบายใต้ป้ายต้องขึ้นบรรทัดได้ — ประโยคเตือนยาวกว่าหนึ่งบรรทัดบนจอแคบ */
.ab-pick .sb { white-space: normal; line-height: 1.45; }
/* ตัวเลือกสัปดาห์ในฟอร์มคาบเรียน — สามช่องกว้างเท่ากัน ไม่ใช่เจ็ดช่องแคบ ๆ แบบเลือกวัน */
.ctx-wks { grid-template-columns: repeat(3, 1fr); }
.ctx-wks .ctx-day { font-size: 12.5px; }
/* ป้ายสัปดาห์บนแถวคาบ — โทนเดียวกับป้ายวัน แต่ทำให้แยกออกว่าเป็นคนละมิติ */
.ctx-per u.wk {
  text-decoration: none; background: var(--blue-soft); color: var(--blue);
  border-radius: 999px; padding: 1px 7px; font-size: 10.5px; font-weight: 700;
}

/* ============================================================
   1B46 · กล่อง "ไม่ทัน" บนจอรายวัน — แยกชื่องานออกจากกัน
   ============================================================
   ของเดิมเอาชื่องานมาต่อกันด้วย " · " ทั้งที่ตัวชื่องานเองก็ใช้ " · "
   คั่นวิชากับรายละเอียดอยู่แล้ว ("ภาษาอังกฤษ · เขียน Essay") ผลคือสองงาน
   กลายเป็นสี่ท่อนที่คั่นเหมือนกันหมด แล้วอ่านไม่ออกว่างานไหนจบตรงไหน
   ชื่องานจึงต้องหนากว่าตัวคั่น ตัวคั่นจึงต้องจางกว่าทุกอย่าง */
.dayvd p .vd-t { font-weight: 700; }
.dayvd p .vd-sep {
  font-style: normal; opacity: .45; padding: 0 7px; font-weight: 400;
}

/* ============================================================
   1B47 · มุมมองสัปดาห์ — จอเดียวแทนสามโหมด
   ============================================================
   โครงคือสองคอลัมน์: เลขวันซ้าย งานขวา · เส้นแนวตั้งเส้นเดียวลากผ่านทั้งสัปดาห์
   ทำให้อ่านเป็น "แกนเวลา" ไม่ใช่ "รายการที่มีหัวข้อคั่น" ซึ่งเป็นคนละความหมาย */
.wk { display: flex; flex-direction: column; }
.wk-row {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 10px 0 12px; border-bottom: 1px solid var(--line);
}
.wk-row:last-child { border-bottom: none; }

/* คอลัมน์วัน — กว้างคงที่ทุกแถว ไม่งั้นเลขหลักเดียวกับสองหลักทำให้งานเยื้องกันทั้งสัปดาห์ */
.wk-d {
  flex: none; width: 46px; text-align: center; padding-top: 4px;
  line-height: 1.05; border-radius: 12px;
}
.wk-d b { display: block; font-size: 19px; font-weight: 700; letter-spacing: -.03em; }
.wk-d i { font-style: normal; display: block; margin-top: 3px; font-size: 10.5px; color: var(--muted); }
/* วันนี้เป็นวันเดียวที่มีพื้น — ไม่ใช่สีที่ต่างกันเฉย ๆ เพราะสีอย่างเดียว
   ในคอลัมน์ที่มีตัวเลขเรียงกันสิบกว่าตัวหาไม่เจอด้วยการกวาดตา */
.wk-row.now .wk-d { background: var(--blue-soft); padding: 4px 0 6px; }
.wk-row.now .wk-d b { color: var(--blue); }
.wk-row.now .wk-d i { color: var(--blue); font-weight: 700; }

.wk-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
/* วันที่ไม่มีงานต้องเบาที่สุดบนจอ — มันคือ "ที่ว่าง" ซึ่งเป็นข้อมูล ไม่ใช่ของที่ต้องอ่าน */
.wk-row.empty { padding: 6px 0 7px; }
.wk-none { font-size: 12.5px; color: var(--faint); padding-top: 6px; }

/* การ์ดงานในมุมมองสัปดาห์แคบกว่าตอนอยู่ในลิสต์เต็มความกว้าง ต้องบีบระยะในตัวการ์ดตาม
   ไม่งั้นชื่องานเหลือที่ไม่ถึงครึ่งการ์ด แล้วโดนตัดกลางคำแทบทุกใบ */
.wk-b .tk { padding: 11px 12px; }
.wk-b .tk-ttl { font-size: 14px; }
.wk-b .swipe { margin: 0; }

/* ---- กล่องเลยกำหนด อยู่เหนือสัปดาห์ ----
   ไม่มีวันของตัวเองบนสัปดาห์นี้แล้ว จึงต้องมีที่ของมันเอง
   ยัดลงแถว "วันนี้" ไม่ได้เพราะมันไม่ได้ถึงกำหนดวันนี้ */
.wk-late, .wk-undated { margin-bottom: 14px; }
.wk-late-h {
  display: flex; align-items: center; gap: 7px; padding: 2px 2px 8px;
  font-size: 13px; color: var(--muted);
}
.wk-late-h svg { width: 15px; height: 15px; color: var(--alert); }
.wk-late-h b { font-weight: 700; color: var(--ink); }
.wk-late-h i {
  font-style: normal; margin-left: auto; font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  background: var(--alert-soft); color: var(--alert);
}
.wk-undated .wk-late-h i { background: var(--card2); color: var(--muted); }
.wk-late .tk, .wk-undated .tk { margin-bottom: 8px; }
/* หมุดที่ยกมาจากปฏิทินที่ถูกตัดทิ้ง — ป้ายเล็กเหนืองานของวันนั้น
   ไม่ใช่การ์ด เพราะมันไม่ใช่งานที่ต้องทำ มันคือคำกำกับของวัน */
.wk-marks { display: flex; flex-wrap: wrap; gap: 5px; }
.wk-mark {
  font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  background: var(--card2); color: var(--sj, var(--muted));
  box-shadow: inset 0 0 0 1px var(--line);
}
/* ปุ่ม "ดูอีก N งานที่เลยกำหนด" ท้ายกล่องแดง — เป็นตัวหนังสือ ไม่ใช่ปุ่มทึบ
   กล่องนี้ดังพอแล้วด้วยสีแดงกับตัวเลข ปุ่มทึบอีกใบคือการตะโกนซ้ำ */
.wk-more {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; margin-top: 2px; padding: 10px 0; background: none; border: none;
  cursor: pointer; font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--alert);
}
.wk-more svg { width: 14px; height: 14px; }
/* แถววันที่ถูกยุบ — ช่วงวันแทนเลขวันเดียว ตัวเล็กลงเพราะมันคือ "ที่ว่าง" ไม่ใช่วัน */
.wk-d2 b { font-size: 14px; letter-spacing: -.02em; }
.wk-span .wk-d { padding-top: 6px; }

/* ============================================================
   1B49 · ชิปงานบรรทัดเดียวในมุมมองสัปดาห์
   ============================================================
   ~34px ต่อหนึ่งงาน แทนการ์ดเต็มใบที่ ~90px · ห้าวันจึงอยู่ในพื้นที่เท่ากับ
   ที่การ์ดเต็มใบใช้กับสองงาน ซึ่งเป็นเหตุผลทั้งหมดของมุมมองสัปดาห์
   แถบสีซ้ายคือสีวิชา (คลาส sj-* ชุดเดียวกับทั้งแอป) ไม่ใช่สีความด่วน */
.wc {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 0 8px 0 0; min-height: 34px;
  background: var(--card); border: none; border-radius: 9px;
  border-left: 3px solid var(--sj, var(--muted));
  cursor: pointer; font-family: inherit; color: var(--ink); text-align: left;
  transition: background .14s ease;
}
.wc:active { background: var(--card2); }
.wc b {
  flex: 1; min-width: 0; padding-left: 9px;
  font-size: 13px; font-weight: 600; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ตัวนับข้อย่อย — บอกว่างานใหญ่ใบนี้เดินไปถึงไหนโดยไม่ต้องกางออกมาดู */
.wc u {
  flex: none; text-decoration: none; font-size: 10px; font-weight: 700;
  color: var(--muted); background: var(--card2); border-radius: 999px; padding: 2px 7px;
}
.wc i {
  flex: none; font-style: normal; font-size: 11px; font-weight: 600; color: var(--muted);
}
/* 1B76 · นาฬิกา "เริ่มไม่ทันแล้ว" ในช่องตัวเลขขวาสุด
   ย้อมแค่ตัวเลข ไม่ย้อมแถบสีวิชาและไม่ย้อมพื้นชิป — ตามกฎ 60/30/10 ข้างล่างนี้
   ("สีเตือนควรเป็นของน้อยที่สุดบนจอ") · ตัวเลขสี่ตัวอักษรคือปริมาณสีที่พอดีสำหรับ 10% */
.wc i.hot  { color: var(--alert); }
.wc i.warm { color: var(--warn); }
/* ============================================================
   1B60 · กฎ 60/30/10 บนแถบสีของชิป
   ============================================================
   ของเดิม: งานที่เลยกำหนดได้แถบสีแดงเต็มความสูงชิป แทนที่สีวิชาของมัน
   ผู้ใช้ที่ค้างสี่ใบจึงเห็นแถบแดงสี่แท่งเรียงกันในคอลัมน์เดียว
   บวกตัวเลขแดงอีกสี่ตัว — สีเตือนกลายเป็นสีที่กินพื้นที่มากที่สุดบนจอ
   ซึ่งกลับหัวกฎที่เขียนไว้เองท้ายไฟล์นี้ว่า "สีเตือนควรเป็นของน้อยที่สุดบนจอ"

   แถบสีเป็น "ป้ายชื่อวิชา" ไม่ใช่ "ระดับความด่วน" — สองอย่างนี้แยกกันมาตั้งแต่
   บล็อกสีประจำวิชาใน app.js ("สีชุดนี้เป็นป้ายชื่อ ไม่ใช่ระดับความด่วน")
   งานที่เลยกำหนดก็ยังเป็นวิชานั้นอยู่ การเอาสีแดงไปทับจึงลบข้อมูลหนึ่งชิ้นทิ้ง
   เพื่อบอกอีกชิ้นที่ตัวเลขข้าง ๆ บอกอยู่แล้ว

   ความด่วนเหลืออยู่ที่ตัวเลข "−16ว." ตัวเดียว ซึ่งเล็กแต่ชัดเพราะเป็นสีเดียว
   บนแถวที่เหลือเป็นสีกลางทั้งหมด — เห็นก่อนเพื่อนอยู่ดี */
.wc.late i { color: var(--alert); font-weight: 700; }
/* ปุ่มติ๊ก — วงกลมเปล่าจนกว่าจะกด · เล็กกว่าในการ์ดเต็มใบเพราะชิปทั้งใบก็เตี้ยกว่า
   แต่กล่องกดจริงกินความสูงเต็มชิป (34px) ซึ่งยังพอให้นิ้วกดติด */
.wc-tick {
  flex: none; display: grid; place-items: center;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid var(--line); color: transparent;
  transition: background .14s ease, border-color .14s ease;
}
.wc-tick svg { width: 12px; height: 12px; stroke-width: 3; }
.wc-tick:active { background: var(--good); border-color: var(--good); color: #fff; }

/* ชิปในกองเลยกำหนด/ไม่มีวัน เว้นระยะกันเองเหมือนในแถววัน */
.wk-late .wc, .wk-undated .wc { margin-bottom: 6px; }
.wk-b .wc + .wc { margin-top: 0; }


/* ============================================================
   1B50 · แถววันตามภาพร่าง — คอลัมน์วันมีเส้นแบ่งของตัวเอง
   ============================================================
   ภาพร่างวาดคอลัมน์วันเป็นช่องซ้ายที่แยกออกจากงานด้วยเส้นตั้ง ไม่ใช่เลขลอย ๆ
   เส้นตั้งคือสิ่งที่ทำให้ทั้งก้อนอ่านเป็น "ตาราง" ไม่ใช่ "ลิสต์ที่มีหัวข้อคั่น" */
.wk-row { border-bottom: 1px solid var(--line); padding: 9px 0 10px; }
.wk-b { border-left: 1px solid var(--line); padding-left: 11px; }
.wk-row.now .wk-b { border-left-color: color-mix(in srgb, var(--blue) 45%, transparent); }

/* บรรทัดใต้ชิป — เวลาเรียนกับเวลาว่างของวันนั้น
   ภาพร่างมี "ว่าง 2 ชม. 20 นาที" และ "เรียน 07:40–15:10" ใต้ชิปของวันนั้น
   สองอย่างนี้อธิบายกันเอง: เรียนถึงบ่ายสามจึงว่างแค่นี้ */
.wk-sub { font-size: 11px; color: var(--faint); line-height: 1.5; padding-top: 2px; }
.wk-row.empty .wk-sub { padding-top: 0; }
.wk-row.empty { padding: 7px 0 8px; }

/* ช่องค้นหาย้ายมาท้ายจอ — เบาลงเพราะไม่ใช่ของที่ต้องเห็นก่อน */
#taskList .fr-search { margin-top: 18px; opacity: .85; }

/* ============================================================
   1B51 "Soft" — ชั้นผิวใหม่ทั้งแอป
   ============================================================
   มาจากภาพอ้างอิงที่เจ้าของส่งมา (แอปเรียน/แอปโซเชียลสาย Dribbble)
   สี่อย่างที่ทำให้ภาพพวกนั้นดูแพงกว่าของเรา และไม่มีข้อไหนเกี่ยวกับ "จัดของยังไง":

     1 พื้นจอเป็นไล่สีหลายจุด ไม่ใช่สีเดียว
     2 การ์ดโปร่งแสง + เบลอหลัง + เงานุ่มสองชั้น ไม่ใช่กล่องทึบเงาชั้นเดียว
     3 มุมมนใหญ่ 22–26px
     4 ตัวเลขใช้ฟอนต์คนละตัวกับตัวหนังสือ ตัวเลขจึงอ่านเป็น "ค่า" ไม่ใช่ "คำ"

   ทั้งสี่ข้อเป็นเรื่องผิวล้วน ไม่แตะโครงจอหรือตรรกะสักบรรทัด
   สีเน้นยังเป็นน้ำเงินของ StudentOS ตามที่เจ้าของสั่ง — ความนุ่มมาจากพื้นกับการ์ด
   ไม่ได้มาจากสี (รอบแรกผมลองเป็นม่วงตามภาพอ้างอิง แล้วโดนสั่งกลับมาถูกต้องแล้ว)
   ============================================================ */

/* ---- 1 · พื้นจอไล่สีสามจุด ---- */
/* ธีมสว่าง: ฟ้า/ฟ้าอมเขียว/น้ำเงินอ่อน วางเป็นวงกลมจาง ๆ สามวง
   ต้องอยู่บน .phone ไม่ใช่ body — body อยู่หลังกรอบเครื่องบนจอคอม */
:root[data-theme="light"] .phone,
:root:not([data-theme]) .phone {
  background:
    radial-gradient(120% 80% at 8% 0%, #E6EFFF 0%, transparent 55%),
    radial-gradient(110% 70% at 100% 12%, #E4F6FF 0%, transparent 52%),
    radial-gradient(130% 90% at 50% 100%, #EEF1FF 0%, transparent 58%),
    var(--scr);
}
/* ธีมมืดใช้วงเดียวกันแต่เป็นแสงจาง ๆ ไม่ใช่สีอ่อน — สีอ่อนบนพื้นเข้มกลายเป็นหมอกสีเทา */
:root[data-theme="dark"] .phone {
  background:
    radial-gradient(120% 80% at 8% 0%, rgba(80,130,255,.13) 0%, transparent 55%),
    radial-gradient(110% 70% at 100% 12%, rgba(60,190,255,.09) 0%, transparent 52%),
    radial-gradient(130% 90% at 50% 100%, rgba(110,90,255,.10) 0%, transparent 58%),
    var(--scr);
}

/* ---- 2 · การ์ดโปร่ง + เงานุ่มสองชั้น ---- */
/* เงาสองชั้น: ชั้นบนสั้นและคม (ขอบวัตถุ) ชั้นล่างยาวและจาง (ระยะลอย)
   เงาชั้นเดียวได้ขอบแข็งหรือฟุ้งอย่างใดอย่างหนึ่ง ไม่ได้ทั้งสองอย่าง */
:root {
  --soft-card: rgba(255, 255, 255, .78);
  --soft-shadow: 0 2px 4px rgba(20, 45, 110, .05), 0 14px 34px -12px rgba(20, 45, 110, .18);
  --soft-shadow-lg: 0 4px 10px rgba(20, 45, 110, .07), 0 30px 60px -18px rgba(20, 45, 110, .26);
}
:root[data-theme="dark"] {
  --soft-card: rgba(30, 39, 64, .72);
  --soft-shadow: 0 2px 4px rgba(0, 0, 0, .35), 0 14px 34px -12px rgba(0, 0, 0, .6);
  --soft-shadow-lg: 0 4px 10px rgba(0, 0, 0, .4), 0 30px 60px -18px rgba(0, 0, 0, .7);
}
/* ============================================================
   1B98 · --soft-card เคยมีสองค่าเท่านั้น: ขาว .78 กับค่าของธีม "มืด"
   ------------------------------------------------------------
   แต่ธีมมืดในแอปนี้มีเจ็ดอัน · อีกหกอัน (อวกาศ · เวทมนตร์ · กาแล็กซี · ทะเลลึก ·
   Metaverse · Glitch) จึงตกมาที่ค่า :root ซึ่งเป็น **ขาวทึบ .78**
   แล้วคลาสที่กินค่านี้คือเกือบทุกการ์ดในแอป (.card .st-card .mtile .fd-post .tk
   .hw-now .sd-task .td-rail .td-risk .wg-urgent .pf-list .pf-entry)
   ผลคือการ์ดขาวพร้อมตัวหนังสือสีอ่อนของธีมมืดทับอยู่ = อ่านไม่ออกทั้งใบ
   นี่คือ "บัคการ์ดแบบนี้มีเยอะ" ที่เจ้าของวงมาให้ดูซ้ำหลายรอบ — ต้นเหตุเดียว ไม่ใช่หลายใบ

   ค่าที่ใส่คือสีการ์ดของธีมนั้นเองที่ความทึบ .74 (ยังเป็นกระจกอยู่ ไม่ได้ทึบตัน)
   ⚠️ เพิ่มธีมมืดใหม่เมื่อไหร่ ต้องเพิ่มบรรทัดที่นี่ด้วย ไม่งั้นได้การ์ดขาวกลับมาทันที
   (เจเนซิสเป็น color-scheme: dark ก็จริง แต่พื้นการ์ดมันสว่าง จึงใช้ค่าขาวถูกอยู่แล้ว) */
:root[data-theme="space"]     { --soft-card: rgba(20, 26, 56, .74); }
:root[data-theme="magic"]     { --soft-card: rgba(32, 22, 58, .74); }
:root[data-theme="galaxy"]    { --soft-card: rgba(23, 13, 46, .74); }
:root[data-theme="deepocean"] { --soft-card: rgba(11, 32, 51, .74); }
:root[data-theme="meta"]      { --soft-card: rgba(12, 21, 38, .74); }
:root[data-theme="glitch"]    { --soft-card: rgba(10, 15, 22, .74); }
:root[data-theme="space"], :root[data-theme="magic"], :root[data-theme="galaxy"],
:root[data-theme="deepocean"], :root[data-theme="meta"], :root[data-theme="glitch"] {
  --soft-shadow: 0 2px 4px rgba(0, 0, 0, .35), 0 14px 34px -12px rgba(0, 0, 0, .6);
  --soft-shadow-lg: 0 4px 10px rgba(0, 0, 0, .4), 0 30px 60px -18px rgba(0, 0, 0, .7);
}
.card, .td-rail, .td-risk, .fd-post, .fd-ask, .tk, .st-card, .wg-urgent,
.pf-list, .pf-entry, .mtile, .hw-now, .sd-task {
  background: var(--soft-card);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  box-shadow: var(--soft-shadow);
}

/* ---- 3 · มุมมนใหญ่ขึ้น ---- */
/* ต้องระบุ [data-theme] ให้ครบทุกค่า — style.css ประกาศไว้ที่ :root[data-theme="light"]
   ซึ่งชนะ :root เปล่า ๆ ด้วยความจำเพาะ ต่อให้ไฟล์เราโหลดทีหลังก็ตาม */
:root, :root[data-theme="light"], :root[data-theme="dark"],
:root[data-theme="mono"], :root[data-theme="genesis"] { --r-card: 24px; --r-tile: 18px; }
.card, .td-rail, .td-risk, .fd-post, .wg-urgent { border-radius: var(--r-card); }
.tk { border-radius: 20px; }

/* ---- 4 · ตัวเลขมีฟอนต์ของตัวเอง ---- */
/* Outfit เป็นเรขาคณิตกลม ๆ ตัวเลขจึงอ่านเป็น "ค่า" แยกจากเนื้อความไทย
   ใส่เฉพาะที่ที่ตัวเลขเป็นของหลักจริง ๆ ไม่ใช่ทุกที่ที่มีตัวเลขปน */
.mono, .tk-min, .wc i, .st b, .dr-t, .rk-d b, .tn-title .num,
.page-sub b, .fd-act b, .st-big, .wd b {
  font-family: 'Outfit', 'Space Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* ============================================================
   1B55 · จอ "ฉัน" — แถวสถิติสี่ช่อง
   ============================================================
   สี่ช่องบนความกว้าง 375px เหลือช่องละ ~80px · ระยะห่าง 22px ของสามช่องเดิม
   จึงกว้างเกินไป ตัวเลขจะชิดขอบซ้ายแล้วช่องสุดท้ายล้น
   เปลี่ยนเป็นแบ่งเท่ากันด้วย flex:1 แล้วเส้นคั่นเป็นตัวกำหนดระยะแทน */
.pf-stats.four { gap: 0; justify-content: space-between; }
.pf-stats.four > div:not(.sep) { flex: 1; min-width: 0; text-align: center; }
.pf-stats.four .sep { flex: none; margin: 2px 0; }
.pf-stats.four .v {
  font-size: 21px; letter-spacing: -.03em;
  font-family: 'Outfit', ui-monospace, monospace;
}
.pf-stats.four .k {
  font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ชื่อผู้ใช้ใต้ชื่อจริง — เบากว่าชื่อ แต่ต้องอ่านออกจริง ไม่ใช่จางจนเป็นลายน้ำ
   ใช้ฟอนต์ตัวเลขเพราะ @handle เป็นสตริงระบบ ไม่ใช่คำในภาษา */
.pf-at {
  font-family: 'Outfit', ui-monospace, monospace;
  font-size: 12.5px; font-weight: 600;
  color: rgba(255, 255, 255, .72); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- 1B58 · สัปดาห์ทั้งก้อนอยู่ในการ์ดใบเดียว ----
   แถวที่วางเปล่า ๆ บนพื้นจออ่านเป็น "รายการยาวที่ไม่รู้จบตรงไหน"
   ก้อนที่มีขอบเขตชัดอ่านเป็น "ตารางหนึ่งใบ" ซึ่งเป็นสิ่งที่มันเป็นจริง ๆ */
.wk-card {
  background: var(--soft-card, var(--card));
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow, var(--shadow));
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  padding: 4px 14px;
  margin-top: 14px;
}
/* ชิปในการ์ดไม่ต้องมีพื้นของตัวเองอีก — การ์ดซ้อนการ์ดคือสองขอบเขตทับกัน
   เหลือแค่แถบสีวิชากับเส้นแบ่งแถว ซึ่งพอแล้วสำหรับการแยกงานออกจากกัน */
.wk-card .wc { background: none; border-radius: 0; padding-right: 0; }
.wk-card .wc:active { background: var(--press, rgba(127,127,127,.07)); border-radius: 10px; }
.wk-card .wk-row:last-child { border-bottom: none; }
/* กองเลยกำหนด/ไม่มีวัน ก็เป็นการ์ดใบของตัวเองเหมือนกัน ไม่ใช่แถวลอย */
.wk-late, .wk-undated {
  background: var(--soft-card, var(--card));
  border-radius: var(--r-card);
  box-shadow: var(--soft-shadow, var(--shadow));
  padding: 12px 14px 6px;
}
.wk-late .wc, .wk-undated .wc { background: none; padding-right: 0; }
/* 1B59 · บรรทัด "อีก N ใบที่ค้างอยู่" ในแถววันนี้
   เยื้องเท่าชิป ไม่ใช่เต็มความกว้าง — มันเป็นของของวันนั้น ไม่ใช่ของทั้งสัปดาห์ */
.wk-b .wk-more {
  justify-content: flex-start; padding: 7px 0 4px; margin-top: 0;
  color: var(--muted); font-size: 12px;
}
.wk-b .wk-more svg { opacity: .6; }

/* ============================================================
   1B77 · จอ "AI คิดยังไง" — การ์ดเทียบทางเลือก + คำอธิบายหกข้อ
   ============================================================
   จอนี้มีหน้าที่เดียว: ทำให้ตัวเลขสามตัวเทียบกันได้ด้วยตาในหนึ่งวินาที
   แล้วค่อยให้เหตุผลกับคนที่อยากอ่านต่อ · ลำดับจึงเป็น ตัวเลข → หน่วย → เหตุผล
   ไม่ใช่ เหตุผล → ตัวเลข ซึ่งบังคับให้อ่านก่อนถึงจะเทียบได้ */

.wy-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
/* งานสองใบก็มีแค่การ์ด A กับ B — สองช่องต้องเต็มความกว้าง ไม่ใช่ทิ้งช่องว่างไว้ข้างขวา */
.wy-tiles:has(.wy-t:nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.wy-t {
  border-radius: 14px; padding: 12px 10px; text-align: center;
  background: var(--card2); min-width: 0;
}
.wy-t.good { background: var(--good-soft); }
.wy-t.warn { background: var(--warn-soft); }
.wy-tag {
  font-size: 10.5px; letter-spacing: .04em; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wy-t.good .wy-tag { color: var(--good); }
.wy-t.warn .wy-tag { color: var(--warn); }
/* ตัวเลขคือพระเอกของจอนี้ — ตัวเดียวที่ใหญ่กว่าตัวหนังสือปกติ */
.wy-num { font-size: 26px; font-weight: 700; line-height: 1.25; margin: 2px 0; }
.wy-t.good .wy-num { color: var(--good); }
.wy-t.warn .wy-num { color: var(--warn); }
.wy-act {
  font-size: 11.5px; color: var(--muted); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wy-unit { font-size: 12px; color: var(--faint); margin: 10px 2px 0; line-height: 1.6; }
.wy-unit b { color: var(--muted); font-weight: 600; }

/* แถบ "คืนนี้พักได้" — ขึ้นน้อยมากโดยตั้งใจ ของที่ขึ้นทุกวันไม่มีใครเชื่อ */
.wy-rest {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding: 12px 14px; border-radius: 14px;
  background: var(--good-soft); color: var(--good);
}
.wy-rest svg { width: 18px; height: 18px; flex: none; }
.wy-rest b { font-size: 14px; }
.wy-rest span { font-size: 12.5px; opacity: .85; width: 100%; line-height: 1.5; }

/* หกแถวเหตุผล — คำถามซ้าย คำตอบขวา ไม่มีการ์ดซ้อนการ์ด */
.wy-rows {
  margin-top: 16px; border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; background: var(--card);
}
.wy-r { padding: 11px 14px; border-bottom: 1px solid var(--line); }
.wy-r:last-child { border-bottom: 0; }
.wy-k { font-size: 11.5px; color: var(--faint); margin-bottom: 3px; }
.wy-v { font-size: 13.5px; line-height: 1.6; }
.wy-note { font-size: 11.5px; color: var(--faint); line-height: 1.65; margin: 14px 2px 0; }

/* ทางเข้าบนการ์ด "ตอนนี้" — บรรทัดเงียบ ไม่ใช่ปุ่มที่สอง
   การ์ดใบนั้นมีจุดโฟกัสได้จุดเดียว และจุดนั้นคือ "เริ่มทำเลย" (ดู 1B24) */
.tn-why-go {
  display: flex; align-items: center; gap: 6px; width: 100%;
  margin-top: 10px; padding: 9px 2px 0; border: 0; border-top: 1px solid var(--line);
  background: none; color: var(--muted); font: inherit; font-size: 12.5px;
  text-align: left; cursor: pointer;
}
.tn-why-go svg { width: 15px; height: 15px; flex: none; }
.tn-why-go svg:last-child { margin-left: auto; opacity: .6; }
.tn-why-go:active { opacity: .6; }

/* ตัวเลขประกอบจากอะไร — ก้อนที่เป็นศูนย์ไม่ขึ้น (ดูหมายเหตุใน renderWhy) */
.wy-bd {
  margin-top: 12px; padding: 11px 14px; border-radius: 14px;
  background: var(--card2); display: flex; flex-wrap: wrap; gap: 6px 16px;
}
.wy-bd-h { width: 100%; font-size: 11px; color: var(--faint); margin-bottom: 2px; }
.wy-bd span {
  font-size: 12.5px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: 5px;
}
.wy-bd i { font-style: normal; font-weight: 400; color: var(--muted); font-size: 12px; }

/* การ์ดที่ผลไม่ต่างจากทางที่แนะนำอย่างมีนัยสำคัญ — เป็นกลาง ไม่ใช่สีเตือน
   สีเตือนบนตัวเลขที่เท่ากันคือการบอกข้อมูลผิดด้วยสี ทั้งที่ตัวเลขข้างบนบอกถูกอยู่แล้ว */
.wy-t.flat { background: var(--card2); }
.wy-t.flat .wy-num { color: var(--ink); }

/* 1B78 · สองบรรทัดท้ายจอที่แอปพูดถึงตัวเอง — โปรไฟล์ที่เรียนมา + คะแนนคำทำนายของมันเอง
   แยกกล่องจากหกแถวข้างบนโดยตั้งใจ: ข้างบนคือเรื่องของงาน ตรงนี้คือเรื่องของแอป */
.wy-self {
  margin-top: 14px; border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; background: var(--card2);
}
.wy-self .wy-r { border-bottom-color: var(--line); }
.wy-self .wy-r.soft .wy-v { color: var(--muted); }

/* 1B80 · "ต้องเลือกแล้ว" — ขึ้นเหนือทุกอย่างเมื่อเวลาไม่พอสำหรับทุกใบจริง ๆ
   เป็นก้อนเดียวบนจอนี้ที่ใช้สีเตือนเต็มพื้น เพราะมันเปลี่ยนกรอบของคำถามทั้งหมด
   จาก "ทำอันไหนก่อน" เป็น "ทำทุกอันไม่ได้แล้ว" — ของแบบนี้ขึ้นนาน ๆ ครั้งถึงจะมีน้ำหนัก */
.wy-sac {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: 14px; padding: 13px 15px; border-radius: 14px;
  background: var(--alert-soft); color: var(--alert);
}
.wy-sac svg { width: 18px; height: 18px; flex: none; }
.wy-sac b { font-size: 14px; }
.wy-sac span { width: 100%; font-size: 12.5px; line-height: 1.6; opacity: .9; }

/* ซ้อมรับมือ — แถวเดียวต่อท้ายหกเหตุผล ไม่ใช่กล่องของตัวเอง
   มันเป็นข้อมูลประกอบ ไม่ใช่คำแนะนำ · ขึ้นเฉพาะตอนแผนเปราะจริง */
.wy-frag {
  margin-top: 12px; padding: 11px 14px; border-radius: 14px;
  background: var(--warn-soft);
}
.wy-frag .wy-k { color: var(--warn); }
.wy-frag .wy-v { color: var(--warn); font-size: 13px; }

/* ============================================================
   1B94 · ปุ่มรวม — เมนูสองทาง + แผ่นผู้ช่วย
   ============================================================
   ทรงและระยะยืมจาก .add-sheet (today.css) ทั้งชุด — แผ่นสองแผ่นที่เลื่อนขึ้น
   จากก้นจอเหมือนกันต้องเคลื่อนที่เหมือนกัน ไม่งั้นมันอ่านเป็นคนละแอป
   ตัวเลข z-index ต้องสูงกว่าแถบล่าง (.tabbar) และปุ่มลอย (.fd-fab z-index 6)
   แต่ต่ำกว่าแผ่นเพิ่มงาน (95) ไม่ได้ — ทั้งสองไม่มีวันเปิดพร้อมกัน จึงใช้ชั้นเดียวกันได้ */

/* ---------- เมนูสองทางที่กางจากปุ่ม ---------- */
.fab-hub { position: absolute; inset: 0; z-index: 94; }
.fab-hub[hidden] { display: none; }
.fh-scrim {
  position: absolute; inset: 0; background: rgba(0, 0, 0, .38);
  opacity: 0; transition: opacity .2s ease;
}
.fab-hub.on .fh-scrim { opacity: 1; }

/* --y คือระยะเหนือปุ่มหลัก · ตั้งค่าเป็น inline style ตอนวาด เพราะจำนวนตัวเลือก
   เปลี่ยนได้ (ยังไม่ล็อกอิน = ไม่มีเมนูเลย กดแล้วเปิดผู้ช่วยตรง ๆ) */
.fh-op {
  position: absolute; right: 16px;
  bottom: calc(var(--tabgap) + 78px + var(--y, 52px));
  display: flex; align-items: center; gap: 10px;
  border: 0; background: none; padding: 0; font: inherit; cursor: pointer;
  opacity: 0; transform: translateY(10px);
  transition: opacity .18s ease var(--d, 0s), transform .18s ease var(--d, 0s);
}
.fab-hub.on .fh-op { opacity: 1; transform: none; }
.fh-lb {
  padding: 6px 12px; border-radius: 10px;
  background: var(--card); color: var(--ink);
  font-size: 13.5px; font-weight: 600; white-space: nowrap;
  box-shadow: var(--shadow-lg);
}
.fh-cir {
  position: relative; flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--card); color: var(--blue);
  box-shadow: var(--shadow-lg);
}
.fh-cir svg { width: 20px; height: 20px; }
.fh-op:active .fh-cir { transform: scale(.92); }
.fh-cir i {
  position: absolute; top: -2px; right: -2px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 999px;
  background: var(--bad, #e5484d); color: #fff;
  border: 2px solid var(--card);
  font-style: normal; font-size: 10px; font-weight: 700; line-height: 14px;
  display: flex; align-items: center; justify-content: center;
}
/* ปุ่มหลักหมุนเป็นกากบาทตอนกางอยู่ — บอกว่าการกดครั้งต่อไปคือ "ปิด" ไม่ใช่ "เปิดอีกอัน" */
.fd-fab.open { transform: rotate(90deg); }
.fd-fab { transition: transform .2s ease; }
@media (prefers-reduced-motion: reduce) {
  .fh-scrim, .fh-op, .fd-fab { transition: none; }
}

/* ---------- แผ่นผู้ช่วย ---------- */
.ai-sheet { position: absolute; inset: 0; z-index: 95; }
.ai-sheet[hidden] { display: none; }
.ah-scrim {
  position: absolute; inset: 0; background: rgba(0, 0, 0, .5);
  opacity: 0; transition: opacity .2s ease;
}
.ai-sheet.on .ah-scrim { opacity: 1; }
.ah-card {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 8px 14px calc(20px + env(safe-area-inset-bottom));
  background: var(--card); border-radius: 22px 22px 0 0;
  transform: translateY(100%); transition: transform .24s cubic-bezier(.22, 1, .36, 1);
  max-height: 86%; overflow-y: auto;
}
.ai-sheet.on .ah-card { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .ah-scrim, .ah-card { transition: none; }
}
.ah-grip { width: 38px; height: 4px; margin: 4px auto 12px; border-radius: 999px; background: var(--line); }
.ah-h { margin-bottom: 12px; font-size: 16px; font-weight: 700; color: var(--ink); }
/* บรรทัดรอง = ตัวเลขจริงว่าผู้ช่วยเห็นอะไร ไม่ใช่คำโปรย — จึงเป็นสีปกติที่อ่านออก
   ไม่ใช่สีจางระดับคำบรรยายที่สายตากวาดข้าม */
.ah-h i { display: block; margin-top: 2px; font-style: normal; font-size: 12px;
  font-weight: 400; color: var(--muted); }

.ah-tools { display: flex; flex-direction: column; gap: 8px; }
.ah-tool {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 11px 12px; border: 0; border-radius: 14px;
  background: var(--surface); font: inherit; text-align: left; cursor: pointer;
}
.ah-tool:active { transform: scale(.985); }
.ah-ic {
  flex: none; width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 12px; background: var(--blue); color: var(--on-accent);
}
.ah-ic svg { width: 18px; height: 18px; }
.ah-tx { flex: 1; min-width: 0; }
.ah-tx b { display: block; font-size: 14.5px; font-weight: 600; color: var(--ink); }
.ah-tx span { display: block; margin-top: 1px; font-size: 12px; color: var(--muted); }

/* ทางลัดเป็นชิปแบน ๆ ไม่ใช่การ์ด — ความต่างของรูปทรงคือสิ่งที่บอกว่า
   ของกลุ่มนี้ไปที่น้องไซตัวเดียวกันหมด ไม่ใช่เครื่องมือคนละตัว (เจ้าของสั่งข้อนี้ตรง ๆ) */
.ah-qa-h { margin: 16px 0 7px; font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em; color: var(--muted); }
.ah-qa { display: flex; flex-wrap: wrap; gap: 6px; }
.ah-qa button {
  padding: 7px 13px; border: 1px solid var(--line); border-radius: 999px;
  background: none; color: var(--ink); font: inherit; font-size: 13px; cursor: pointer;
}
.ah-qa button:active { background: var(--surface); transform: scale(.96); }

.ah-ask {
  display: flex; align-items: center; width: 100%; margin-top: 14px;
  padding: 12px 10px 12px 16px; border: 1px solid var(--line); border-radius: 999px;
  background: none; color: var(--muted); font: inherit; font-size: 14px;
  text-align: left; cursor: pointer;
}
.ah-ask-go {
  margin-left: auto; flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; background: var(--blue); color: var(--on-accent);
}
.ah-ask-go svg { width: 15px; height: 15px; }

/* ============================================================
   1B94 · จอ A — งาน › วันนี้ + ตารางเต็มวัน
   ============================================================
   จอนี้ไม่ได้ใช้ .card เป็นทรงหลัก เพราะการ์ดทุกก้อนเท่ากันหมดคือจอที่ไม่มีลำดับ
   สามชั้นที่ต่างกันตั้งใจ: แถวตัวเลข (แบน) · คาบเรียน (การ์ดเงียบ) ·
   งานที่ควรทำก่อน (การ์ดสีเน้น — จุดเดียวที่การตัดสินใจจบ) */

/* ---------- แถวตัวเลขสามช่อง ---------- */
.tb-stats { display: flex; gap: 8px; margin-bottom: 12px; }
.tb-st {
  flex: 1; min-width: 0; padding: 10px 8px; border-radius: 14px;
  background: var(--card); text-align: center;
}
.tb-st b { display: block; font-size: 20px; font-weight: 700; line-height: 1.2; color: var(--ink); }
.tb-st i { display: block; margin-top: 1px; font-style: normal; font-size: 11.5px; color: var(--muted); }

/* ---------- คาบถัดไป ---------- */
/* การ์ดเงียบ: ไม่มีปุ่ม ไม่มีสีเน้น เพราะคาบเรียนไม่ใช่สิ่งที่ผู้ใช้ตัดสินใจได้
   มันคือกรอบที่ทุกอย่างอื่นต้องวางตัวอยู่ข้างใน */
.tb-cls { padding: 12px 14px; border-radius: 16px; background: var(--card); margin-bottom: 10px; }
.tb-cl-lb {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; color: var(--muted); margin-bottom: 4px;
}
.tb-cl-lb svg { width: 13px; height: 13px; }
.tb-cl-t { font-size: 16px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.tb-cl-s { margin-top: 2px; font-size: 12.5px; color: var(--muted); }
.tb-cls.quiet {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 14px; font-size: 13px; color: var(--muted); background: var(--surface);
}
.tb-cls.quiet svg { width: 15px; height: 15px; flex: none; }

/* ชวนสแกนตารางเรียน — ดังกว่าการ์ดอื่นได้ เพราะถ้าไม่มีตารางเรียน
   ตัวเลขทุกตัวบนจอนี้ตั้งอยู่บนการเดา และผู้ใช้ควรรู้ตัว */
.tb-nudge {
  display: flex; align-items: center; gap: 12px; width: 100%; margin-bottom: 10px;
  padding: 12px 14px; border: 1px solid var(--blue); border-radius: 16px;
  background: var(--blue-soft); font: inherit; text-align: left; cursor: pointer;
}
.tb-nd-ic { flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 11px; background: var(--blue); color: var(--on-accent); }
.tb-nd-ic svg { width: 17px; height: 17px; }
.tb-nd-tx { flex: 1; min-width: 0; }
.tb-nd-tx b { display: block; font-size: 14px; font-weight: 600; color: var(--ink); }
/* บรรทัดอธิบายเคยเป็น --muted ตัวบาง บนพื้นการ์ดที่ติดสีธีมอยู่แล้ว — ธีมมืดเหลือเทาจางบนเทา
   (เจ้าของ: "ทำให้สีชัดขึ้น") · หมึกของธีม 85% + หนา 500 ยังเบากว่าหัวข้อหนึ่งขั้น */
.tb-nd-tx span { display: block; margin-top: 1px; font-size: 12px; font-weight: 500; color: color-mix(in srgb, var(--ink) 85%, transparent); line-height: 1.45; }
.tb-nd-go { flex: none; display: flex; color: var(--blue); }
.tb-nd-go svg { width: 16px; height: 16px; }

/* ---------- งานที่ควรทำก่อน ---------- */
.tb-focus {
  padding: 14px 16px 15px; border-radius: 18px;
  background: var(--blue); color: var(--on-accent); margin-bottom: 12px;
}
.tb-fc-lb {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; opacity: .85; margin-bottom: 5px;
}
.tb-fc-lb svg { width: 13px; height: 13px; }
.tb-fc-t { font-size: 17px; font-weight: 700; line-height: 1.32; }
.tb-fc-s { margin-top: 3px; font-size: 12.5px; opacity: .85; }
.tb-fc-go {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; margin-top: 12px; padding: 11px 0; border: 0; border-radius: 12px;
  background: var(--card); color: var(--blue);
  font: inherit; font-size: 14.5px; font-weight: 600; cursor: pointer;
}
.tb-fc-go svg { width: 15px; height: 15px; }
.tb-fc-go:active { transform: scale(.98); }
/* จอว่าง/หมดเวลา — ไม่ใช่สีเน้น เพราะไม่มีอะไรให้ลงมือ การ์ดสีเน้นที่ไม่มีปุ่ม
   คือคำสัญญาที่ไม่มีของจริงรองรับ */
.tb-focus.flat {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 20px 18px; background: var(--card); color: var(--ink);
  border: 0; width: 100%; font: inherit;
}
.tb-focus.flat svg { width: 20px; height: 20px; color: var(--muted); margin-bottom: 3px; }
.tb-focus.flat b { font-size: 14.5px; font-weight: 600; }
.tb-focus.flat span { font-size: 12.5px; color: var(--muted); text-align: center; line-height: 1.5; }
.tb-focus.flat.tap { cursor: pointer; }
.tb-focus.flat.tap:active { transform: scale(.99); }

/* ---------- ไทม์ไลน์ย่อ ---------- */
.tb-tl { display: flex; flex-direction: column; border-radius: 16px; background: var(--card); overflow: hidden; }
.tb-tl-r {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 14px; border: 0; background: none; font: inherit; text-align: left; cursor: pointer;
}
.tb-tl-r + .tb-tl-r { border-top: 1px solid var(--line); }
.tb-tl-r:active { background: var(--surface); }
.tb-tl-t {
  flex: none; width: 38px; font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11.5px; color: var(--muted);
}
.tb-tl-bar { flex: none; width: 3px; align-self: stretch; min-height: 26px; border-radius: 2px; background: var(--blue); }
.tb-tl-bar.ev { background: var(--muted); }
.tb-tl-x { flex: 1; min-width: 0; }
.tb-tl-x b { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tb-tl-x i { display: block; font-style: normal; font-size: 11.5px; color: var(--muted); }

.tb-more {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; margin-top: 10px; padding: 12px 0;
  border: 0; border-radius: 14px; background: var(--surface); color: var(--blue);
  font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
}
.tb-more svg { width: 15px; height: 15px; }
.tb-more:active { transform: scale(.99); }

/* ---------- ตารางเต็มวัน ---------- */
.df-list { display: flex; flex-direction: column; border-radius: 16px; background: var(--card); overflow: hidden; }
.df-r {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 14px; border: 0; background: none; font: inherit; text-align: left;
}
.df-r + .df-r { border-top: 1px solid var(--line); }
button.df-r { cursor: pointer; }
button.df-r:active { background: var(--surface); }
/* ของที่ผ่านไปแล้วยังอยู่ครบแต่จาง — มันคือคำตอบของ "ทำไมวันนี้ถึงไม่เหลือเวลา" */
.df-r.past { opacity: .42; }
.df-t { flex: none; width: 38px; font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11.5px; color: var(--muted); }
.df-bar { flex: none; width: 3px; align-self: stretch; min-height: 24px; border-radius: 2px; background: var(--line); }
/* สีของแถบซ้ายคือชนิดของเวลา ไม่ใช่ความด่วน — คาบเรียนกับกิจวัตรเลือกไม่ได้
   งานเลือกได้ · ความต่างนี้คือสิ่งเดียวที่ทำให้ตารางเต็มวันอ่านเร็วกว่ารายการเรียบ */
.df-r.class .df-bar { background: var(--blue); }
.df-r.rt .df-bar { background: var(--muted); }
.df-r.work .df-bar { background: var(--pri-green, #2E9E6B); }
.df-r.ev .df-bar { background: var(--muted); }
.df-r.brk .df-bar { background: var(--line); }
.df-x { flex: 1; min-width: 0; }
.df-x b { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-x i { display: block; font-style: normal; font-size: 11.5px; color: var(--muted); }

/* ============================================================
   1B95 · แผ่น "เร็ว ๆ นี้"
   ============================================================
   ยืมโครง .add-sheet/.as-scrim/.as-card จาก today.css ทั้งก้อน — ของใหม่มีแค่เนื้อใน
   จัดกลางจอทั้งแผ่น เพราะแผ่นนี้ไม่มีรายการให้เลือก มีข้อความเดียวกับทางไปต่อทางเดียว
   (ต่างจากแผ่นเพิ่มงานที่เป็นรายการ จึงชิดซ้ายเหมือนรายการทุกอัน) */
.soon-card { text-align: center; padding-bottom: calc(24px + env(safe-area-inset-bottom)); }
.soon-ic {
  width: 56px; height: 56px; margin: 4px auto 12px;
  display: grid; place-items: center;
  border-radius: 18px; background: var(--blue-soft); color: var(--blue-deep);
}
.soon-ic svg { width: 26px; height: 26px; }
.soon-t { margin: 0 0 5px; font-size: 19px; font-weight: 700; color: var(--ink); }
/* ความกว้างสูงสุดบังคับให้ข้อความตัดบรรทัดตรงที่อ่านง่าย ไม่ใช่ตรงขอบจอ
   ย่อหน้ากลางจอที่ยาวเต็มความกว้างอ่านยากกว่าย่อหน้าชิดซ้ายเสมอ */
.soon-b {
  margin: 0 auto 18px; max-width: 30ch;
  font-size: 14px; line-height: 1.55; color: var(--muted);
}
.soon-go {
  width: 100%; padding: 13px; border: 0; border-radius: 14px;
  background: var(--fill); color: var(--on-fill);
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
}
.soon-go:active { transform: scale(.98); }
.soon-x {
  width: 100%; margin-top: 6px; padding: 11px; border: 0; border-radius: 14px;
  background: none; color: var(--muted);
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
}

/* ---------- แผ่นบอกทางก่อนออกไปหน้าอนุญาตของ Google (integrations.js) ----------
   ยืมทรง .soon-card ทั้งแผ่น · ขั้นตอนชิดซ้ายเพราะเป็นลำดับที่ต้องอ่านทีละข้อ
   ข้อความกลางจอสามบรรทัดซ้อนกันอ่านเป็นลำดับไม่ออก */
.gg-steps {
  margin: 4px 0 12px; padding-left: 1.3em; text-align: left;
  font-size: 14px; line-height: 1.55; color: var(--ink);
}
.gg-steps li + li { margin-top: 6px; }
.gg-note {
  margin: 0 0 16px; text-align: left;
  font-size: 12.5px; line-height: 1.5; color: var(--muted);
}

/* ---------- แถวในลิสต์แท็บ "ฉัน" ที่ยังไม่เปิด (1B95) ---------- */
/* ป้ายใช้ทรง .pe-wip เดิมของร้านค้า/Pro — แต่โทนฟ้าแทนเหลือง
   เหลือง = "กำลังทำอยู่" · ฟ้า = "ทำเสร็จแล้วแต่ยังไม่เปิด" ซึ่งเป็นคนละสถานะ */
.pe-soon-tag { background: var(--blue-soft); color: var(--blue-deep); }

/* ตัวเลขข้อความค้างบนแถว "ข้อความ" — ทรงเดียวกับจุดแดงบนแถบล่าง
   ไม่ใช่จุดเปล่า ๆ เพราะจำนวนคือสิ่งที่ตัดสินว่าจะกดเข้าไปตอนนี้หรือทีหลัง */
.pe-n {
  display: inline-block; min-width: 19px; margin-left: 7px; padding: 1px 6px;
  border-radius: 999px; background: var(--fill); color: var(--on-fill);
  font-size: 11px; font-weight: 700; line-height: 1.5; text-align: center;
  vertical-align: 1px;
}
.pe-n[hidden] { display: none; }

/* ============================================================
   1B95 · แถบ "โชว์ · พื้นที่ของฉัน"
   ============================================================
   สามช่องเท่ากันเป๊ะ ขอบ เส้นฐาน และระยะในเท่ากันทุกใบ — มันคือของชนิดเดียวกัน
   สามชิ้น ไม่ใช่การ์ดสามใบที่บังเอิญมาอยู่ติดกัน
   สูงเท่ากันด้วย grid ไม่ใช่ปล่อยให้เนื้อในกำหนด เพราะบรรทัดรองยาวไม่เท่ากัน
   (ห้องของฉันอาจยาวถึง "วางของไว้ 12 ชิ้น" ส่วนเหรียญสั้นแค่ "6 จาก 11") */
/* ⚠️ ชื่อคลาสเคยเป็น .sw / .sw-row / .sw-ic แล้วไป **ทับของเดิมสองชุด**:
   `.th-grid .sw` คือช่องสีตัวอย่างของปุ่มเลือกธีม และ `.sw-ic` คือไอคอนบนแถบปัดการ์ด
   `.sw { background: var(--card) }` ความจำเพาะ (0,1,0) เท่ากับ `.sw-space` / `.sw-light`
   แต่ประกาศทีหลัง จึงชนะ — **ช่องสีของธีมทั้ง 11 อันกลายเป็นสี่เหลี่ยมทึบสีเดียวกันหมด**
   (ผู้ใช้ส่งภาพมา 14 ก.ย. 2569: "สีแปลก ๆ" · จอเลือกธีมเป็นวงกลมดำล้วนทั้งตาราง)
   ใช้ชื่อ .shw- ที่ไม่ชนกับใคร · ก่อนตั้งชื่อคลาสใหม่ให้ grep ชื่อนั้นทั้งโฟลเดอร์ก่อนเสมอ */
.shw-row {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  margin-top: 9px;
}
/* 1B98 · สี่ช่อง (เพิ่ม "ธีมสี") — บนจอ 320px ช่องละ ~70px ยังพอให้ชิป 34px
   กับชื่อสองพยางค์อยู่ได้ · ต่ำกว่านี้ต้องตัดเป็นสองแถว ซึ่งแพงกว่าที่ได้คืน */
.shw-4 { grid-template-columns: repeat(4, 1fr); gap: 6px; }
.shw-4 .shw { padding: 11px 4px 12px; }
.shw-4 .shw-ic { width: 34px; height: 34px; }
.shw-4 .shw b { font-size: 12px; }
.shw-4 .shw i { font-size: 10px; }
/* ช่องสีของธีมที่ใช้อยู่ — ไม่มีไอคอนข้างใน ตัวมันเองคือสัญลักษณ์
   ⚠️ **ห้ามประกาศ background ในกฎนี้เด็ดขาด** และห้ามใส่คลาส .shw-ic ให้ element นี้
   ช่องสีมาจากคลาส .sw-* ซึ่งมีความจำเพาะ (0,1,0) เท่ากับกฎนี้เป๊ะ
   ใครก็ตามที่ประกาศ background ทีหลังจะชนะ แล้วช่องกลายเป็นสี่เหลี่ยมเปล่า
   — นี่คือบั๊กเดิมที่ทำให้ช่องสีในลิสต์ทางเข้าว่างเปล่ามาตลอดตั้งแต่ 1B96
   (ที่นั่นตัวทับคือ `#scr-profile .pf-entry .pe-ic` ซึ่งชนะด้วยไอดี) */
.shw-sw {
  width: 34px; height: 34px; margin-bottom: 5px;
  border-radius: 12px; border: 1px solid var(--line);
  background-size: cover; background-position: center;
}
.shw {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 7px 13px; border: 0; border-radius: var(--r-tile);
  background: var(--card); box-shadow: var(--shadow);
  font: inherit; text-align: center; cursor: pointer;
  transition: transform .14s ease;
}
.shw:active { transform: scale(.97); }
/* 1B97 · ช่องที่ยังไม่มีของก็ต้องมีสี — เดิมใช้ --surface ซึ่งบนธีมมืดคือสีเดียวกับ
   พื้นการ์ดแทบทุกหน่วย ชิปจึงหายไปทั้งใบ (ปัญหาเดียวกับที่เจ้าของวงมาให้ดู)
   ยังแยกสองสถานะได้อยู่ แต่แยกด้วย **เฉดสี** ไม่ใช่แยกด้วย "มีสี / ไม่มีสี":
   ยังไม่มีของ = ฟ้าเย็น · มีของแล้ว = ทอง (กฎเดิม ทองใช้กับของที่สำเร็จจริงเท่านั้น) */
.shw-ic {
  width: 38px; height: 38px; margin-bottom: 5px;
  display: grid; place-items: center; border-radius: 12px;
  background: var(--blue-soft); color: var(--blue);
}
.shw-ic svg { width: 19px; height: 19px; }
/* ============================================================
   1C11 · ชิปไอคอนเป็นพื้นทึบ ไม่ใช่พื้นจาง (เจ้าของวงมาเอง)
   ============================================================
   คำสั่ง: "ใส่สีสัญลักษณ์ด้วยให้เข้มขึ้นให้มันต่างจากพื้นหลัง"

   1C10 แจกสีประจำตัวให้เฉพาะใบที่ "มีของแล้ว" ส่วนใบที่ยังไม่มีได้พื้น --card2
   ซึ่งบนธีมมืดห่างจากพื้นการ์ดแค่ไม่กี่หน่วย ชิปจึงหายไปกับพื้นทั้งใบ —
   **เป็นอาการเดียวกับที่ 1B97 เคยแก้ไปแล้ว** (ตอนนั้นต้นเหตุคือ --surface)
   และเป็นสิ่งที่เจ้าของวงมาให้ดูรอบนี้ · กฎเดิมของ 1B97 ที่ต้องรักษาไว้คือ
   "ยังไม่มีของก็ต้องมีสี · แยกสองสถานะด้วยเฉดสี ไม่ใช่ด้วยมี/ไม่มีสี"

   รอบนี้เลิกแยกด้วยสีไปเลย ทุกใบได้สีประจำตัวเต็มเหมือนกันหมด เพราะ:
     • สถานะเขียนเป็นตัวหนังสืออยู่ใต้ชื่อทุกใบแล้ว ("ยังไม่มีเหรียญ" "6 จาก 11")
       ซึ่งอ่านออกในภาพขาวดำและไม่พึ่งการแยกเฉดที่ต่างกันแค่ไม่กี่หน่วย
     • ชิปพื้นทึบเป็นภาษาเดียวกับไอคอนในลิสต์ข้างล่าง (.pe-ic ใช้ --fill/--on-fill)
       จอเดียวกันจึงมีสองแบบ ไม่ใช่สามแบบ

   สีตัวอักษรบนชิปทอง/ชิปไฟใช้ --card ไม่ใช่ค่าขาวตายตัว เพราะพื้นสองอันนั้น
   **สลับขั้วตามธีม** (ทองเข้มในธีมสว่าง ทองอ่อนในธีมมืด) — เหตุผลเดียวกับที่
   ชิป "รับเลย" ของแถบเช็คอินต้องแก้ใน 1C10 · --card เป็นขั้วตรงข้ามของ --ink
   เสมอทุกธีม จึงตรงข้ามกับพื้นพวกนั้นเสมอด้วย
   ส่วนห้อง (--fill) ใช้ --on-fill ตามคู่ของมันเอง ซึ่งเป็นขาวทั้งสองโทนอยู่แล้ว */
.shw-room   .shw-ic { background: var(--fill); color: var(--on-fill, var(--on-accent)); }
.shw-badge  .shw-ic { background: var(--gold-text, var(--warn)); color: var(--card); }
.shw-streak .shw-ic { background: var(--fire, var(--alert)); color: var(--card); }
/* ใบที่ยังไม่มีของ: สีเดียวกัน แต่หรี่ลงนิดหนึ่ง — พอให้รู้สึกต่างเวลาเห็นคู่กัน
   โดยไม่ทำให้มันจมหายไปกับพื้นการ์ด (ซึ่งเป็นบั๊กที่เพิ่งแก้) */
.shw:not(.got) .shw-ic { opacity: .84; }
.shw b {
  font-size: 13px; font-weight: 700; color: var(--ink);
  line-height: 1.25;
}
.shw i {
  font-style: normal; font-size: 11px; line-height: 1.3; color: var(--faint);
}

/* ตัวเลขส่วนตัวที่ย้ายเข้ามาอยู่หัวการ์ด "ผลของฉัน" — คั่นจากกราฟด้วยเส้นผม
   ไม่ใช่ระยะห่างเปล่า ๆ เพราะสองก้อนนี้อ่านคนละแบบ (ตัวเลข vs กราฟ)
   เส้นบอกว่ามันเป็นสองส่วนของการ์ดใบเดียว ไม่ใช่สองการ์ดที่ติดกัน */
.st-priv {
  padding-bottom: 12px; margin-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
/* ป้ายกุญแจบนหัวการ์ด — คุมทั้งใบ ไม่ใช่แค่แถวตัวเลข */
.st-open .sec-label svg {
  width: 12px; height: 12px; vertical-align: -1px; margin-right: 4px;
}

/* ============================================================
   1B95 · จอ "งาน" โหมดวันนี้ — ชิ้นส่วนที่ยุบน้ำหนักลง
   ============================================================
   สองก้อนนี้เคยเป็นการ์ดเต็มใบทั้งคู่ (.tb-cls สามบรรทัด · .tb-stats สามใบ)
   ทั้งที่ไม่มีก้อนไหนต้องตัดสินใจอะไรเลย · ยุบลงมาเป็นแถบบรรทัดเดียว
   เพื่อคืนความดังทั้งหมดให้การ์ด "ควรทำก่อน" ซึ่งเป็นคำตอบจริงของจอนี้ */

/* คาบที่กำลังเรียน / คาบถัดไป — แถวเดียวจบ */
.tb-now {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 13px; margin-bottom: 10px;
  border-radius: 13px; background: var(--card);
  font-size: 13.5px; line-height: 1.4; color: var(--muted);
}
.tb-now b { font-weight: 700; color: var(--ink); }
/* ประโยคทั้งก้อนเป็นชิ้นเดียวในแถว (ดู app.js) · ตัดบรรทัดแบบประโยคปกติ */
.tb-now-tx { min-width: 0; }
/* จุดเขียว = กำลังเกิดขึ้นอยู่ตอนนี้ · จุดเทา = ยังมาไม่ถึง
   สองสถานะนี้ต่างกันจริงและต้องแยกออกด้วยหางตา ไม่ต้องอ่านคำ */
.tb-now-pip {
  width: 7px; height: 7px; flex: none; border-radius: 50%;
  background: var(--good);
}
.tb-now-pip.next { background: var(--faint); }

/* ภาพรวมวันนี้ — สามเลขในแถบเดียว คั่นด้วยเส้น ไม่ใช่สามการ์ด
   ตัวเลขเป็นสีหมึกธรรมดา ไม่ใช่ฟ้า — มันคือข้อมูล ไม่ใช่ของที่กดได้ */
.tb-strip {
  display: flex; margin-bottom: 12px;
  padding: 10px 4px; border-radius: 14px; background: var(--card);
}
.tb-strip > div {
  flex: 1; min-width: 0; text-align: center;
  border-right: 1px solid var(--line);
}
.tb-strip > div:last-child { border-right: 0; }
.tb-strip b {
  display: block; font-size: 16px; font-weight: 700; line-height: 1.25;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.tb-strip i { font-style: normal; font-size: 11px; color: var(--faint); }

/* หัวข้อกลุ่มของคิว — ถ้าไม่มี สามแถวข้างล่างอ่านเป็น "งานทั้งหมดของวันนี้"
   ซึ่งไม่จริง มันคือสามอันแรกของคิว · ปุ่มขวาคือทางไปดูของที่เหลือ */
.tb-grp {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; margin: 0 2px 8px;
}
.tb-grp b { font-size: 13px; font-weight: 700; color: var(--muted); }
.tb-grp button {
  display: inline-flex; align-items: center; gap: 1px;
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--blue);
}
.tb-grp button svg { width: 14px; height: 14px; }

/* ============================================================
   1B96 · แถบเช็คอินรายวันบนสุดของแท็บ "ฉัน"
   ============================================================
   สองสถานะ ต่างกันที่ "เสียง" ไม่ใช่ที่การมีอยู่ — รับแล้วแถบต้องยังอยู่
   ของที่หายไปเลยหลังกด อ่านว่า "แอปพัง" มากกว่า "รับไปแล้ว" */
/* 1C09 · แถวเดียว ไม่ใช่การ์ดสองบรรทัด — วัดของเดิมได้ 68px
   ทรงเดียวกับแถวในลิสต์ข้างล่างเป๊ะ (ชื่อซ้าย · ค่าขวา · สถานะขวาสุด)
   ต่างที่มันเป็นการ์ดของตัวเอง เพราะมันกดแล้วได้ของทันที ไม่ใช่ทางไปจออื่น */
.pe-daily {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 11px 15px;
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); box-shadow: var(--shadow);
  font: inherit; text-align: left; cursor: pointer;
  transition: background .16s ease;
}
.pe-daily:active { background: var(--press, rgba(127,127,127,.07)); }
.pe-daily .pe-ic {
  width: 32px; height: 32px; border-radius: 11px; flex: none;
  display: grid; place-items: center;
  background: var(--gold-soft, var(--warn-soft)); color: var(--gold-text, var(--warn));
}
.pe-daily .pe-ic svg { width: 17px; height: 17px; }
.pe-daily .pe-tx { flex: 1 1 auto; min-width: 0; }
.pe-daily .pe-tx b { font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -.015em; }
/* ค่าชิดขวาก่อนป้ายสถานะ — คอลัมน์เดียวกับลิสต์ข้างล่าง ตาจึงกวาดลงมาได้ทีเดียว */
.pe-daily .pe-v {
  flex: 0 1 auto; min-width: 0;
  font-style: normal; font-size: 12px; font-weight: 500; color: var(--faint);
  text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pe-daily-go { flex: none; font-size: 11.5px; font-weight: 600; color: var(--faint); }

/* ยังไม่ได้รับ = ขอบทอง + ป้ายทึบ · ทองใช้ได้เพราะมันคือของที่ "ได้จริง" เดี๋ยวนี้
   ไม่ใช่ของที่ยังไม่ได้ทำ (กฎเดิมของโปรเจกต์เรื่องสีทอง) */
.pe-daily.live { border-color: var(--gold-text, var(--warn)); }
/* 1C10 · ตัวอักษรบนชิปทองใช้ --card ไม่ใช่ --pg
   ------------------------------------------------------------
   พื้นชิปคือ --gold-text ซึ่ง **สลับขั้วตามธีม**: ธีมสว่างเป็นทองเข้ม (#8A6206)
   ธีมมืดเป็นทองอ่อน (#F0C14A) · ตัวอักษรจึงต้องสลับขั้วตามไปด้วย
   --pg เป็นสีกรอบจอ ซึ่งเข้มเฉพาะในธีมมืด — พอเจอธีมที่ --pg สว่าง
   ได้ตัวอักษรสว่างบนทองเข้ม วัดได้ 1.71:1 ในธีม genesis (--pg #7C8AE0)
   --card เป็นขั้วตรงข้ามของ --ink เสมอทุกธีม จึงตรงข้ามกับ --gold-text เสมอด้วย
   วัดแล้วได้ 5.6–9.9:1 ครบทั้ง 15 ธีม */
.pe-daily.live .pe-daily-go {
  padding: 3px 10px; border-radius: 999px;
  background: var(--gold-text, var(--warn)); color: var(--card);
  font-weight: 700;
}

/* ============================================================
   1C15 · ฟอร์มเพิ่ม/แก้งาน — โครงบล็อกแบบหน้าสั่งอาหาร
   ------------------------------------------------------------
   จอนี้ไม่มี .fm-card ห่ออีกแล้ว (เป็น .fm-sec หลายใบแทน) หน้าตาของช่องกรอก
   ที่ style.css เขียนไว้ให้ลูกของ .fm-card จึงมาไม่ถึง — ต้องเขียนซ้ำให้ .fm-sec
   ทั้งชุด ตัวเลขทุกตัวลอกมาจากของเดิมเป๊ะ เพื่อให้ช่องในจอนี้หน้าตาเดียวกับ
   ช่องกรอกที่อื่นทั้งแอป (ดูบล็อก 1A6M3 ข้างบน)
   สีทุกจุดเป็นโทเคน ไม่มีค่าดิบ — ธีมมืด/โอเชียนจึงไม่ต้องแก้อะไรเพิ่ม
   ============================================================ */
/* จอนี้คุมระยะขอบล่างเองด้วยปุ่มที่ติดขอบ — padding ของจอ (22px จากกฎกลาง)
   ดันขอบล่างของ sticky ขึ้นมา แล้วเนื้อหาโผล่ใต้ปุ่มเป็นแถบ อ่านว่าเลย์เอาต์หลุด */
#scr-form { padding-bottom: 0; }
#scr-form .form-body { padding-top: 14px; padding-bottom: 8px; gap: 10px; }
#scr-form .fm-chips:empty { display: none; }

.fm-sec {
  background: var(--card);
  border-radius: 18px;
  box-shadow: var(--shadow);
  padding: 15px 15px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.fs-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* หัวบล็อก 17px หนา — ของเดิมเป็นป้าย 12px ตัวพิมพ์ใหญ่ ซึ่งอ่านเป็น "ชื่อช่อง"
   ไม่ใช่ "หัวข้อของกลุ่ม" ทั้งฟอร์มจึงแบนเท่ากันหมดไม่มีอะไรนำสายตา
   ไม่ถ่างตัวอักษร (letter-spacing ติดลบ) — คำไทยแตกเป็นตัว ๆ ถ้าถ่าง ดู 1C07–1C08 */
.fs-h { font-size: 17px; font-weight: 700; letter-spacing: -.02em; margin: 0; line-height: 1.3; }
.fs-badge {
  flex: none; font-size: 11.5px; font-weight: 600; white-space: nowrap;
  padding: 4px 10px; border-radius: 999px;
  background: var(--card2); color: var(--muted);
}
.fs-badge.req { background: var(--blue-soft); color: var(--blue-deep); }
.fs-note { margin: -4px 0 0; font-size: 12px; color: var(--faint); line-height: 1.55; }

/* ---- ช่องกรอกในบล็อก (ลอกหน้าตาจาก .fm-card เดิม) ---- */
.fm-sec input[type=text], .fm-sec input[type=number], .fm-sec input[type=date],
.fm-sec input[type=time], .fm-sec select, .fm-sec textarea {
  background: var(--card2); border: none; border-radius: 14px; min-height: 48px; padding: 0 13px;
  font-size: 15px; font-weight: 500; font-family: inherit; color: var(--ink); width: 100%;
  box-shadow: inset 0 0 0 1px var(--line); font-variant-numeric: tabular-nums;
  -webkit-appearance: none; appearance: none;
}
.fm-sec select { background-image: none; }
.fm-sec textarea {
  padding: 12px 13px; line-height: 1.65; display: block; resize: none; overflow: hidden;
}
.fm-sec input:focus, .fm-sec select:focus, .fm-sec textarea:focus {
  box-shadow: none; outline: 2px solid var(--blue); outline-offset: -2px;
}
/* ช่องชื่องานคือช่องเดียวที่ต้องพิมพ์จริง — ให้ตัวใหญ่กว่าช่องอื่นหนึ่งขั้น */
#fDetail { font-size: 16.5px; }
.fm-sec input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px; min-height: 0;
  background: var(--card2); border-radius: 99px; padding: 0; box-shadow: none; outline: none;
}
.fm-sec input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 50%; background: var(--card);
  box-shadow: 0 2px 8px rgba(15,23,42,.2), 0 0 0 2px var(--blue); cursor: pointer;
}
.fm-sec input[type=range]::-moz-range-thumb {
  width: 20px; height: 20px; border: none; border-radius: 50%; background: var(--card);
  box-shadow: 0 2px 8px rgba(15,23,42,.2), 0 0 0 2px var(--blue); cursor: pointer;
}

/* ---- แถวตัวเลือก (ประเภท · วิชา · กำหนดส่ง) ----
   หนึ่งแถวต่อหนึ่งตัวเลือก สูง 52px กดพลาดยาก และตาไล่ลงเป็นคอลัมน์เดียว
   ของเดิมเป็น dropdown สองแตะ กับตาราง 2×2 ที่ตาต้องไล่สองทิศ */
.pick-rows { display: flex; flex-direction: column; }
.pick-rows .pk, .pick-rows .tp {
  display: flex; align-items: center; gap: 11px; width: 100%; min-height: 52px;
  padding: 6px 2px; border: none; border-radius: 0; background: none; box-shadow: none;
  border-bottom: 1px solid var(--line);
  font-family: inherit; font-size: 15.5px; font-weight: 600; color: var(--ink);
  text-align: left; cursor: pointer; transition: color .14s ease;
}
.pick-rows > :last-child { border-bottom: none; }
.pick-rows .tp svg { width: 18px; height: 18px; flex: none; color: var(--faint); }
/* แถวที่เลือกอยู่บอกด้วยจุดกลมกับน้ำหนักตัวอักษร ไม่ใช่สีของตัวหนังสือ
   วัดแล้ว --blue-deep บน --card เหลือ 2.5:1 ในธีม earth กับ 2.97:1 ใน warm
   ซึ่งต่ำกว่าเกณฑ์ของตัวอักษรปกติ — และการอ่านหลักของแถวห้ามพึ่งสีอยู่แล้ว */
.pick-rows .pk.on, .pick-rows .tp.active, .pick-rows .tp.on {
  color: var(--ink); font-weight: 700; background: none; box-shadow: none;
}
.pick-rows .tp.active svg { color: var(--blue); }
/* จุดกลมหน้าแถว: วงแหวนหนา = อันที่เลือกอยู่ (ภาษาเดียวกับ radio ของทั้งโลก) */
.pk-dot {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--line); box-sizing: border-box; transition: border .14s ease;
}
.pick-rows .pk.on .pk-dot, .pick-rows .tp.active .pk-dot { border-width: 7px; border-color: var(--blue); }
.pk-s { margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--faint); }
.pick-rows .pk.on .pk-s { color: var(--blue); }

/* ปุ่มรองใต้บล็อก (พูด/ถ่ายรูปแทน · ดูวิชาทั้งหมด) */
.fs-alt {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; min-height: 44px; border: none; border-radius: 12px;
  background: var(--card2); color: var(--muted);
  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.fs-alt:active { transform: scale(.98); }
.fs-alt svg { width: 15px; height: 15px; }
/* #lu-chevron ชี้ขวาโดยกำเนิด — หมุนให้ชี้ลง แล้วชี้ขึ้นตอนกางครบ */
#subjMore svg { transform: rotate(90deg); transition: transform .16s ease; }
#subjMore.up svg { transform: rotate(-90deg); }

/* เวลาส่ง: แถวเดียว ป้ายซ้าย ช่องขวา — ไม่ต้องมีหัวข้อของตัวเอง */
.due-time { display: flex; align-items: center; gap: 12px; padding-top: 2px; }
.due-time .dt-l { flex: 1; font-size: 14px; font-weight: 600; color: var(--muted); }
.due-time input[type=time] { width: auto; max-width: 132px; }

/* ---- เวลาส่ง: ปุ่มเวลา + หน้าปัด 24 ชม. (renderTimeDial ใน app.js) ----
   แบบหน้าปัดเวลานอนของ iPhone ที่เทสเตอร์ส่งมา: 0 บน 12 ล่าง ลากปุ่มรอบวง ส่วนโค้งนับจากเที่ยงคืน
   ตัวเลขกลางวงคือช่องพิมพ์จริง ไม่ใช่ป้าย */
.due-time .dt-btn {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 10px 0 14px; border: 0; border-radius: 12px;
  background: var(--card2); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--line);
  font-family: inherit; font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums;
  cursor: pointer; transition: transform .15s ease-out, box-shadow .15s ease, color .15s ease;
}
.dt-btn svg { width: 15px; height: 15px; color: var(--faint); transform: rotate(90deg); transition: transform .16s ease; }
.dt-btn.up { color: var(--blue); box-shadow: inset 0 0 0 1.5px var(--blue); }
.dt-btn.up svg { color: var(--blue); transform: rotate(-90deg); }
.dt-btn:active { transform: scale(.96); }
.tdial-wrap[hidden] { display: none; }
.tdial-wrap {
  margin-top: 10px; padding: 14px 10px 10px; border-radius: 18px;
  border: 1.5px solid var(--line); background: var(--card2);
}
#scr-form .tdial-wrap.dcal-open { animation: dcal-open .32s cubic-bezier(.22, 1, .36, 1) both; }
.td-dial { position: relative; width: min(100%, 264px); aspect-ratio: 1; margin: 0 auto; }
.td-dial svg {
  display: block; width: 100%; height: 100%; overflow: visible;
  user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; outline: none;
}
.td-dial svg:focus-visible .td-track { stroke: color-mix(in srgb, var(--blue) 18%, var(--scr)); }
.td-track { fill: none; stroke: var(--scr); stroke-width: 34; }
.td-arc { fill: none; stroke: color-mix(in srgb, var(--blue) 30%, transparent); stroke-width: 34; }
.td-face { fill: var(--card); }
.td-ticks line { stroke: var(--faint); stroke-width: 1; opacity: .45; stroke-linecap: round; }
.td-ticks line.hr { stroke-width: 1.6; opacity: .8; }
.td-nums text {
  fill: var(--muted); font-family: inherit; font-size: 12.5px; font-weight: 700;
  text-anchor: middle; dominant-baseline: central;
}
.td-moon { fill: color-mix(in srgb, var(--blue) 70%, var(--muted)); }
.td-sun circle { fill: var(--warn); }
.td-sun line { stroke: var(--warn); stroke-width: 1.8; stroke-linecap: round; }
.td-knob circle { fill: var(--blue); stroke: var(--card); stroke-width: 3; }
.td-knob .td-knob-dot { fill: var(--on-accent); stroke: none; }
.td-knob { cursor: grab; }
.td-dial svg.drag .td-knob circle:first-child { r: 19; }
.td-dial svg.drag { cursor: grabbing; }
.td-mid {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 1px;
}
.td-mid b { font-size: 26px; font-weight: 800; color: var(--muted); line-height: 1; padding-bottom: 3px; }
#scr-form .td-mid input {
  width: 46px; height: 46px; min-height: 0; padding: 0; margin: 0;
  border: 0; border-radius: 10px; background: transparent; box-shadow: none;
  font-family: inherit; font-size: 30px; font-weight: 800; color: var(--ink); text-align: center;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; caret-color: var(--blue);
}
#scr-form .td-mid input:focus { outline: none; background: var(--blue-soft); color: var(--blue); }
.td-quick { display: flex; gap: 6px; margin-top: 8px; }
.td-quick button {
  flex: 1; min-width: 0; min-height: 36px; padding: 0; border: 0; border-radius: 10px;
  background: var(--card); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line);
  font-family: inherit; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer;
}
.td-quick button.on { background: var(--blue); color: var(--on-accent); box-shadow: none; }
.td-quick button:active { transform: scale(.95); }
@media (prefers-reduced-motion: reduce) { #scr-form .tdial-wrap.dcal-open { animation: none; } }

/* ---- แถวสรุปของช่องที่ข้ามได้ (<details>) ----
   ปิดอยู่ = อ่านได้ว่าค่าปัจจุบันคืออะไรโดยไม่ต้องเปิด
   ซึ่งเป็นเหตุผลที่ยุบได้โดยไม่ทำให้ใครหาช่องไม่เจอ */
.fm-row { display: block; border-bottom: 1px solid var(--line); }
/* กฎคู่แฝดของ .fld[hidden] ใน style.css — ของที่ตั้ง display เองต้องเขียนบรรทัดนี้เสมอ
   ไม่งั้น hidden ของเบราว์เซอร์แพ้ (fGotWrap โผล่ในงานที่ยังไม่มีผลคะแนน) */
.fm-row[hidden] { display: none; }
/* ตัวเดียวกัน: .fm-del ใน style.css เป็น display:flex ปุ่มลบจึงโผล่ในงานที่เพิ่งเพิ่ม
   ทั้งที่ openForm() สั่ง hidden ไว้ถูกแล้ว (วัดด้วย getComputedStyle ได้ flex) */
.fm-del[hidden] { display: none; }
.fm-row:last-child { border-bottom: none; }
.fm-row > summary {
  display: flex; align-items: center; gap: 10px; min-height: 52px;
  cursor: pointer; list-style: none; -webkit-tap-highlight-color: transparent;
}
.fm-row > summary::-webkit-details-marker { display: none; }
.rw-l { font-size: 15px; font-weight: 600; color: var(--ink); }
.rw-v {
  margin-left: auto; display: flex; align-items: center; gap: 9px;
  font-size: 13.5px; font-weight: 600; color: var(--faint);
  font-variant-numeric: tabular-nums; text-align: right;
}
.rw-v::after {
  content: ''; flex: none; width: 7px; height: 7px; margin-right: 2px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  /* 31 ต.ค. 69 · หมุนพร้อมกับแถวที่กาง (app.js · FMROW_MS 280 · ease-out ของ React Bits) — เดิม .16s ease จบก่อนแถวกางเสร็จ */
  opacity: .6; transform: rotate(45deg) translate(-1px, -1px); transition: transform .28s cubic-bezier(.23, 1, .32, 1);
}
.rw-l { transition: color .2s ease-out; }
.fm-row[open] > summary .rw-l { color: var(--blue-deep); }
.fm-row[open] > summary .rw-v::after { transform: rotate(-135deg) translate(-1px, -1px); }
.rw-body { display: flex; flex-direction: column; gap: 9px; padding: 2px 0 14px; }

/* ---- ปุ่มบันทึกที่ติดขอบล่างตลอดการเลื่อน ----
   sticky ไม่ใช่ fixed: มันอยู่ใน .screen ที่เลื่อนอยู่แล้ว จึงไม่ต้องรู้พิกัดจอ
   z-index ต่ำกว่าแถบแท็บ (5) เพื่อไม่ให้พื้นของมันไปบังแคปซูลแท็บ */
.fm-bar {
  position: sticky; bottom: 0; z-index: 4;
  padding: 10px 20px calc(var(--tabgap) + 70px);
  background: linear-gradient(to bottom, transparent, var(--scr) 26%);
}
.fm-bar .fm-save {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; min-height: 58px; border-radius: 18px;
}
.fb-t { font-size: 15.5px; font-weight: 700; letter-spacing: -.01em; }
.fb-s { font-size: 11.5px; font-weight: 600; opacity: .85; font-variant-numeric: tabular-nums; }
.fb-s:empty { display: none; }

/* ---- 16 ต.ค. 69 · ฟอร์มเพิ่มงานสองขั้น (formStep ใน app.js) ----
   ขั้น 1 เห็นแค่ .s1 (งานอะไร · ส่งวันไหน) · ขั้น 2 เห็นแค่ .s2 (ประเภท · วิชา · เวลา · รายละเอียด)
   ไม่มีคลาสขั้นบนจอ (แก้งานเดิม · ตรวจผล AI) = ทุกบล็อกโผล่ครบเหมือนเดิม
   !important เพราะ #fSubjectWrap ถูก setTypePick ตั้ง style.display ตรง ๆ */
#scr-form.fm-s1 .s2, #scr-form.fm-s2 .s1 { display: none !important; }
#scr-form.fm-s1 #fDetail { font-size: 18px; min-height: 58px; }
.fm-step {
  display: inline-block; vertical-align: 3px; margin-left: 8px;
  padding: 3px 9px; border-radius: 999px;
  background: var(--blue-soft); color: var(--ink);
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
}
/* สิ่งที่แกะได้จากชื่องาน — แถวป้ายใต้ช่อง ไม่ใช่ช่องให้กรอก */
.fm-auto { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.fm-auto[hidden] { display: none; }
.fm-auto .fa-l { font-size: 12px; font-weight: 600; color: var(--muted); margin-right: 2px; }
.fm-auto .chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--card2); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12.5px; font-weight: 600;
  animation: chip-pop .4s cubic-bezier(.3, 1.5, .5, 1) backwards;
}
.fm-auto .chip svg { width: 13px; height: 13px; color: var(--good); }
@media (prefers-reduced-motion: reduce) { .fm-auto .chip { animation: none; } }
/* ขั้น 2 · ปุ่มข้ามใต้ปุ่มเสร็จ — งานอยู่ในแผนแล้ว ข้ามจึงต้องดูปลอดภัยพอ ๆ กับกดเสร็จ */
.fm-skip {
  display: block; width: 100%; min-height: 44px; margin-top: 4px;
  border: none; background: none; color: var(--muted);
  font-family: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
}
.fm-skip[hidden] { display: none; }
/* บนเครื่องจริง/จอแคบ แถบแท็บอยู่ในผัง (ดู 1A9n ข้างบน) .screens หดให้เองแล้ว
   ปุ่มจึงไม่ต้องเผื่อที่ให้แถบอีก — ถ้าเผื่อซ้ำจะเหลือช่องว่างใต้ปุ่มเกือบสองนิ้ว */
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) .fm-bar { padding-bottom: 12px; }
}

/* ============================================================
   1C16 · จอสแกนตารางเรียน — เวทีกล้องสด
   ------------------------------------------------------------
   เวทีเป็นพื้นเข้มเสมอทุกธีม และนั่นตั้งใจ: มันคือช่องมองของกล้อง ไม่ใช่การ์ดของแอป
   ทุกแอปที่มีกล้องทำแบบนี้ เพราะภาพจริงต้องเป็นของที่สว่างที่สุดในจอ
   สีตัวอักษรบนเวทีจึงเขียนตรง ๆ ไม่ใช่โทเคน — โทเคนของธีมสว่างจะอ่านไม่ออกบนพื้นนี้
   ============================================================ */
#scr-ttscan { padding-bottom: 0; }
.tt-body { padding-bottom: 8px; gap: 14px; }

/* width: 100% ต้องเขียนตรง ๆ (เจ้าของ 8 ต.ค. 69: "แสกนเราอัตราส่วนไม่อยู่ตรงกลาง")
   aspect-ratio + max-height โดยไม่บอกความกว้าง Chrome ยืดเต็มแถว แต่ Safari หดความกว้างตามสัดส่วน
   แล้วชิดซ้าย — บน iPhone เวทีจึงเหลือ 3/4 ของจอ เบี้ยวไปทางซ้าย ขวาโล่ง
   บอกความกว้างแล้วทั้งสองเจ้าคิดเหมือนกัน: กว้างเต็ม สูง 4/3 ของความกว้างจนชนเพดาน
   ภาพที่ถ่ายได้ตัดตามกรอบจริงอยู่แล้ว (camGrab) สัดส่วนกรอบจะเพี้ยนจาก 3:4 นิดหน่อยก็ไม่เป็นไร
   เพดานขยับ 46 → 54vh: ใต้ชิปคำแนะนำยังว่างอยู่ราวหนึ่งนิ้ว กรอบใหญ่ขึ้น = ตัวหนังสือในภาพใหญ่ขึ้น */
.tt-stage {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  background: #0B1220;
  width: 100%;
  aspect-ratio: 3 / 4;
  max-height: 54vh;
  display: flex; align-items: center; justify-content: center;
}
.tt-stage[hidden] { display: none; }
.tt-stage video, .tt-stage img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.tt-stage video[hidden], .tt-stage img[hidden] { display: none; }
/* ตอนยังไม่มีภาพ: ลายตารางจาง ๆ ให้เห็นว่ากรอบนี้รอรับอะไร ไม่ใช่กล่องดำที่พัง */
.tt-stage.empty::before {
  content: '';
  position: absolute; inset: 26px;
  background:
    repeating-linear-gradient(to right, rgba(255,255,255,.14) 0 1px, transparent 1px 20%),
    repeating-linear-gradient(to bottom, rgba(255,255,255,.14) 0 1px, transparent 1px 25%);
  border-radius: 6px;
}
/* มุมเล็งสี่มุม — ภาษาเดียวกับกล้องสแกนทุกตัว บอกว่า "ให้ของอยู่ในนี้" */
.ttf {
  position: absolute; width: 26px; height: 26px; border: 3px solid var(--neon, #4DA3FF);
  filter: drop-shadow(0 0 6px rgba(77,163,255,.55));
}
/* มุมซ้ายบนเคยต่ำกว่ามุมขวา 18px และมีขีดฟ้าโผล่ข้างใน — คลาส .tl ชนกับ "เส้นเวลา" (.tl ข้างบน)
   ที่ใส่ margin-top/padding/::before ให้ทุกตัวที่ชื่อ tl · กรอบครอบรูปเจอบั๊กเดียวกันและแก้ไปแล้ว (.crop-box .h) */
.tt-stage .ttf { margin: 0; padding: 0; }
.tt-stage .ttf::before { content: none; }
.ttf.tl { top: 12px; left: 12px; border-right: none; border-bottom: none; border-radius: 9px 0 0 0; }
.ttf.tr { top: 12px; right: 12px; border-left: none; border-bottom: none; border-radius: 0 9px 0 0; }
.ttf.bl { bottom: 12px; left: 12px; border-right: none; border-top: none; border-radius: 0 0 0 9px; }
.ttf.br { bottom: 12px; right: 12px; border-left: none; border-top: none; border-radius: 0 0 9px 0; }
/* เส้นกวาด: วิ่งตลอดตอนเล็ง และเร็วขึ้นตอนกำลังอ่าน — เป็นตัวบอกว่าเครื่องยังทำงานอยู่
   จังหวะเดียวกับแถบโหลด แต่ไม่กินที่เพิ่มเลยสักพิกเซล */
.tt-sweep {
  position: absolute; left: 14px; right: 14px; height: 2px; top: 14%;
  background: var(--neon, #4DA3FF);
  box-shadow: 0 0 14px 2px rgba(77,163,255,.65);
  animation: ttSweep 3.2s ease-in-out infinite;
}
.tt-stage.reading .tt-sweep { animation-duration: 1.4s; }
@keyframes ttSweep { 0%, 100% { top: 12% } 50% { top: 84% } }
@media (prefers-reduced-motion: reduce) { .tt-sweep { animation: none; opacity: .5 } }
/* ม่านดำที่ก้นเวที — ประโยคบอกวิธีเล็งต้องอ่านออกแม้เล็งอยู่กับกระดาษขาว
   เงาตัวอักษรอย่างเดียวไม่พอ ภาพสดสว่างกว่าเงาเสมอ */
.tt-stage::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 74px;
  background: linear-gradient(to top, rgba(6,12,24,.72), transparent);
  pointer-events: none;
}
.tt-stage-h {
  position: absolute; left: 0; right: 0; bottom: 14px; text-align: center; z-index: 1;
  font-size: 12px; font-weight: 600; color: #EAF2FF;
  text-shadow: 0 1px 6px rgba(0,0,0,.8);
}

/* แถวชัตเตอร์ */
.tt-shoot { display: flex; align-items: center; justify-content: space-between; gap: 18px; }
.tt-shutter {
  flex: none; width: 72px; height: 72px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--card); box-shadow: inset 0 0 0 3px var(--blue), var(--shadow);
  display: flex; align-items: center; justify-content: center;
  transition: transform .12s ease;
}
.tt-shutter i { width: 56px; height: 56px; border-radius: 50%; background: var(--blue); display: block; }
.tt-shutter:active { transform: scale(.93); }
.tt-gal {
  flex: none; width: 48px; height: 48px; border-radius: 16px; border: none; cursor: pointer;
  background: var(--card2); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
}
.tt-gal svg { width: 20px; height: 20px; }
.tt-gal.ghost { background: none; pointer-events: none; }

.tt-2nd {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  min-height: 46px; border: none; border-radius: 14px; background: var(--card2); color: var(--ink);
  font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; margin-top: 9px;
}
.tt-2nd svg { width: 16px; height: 16px; }
.tt-2nd:active { transform: scale(.98); }

.tt-tips { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-top: 14px; }
/* บรรทัดอธิบายท้ายจอนั่งบนพื้นเพจ ไม่ใช่บนการ์ด — --faint จึงเหลือ 2.16:1 ในธีม genesis
   (วัดแล้ว: --muted ได้ 4.52 · --ink ได้ 5.75) กฎนี้คุมเฉพาะจอนี้ */
#scr-ttscan .tt-foot { color: var(--muted); }
.tt-tips span {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--card2); border-radius: 999px; padding: 6px 11px;
}

/* ขั้นตอนตอนกำลังอ่าน — แทนวงกลมหมุนเปล่า ๆ ที่ไม่ได้บอกว่ากำลังทำอะไรถึงไหน */
.tt-steps { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
.tts { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--faint); }
.tts.done { color: var(--ink); }
.tts.now { color: var(--ink); }
.tts svg { width: 17px; height: 17px; flex: none; color: var(--good); }
.tts i {
  width: 17px; height: 17px; flex: none; border-radius: 50%;
  border: 2px solid var(--line); box-sizing: border-box;
}
.tts.now i { border-color: var(--blue); border-top-color: transparent; animation: ttSpin .9s linear infinite; }

/* หน้าตรวจ — ภาษาเดียวกับฟอร์มเพิ่มงาน 1C15 (บล็อกมีหัวข้อ + ป้ายขวา + ปุ่มติดขอบล่าง) */
.tt-top { margin-top: 2px; }
.tt-day { gap: 8px; padding: 14px 14px 15px; }
.tt-day .tt-list { gap: 0; }
.tt-day .tt-row {
  background: none; box-shadow: none; border-radius: 0; padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.tt-day .tt-row:last-child { border-bottom: none; }
/* ต้องเขียน .fm-sec.tt-day (สองคลาสชนกัน) ไม่ใช่ .tt-day เฉย ๆ
   เพราะ [type=text] นับน้ำหนักเท่า class — .fm-sec input[type=text] จึงเป็น 0,2,1
   ชนะ .tt-day .tt-sub ที่เป็น 0,2,0 — รอบแรกเขียนสั้นไปแล้วกฎไม่ติดสักข้อ */
/* กับดัก: .tt-day ใช้คลาส .fm-sec ด้วย กฎช่องกรอกของ 1C15
   (width:100% · min-height:48px) จึงมาโดนช่องเล็ก ๆ ในแถวคาบเต็ม ๆ
   แล้วช่องเวลาถูกดันหลุดขอบจอ — คืนขนาดของแถวให้กลับมาตรงนี้ */
.fm-sec.tt-day .tt-row { align-items: center; gap: 10px; }
.fm-sec.tt-day .tt-fields { flex: 1; min-width: 0; }
.fm-sec.tt-day .tt-sub {
  background: none; box-shadow: none; border-radius: 0; min-height: 0; padding: 0;
  font-size: 14.5px; font-weight: 650;
}
.fm-sec.tt-day .tt-sub:focus { outline: none; box-shadow: none; border-bottom: 1.5px solid var(--blue); }
.fm-sec.tt-day .tt-when select, .fm-sec.tt-day .tt-when input[type=time] {
  width: auto; min-height: 34px; padding: 0 8px; font-size: 12.5px; border-radius: 10px;
  box-shadow: inset 0 0 0 1px var(--line);
}
.fm-sec.tt-day .tt-when { gap: 5px; }
.fm-sec.tt-day .tt-when select { flex: none; width: 52px; padding: 0 4px; }
/* ช่องเวลายืดเอง — บางเครื่องแสดง AM/PM ซึ่งกินที่กว่าแบบ 24 ชม. อยู่สิบกว่าพิกเซล */
.fm-sec.tt-day .tt-when input[type=time] { flex: 1; min-width: 0; padding: 0 6px; }
.tt-bar { margin: 0 -20px; }
.tt-bar .fm-save:disabled { opacity: .45; }

/* ดาวระดับความสำคัญในป้าย — สีตามป้าย (ไม่ใช่ทอง) · ดวงว่างจางลง */
.pstars { display: inline-block; margin-right: 5px; font-size: .92em; letter-spacing: .5px;
  line-height: 1; font-family: system-ui, sans-serif; }
.pstars .off { opacity: .28; }
/* การ์ด "ควรทำก่อน" (พื้นน้ำเงิน) — ดาวใช้สีตัวอักษรของการ์ด ชิดขวาแถวหัว */
.tb-fc-pri { margin-left: auto; display: inline-flex; align-items: center; font-weight: 700; }
/* แถวคิวถัดไป — ดาวชิดขวา สีตามระดับ (ชุด --pri-* คงที่ทุกธีม) */
.tb-tl-pri { flex: none; font-size: 11px; }
.tb-tl-pri .pstars { margin-right: 0; }
.tb-tl-pri.red { color: var(--pri-red-text); }
.tb-tl-pri.yellow { color: var(--pri-yellow-text); }
.tb-tl-pri.green { color: var(--pri-green-text); }
/* การ์ดในแท็บ "รายการ" — ดาวต่อท้ายชื่อวิชา */
.tk-sub .tk-pri { margin-left: 6px; font-size: 10.5px; }
.tk-sub .tk-pri.solo { margin-left: 0; }
.tk-pri.red { color: var(--pri-red-text); }
.tk-pri.yellow { color: var(--pri-yellow-text); }
.tk-pri.green { color: var(--pri-green-text); }

/* ============================================================
   หัวจอย่อยแบบฝังในเนื้อจอ (.sh-inline) — แบบเดียวกันทุกจอที่เปิดจากแท็บ "ฉัน"
   ------------------------------------------------------------
   เดิมเก้าจอเขียน style="position:static;padding:0" ทับหัวจอปกติไว้ตรง ๆ
   แต่ไม่ได้ถอดพื้นกระจกออก ผลคือมีกล่องสีจางเหลื่อมอยู่หลังชื่อจอ และชื่อจอชิดขอบบน
   กว่าจออื่น 6px (บริบทของฉัน · สแกนตารางเรียน · ถ่ายรูปใบงาน เห็นชัดสุด)
   ส่วน "ผลของฉัน" กับ "ตั้งค่า" ใช้หัวคนละแบบ (ชื่อกึ่งกลาง 17px ลูกศรเปล่า) ย้ายมาใช้ตัวนี้ด้วย
   ระยะบนคิดให้ชื่อจอลงตรงบรรทัดเดียวกับจอแผนวันนี้ (pf-body 6px + 6px = 12px)
   ============================================================ */
.sticky-head.sh-inline {
  position: static; padding: 6px 0 0; margin-bottom: 10px;
  background: none; border-bottom: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
/* จอที่ชื่อจอใหญ่อยู่บรรทัดถัดไป (ร้านค้า · Pro · คนในห้อง · สุ่มสกิน) — ไม่ต้องเว้นซ้ำอีกชั้น */
.sticky-head.sh-inline + .page-head,
.sticky-head.sh-inline + * > .page-head:first-child { padding-top: 0; }

/* ============================================================
   1C33 · จอ "ทำไมอันนี้ก่อน" — ลำดับการมอง: งานที่ต้องทำ → เหตุผล → อันดับ
   สีเดียว (--fill) + แดงเฉพาะตอนเสี่ยงจริง · ไม่มีพื้นสีจาง · ข้อความสั้นที่สุดที่ยังครบ
   ============================================================ */
.wy2-hero { margin: 4px 0 0; padding: 18px; border-radius: 22px; background: var(--fill); color: var(--on-fill); }
.wy2-k { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; opacity: .72; }
.wy2-hero h3 { margin: 4px 0 16px; font-size: 22px; font-weight: 800; line-height: 1.25; letter-spacing: -.02em; }
.wy2-stats { display: flex; gap: 18px; }
.wy2-stats > div + div { padding-left: 18px; border-left: 1px solid rgba(255,255,255,.25); }
.wy2-stats b { display: block; font-size: 22px; font-weight: 800; line-height: 1.1; }
.wy2-stats span { display: block; margin-top: 3px; font-size: 11.5px; opacity: .75; }
.wy2-warn { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; padding: 6px 10px;
  border-radius: 10px; background: rgba(255,255,255,.16); font-size: 12.5px; font-weight: 700; }
.wy2-warn svg { width: 14px; height: 14px; }

.wy2-card { margin-top: 14px; padding: 16px; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); }
.wy2-cap { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; color: var(--faint); margin-bottom: 2px; }
.wy2-row { display: flex; gap: 10px; align-items: center; padding: 11px 0; }
.wy2-row + .wy2-row { border-top: 1px solid var(--line); }
.wy2-n { flex: none; width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center;
  font-size: 12px; font-weight: 800; background: var(--surface); color: var(--fill); }
.wy2-row.top .wy2-n { background: var(--fill); color: var(--on-fill); }
.wy2-main { flex: 1; min-width: 0; }
.wy2-line { display: flex; align-items: baseline; gap: 8px; }
.wy2-line b { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wy2-row.top .wy2-line b { font-weight: 800; }
.wy2-line i { flex: none; font-style: normal; font-size: 12px; color: var(--faint); }
.wy2-more { margin-top: 12px; font-size: 12.5px; color: var(--faint); }


/* ============================================================
   1C33 · เลิกใช้พื้นเขียว/เหลืองจางกับบล็อกใหญ่
   ------------------------------------------------------------
   เจ้าของ: "การ์ดสีเขียวเหลืองมันแปลก ๆ จางแปลก ๆ" · พื้นสีจางทั้งใบทำให้การ์ดดูซีด
   และแย่งสายตากับการ์ดหลักสีน้ำเงิน ทั้งที่ข้อมูลข้างในเป็นเรื่องรอง
   กติกาใหม่: บล็อกใหญ่เป็นการ์ดขาวเสมอ · สีของสถานะอยู่ที่ "เส้นหรือตัวอักษร" เท่านั้น
   ชิปเล็ก ๆ (tk-chip · src-tag · ป้าย) ยังใช้พื้นอ่อนได้ เพราะเล็กพอจะอ่านเป็นป้าย ไม่ใช่การ์ด
   ทองไม่แตะ — ทองคือ "ทำสำเร็จแล้ว" ตามกฎของโปรเจกต์ (an-tile.gold · an-bd.got)
   ============================================================ */
.povf .it { background: var(--card); box-shadow: inset 3px 0 0 var(--warn), var(--shadow); }
.povf.danger .it { background: var(--card); box-shadow: inset 3px 0 0 var(--alert), var(--shadow); }
.povf-head { color: var(--warn); }

.wy-t.good, .wy-t.warn, .wy-t.flat { background: var(--card); box-shadow: inset 0 0 0 1px var(--line); }
.wy-frag { background: var(--card); box-shadow: inset 3px 0 0 var(--warn); }

.src-need, .src-warn { background: none; padding: 2px 0 0; color: var(--warn); }
.src-alt { background: none; padding: 2px 0 0; color: var(--good); }

/* ============================================================
   1C33 · จอบริบทของฉัน — การ์ดขาวชุดเดียวกับจอ "ทำไมอันนี้ก่อน"
   ============================================================ */
.cx2-card { margin-top: 12px; padding: 16px; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); }
.cx2-card:first-child { margin-top: 0; }
.cx2-cap { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em; color: var(--faint); }
.cx2-cap b { font-size: 12px; color: var(--fill); letter-spacing: 0; }
.cx2-pick { border: 0; background: var(--surface); color: var(--ink); font: inherit; font-size: 12px;
  font-weight: 600; letter-spacing: 0; padding: 5px 8px; border-radius: 9px; }
.cx2-big { margin: 4px 0 14px; font-size: 32px; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.cx2-bar { position: relative; display: flex; gap: 2px; height: 14px; border-radius: 6px; overflow: visible; }
.cx2-bar > i { display: block; min-width: 2px; border-radius: 3px; box-shadow: none; }
.cx2-now { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--ink); }
.cx2-axis { display: flex; justify-content: space-between; margin-top: 6px; font-size: 10.5px; color: var(--faint); }
.cx2-slots { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.cx2-slots span { font-size: 12px; font-weight: 600; padding: 4px 9px; border-radius: 8px; background: var(--surface); color: var(--fill); }

.cx2-week { display: flex; gap: 8px; align-items: flex-end; height: 76px; margin-top: 12px; }
.cx2-day { flex: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: stretch;
  gap: 5px; border: 0; background: none; padding: 0; font: inherit; }
.cx2-day i { display: block; border-radius: 5px; background: var(--fill); opacity: .32; }
.cx2-day span { font-size: 11px; color: var(--faint); text-align: center; }
.cx2-day.on i { opacity: 1; }
.cx2-day.on span { color: var(--fill); font-weight: 700; }
.cx2-day.low i { background: var(--alert); opacity: .85; }
.cx2-day.low span { color: var(--alert); font-weight: 700; }

.cx2-gap { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 0; border: 0; background: none;
  font: inherit; font-size: 14px; color: var(--ink); text-align: left; }
.cx2-gap + .cx2-gap { border-top: 1px solid var(--line); }
.cx2-cap + .cx2-gap { margin-top: 4px; }
.cx2-gap span { flex: 1; min-width: 0; }
.cx2-gap > svg { width: 16px; height: 16px; color: var(--faint); }
.cx2-gap.done > svg { width: 18px; height: 18px; color: var(--fill); }
.cx2-gap.done span { color: var(--muted); }
.cx2-plus { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; flex: none;
  font-style: normal; font-size: 13px; font-weight: 700; line-height: 1; color: var(--fill); box-shadow: inset 0 0 0 1.5px var(--fill); }
.cx2-scan { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin-top: 12px;
  padding: 12px; border: 0; border-radius: 14px; background: var(--fill); color: var(--on-fill); font: inherit; font-size: 14.5px; font-weight: 700; }
.cx2-scan svg { width: 18px; height: 18px; }

.cx2-times { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.cx2-times label { display: flex; flex-direction: column; gap: 2px; padding: 10px; border-radius: 16px; background: var(--card); box-shadow: var(--shadow); }
.cx2-times span { font-size: 11px; font-weight: 600; color: var(--faint); }
.cx2-times input { border: 0; background: none; padding: 0; font: inherit; font-size: 17px; font-weight: 800; color: var(--ink); width: 100%; }
.cx2-past { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px 0 0 6px; background: var(--card); opacity: .72; }

/* ============================================================
   1C34 · ปุ่ม + อยู่ในแถบ ไม่ยื่นออกมา
   ------------------------------------------------------------
   เจ้าของ: "ปุ่ม 5 ช่องล่าง มันยืดออกมาอยู่ดี" · วัดจากของจริง: ก้อนกลม 42px ล้นพ้นขอบบน
   ของแถบ 13px และล้นลงล่าง 8px ไปทับป้าย "เพิ่ม" ของตัวเองจนอ่านได้ครึ่งคำ
   แบบเดียวกับ Instagram/TikTok: ก้อนสีอยู่ในแถบพอดี ไม่มีป้าย (ปุ่มมี aria-label อยู่แล้ว)
   ก้อนยังเป็นของชิ้นเดียวในแถบที่มีสีเต็ม จึงยังบอกได้ว่า "ปุ่มนี้ทำงานต่างจากแท็บ"
   ============================================================ */
:root:not([data-nav="side"]) .tab.scan .scan-dot {
  width: 46px; height: 34px; margin: 0; border-radius: 12px;
  outline: 0; box-shadow: none;
}
:root:not([data-nav="side"]) .tab.scan .scan-dot svg { width: 20px; height: 20px; }
:root:not([data-nav="side"]) .tab.scan > span:last-child { display: none; }
/* 1C34 · แถวเหตุผลในจอ "ทำไมอันนี้ก่อน" */
.wy2-why { display: flex; align-items: center; gap: 10px; padding: 9px 0; font-size: 14px; color: var(--ink); }
.wy2-why + .wy2-why { border-top: 1px solid var(--line); }
.wy2-cap + .wy2-why { margin-top: 2px; }
.wy2-why svg { flex: none; width: 16px; height: 16px; color: var(--fill); }
.wy2-why.rest svg { color: var(--good); }
/* 1C34 · จอบริบทแบบกระชับ */
.cx2-wk { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.cx2-wk .cx2-week { height: 56px; margin-top: 10px; }
.cx2-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.cx2-chip { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 0; border-radius: 10px;
  font: inherit; font-size: 12.5px; font-weight: 600; background: var(--surface); color: var(--fill); }
.cx2-chip.done { background: none; color: var(--muted); padding-left: 2px; }
.cx2-chip svg { width: 13px; height: 13px; color: var(--fill); }
.cx2-times { margin-top: 12px; }
.cx2-list { margin-top: 12px; border-radius: 20px; background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.cx2-sec + .cx2-sec { border-top: 1px solid var(--line); }
.cx2-sec > summary { list-style: none; display: flex; align-items: center; gap: 10px; padding: 15px 16px; cursor: pointer;
  font-size: 14.5px; font-weight: 600; color: var(--ink); }
.cx2-sec > summary::-webkit-details-marker { display: none; }
.cx2-sec > summary span { flex: 1; }
.cx2-sec > summary i { font-style: normal; font-size: 13px; font-weight: 500; color: var(--faint); }
.cx2-sec > summary svg { width: 16px; height: 16px; color: var(--faint); transition: transform .15s; }
.cx2-sec[open] > summary svg { transform: rotate(90deg); }
.cx2-sec-body { padding: 0 12px 14px; }
#ctxBody .ctx-wipe { margin-top: 14px; }
.cx2-times label { position: relative; }
.cx2-times b { font-size: 18px; font-weight: 800; color: var(--ink); }
.cx2-times input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }
.cx2-wk .cx2-week { height: 48px; }
#whyBody > .wy2-card { margin-top: 0; }

/* ============================================================
   1C36 · แถบล่างเป็นกระจกใสแบบ iPhone
   ------------------------------------------------------------
   เจ้าของ: "ขอบล่างให้เป็นขอบใส การ์ดนี้ดูใส ๆ ก็ได้ เหมือนไอโฟน"
   กระจกจะดูเป็นกระจกได้ต้องมีของเลื่อนอยู่ข้างหลัง — แถบอยู่ในผังปกติ (1A9n) ไม่มีอะไรลอดใต้มัน
   ทำใสอย่างเดียวจึงได้แค่แผ่นสีจาง · ทางที่ไม่ต้องกลับไปใช้ fixed/absolute (ซึ่ง iOS ตีความเพี้ยน):
   ให้ .screens ยื่นลงไปใต้แถบด้วย margin ติดลบเท่าที่แถบกินที่ (สูง 48 + ระยะล่างของแถบ)
   แล้วชดเชยด้วย padding ล่างของแต่ละจอ เนื้อหาจึงเลื่อนลอดใต้กระจก แต่ของชิ้นสุดท้ายยังพ้นแถบ
   แถบยังอยู่ในผังเหมือนเดิมทุกอย่าง ไม่มีพิกัดขอบจอให้ iOS ตีความผิด
   ============================================================ */
@media (max-width: 768px), (display-mode: standalone) {
  :root { --tb-under: calc(48px + max(6px, calc(env(safe-area-inset-bottom) - 18px))); }
  :root[data-vpshort] { --tb-under: 52px; }
  :root:not([data-nav="side"]) .tabbar {
    position: relative; left: auto; right: auto; bottom: auto; z-index: 5;
    background: color-mix(in srgb, var(--card) 62%, transparent);
    backdrop-filter: blur(22px) saturate(180%); -webkit-backdrop-filter: blur(22px) saturate(180%);
    border: 1px solid var(--glass-line);
    box-shadow: 0 10px 30px -12px rgba(15, 40, 80, .35);
  }
  :root:not([data-nav="side"]) body:not(.login-mode) .screens { margin-bottom: calc(-1 * var(--tb-under)); }
  :root:not([data-nav="side"]) body:not(.login-mode) .screens > .screen { padding-bottom: calc(22px + var(--tb-under)); }
  /* ของที่ปักขอบล่างของจอไว้เอง ต้องยกพ้นกระจกเอง — padding ของจอไม่มีผลกับมัน
     จอแชท: today.css ตั้ง #scr-ai.screen { padding: 0 } ด้วย id จึงต้องทับด้วย id
     ปุ่มบันทึกจอเพิ่มงาน: sticky bottom:0 วัดจากขอบช่องเลื่อน ไม่ใช่จาก padding */
  :root:not([data-nav="side"]) body:not(.login-mode) #scr-ai.screen { padding-bottom: var(--tb-under); }
  :root:not([data-nav="side"]) .fm-bar { bottom: var(--tb-under); }
}

/* ============================================================
   1C40 · กระจก Liquid Glass ทั้งแอป — ยกมาจากไฟล์ที่เจ้าของแต่งไว้ในตัวแก้ดีไซน์
   ------------------------------------------------------------
   แถบล่างเป็นกรอบ dock · ไอคอนบนไทล์/ปุ่มหลัก/ปุ่มกลับเป็นกระจกขอบสะท้อน ·
   หัวจอไม่มีพื้นกระจกยาว · ช่องพิมพ์น้องไซเป็นแคปซูลเดียวกับช่องถามหน้าแรก + แสงฮาโล
   ทุกกฎผูกกับ .phone และใช้ !important เพราะต้องชนะกฎเดิมที่กระจายอยู่ในหลายไฟล์
   การเคลื่อนไหว (ขยายแบบ dock · ฮาโล) อยู่ท้าย app.js
   ============================================================ */
/* dock frame around bottom tab bar (macOS-dock glass pill) */
.phone .tabbar{
  border-radius:26px !important; padding:6px 8px !important;
  background:linear-gradient(180deg,rgba(255,255,255,.62) 0%,rgba(250,252,255,.4) 45%,rgba(255,255,255,.3) 100%) !important;
  -webkit-backdrop-filter:blur(28px) saturate(190%) !important; backdrop-filter:blur(28px) saturate(190%) !important;
  border:1px solid rgba(37,99,235,.30) !important;
  box-shadow:0 0 0 .5px rgba(255,255,255,.75),0 0 0 1px rgba(15,27,45,.06),
    inset 0 1px 0 rgba(255,255,255,.85),inset 0 -1px 0 rgba(15,27,45,.05),
    0 12px 32px rgba(15,27,45,.16) !important;
}
:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch],[data-theme=astral]) .phone .tabbar{
  background:linear-gradient(180deg,rgba(40,52,82,.62),rgba(20,28,48,.5)) !important;
  border-color:rgba(160,185,255,.35) !important;
  box-shadow:0 0 0 .5px rgba(255,255,255,.18),inset 0 1px 0 rgba(255,255,255,.16),0 12px 32px rgba(0,0,0,.45) !important;
}
.tabbar .tab,.tg-grid .tg-t{will-change:transform}
.tabbar .tab{transform-origin:50% 100%}
/* แถบตั้งด้านซ้าย: ขยายจากขอบซ้าย ดันออกไปทางเนื้อหา — แบบ dock ที่วางไว้ข้างจอ */
:root[data-nav="side"] .tabbar .tab{transform-origin:0% 50%}
.tg-grid .tg-t{position:relative;transform-origin:50% 60%}

/* AI composer = same capsule + glass send button as the home ask bar */
.phone .sai-bar{
  align-items:center !important; gap:9px !important; margin-top:10px;
  padding:4px 4px 4px 13px !important; min-height:44px; border-radius:22px !important;
  border:0 !important; outline:0 !important; box-shadow:none !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
  background:var(--card2) !important;
}
.phone .sai-bar:focus-within{border:0 !important; background:var(--card2) !important}
.phone .sai-bar .ai-in{padding:10px 0 10px 6px !important; min-height:0 !important; border-radius:0 !important; background:transparent !important; border:0 !important}
.phone .sai-bar .sb-mic{display:none !important}
.phone .sai-bar .sb-send{
  width:34px !important; height:34px !important; flex:none; align-self:flex-end; margin-bottom:0;
  color:var(--muted) !important;
  background:linear-gradient(135deg,rgba(255,255,255,.23) 0%,rgba(255,255,255,.05) 38%,rgba(255,255,255,.02) 62%,rgba(255,255,255,.13) 100%),rgba(255,255,255,.3) !important;
  border:1px solid rgba(255,255,255,.275) !important;
  box-shadow:0 10px 32px rgba(20,30,90,.16),inset 1.5px 1.5px 0 rgba(255,255,255,.424),inset -1px -1px 0 rgba(255,255,255,.176),inset 0 0 22px rgba(255,255,255,.11),inset 0 -8px 16px -8px rgba(255,255,255,.176) !important;
  -webkit-backdrop-filter:blur(30px) saturate(1.9) brightness(.95) !important;
  backdrop-filter:blur(30px) saturate(1.9) brightness(.95) !important;
}

/* iOS 26 Liquid Glass pass — crisp specular rims, refraction blur, soft lift */
:root{--lg-hi:rgba(255,255,255,.95);--lg-mid:rgba(255,255,255,.55);--lg-lo:rgba(255,255,255,.3);--lg-glow:rgba(255,255,255,.2);--lg-drop:rgba(15,27,45,.34)}
:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch],[data-theme=astral]){--lg-hi:rgba(255,255,255,.72);--lg-mid:rgba(255,255,255,.38);--lg-lo:rgba(255,255,255,.18);--lg-glow:rgba(255,255,255,.12);--lg-drop:rgba(0,0,0,.55)}
.phone .tg-ic{
  background-image:
    radial-gradient(130% 80% at 16% -6%,rgba(255,255,255,.62) 0%,rgba(255,255,255,.14) 38%,transparent 62%),
    radial-gradient(90% 60% at 88% 112%,rgba(255,255,255,.3) 0%,transparent 62%),
    linear-gradient(180deg,rgba(255,255,255,.2),rgba(255,255,255,0) 42%,rgba(255,255,255,.1)) !important;
  border:1px solid var(--lg-mid) !important;
  box-shadow:
    inset 0 1.5px 0 var(--lg-hi), inset 1.5px 0 0 var(--lg-mid),
    inset 0 -1.5px 0 var(--lg-lo), inset -1px 0 0 var(--lg-lo),
    inset 0 0 26px var(--lg-glow),
    0 0 0 .5px rgba(15,27,45,.14),
    0 14px 24px -12px var(--lg-drop), 0 3px 6px -2px rgba(15,27,45,.2) !important;
  -webkit-backdrop-filter:blur(18px) saturate(200%) brightness(1.06) !important;
  backdrop-filter:blur(18px) saturate(200%) brightness(1.06) !important;
}
.phone .tg-ic svg{
  background:linear-gradient(160deg,rgba(255,255,255,.98),rgba(232,243,255,.8)) !important;
  border:1px solid rgba(255,255,255,.95) !important;
  box-shadow:inset 0 1px 0 #fff, inset 0 -1.5px 2px rgba(15,27,45,.12), 0 5px 10px -3px rgba(15,27,45,.3), 0 0 0 .5px rgba(15,27,45,.1) !important;
}
.phone .tc-cta{
  background-image:
    radial-gradient(120% 90% at 18% -10%,rgba(255,255,255,.55) 0%,rgba(255,255,255,.1) 42%,transparent 62%),
    linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,0) 48%,rgba(0,0,0,.08)) !important;
  border:1px solid rgba(255,255,255,.5) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.85), inset 1.5px 0 0 rgba(255,255,255,.4),
    inset 0 -2px 3px rgba(0,0,0,.14), inset 0 0 22px rgba(255,255,255,.14),
    0 0 0 .5px rgba(15,27,45,.2),
    0 14px 26px -10px var(--lg-drop), 0 2px 4px rgba(15,27,45,.2) !important;
}
.phone .tabbar{
  box-shadow:
    inset 0 1.5px 0 var(--lg-hi), inset 0 -1px 0 var(--lg-lo), inset 0 0 22px var(--lg-glow),
    0 0 0 .5px rgba(255,255,255,.7), 0 0 0 1px rgba(15,27,45,.07),
    0 16px 34px -10px var(--lg-drop) !important;
  -webkit-backdrop-filter:blur(30px) saturate(200%) brightness(1.04) !important;
  backdrop-filter:blur(30px) saturate(200%) brightness(1.04) !important;
}
.phone .tabbar .tab.active{
  background-image:
    radial-gradient(120% 90% at 20% -10%,rgba(255,255,255,.5) 0%,rgba(255,255,255,.08) 45%,transparent 65%),
    linear-gradient(180deg,rgba(255,255,255,.18),rgba(255,255,255,0) 50%,rgba(0,0,0,.07)) !important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.8), inset 0 -1.5px 2px rgba(0,0,0,.14), inset 0 0 0 1px rgba(255,255,255,.3), 0 8px 16px -8px var(--lg-drop) !important;
}
.phone .tabbar .scan-dot{
  background-image:
    radial-gradient(120% 90% at 22% -6%,rgba(255,255,255,.6) 0%,rgba(255,255,255,.1) 44%,transparent 64%),
    linear-gradient(180deg,rgba(255,255,255,.2),rgba(255,255,255,0) 50%,rgba(0,0,0,.1)) !important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.85), inset 0 -2px 3px rgba(0,0,0,.16), 0 0 0 3px rgba(255,255,255,.9), 0 0 0 3.5px rgba(15,27,45,.1), 0 10px 18px -6px var(--lg-drop) !important;
}

/* back / exit buttons — thicker chevron, softly rounded liquid-glass tile */
.phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]){
  width:42px !important; height:42px !important; min-width:42px; flex:none;
  display:inline-grid !important; place-items:center; padding:0 !important;
  border-radius:15px !important;
  background:linear-gradient(160deg,rgba(255,255,255,.34),rgba(255,255,255,.08) 55%,rgba(255,255,255,.18)),rgba(255,255,255,.14) !important;
  border:1px solid var(--lg-mid) !important;
  box-shadow:inset 0 1.5px 0 var(--lg-hi), inset 1px 0 0 var(--lg-mid), inset 0 -1px 0 var(--lg-lo), inset 0 0 14px var(--lg-glow),
    0 0 0 .5px rgba(15,27,45,.12), 0 8px 16px -8px var(--lg-drop) !important;
  -webkit-backdrop-filter:blur(16px) saturate(190%) !important; backdrop-filter:blur(16px) saturate(190%) !important;
  color:var(--ink) !important;
}
.phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) svg{
  width:22px !important; height:22px !important; stroke-width:3 !important; stroke-linecap:round; stroke-linejoin:round;
}
.phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]):active{transform:scale(.94)}

/* remove the long glass frame behind sticky headers */
.phone .sticky-head,.phone .sticky-head.row{
  background:transparent !important; border:0 !important; box-shadow:none !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important; outline:0 !important;
}

/* theme picker: drop the square frame nested inside the rounded sheet */
.phone #setBlkTheme,.phone #setBlkTheme.pf-row{
  background:transparent !important; border:0 !important; box-shadow:none !important; outline:0 !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important; border-radius:0 !important;
}

/* theme picker: unused themes = thin outline only (no glass); the one in use keeps the glass frame */
.phone #themePick button:not(.active){
  background:transparent !important; border:1px solid color-mix(in srgb,currentColor 24%,transparent) !important; box-shadow:none !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important; outline:0 !important;
}

/* add-sheet: whiter sheet body on light themes */
:is(:root:not([data-theme]),[data-theme=light],[data-theme=warm],[data-theme=earth],[data-theme=ocean]) .phone .as-card{
  background-image:linear-gradient(180deg,rgba(255,255,255,.97),rgba(255,255,255,.92)) !important;
  background-color:rgba(255,255,255,.94) !important;
}

/* keep the "ask" card readable on the whiter sheet */
:is(:root:not([data-theme]),[data-theme=light],[data-theme=warm],[data-theme=earth],[data-theme=ocean]) .phone .as-hero.wide{
  background:color-mix(in srgb,var(--blue,#2563EB) 6%,#fff) !important;
  border:1px solid color-mix(in srgb,var(--blue,#2563EB) 16%,#fff) !important;
  box-shadow:0 6px 16px -10px rgba(15,27,45,.2) !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
}

/* AI quick-chips: stop the scroller from clipping chip shadows into a grey band */
.phone .sai-qa{padding:8px 0 14px !important; margin:-8px 0 -14px !important; background:transparent !important}
.phone .sai-qa > button{
  box-shadow:inset 1.5px 1.5px 0 rgba(255,255,255,.45), inset -1px -1px 0 rgba(255,255,255,.2), inset 0 0 18px rgba(255,255,255,.12),
    0 4px 10px -6px rgba(20,30,90,.24) !important;
}

.fd-top .fd-title{flex:1;min-width:0}.fd-top .fd-back{margin-right:2px}

/* clearer secondary values in list rows (right column) */
#scr-profile .pf-entry .pe-v, .phone .pe-v{
  color:color-mix(in srgb,var(--ink) 80%,transparent);
  font-size:13px; font-weight:600; letter-spacing:.005em;
}

/* Halo search motion → AI chat composer (ported from cult-ui HaloSearchInput; motion only) */
.phone .sai-bar{position:relative;isolation:isolate}
.phone .sai-bar > :not(.hs-glow):not(.hs-ph){position:relative;z-index:1}
.hs-glow{position:absolute;inset:0;overflow:hidden;border-radius:inherit;pointer-events:none;z-index:0}
.hs-wrap{position:absolute;left:0;right:0;bottom:0;height:50%;opacity:var(--hs-op,.2);transition:opacity .25s ease-out}
.hs-b{position:absolute}
/* สีแสงตามธีม — เจ้าของ: "ตรงแสงที่เคลื่อนไหวข้างล่างใช้สีตามแต่ละธีม"
   ของต้นทางเป็นชมพู/ม่วง/ฟ้า/เหลืองตายตัว ทุกธีมเลยได้แสงสีรุ้งชุดเดียวกัน (ธีมเขียว ธีมส้ม ก็ยังเรืองชมพูม่วง)
   ก้อนใหญ่ = ไล่สีแบรนด์ของธีม (--grad-brand · ธีมที่ตั้งเป็นสีทึบก็ใช้ได้) ·
   ก้อนกลาง = สีเน้นอ่อน · ก้อนเล็ก = สีเน้นเต็ม → อ่อน · Astral Black ทับเป็นเงินไว้ในบล็อกของตัวเอง */
.hs-b1{bottom:-16px;width:192px;height:64px;filter:blur(24px);background:var(--grad-brand,var(--fill));animation:hsA var(--d1,6s) ease-in-out infinite}
.hs-b2{bottom:-12px;width:128px;height:48px;filter:blur(16px);background:linear-gradient(90deg,color-mix(in srgb,var(--fill) 55%,#fff),var(--fill),color-mix(in srgb,var(--fill) 70%,#fff));animation:hsB var(--d2,5s) ease-in-out infinite}
.hs-b3{bottom:-8px;width:96px;height:40px;filter:blur(16px);background:linear-gradient(90deg,var(--fill),color-mix(in srgb,var(--fill) 45%,#fff));animation:hsC var(--d3,4s) ease-in-out infinite}
@keyframes hsA{0%,100%{left:-5%}50%{left:75%}}
@keyframes hsB{0%,100%{left:65%}50%{left:10%}}
@keyframes hsC{0%,100%{left:25%}50%{left:55%}}
.phone .sai-bar.hs-focus{--hs-op:.34;box-shadow:0 0 0 1px color-mix(in srgb,var(--fill) 45%,transparent),0 8px 22px -10px color-mix(in srgb,var(--fill) 50%,transparent) !important}
.phone .sai-bar.hs-type{--d1:3.5s;--d2:3s;--d3:2.4s}
.phone .sai-bar.hs-load{--hs-op:.42;--d1:2.4s;--d2:2s;--d3:1.7s}
.phone .sai-bar.hs-del{--hs-op:.42;--d1:2.35s;--d2:2s;--d3:1.65s}
.hs-del .hs-b1{background:linear-gradient(90deg,#fb7185,#f43f5e,#f97316,#ec4899,#a855f7)}
.hs-del .hs-b2{background:linear-gradient(90deg,#fda4af,#fb923c,#f472b6,#fb7185)}
.hs-del .hs-b3{background:linear-gradient(90deg,#e11d48,#db2777,#c026d3,#9333ea)}
.hs-ph{position:absolute;z-index:2;pointer-events:none;display:flex;white-space:pre;color:var(--faint,#8a94a6)}
.hs-ph.ld{color:var(--muted,#6b7a90)}
.hs-ph span{display:inline-block;white-space:pre;opacity:0;animation:hsIn .16s ease-out forwards}
@keyframes hsIn{to{opacity:1}}
.phone .sai-bar .ai-in::placeholder{color:transparent !important}
.phone .sai-bar.hs-load .ai-in{opacity:1 !important}
.phone .sai-bar .sb-send svg{transition:opacity .2s ease-out,transform .2s ease-out}
.phone .sai-bar.hs-load .sb-send{opacity:1 !important}
.phone .sai-bar.hs-load .sb-send svg{opacity:0;transform:scale(.88) rotate(-90deg)}
.phone .sai-bar.hs-load .sb-send::after{content:"";position:absolute;inset:0;margin:auto;width:14px;height:14px;border-radius:50%;border:2.25px solid currentColor;border-right-color:transparent;opacity:.8;animation:hsSpin .8s linear infinite}
@keyframes hsSpin{to{transform:rotate(360deg)}}
.hs-ghost{position:fixed;z-index:9999;pointer-events:none;white-space:pre-wrap;overflow:hidden}
.hs-ghost span{display:inline-block;white-space:pre}
@media (prefers-reduced-motion:reduce){.hs-b{animation:none}.hs-ph span{animation:none;opacity:1}.phone .sai-bar.hs-load .sb-send::after{animation:none}}

/* ============================================================
   1C40 · ปุ่มกระจก Liquid Glass (ตามภาพ iOS 26 Liquid Glass UI Kit ที่เจ้าของส่งมา)
   ------------------------------------------------------------
   ปุ่มมีสองแบบ แบบเดียวกับใน iOS 26:
   • กระจกสี — ปุ่มหลักของจอ คงสีเดิมของธีมไว้ (background-color ไม่แตะ) แล้วซ้อน
     ประกายบนซ้าย + ขอบขาวใส + เงาในด้านล่างทับลงไป จึงเป็นสีของธีมนั้นเสมอ
   • กระจกใส — ปุ่มรอง/ชิป/ปุ่มไอคอนกลม พื้นฝ้าโปร่ง เบลอของข้างหลัง ขอบขาวสะท้อน
   ของที่ "เลือกอยู่" (ชิป · แท็บ · ช่องวัน · สวิตช์ที่เปิด) เป็นกระจกสี เหมือนปุ่มที่เปิดอยู่ในศูนย์ควบคุม
   ทรงแคปซูล · กดแล้วยุบแล้วเด้งกลับ
   ไม่แตะ: การ์ดเนื้อหา/แถวรายการ (กระจกใน iOS 26 เป็นของปุ่มควบคุม ไม่ใช่ของเนื้อหา) ·
   ปุ่มเข้าสู่ระบบของแบรนด์ (Google/Apple/…) · ปุ่มตัวหนังสือล้วน (.text/.danger/.pf-quiet/.ck-close)
   ของชิ้นเล็ก (แท็บโหมด · ดาว · ช่องวัน · ชิป · สวิตช์) ไม่มีเงาฟุ้งใต้ตัว — ตามที่เจ้าของเคยสั่งไว้ที่ .tk-mode.on:
   เงาฟุ้งใต้ของเล็กอ่านเป็นรอยเปื้อน ไม่ใช่ความสูง
   ใช้โทเคน --lg-* ชุดเดียวกับกระจกด้านบน (ธีมมืดปรับให้เองแล้ว)
   ============================================================ */
:root { --lgb-top: rgba(255,255,255,.42); --lgb-bot: rgba(255,255,255,.06); --lgb-edge: rgba(15,27,45,.10); }
:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch],[data-theme=astral]) {
  --lgb-top: rgba(255,255,255,.14); --lgb-bot: rgba(255,255,255,.02); --lgb-edge: rgba(0,0,0,.35);
}

/* ---------- การกด (ทุกปุ่มในชุดนี้) ---------- */
:root :is(.btn.primary, .btn.secondary, .btn.ghost, .fm-save, .fm-cancel, .sai-cta, .daysheet-go,
          .ib-go, .fr-go, .gc-go, .cp-chip, .so-retry, .ai-read, .cx2-scan, .ep-save, .ep-face-go,
          .pro-cta, .ck-cta, .ig-btns button, .fs-alt, .tb-more, .ib-wide, .ctx-add, .ctx-wipe,
          .bg-pick, .bg-del, .sai-qa > button, .cx2-chip, .sp, .tk-mode, .rm-tab, .ds,
          .th-bell, .tk-go, .sh-wipe, .ig-set, .fd-people, .scan-tile, .voice-hero) {
  transition: transform .42s cubic-bezier(.3,1.6,.5,1), filter .2s ease, box-shadow .2s ease, background-color .14s ease;
}
:root :is(.btn.primary, .btn.secondary, .btn.ghost, .fm-save, .fm-cancel, .sai-cta, .daysheet-go,
          .ib-go, .fr-go, .gc-go, .cp-chip, .so-retry, .ai-read, .cx2-scan, .ep-save, .ep-face-go,
          .pro-cta, .ck-cta, .ig-btns button, .fs-alt, .tb-more, .ib-wide, .ctx-add, .ctx-wipe,
          .bg-pick, .bg-del, .sai-qa > button, .cx2-chip, .sp, .tk-mode, .rm-tab, .ds,
          .th-bell, .tk-go, .sh-wipe, .ig-set, .fd-people, .scan-tile, .voice-hero):active {
  transform: scale(.955);
  filter: brightness(1.07) saturate(1.12);
  transition-duration: .12s;
}

/* ---------- ทรงแคปซูล ---------- */
:root :is(.btn.primary, .btn.secondary, .btn.ghost, .fm-save, .fm-cancel, .sai-cta, .daysheet-go, .ib-go,
          .ai-read, .cx2-scan, .ep-save, .ep-face-go, .pro-cta, .ck-cta, .ig-btns button, .fs-alt,
          .tb-more, .ib-wide, .ctx-add, .ctx-wipe, .bg-pick, .cx2-chip, .sp, .tk-mode, .tk-modes) {
  border-radius: 999px !important;
}
:root .bg-del { border-radius: 50% !important; }

/* ---------- กระจกสี ---------- */
:root :is(.btn.primary, .fm-save, .sai-cta, .daysheet-go:not(.ghost), .ib-go, .fr-go, .ai-read, .cx2-scan,
          .ep-save, .ep-face-go, .pro-cta:not(.done), .ig-btns button.pri, .ig-av-cam,
          .cp-chip.on, .sp.active, .tk-mode.on, .rm-tab.on, .ds.on, .tg.on, .ctx-sw.on) {
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.46) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,0) 50%, rgba(0,0,0,.08)) !important;
  border: 1px solid rgba(255,255,255,.4) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.62), inset 1px 0 0 rgba(255,255,255,.22),
    inset 0 -2px 4px rgba(0,0,0,.14), inset 0 0 18px rgba(255,255,255,.12),
    0 0 0 .5px var(--lgb-edge), 0 12px 24px -12px var(--lg-drop) !important;
}
/* ของชิ้นเล็ก: ประกายเท่าเดิม แต่ไม่มีเงาฟุ้ง */
:root :is(.cp-chip.on, .sp.active, .tk-mode.on, .rm-tab.on, .ds.on, .tg.on, .ctx-sw.on, .ig-av-cam) {
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.6), inset 0 -1.5px 3px rgba(0,0,0,.14),
    inset 0 0 12px rgba(255,255,255,.12), 0 0 0 .5px var(--lgb-edge) !important;
}
:root .cp-chip.on { background-color: var(--blue) !important; color: var(--on-accent) !important; }
/* ปุ่มที่พื้นเป็นไล่สีอยู่แล้ว — ต้องใส่ไล่สีเดิมกลับเป็นชั้นล่างสุด ไม่งั้นประกายกระจกทับสีเดิมหาย */
:root :is(.gc-go.lead, .ck-cta) {
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.5) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0) 50%, rgba(0,0,0,.06)),
    linear-gradient(135deg, #C8850F, #FFD87A) !important;
  border: 1px solid rgba(255,255,255,.5) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.7), inset 0 -2px 4px rgba(120,70,0,.18), inset 0 0 18px rgba(255,255,255,.14),
    0 0 0 .5px rgba(120,70,0,.2), 0 13px 28px -12px rgba(233,169,60,.8) !important;
}
:root .voice-hero {
  background:
    radial-gradient(120% 100% at 14% -10%, rgba(255,255,255,.4) 0%, rgba(255,255,255,.08) 40%, transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,0) 50%, rgba(0,0,0,.08)),
    var(--grad-brand) !important;
  border: 1px solid rgba(255,255,255,.4) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.6), inset 0 -2px 4px rgba(0,0,0,.14), inset 0 0 22px rgba(255,255,255,.12),
    0 0 0 .5px var(--lgb-edge), var(--shadow-brand) !important;
}
:root .voice-hero.rec {
  background:
    radial-gradient(120% 100% at 14% -10%, rgba(255,255,255,.4) 0%, rgba(255,255,255,.08) 40%, transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,0) 50%, rgba(0,0,0,.08)),
    linear-gradient(135deg,#B91C1C 0%,#DC2626 55%,#EA580C 100%) !important;
}
/* ปุ่มกลมของสวิตช์ — หยดแก้วขาว ประกายบน เงาล่าง */
:root :is(.tg .tg-k, .ctx-sw i) {
  background-image: linear-gradient(180deg, #fff, rgba(255,255,255,.86)) !important;
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 2px rgba(15,27,45,.12), 0 0 0 .5px rgba(15,27,45,.12), 0 3px 8px -2px rgba(15,27,45,.35) !important;
}

/* ---------- กระจกใส ---------- */
:root :is(.btn.secondary, .btn.ghost, .fm-cancel, .daysheet-go.ghost, .gc-go:not(.lead), .cp-chip:not(.on), .so-retry,
          .ig-btns button:not(.pri), .fs-alt, .tb-more, .ib-wide, .ctx-add, .ctx-wipe, .bg-pick, .bg-del,
          .sai-qa > button:not(.qa-priv), .cx2-chip:not(.done), .sp:not(.active), .rm-tab:not(.on), .tk-modes,
          .th-bell, .tk-go, .sh-wipe, .ig-set, .fd-people, .scan-tile) {
  /* --lgb-bg ให้ธีมตั้งพื้นกระจกเองได้ (Astral Black) · ไม่ตั้ง = การ์ดของธีมนั้นโปร่ง 52% */
  background-color: var(--lgb-bg, color-mix(in srgb, var(--card) 52%, transparent)) !important;
  background-image: linear-gradient(180deg, var(--lgb-top), var(--lgb-bot) 58%, color-mix(in srgb, var(--lgb-top) 40%, transparent)) !important;
  border: 1px solid var(--lg-mid) !important;
  box-shadow:
    inset 0 1.5px 0 var(--lg-hi), inset 1px 0 0 var(--lg-mid), inset 0 -1px 0 var(--lg-lo),
    inset 0 0 16px var(--lg-glow),
    0 0 0 .5px var(--lgb-edge), 0 8px 18px -10px var(--lg-drop) !important;
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
}
/* ของชิ้นเล็กกับรางของแท็บโหมด: ไม่มีเงาฟุ้ง */
:root :is(.cp-chip:not(.on), .sai-qa > button:not(.qa-priv), .cx2-chip:not(.done), .sp:not(.active), .rm-tab:not(.on), .tk-modes) {
  box-shadow:
    inset 0 1.5px 0 var(--lg-hi), inset 0 -1px 0 var(--lg-lo), inset 0 0 12px var(--lg-glow),
    0 0 0 .5px var(--lgb-edge) !important;
}
/* ปุ่มไอคอนกลม — ไอคอนต้องเข้มพอบนพื้นที่โปร่งลง */
:root :is(.th-bell, .tk-go, .sh-wipe, .ig-set, .fd-people) { color: var(--ink) !important; }
:root .ctx-wipe { color: var(--alert) !important; }
/* ตัวหนังสือบนกระจกใสต้องเข้มพอจะอ่านบนพื้นที่โปร่งลง (ghost เดิมอยู่บนพื้นทึบ --card2) */
:root .btn.secondary { color: var(--blue) !important; }
:root .fm-cancel { color: var(--ink) !important; }

/* ============================================================
   1C40 · แถบล่าง: แท็บที่อยู่เป็นก้อนกระจกสีของธีม · ปุ่ม + กลมมีวงแหวนและป้าย "เพิ่ม"
   ------------------------------------------------------------
   เจ้าของส่งภาพแถบล่างแบบจอกว้างมาให้ทำบนมือถือด้วย และให้ใช้สีตามธีม
   **กลับคำตัดสินเก่าสองข้อโดยตั้งใจ:** 1A9k/1B39 (แท็บที่อยู่เป็นแค่สีตัวอักษร ไม่ใช่ก้อน)
   กับ 1C34 (ปุ่ม + เป็นก้อนเหลี่ยมในแถบ ไม่มีป้าย)
   • แท็บที่อยู่: พื้น --fill / ตัวอักษร --on-fill ของธีม — คู่สีที่ธีมกำหนดความต่างไว้แล้ว อ่านออกทุกธีม
     ประกายกระจกมาจากกฎ .phone .tabbar .tab.active ด้านบน
   • ปุ่ม +: กลม พื้น --grad-brand ของธีม (คนละสีกับก้อนแท็บ ยืนติดกันก็ยังแยกออก)
     วงแหวนเป็นสีธีมผสมขาว · ป้าย "เพิ่ม" กลับมา
     ข้อที่ 1C34 แก้ไว้ยังต้องจริง: ก้อนห้ามทับป้ายของตัวเอง — กินที่ในผัง 21px เท่าไอคอนอื่นเป๊ะ
     (34 − 11 บน − 2 ล่าง) ล้นขึ้นบนนิดเดียว ล้นลงล่าง 2px ซึ่งยังอยู่ในช่องไฟ 3px เหนือป้าย
   • กรอบแถบเป็นสีธีมจาง ๆ แทนน้ำเงินตายตัว
   --grad-brand ของธีมมืดเป็นสีเดี่ยว ไม่ใช่ไล่สี จึงต้องใช้ background แบบย่อ
   (ชั้นสุดท้ายของ background ย่อรับสีได้ ส่วน background-image รับไม่ได้ ทั้งบรรทัดจะเป็นโมฆะ)
   ============================================================ */
.phone .tabbar { border-color: color-mix(in srgb, var(--fill) 34%, transparent) !important; }

:root:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) {
  background-color: var(--fill) !important;
  color: var(--on-fill) !important;
  border-radius: 16px;
}

/* หน้าตาปุ่ม + ใช้ชุดเดียวกันทั้งแถบล่างและแถบตั้งด้านซ้าย (จอกว้าง)
   เจ้าของ: "ตรงปุ่มตรงกลาง ทำให้รูปแรก (แถบข้าง) เหมือนรูปสอง (แถบล่าง)" — แถบข้างเคยเป็นวงกลมกระจกเข้ม
   มีวงแหวนขาวหนา ไม่ใช่ปุ่มสีธีม · ต่างกันแค่ขนาด/ระยะ ซึ่งแยกไว้ข้างล่างตามโหมด */
.phone .tabbar .tab.scan .scan-dot {
  border-radius: 50%;
  outline: none;
  color: #fff;
  background:
    radial-gradient(120% 90% at 26% -4%, rgba(255,255,255,.55) 0%, rgba(255,255,255,.1) 44%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,0) 50%, rgba(0,0,0,.12)),
    var(--grad-brand) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.75), inset 0 -2px 3px rgba(0,0,0,.18),
    0 0 0 2.5px color-mix(in srgb, var(--fill) 42%, #fff),
    0 8px 16px -6px var(--lg-drop) !important;
}
:root:not([data-nav="side"]) .phone .tabbar .tab.scan .scan-dot {
  width: 34px; height: 34px;
  margin: -11px 0 -2px;
}
:root:not([data-nav="side"]) .phone .tabbar .tab.scan .scan-dot svg { width: 19px; height: 19px; stroke-width: 2.4; }
/* แถบข้างมีที่แนวตั้งเหลือ ไม่ต้องยกลอยขึ้นจากแถบ — วางในก้อนตรง ๆ ใหญ่กว่าแถบล่างนิดหนึ่งตามความกว้างแถบ */
:root[data-nav="side"] .phone .tabbar .tab.scan .scan-dot {
  width: 42px; height: 42px;
  margin: 0 0 4px;
}
:root[data-nav="side"] .phone .tabbar .tab.scan .scan-dot svg { width: 22px; height: 22px; stroke-width: 2.4; }
:root:not([data-nav="side"]) .phone .tabbar .tab.scan > span:last-child { display: block; }

/* ============================================================
   1C40 · ธีม Astral Black — อวกาศขาวดำ
   ------------------------------------------------------------
   ดำสนิท #000 แบบจอ OLED · ทุกอย่างเป็นขาว–เงิน–เทา ไม่มีสีอิ่มเลยนอกจากสีสถานะ
   (แดง/เหลือง/เขียวของป้ายความสำคัญยังต้องแยกกันออก — ลดความสดลงแต่ไม่ทำเป็นเทา)
   รอบสาม: เจ้าของส่งภาพแนวอ้างอิงมา (อวกาศขาวดำ · สายคลื่นเงินไหลเป็นชั้นเหมือนหมึก ·
   ดาวเคราะห์ลายแถบ · ดาวจิ๋วเต็มฟ้า) และสั่งให้ "เอาแนวมาใช้ รวมถึงสี UI" — **ไม่ได้ใส่ภาพ**
   ฉากทั้งหมดวาดใหม่เป็น SVG ในไฟล์นี้ (สร้างด้วย seed ตายตัว ลายเดิมทุกครั้ง)
   สีรอบสอง (เงินน้ำแข็ง/ฟ้าเหล็ก) จึงถูกถอดเป็นขาวดำทั้งหมดตามภาพนี้
   ⚠️ ธีมมืดมีรายชื่อกระจายอยู่หลายที่ — บล็อกนี้ประกาศของตัวเองครบในที่เดียว
   ส่วนรายชื่อ :is(...) ของกระจก 1C40 ถูกเติม astral เข้าไปตรง ๆ
   ============================================================ */
:root[data-theme="astral"] {
  color-scheme: dark;
  --scr:#000000; --card:#0D0D0D; --card2:#181818; --surface:#181818;
  --ink:#F5F5F5; --muted:#A9A9A9; --faint:#8E8E8E;
  --line:rgba(255,255,255,.09);
  /* สีเน้น = เงินขาว · ก้อนสีเน้นจึงเป็นเงินสว่าง ตัวอักษรบนก้อนเป็นดำ (15.9:1) */
  --blue:#E6E6E6; --blue-soft:rgba(230,230,230,.16); --blue-deep:#FFFFFF; --on-accent:#0A0A0A;
  --neon:#FFFFFF;
  --alert:#F28B8B; --alert-soft:rgba(242,139,139,.22);
  --warn:#E8CC85;  --warn-soft:rgba(232,204,133,.22);
  --good:#8FD9B8;  --good-soft:rgba(143,217,184,.22); --fire:#F28B8B;
  --shadow:0 2px 8px rgba(0,0,0,.7), 0 18px 42px -14px rgba(0,0,0,.95);
  --shadow-lg:0 4px 12px rgba(0,0,0,.75), 0 36px 68px -18px rgba(0,0,0,1);
  --shadow-brand:0 10px 30px -8px rgba(255,255,255,.16);
  --glass:rgba(0,0,0,.78); --glass-line:rgba(255,255,255,.12);
  --skel:rgba(255,255,255,.06); --skel-hi:rgba(255,255,255,.12);
  /* ไล่สีแบรนด์มีตัวหนังสือ/ไอคอนขาวทับเสมอ (ปุ่ม + · ปุ่มไมค์) → เทากราไฟต์
     ขาวทับได้ 5.1:1 ขึ้นไปตลอดเส้น (เงินอ่อนแบบสีเน้นได้แค่ 1.2:1) */
  --grad-brand:linear-gradient(135deg,#6E6E6E 0%,#2B2B2B 100%);
  --grad-hero:linear-gradient(150deg,#262626 0%,#070707 100%);
  --glow-scan:0 0 0 1px rgba(255,255,255,.35), 0 8px 28px -4px rgba(255,255,255,.16);
  --pg:#000000; --pg-ink:#F5F5F5; --pg-muted:#A9A9A9; --frame:#000000;
  --r-card:22px; --r-tile:15px;
  /* การ์ดกระจก — ดำโปร่งบนดำ แยกจากพื้นด้วยขอบกับเงา ไม่ใช่ด้วยความสว่าง */
  --soft-card:rgba(12,12,12,.74);
  --soft-shadow:0 0 0 1px rgba(255,255,255,.06), 0 14px 34px -12px rgba(0,0,0,.9);
  --soft-shadow-lg:0 0 0 1px rgba(255,255,255,.07), 0 30px 60px -18px rgba(0,0,0,1);
  /* ป้ายความสำคัญ + ทอง: ค่าของธีมสว่างบนพื้นดำมองไม่เห็น (บทเรียน 1B98) */
  --pri-red-soft:rgba(242,139,139,.26);  --pri-red-text:#F5A3A3;
  --pri-yellow-soft:rgba(232,204,133,.26); --pri-yellow-text:#EBD08E;
  --pri-green-soft:rgba(143,217,184,.26);  --pri-green-text:#9FDFC2;
  --gold-soft:rgba(240,193,74,.24);       --gold-text:#EFCB72;
  /* ปุ่มกระจกใสเป็น "กระจกเงิน" — เจ้าของ: "พวกปุ่มเป็นดำ"
     สูตรกลางผสมพื้นกระจกจากสีการ์ด ซึ่งบนธีมนี้คือเกือบดำ ปุ่มจึงจมหายเป็นหลุมดำ
     ที่นี่ใช้ขาวโปร่งแทน + ขอบสะท้อนแรงขึ้น · การ์ดยังดำอยู่ (ปุ่มต้องเด่นกว่าการ์ด) */
  --lgb-bg:rgba(255,255,255,.085); --lgb-top:rgba(255,255,255,.24); --lgb-bot:rgba(255,255,255,.05);
  --lgb-edge:rgba(0,0,0,.5);
  --lg-hi:rgba(255,255,255,.88); --lg-mid:rgba(255,255,255,.3); --lg-lo:rgba(255,255,255,.14);
  --lg-glow:rgba(255,255,255,.1); --lg-drop:rgba(0,0,0,.7);
}
/* ไอคอนบนไทล์หน้าแรก + ตราบนหัวตั๋ว "ตอนนี้" — เจ้าของ: "ตรงนี้สีออกฟ้า ๆ ให้เปลี่ยนเป็นสีดำ"
   สามที่ที่ยังเป็นน้ำเงินในธีมขาวดำ: ไอคอนกรมท่า #16306B (today.css — ตั้งไว้ให้ไม่ชนสีหัวตั๋ว) ·
   แผ่นกลมใต้ไอคอนที่ไล่ไปฟ้าอ่อน (232,243,255) · เงาของแผ่นที่อมกรม (15,27,45)
   ธีมนี้ไม่มีสีอื่นให้ชน จึงเป็นดำบนขาวล้วน · แผ่นไล่จากขาวไปเทาอ่อน เงาเป็นดำกลาง */
:root[data-theme="astral"] .tg-ic svg,
:root[data-theme="astral"] .td-now .tn-mark { color: #0A0A0A; }
:root[data-theme="astral"] .phone .tg-ic svg {
  background: linear-gradient(160deg, #FFFFFF, rgba(230,230,230,.9)) !important;
  box-shadow: inset 0 1px 0 #fff, inset 0 -1.5px 2px rgba(0,0,0,.14), 0 5px 10px -3px rgba(0,0,0,.45), 0 0 0 .5px rgba(0,0,0,.12) !important;
}
/* ตราสว่างบนพื้นมืด */
:root[data-theme="astral"] .brand-light { display: none; }
:root[data-theme="astral"] .brand-dark { display: inline; }

/* ---------- ฉากหลัง ----------
   ซ้อนจากหลังไปหน้า: ดาวฝุ่นลอย → ดาวเคราะห์ + ดาวนิ่ง → คลื่นชั้นหลัง → คลื่นชั้นหน้า →
   ประกาย → ขอบจอจมดำ (z-index ภายใน .fx — ลำดับใน DOM ไม่ตรงกับลำดับความลึกที่ต้องการ)
   ทุกชั้นขยับด้วย transform/opacity เท่านั้น เบราว์เซอร์วาด SVG ครั้งเดียวแล้วแค่เลื่อนภาพ */
:root[data-theme="astral"] .fx {
  display: block; position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
}
/* ดาวฝุ่นสองชั้น ลอยขึ้นช้าไม่เท่ากัน · เลื่อนทีละหนึ่งช่องลาย (320/420px) จึงวนต่อกันไม่กระตุก */
:root[data-theme="astral"] .fx-b {
  z-index: 1;
  top: 0; left: 0; right: 0; bottom: -320px;
  background-image:
    radial-gradient(1px 1px at 24px 38px, #fff 100%, transparent),
    radial-gradient(1px 1px at 96px 120px, rgba(255,255,255,.8) 100%, transparent),
    radial-gradient(1.2px 1.2px at 170px 64px, #fff 100%, transparent),
    radial-gradient(.9px .9px at 214px 210px, rgba(230,230,230,.85) 100%, transparent),
    radial-gradient(1px 1px at 58px 262px, rgba(255,255,255,.75) 100%, transparent),
    radial-gradient(.8px .8px at 140px 300px, #fff 100%, transparent),
    radial-gradient(1.1px 1.1px at 248px 18px, rgba(240,240,240,.9) 100%, transparent);
  background-size: 260px 320px;
  opacity: .5;
  animation: as-drift-b 140s linear infinite;
}
:root[data-theme="astral"] .fx-c {
  z-index: 1;
  top: 0; left: 0; right: 0; bottom: -420px;
  background-image:
    radial-gradient(1.6px 1.6px at 60px 90px, #fff 100%, transparent),
    radial-gradient(1.3px 1.3px at 250px 40px, rgba(235,235,235,.95) 100%, transparent),
    radial-gradient(1.5px 1.5px at 300px 300px, #fff 100%, transparent),
    radial-gradient(1.2px 1.2px at 130px 380px, rgba(225,225,225,.95) 100%, transparent);
  background-size: 340px 420px;
  animation: as-drift-c 220s linear infinite, as-twinkle 6s ease-in-out infinite;
}
/* ดาวเคราะห์ลายแถบสี่ดวง + ดาวจิ๋วเต็มฟ้า — ลอยขึ้นลงช้า ๆ ไม่ใช่ติดตายบนวอลเปเปอร์ */
:root[data-theme="astral"] .fx-d {
  z-index: 2;
  inset: -10px 0 0 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 860' preserveAspectRatio='xMidYMin slice'%3E%3Cdefs%3E%3CradialGradient id='s' cx='.34' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='rgb(232,232,232)'/%3E%3Cstop offset='.55' stop-color='rgb(120,120,120)'/%3E%3Cstop offset='1' stop-color='rgb(14,14,14)'/%3E%3C/radialGradient%3E%3CradialGradient id='n' cx='.78' cy='.82' r='.75'%3E%3Cstop offset='0' stop-color='rgb(0,0,0)' stop-opacity='.85'/%3E%3Cstop offset='1' stop-color='rgb(0,0,0)' stop-opacity='0'/%3E%3C/radialGradient%3E%3CclipPath id='c0'%3E%3Ccircle cx='96' cy='150' r='44'/%3E%3C/clipPath%3E%3CclipPath id='c1'%3E%3Ccircle cx='306' cy='92' r='23'/%3E%3C/clipPath%3E%3CclipPath id='c2'%3E%3Ccircle cx='236' cy='268' r='12'/%3E%3C/clipPath%3E%3CclipPath id='c3'%3E%3Ccircle cx='58' cy='372' r='7'/%3E%3C/clipPath%3E%3C/defs%3E%3Ccircle cx='249.2' cy='459.3' r='0.9' fill='rgba(255,255,255,0.82)'/%3E%3Ccircle cx='296' cy='571.1' r='0.4' fill='rgba(255,255,255,0.53)'/%3E%3Ccircle cx='377.3' cy='401.8' r='1' fill='rgba(255,255,255,0.32)'/%3E%3Ccircle cx='187.6' cy='152.7' r='0.8' fill='rgba(255,255,255,0.59)'/%3E%3Ccircle cx='5.2' cy='134.2' r='0.6' fill='rgba(255,255,255,0.80)'/%3E%3Ccircle cx='306.3' cy='98.8' r='0.9' fill='rgba(255,255,255,0.33)'/%3E%3Ccircle cx='247' cy='78.5' r='0.4' fill='rgba(255,255,255,0.77)'/%3E%3Ccircle cx='83.8' cy='133.4' r='1.1' fill='rgba(255,255,255,0.77)'/%3E%3Ccircle cx='115.7' cy='595.3' r='0.8' fill='rgba(255,255,255,0.66)'/%3E%3Ccircle cx='81.9' cy='582.7' r='0.9' fill='rgba(255,255,255,0.83)'/%3E%3Ccircle cx='357.5' cy='185' r='0.6' fill='rgba(255,255,255,0.35)'/%3E%3Ccircle cx='58.3' cy='40.3' r='0.6' fill='rgba(255,255,255,0.61)'/%3E%3Ccircle cx='1.4' cy='419.8' r='0.6' fill='rgba(255,255,255,0.44)'/%3E%3Ccircle cx='327.4' cy='297.7' r='0.6' fill='rgba(255,255,255,0.54)'/%3E%3Ccircle cx='281.9' cy='35.3' r='1.1' fill='rgba(255,255,255,0.26)'/%3E%3Ccircle cx='299.9' cy='523.2' r='0.4' fill='rgba(255,255,255,0.72)'/%3E%3Ccircle cx='146.5' cy='358.2' r='0.4' fill='rgba(255,255,255,0.28)'/%3E%3Ccircle cx='72.4' cy='591.4' r='0.5' fill='rgba(255,255,255,0.70)'/%3E%3Ccircle cx='371.9' cy='583.3' r='0.6' fill='rgba(255,255,255,0.46)'/%3E%3Ccircle cx='209.9' cy='480.3' r='0.4' fill='rgba(255,255,255,0.70)'/%3E%3Ccircle cx='318.9' cy='532.3' r='0.4' fill='rgba(255,255,255,0.82)'/%3E%3Ccircle cx='36.5' cy='211' r='0.8' fill='rgba(255,255,255,0.80)'/%3E%3Ccircle cx='136' cy='572.3' r='0.8' fill='rgba(255,255,255,0.44)'/%3E%3Ccircle cx='126.7' cy='109.9' r='0.4' fill='rgba(255,255,255,0.34)'/%3E%3Ccircle cx='275.7' cy='617.2' r='0.5' fill='rgba(255,255,255,0.28)'/%3E%3Ccircle cx='394.7' cy='330.4' r='0.7' fill='rgba(255,255,255,0.39)'/%3E%3Ccircle cx='237.6' cy='511.6' r='0.7' fill='rgba(255,255,255,0.50)'/%3E%3Ccircle cx='22.3' cy='567.2' r='0.4' fill='rgba(255,255,255,0.55)'/%3E%3Ccircle cx='335.4' cy='80.9' r='0.9' fill='rgba(255,255,255,0.82)'/%3E%3Ccircle cx='252.2' cy='487.9' r='0.4' fill='rgba(255,255,255,0.51)'/%3E%3Ccircle cx='59.7' cy='523.1' r='0.6' fill='rgba(255,255,255,0.52)'/%3E%3Ccircle cx='399.7' cy='527.7' r='1.1' fill='rgba(255,255,255,0.52)'/%3E%3Ccircle cx='195.3' cy='451.7' r='0.7' fill='rgba(255,255,255,0.42)'/%3E%3Ccircle cx='161.5' cy='90.7' r='0.6' fill='rgba(255,255,255,0.84)'/%3E%3Ccircle cx='383.9' cy='388.2' r='0.7' fill='rgba(255,255,255,0.45)'/%3E%3Ccircle cx='35.7' cy='168.6' r='0.9' fill='rgba(255,255,255,0.77)'/%3E%3Ccircle cx='144.5' cy='486.7' r='0.9' fill='rgba(255,255,255,0.67)'/%3E%3Ccircle cx='265.6' cy='470.4' r='0.6' fill='rgba(255,255,255,0.67)'/%3E%3Ccircle cx='112.3' cy='300.7' r='0.9' fill='rgba(255,255,255,0.66)'/%3E%3Ccircle cx='117.5' cy='585.5' r='0.8' fill='rgba(255,255,255,0.60)'/%3E%3Ccircle cx='4.6' cy='338.7' r='0.5' fill='rgba(255,255,255,0.65)'/%3E%3Ccircle cx='185.2' cy='505.7' r='0.8' fill='rgba(255,255,255,0.73)'/%3E%3Ccircle cx='139.2' cy='398.8' r='0.9' fill='rgba(255,255,255,0.75)'/%3E%3Ccircle cx='140' cy='521.9' r='1' fill='rgba(255,255,255,0.66)'/%3E%3Ccircle cx='390.4' cy='592.3' r='0.7' fill='rgba(255,255,255,0.57)'/%3E%3Ccircle cx='66.5' cy='518' r='1.1' fill='rgba(255,255,255,0.54)'/%3E%3Ccircle cx='276.6' cy='445.6' r='0.9' fill='rgba(255,255,255,0.35)'/%3E%3Ccircle cx='312.1' cy='359.7' r='0.8' fill='rgba(255,255,255,0.50)'/%3E%3Ccircle cx='249.5' cy='479.7' r='0.8' fill='rgba(255,255,255,0.68)'/%3E%3Ccircle cx='11' cy='99.1' r='0.7' fill='rgba(255,255,255,0.64)'/%3E%3Ccircle cx='87.6' cy='424.7' r='0.8' fill='rgba(255,255,255,0.28)'/%3E%3Ccircle cx='188.6' cy='140.1' r='0.4' fill='rgba(255,255,255,0.33)'/%3E%3Ccircle cx='126.9' cy='112.4' r='0.5' fill='rgba(255,255,255,0.27)'/%3E%3Ccircle cx='186.1' cy='235.5' r='0.8' fill='rgba(255,255,255,0.60)'/%3E%3Ccircle cx='95.1' cy='559.3' r='0.4' fill='rgba(255,255,255,0.49)'/%3E%3Ccircle cx='111.4' cy='253.9' r='0.4' fill='rgba(255,255,255,0.75)'/%3E%3Ccircle cx='149.6' cy='22.3' r='0.8' fill='rgba(255,255,255,0.31)'/%3E%3Ccircle cx='218.1' cy='210.1' r='0.8' fill='rgba(255,255,255,0.82)'/%3E%3Ccircle cx='327.4' cy='259.5' r='1' fill='rgba(255,255,255,0.64)'/%3E%3Ccircle cx='147.8' cy='88' r='0.8' fill='rgba(255,255,255,0.59)'/%3E%3Ccircle cx='382.9' cy='599.4' r='0.8' fill='rgba(255,255,255,0.46)'/%3E%3Ccircle cx='357.4' cy='0.6' r='0.4' fill='rgba(255,255,255,0.59)'/%3E%3Ccircle cx='246.1' cy='87.1' r='0.8' fill='rgba(255,255,255,0.78)'/%3E%3Ccircle cx='150.3' cy='267.3' r='0.5' fill='rgba(255,255,255,0.42)'/%3E%3Ccircle cx='389' cy='235.2' r='1.1' fill='rgba(255,255,255,0.80)'/%3E%3Ccircle cx='238.3' cy='160.9' r='1.1' fill='rgba(255,255,255,0.55)'/%3E%3Ccircle cx='166.2' cy='197.6' r='1.1' fill='rgba(255,255,255,0.55)'/%3E%3Ccircle cx='114.6' cy='295.3' r='0.4' fill='rgba(255,255,255,0.62)'/%3E%3Ccircle cx='177.4' cy='181.5' r='0.9' fill='rgba(255,255,255,0.75)'/%3E%3Ccircle cx='5.3' cy='329.8' r='0.6' fill='rgba(255,255,255,0.81)'/%3E%3Ccircle cx='312.8' cy='152.1' r='0.6' fill='rgba(255,255,255,0.34)'/%3E%3Ccircle cx='395.5' cy='181.5' r='0.8' fill='rgba(255,255,255,0.53)'/%3E%3Ccircle cx='258' cy='373.9' r='0.9' fill='rgba(255,255,255,0.32)'/%3E%3Ccircle cx='304.2' cy='186.2' r='0.8' fill='rgba(255,255,255,0.45)'/%3E%3Ccircle cx='118.7' cy='328.1' r='0.7' fill='rgba(255,255,255,0.47)'/%3E%3Ccircle cx='298' cy='365.8' r='0.4' fill='rgba(255,255,255,0.40)'/%3E%3Ccircle cx='182.2' cy='567.5' r='1' fill='rgba(255,255,255,0.58)'/%3E%3Ccircle cx='5.8' cy='482' r='0.7' fill='rgba(255,255,255,0.60)'/%3E%3Ccircle cx='283.3' cy='391.5' r='0.7' fill='rgba(255,255,255,0.80)'/%3E%3Ccircle cx='154.2' cy='242.6' r='1' fill='rgba(255,255,255,0.37)'/%3E%3Ccircle cx='118.6' cy='514' r='0.4' fill='rgba(255,255,255,0.75)'/%3E%3Ccircle cx='277.8' cy='268' r='0.6' fill='rgba(255,255,255,0.72)'/%3E%3Ccircle cx='364.3' cy='88.4' r='0.7' fill='rgba(255,255,255,0.58)'/%3E%3Ccircle cx='199.1' cy='204.8' r='0.5' fill='rgba(255,255,255,0.60)'/%3E%3Ccircle cx='324.7' cy='42.4' r='0.5' fill='rgba(255,255,255,0.74)'/%3E%3Ccircle cx='316.7' cy='410.9' r='0.4' fill='rgba(255,255,255,0.68)'/%3E%3Ccircle cx='391.5' cy='618.2' r='0.9' fill='rgba(255,255,255,0.28)'/%3E%3Ccircle cx='336.8' cy='135.7' r='0.8' fill='rgba(255,255,255,0.82)'/%3E%3Ccircle cx='285' cy='83.4' r='0.6' fill='rgba(255,255,255,0.80)'/%3E%3Ccircle cx='59.9' cy='378.1' r='0.7' fill='rgba(255,255,255,0.35)'/%3E%3Ccircle cx='249' cy='27' r='0.4' fill='rgba(255,255,255,0.48)'/%3E%3Ccircle cx='28.8' cy='35.6' r='0.8' fill='rgba(255,255,255,0.70)'/%3E%3Ccircle cx='351.4' cy='83.2' r='0.7' fill='rgba(255,255,255,0.44)'/%3E%3Ccircle cx='240.1' cy='303.1' r='1.1' fill='rgba(255,255,255,0.47)'/%3E%3Ccircle cx='22.3' cy='431.8' r='0.5' fill='rgba(255,255,255,0.63)'/%3E%3Ccircle cx='202.3' cy='563.7' r='0.8' fill='rgba(255,255,255,0.62)'/%3E%3Ccircle cx='105.3' cy='341.6' r='0.5' fill='rgba(255,255,255,0.70)'/%3E%3Ccircle cx='206.8' cy='82.8' r='0.5' fill='rgba(255,255,255,0.47)'/%3E%3Ccircle cx='294.7' cy='111' r='0.9' fill='rgba(255,255,255,0.64)'/%3E%3Ccircle cx='34.1' cy='413.6' r='0.4' fill='rgba(255,255,255,0.32)'/%3E%3Ccircle cx='237.6' cy='147.7' r='1' fill='rgba(255,255,255,0.54)'/%3E%3Ccircle cx='129.3' cy='493.2' r='0.4' fill='rgba(255,255,255,0.69)'/%3E%3Ccircle cx='21.5' cy='93.4' r='1.1' fill='rgba(255,255,255,0.66)'/%3E%3Ccircle cx='89.2' cy='71.9' r='1.1' fill='rgba(255,255,255,0.65)'/%3E%3Ccircle cx='328.2' cy='86.5' r='0.8' fill='rgba(255,255,255,0.46)'/%3E%3Ccircle cx='94' cy='206.4' r='0.8' fill='rgba(255,255,255,0.46)'/%3E%3Ccircle cx='154.3' cy='84.5' r='1' fill='rgba(255,255,255,0.64)'/%3E%3Ccircle cx='321.8' cy='268.4' r='1' fill='rgba(255,255,255,0.56)'/%3E%3Ccircle cx='237.1' cy='355' r='0.9' fill='rgba(255,255,255,0.49)'/%3E%3Ccircle cx='38.8' cy='20.5' r='0.5' fill='rgba(255,255,255,0.27)'/%3E%3Ccircle cx='96' cy='150' r='44' fill='url(%23s)'/%3E%3Cg clip-path='url(%23c0)'%3E%3Cg transform='rotate(-14 96 150)'%3E%3Crect x='34.4' y='106' width='123.2' height='6.5' fill='rgba(255,255,255,0.22)'/%3E%3Crect x='34.4' y='112.5' width='123.2' height='4.5' fill='rgba(0,0,0,0.24)'/%3E%3Crect x='34.4' y='118.1' width='123.2' height='4.5' fill='rgba(255,255,255,0.11)'/%3E%3Crect x='34.4' y='123' width='123.2' height='4' fill='rgba(255,255,255,0.24)'/%3E%3Crect x='34.4' y='127.4' width='123.2' height='3.4' fill='rgba(255,255,255,0.11)'/%3E%3Crect x='34.4' y='131.6' width='123.2' height='3.3' fill='rgba(255,255,255,0.09)'/%3E%3Crect x='34.4' y='137.4' width='123.2' height='4' fill='rgba(0,0,0,0.25)'/%3E%3Crect x='34.4' y='143.1' width='123.2' height='4.5' fill='rgba(0,0,0,0.13)'/%3E%3Crect x='34.4' y='149.4' width='123.2' height='3.6' fill='rgba(0,0,0,0.26)'/%3E%3Crect x='34.4' y='153.4' width='123.2' height='3.2' fill='rgba(255,255,255,0.12)'/%3E%3Crect x='34.4' y='156.8' width='123.2' height='4.1' fill='rgba(0,0,0,0.18)'/%3E%3Crect x='34.4' y='161.8' width='123.2' height='4.5' fill='rgba(255,255,255,0.21)'/%3E%3Crect x='34.4' y='168.1' width='123.2' height='3' fill='rgba(255,255,255,0.20)'/%3E%3Crect x='34.4' y='173.6' width='123.2' height='5.3' fill='rgba(255,255,255,0.26)'/%3E%3Crect x='34.4' y='178.9' width='123.2' height='2.5' fill='rgba(0,0,0,0.19)'/%3E%3Crect x='34.4' y='181.6' width='123.2' height='4.9' fill='rgba(0,0,0,0.21)'/%3E%3Crect x='34.4' y='187.3' width='123.2' height='2.7' fill='rgba(255,255,255,0.24)'/%3E%3Crect x='34.4' y='191.3' width='123.2' height='6.7' fill='rgba(255,255,255,0.12)'/%3E%3C/g%3E%3Ccircle cx='96' cy='150' r='44' fill='url(%23n)'/%3E%3C/g%3E%3Ccircle cx='96' cy='150' r='43.7' fill='none' stroke='rgba(255,255,255,.18)' stroke-width='.6'/%3E%3Ccircle cx='306' cy='92' r='23' fill='url(%23s)'/%3E%3Cg clip-path='url(%23c1)'%3E%3Cg transform='rotate(10 306 92)'%3E%3Crect x='273.8' y='69' width='64.4' height='2.2' fill='rgba(255,255,255,0.13)'/%3E%3Crect x='273.8' y='71.7' width='64.4' height='1.9' fill='rgba(255,255,255,0.09)'/%3E%3Crect x='273.8' y='75' width='64.4' height='1.6' fill='rgba(0,0,0,0.19)'/%3E%3Crect x='273.8' y='77.3' width='64.4' height='1.4' fill='rgba(255,255,255,0.10)'/%3E%3Crect x='273.8' y='79.4' width='64.4' height='3.5' fill='rgba(0,0,0,0.29)'/%3E%3Crect x='273.8' y='83.2' width='64.4' height='1.2' fill='rgba(0,0,0,0.21)'/%3E%3Crect x='273.8' y='85.2' width='64.4' height='2.1' fill='rgba(0,0,0,0.26)'/%3E%3Crect x='273.8' y='88.6' width='64.4' height='1.9' fill='rgba(255,255,255,0.23)'/%3E%3Crect x='273.8' y='90.8' width='64.4' height='1.4' fill='rgba(255,255,255,0.10)'/%3E%3Crect x='273.8' y='93.3' width='64.4' height='3.2' fill='rgba(255,255,255,0.10)'/%3E%3Crect x='273.8' y='96.6' width='64.4' height='1.8' fill='rgba(255,255,255,0.16)'/%3E%3Crect x='273.8' y='99.2' width='64.4' height='1.8' fill='rgba(255,255,255,0.21)'/%3E%3Crect x='273.8' y='101' width='64.4' height='1.7' fill='rgba(255,255,255,0.15)'/%3E%3Crect x='273.8' y='102.8' width='64.4' height='2.2' fill='rgba(255,255,255,0.22)'/%3E%3Crect x='273.8' y='105.8' width='64.4' height='3.4' fill='rgba(0,0,0,0.27)'/%3E%3Crect x='273.8' y='110' width='64.4' height='2.3' fill='rgba(0,0,0,0.24)'/%3E%3Crect x='273.8' y='113.6' width='64.4' height='3' fill='rgba(0,0,0,0.16)'/%3E%3C/g%3E%3Ccircle cx='306' cy='92' r='23' fill='url(%23n)'/%3E%3C/g%3E%3Ccircle cx='306' cy='92' r='22.7' fill='none' stroke='rgba(255,255,255,.18)' stroke-width='.6'/%3E%3Ccircle cx='236' cy='268' r='12' fill='url(%23s)'/%3E%3Cg clip-path='url(%23c2)'%3E%3Cg transform='rotate(-6 236 268)'%3E%3Crect x='219.2' y='256' width='33.6' height='1.1' fill='rgba(255,255,255,0.09)'/%3E%3Crect x='219.2' y='257.2' width='33.6' height='0.9' fill='rgba(0,0,0,0.16)'/%3E%3Crect x='219.2' y='258.2' width='33.6' height='1.6' fill='rgba(0,0,0,0.11)'/%3E%3Crect x='219.2' y='259.9' width='33.6' height='0.8' fill='rgba(255,255,255,0.23)'/%3E%3Crect x='219.2' y='261.3' width='33.6' height='1.4' fill='rgba(255,255,255,0.16)'/%3E%3Crect x='219.2' y='263' width='33.6' height='1' fill='rgba(255,255,255,0.19)'/%3E%3Crect x='219.2' y='264.6' width='33.6' height='1.6' fill='rgba(255,255,255,0.18)'/%3E%3Crect x='219.2' y='266.3' width='33.6' height='1.5' fill='rgba(255,255,255,0.25)'/%3E%3Crect x='219.2' y='268.4' width='33.6' height='0.8' fill='rgba(255,255,255,0.24)'/%3E%3Crect x='219.2' y='269.5' width='33.6' height='1.2' fill='rgba(255,255,255,0.22)'/%3E%3Crect x='219.2' y='271.3' width='33.6' height='1.3' fill='rgba(0,0,0,0.23)'/%3E%3Crect x='219.2' y='272.7' width='33.6' height='1.7' fill='rgba(255,255,255,0.09)'/%3E%3Crect x='219.2' y='275.1' width='33.6' height='0.6' fill='rgba(0,0,0,0.21)'/%3E%3Crect x='219.2' y='276.4' width='33.6' height='1.1' fill='rgba(255,255,255,0.13)'/%3E%3Crect x='219.2' y='277.6' width='33.6' height='1.3' fill='rgba(255,255,255,0.22)'/%3E%3Crect x='219.2' y='279.2' width='33.6' height='1.1' fill='rgba(255,255,255,0.26)'/%3E%3C/g%3E%3Ccircle cx='236' cy='268' r='12' fill='url(%23n)'/%3E%3C/g%3E%3Ccircle cx='236' cy='268' r='11.7' fill='none' stroke='rgba(255,255,255,.18)' stroke-width='.6'/%3E%3Ccircle cx='58' cy='372' r='7' fill='url(%23s)'/%3E%3Cg clip-path='url(%23c3)'%3E%3Cg transform='rotate(0 58 372)'%3E%3Crect x='48.2' y='365' width='19.6' height='1' fill='rgba(0,0,0,0.19)'/%3E%3Crect x='48.2' y='366.1' width='19.6' height='1' fill='rgba(255,255,255,0.09)'/%3E%3Crect x='48.2' y='367.1' width='19.6' height='0.4' fill='rgba(0,0,0,0.30)'/%3E%3Crect x='48.2' y='367.6' width='19.6' height='1' fill='rgba(255,255,255,0.20)'/%3E%3Crect x='48.2' y='369' width='19.6' height='0.8' fill='rgba(0,0,0,0.18)'/%3E%3Crect x='48.2' y='369.8' width='19.6' height='0.7' fill='rgba(0,0,0,0.14)'/%3E%3Crect x='48.2' y='370.7' width='19.6' height='0.6' fill='rgba(255,255,255,0.14)'/%3E%3Crect x='48.2' y='371.5' width='19.6' height='0.7' fill='rgba(0,0,0,0.19)'/%3E%3Crect x='48.2' y='372.6' width='19.6' height='1' fill='rgba(0,0,0,0.25)'/%3E%3Crect x='48.2' y='373.8' width='19.6' height='0.8' fill='rgba(0,0,0,0.18)'/%3E%3Crect x='48.2' y='374.9' width='19.6' height='0.9' fill='rgba(0,0,0,0.16)'/%3E%3Crect x='48.2' y='375.8' width='19.6' height='0.4' fill='rgba(255,255,255,0.18)'/%3E%3Crect x='48.2' y='376.5' width='19.6' height='0.9' fill='rgba(255,255,255,0.25)'/%3E%3Crect x='48.2' y='377.5' width='19.6' height='0.9' fill='rgba(255,255,255,0.22)'/%3E%3Crect x='48.2' y='378.7' width='19.6' height='1.1' fill='rgba(0,0,0,0.25)'/%3E%3C/g%3E%3Ccircle cx='58' cy='372' r='7' fill='url(%23n)'/%3E%3C/g%3E%3Ccircle cx='58' cy='372' r='6.7' fill='none' stroke='rgba(255,255,255,.18)' stroke-width='.6'/%3E%3C/svg%3E") center top / cover no-repeat;
  /* 13 ต.ค. 69 · .9 → .72 — ดาวดวงใหญ่ลอยผ่านหลังตัวเลขหัวโปรไฟล์และฟองแชทจนอ่านยาก (เจ้าของ: "ไม่เอาให้มันรกเกินไป") */
  opacity: .72;
  animation: as-float 18s ease-in-out infinite alternate;
}
/* คลื่นเงินชั้นหลัง — จางกว่า ไหลไปทางขวา */
:root[data-theme="astral"] .fx-a {
  z-index: 3;
  inset: 0 -64px;
  transform-origin: 50% 100%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 860' preserveAspectRatio='xMidYMax slice'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(10,10,10)' stop-opacity='.92'/%3E%3Cstop offset='.5' stop-color='rgb(3,3,3)' stop-opacity='.97'/%3E%3Cstop offset='1' stop-color='rgb(0,0,0)'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M-40 547Q-18 524.4 -7 512.7Q4 501 15 489.5Q26 478 37 467.3Q48 456.5 59 446.8Q70 437 81 428.5Q92 419.9 103 412.3Q114 404.8 125 397.9Q136 391.1 147 384.6Q158 378.1 169 371.6Q180 365.1 191 358.4Q202 351.7 213 344.7Q224 337.7 235 330.6Q246 323.6 257 316.7Q268 309.9 279 303.8Q290 297.6 301 292.6Q312 287.5 323 283.8Q334 280.2 345 277.9Q356 275.7 367 274.8Q378 273.8 389 273.7Q400 273.7 411 273.9L422 274.1L422 575.9L400 583.8L378 592.2L356 602L334 613.8L312 627.5L290 642.8L268 658.9L246 674.9L224 689.7L202 702.7L180 713.6L158 722.6L136 730.1L114 737.3L92 745L70 754.1L48 765.3L26 778.6L4 793.7L-18 809.9L-40 826.3Z' fill='url(%23g)'/%3E%3Cpath d='M-40 548.3Q-18 523.5 -7 510.9Q4 498.3 15 486.5Q26 474.7 37 464.3Q48 453.9 59 445.1Q70 436.3 81 428.8Q92 421.3 103 414.6Q114 407.8 125 401.1Q136 394.4 147 387.4Q158 380.3 169 372.8Q180 365.3 191 357.5Q202 349.8 213 342.1Q224 334.5 235 327.4Q246 320.4 257 314.3Q268 308.1 279 303.1Q290 298 301 293.9Q312 289.9 323 286.7Q334 283.5 345 281.1Q356 278.7 367 276.9Q378 275.1 389 274Q400 272.8 411 272.1L422 271.4' fill='none' stroke='rgba(255,255,255,0.43)' stroke-width='1.7'/%3E%3Cpath d='M-40 549.6Q-18 529.6 -7 519.2Q4 508.8 15 498.2Q26 487.6 37 477Q48 466.4 59 456.2Q70 446 81 436.7Q92 427.3 103 419.1Q114 410.8 125 403.8Q136 396.8 147 390.8Q158 384.8 169 379.4Q180 373.9 191 368.4Q202 362.9 213 356.8Q224 350.7 235 343.9Q246 337 257 329.7Q268 322.3 279 315Q290 307.8 301 301.4Q312 295.1 323 290.4Q334 285.7 345 283.1Q356 280.5 367 279.9Q378 279.3 389 279.9Q400 280.6 411 281.5L422 282.5' fill='none' stroke='rgba(255,255,255,0.48)' stroke-width='1.4'/%3E%3Cpath d='M-40 552.4Q-18 532.2 -7 522.2Q4 512.3 15 502.6Q26 492.8 37 483.4Q48 473.9 59 464.7Q70 455.4 81 446.6Q92 437.8 103 429.5Q114 421.3 125 413.9Q136 406.4 147 399.9Q158 393.3 169 387.5Q180 381.6 191 376.1Q202 370.5 213 364.9Q224 359.2 235 353.1Q246 347 257 340.3Q268 333.6 279 326.6Q290 319.7 301 313.1Q312 306.5 323 301.1Q334 295.7 345 292.1Q356 288.4 367 286.8Q378 285.1 389 285.1Q400 285.1 411 285.9L422 286.6' fill='none' stroke='rgba(255,255,255,0.41)' stroke-width='1.4'/%3E%3Cpath d='M-40 560.4Q-18 540 -7 529.3Q4 518.7 15 508.1Q26 497.6 37 487.6Q48 477.6 59 468.5Q70 459.4 81 451.4Q92 443.4 103 436.5Q114 429.6 125 423.6Q136 417.5 147 411.8Q158 406.2 169 400.5Q180 394.8 191 388.7Q202 382.5 213 375.8Q224 369.1 235 361.9Q246 354.7 257 347.3Q268 340 279 333.1Q290 326.1 301 320.2Q312 314.3 323 309.8Q334 305.3 345 302.3Q356 299.3 367 297.8Q378 296.2 389 295.5Q400 294.8 411 294.3L422 293.9' fill='none' stroke='rgba(255,255,255,0.33)' stroke-width='1.1'/%3E%3Cpath d='M-40 565.2Q-18 545.6 -7 535.3Q4 525 15 514.7Q26 504.3 37 494.4Q48 484.5 59 475.5Q70 466.5 81 458.7Q92 450.8 103 444.2Q114 437.6 125 431.8Q136 426.1 147 420.9Q158 415.7 169 410.4Q180 405.1 191 399.2Q202 393.3 213 386.6Q224 379.9 235 372.5Q246 365.1 257 357.5Q268 349.8 279 342.5Q290 335.2 301 329Q312 322.8 323 318Q334 313.3 345 310.3Q356 307.2 367 305.6Q378 303.9 389 303.1Q400 302.3 411 301.6L422 300.9' fill='none' stroke='rgba(255,255,255,0.23)' stroke-width='1.1'/%3E%3Cpath d='M-40 573.3Q-18 552.3 -7 541Q4 529.8 15 518.6Q26 507.5 37 497.5Q48 487.4 59 479.1Q70 470.8 81 464.3Q92 457.8 103 452.7Q114 447.6 125 443.1Q136 438.6 147 433.9Q158 429.1 169 423.4Q180 417.7 191 410.8Q202 403.9 213 396Q224 388 235 379.8Q246 371.5 257 363.7Q268 355.9 279 349.2Q290 342.5 301 337.3Q312 332 323 328.3Q334 324.5 345 321.9Q356 319.2 367 317.1Q378 315 389 313Q400 311 411 308.7L422 306.4' fill='none' stroke='rgba(255,255,255,0.24)' stroke-width='1'/%3E%3Cpath d='M-40 577.1Q-18 556.1 -7 545.1Q4 534.1 15 523.5Q26 513 37 503.7Q48 494.4 59 486.7Q70 479.1 81 473.1Q92 467.1 103 462.2Q114 457.4 125 452.8Q136 448.3 147 443.3Q158 438.3 169 432.4Q180 426.5 191 419.6Q202 412.6 213 404.9Q224 397.1 235 389.2Q246 381.3 257 373.8Q268 366.3 279 359.8Q290 353.2 301 347.9Q312 342.5 323 338.3Q334 334.1 345 330.8Q356 327.4 367 324.7Q378 321.9 389 319.3Q400 316.7 411 314.1L422 311.5' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.8'/%3E%3Cpath d='M-40 575.1Q-18 557.5 -7 549Q4 540.5 15 532.3Q26 524.1 37 516.1Q48 508.1 59 500.3Q70 492.6 81 485.2Q92 477.7 103 470.9Q114 464 125 457.9Q136 451.8 147 446.3Q158 440.9 169 436Q180 431 191 426.1Q202 421.1 213 415.7Q224 410.2 235 403.9Q246 397.6 257 390.3Q268 383.1 279 375.3Q290 367.4 301 359.8Q312 352.2 323 345.5Q334 338.9 345 333.9Q356 329 367 325.9Q378 322.8 389 321.4Q400 319.9 411 319.1L422 318.4' fill='none' stroke='rgba(255,255,255,0.19)' stroke-width='0.9'/%3E%3Cpath d='M-40 584.6Q-18 566.3 -7 556.7Q4 547.1 15 537.6Q26 528.1 37 519.3Q48 510.5 59 502.8Q70 495.2 81 488.9Q92 482.6 103 477.6Q114 472.5 125 468.1Q136 463.7 147 459.5Q158 455.2 169 450.3Q180 445.4 191 439.6Q202 433.7 213 426.7Q224 419.8 235 412Q246 404.2 257 396.1Q268 388.1 279 380.4Q290 372.8 301 366.2Q312 359.5 323 354.2Q334 348.9 345 345Q356 341.1 367 338.2Q378 335.3 389 332.9Q400 330.6 411 328.2L422 325.8' fill='none' stroke='rgba(255,255,255,0.13)' stroke-width='0.6'/%3E%3Cpath d='M-40 586.9Q-18 567.6 -7 558.3Q4 549 15 540.6Q26 532.2 37 525Q48 517.7 59 511.5Q70 505.3 81 499.9Q92 494.5 103 489.5Q114 484.4 125 479.4Q136 474.3 147 469Q158 463.7 169 457.9Q180 452.2 191 446.1Q202 439.9 213 433.4Q224 426.9 235 420.1Q246 413.4 257 406.5Q268 399.6 279 392.7Q290 385.8 301 379.2Q312 372.5 323 366.4Q334 360.2 345 354.8Q356 349.5 367 345.1Q378 340.7 389 337.3Q400 333.8 411 331.1L422 328.4' fill='none' stroke='rgba(255,255,255,0.13)' stroke-width='0.7'/%3E%3Cpath d='M-40 589Q-18 572.1 -7 564.2Q4 556.3 15 548.9Q26 541.6 37 534.7Q48 527.8 59 521.3Q70 514.9 81 508.7Q92 502.5 103 496.7Q114 490.9 125 485.5Q136 480.1 147 475.1Q158 470.1 169 465.2Q180 460.4 191 455.5Q202 450.5 213 445Q224 439.6 235 433.2Q246 426.9 257 419.6Q268 412.3 279 404.4Q290 396.5 301 388.6Q312 380.6 323 373.3Q334 366 345 360.1Q356 354.2 367 349.9Q378 345.7 389 342.9Q400 340.2 411 338.2L422 336.3' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.6'/%3E%3Cpath d='M-40 594.6Q-18 577.5 -7 569.4Q4 561.3 15 553.9Q26 546.5 37 539.9Q48 533.2 59 527.3Q70 521.3 81 515.9Q92 510.4 103 505.4Q114 500.3 125 495.4Q136 490.6 147 485.8Q158 481 169 476Q180 471.1 191 465.8Q202 460.5 213 454.6Q224 448.7 235 442.1Q246 435.5 257 428.2Q268 421 279 413.2Q290 405.5 301 397.8Q312 390.1 323 383Q334 375.8 345 369.8Q356 363.8 367 359.1Q378 354.4 389 350.9Q400 347.5 411 344.8L422 342.1' fill='none' stroke='rgba(255,255,255,0.09)' stroke-width='0.6'/%3E%3Cpath d='M-40 599.6Q-18 584.5 -7 577Q4 569.5 15 562.2Q26 554.9 37 547.9Q48 540.9 59 534.4Q70 527.9 81 522.1Q92 516.3 103 511.3Q114 506.3 125 502Q136 497.8 147 493.9Q158 490 169 486.1Q180 482.1 191 477.5Q202 472.9 213 467.2Q224 461.4 235 454.3Q246 447.2 257 439.1Q268 430.9 279 422.2Q290 413.5 301 405.2Q312 396.8 323 389.5Q334 382.2 345 376.4Q356 370.6 367 366.5Q378 362.3 389 359.3Q400 356.2 411 353.6L422 350.9' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.6'/%3E%3Cpath d='M-40 604.9Q-18 589.7 -7 582.2Q4 574.7 15 567.5Q26 560.3 37 553.5Q48 546.8 59 540.8Q70 534.7 81 529.5Q92 524.3 103 519.9Q114 515.4 125 511.6Q136 507.7 147 504.1Q158 500.5 169 496.5Q180 492.5 191 487.7Q202 482.9 213 476.9Q224 470.9 235 463.7Q246 456.4 257 448.2Q268 440 279 431.3Q290 422.7 301 414.4Q312 406.2 323 398.9Q334 391.6 345 385.6Q356 379.7 367 375.1Q378 370.6 389 367Q400 363.4 411 360.1L422 356.9' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.7'/%3E%3Cpath d='M-40 609.9Q-18 595.1 -7 587.7Q4 580.4 15 573.3Q26 566.2 37 559.7Q48 553.2 59 547.5Q70 541.7 81 536.9Q92 532.1 103 528Q114 524 125 520.6Q136 517.1 147 513.8Q158 510.4 169 506.6Q180 502.8 191 498Q202 493.2 213 487.1Q224 481 235 473.6Q246 466.2 257 457.8Q268 449.4 279 440.7Q290 431.9 301 423.6Q312 415.2 323 407.8Q334 400.4 345 394.3Q356 388.2 367 383.4Q378 378.6 389 374.6Q400 370.7 411 366.9L422 363.2' fill='none' stroke='rgba(255,255,255,0.04)' stroke-width='0.5'/%3E%3Cpath d='M-40 614.2Q-18 598.3 -7 590.8Q4 583.2 15 576.6Q26 570 37 564.4Q48 558.9 59 554.3Q70 549.8 81 546Q92 542.3 103 538.8Q114 535.4 125 531.9Q136 528.5 147 524.6Q158 520.7 169 516.2Q180 511.6 191 506.2Q202 500.8 213 494.6Q224 488.4 235 481.3Q246 474.3 257 466.6Q268 459 279 451Q290 443 301 435Q312 427 323 419.4Q334 411.7 345 404.8Q356 398 367 392Q378 386 389 380.9Q400 375.8 411 371.3L422 366.8' fill='none' stroke='rgba(255,255,255,0.05)' stroke-width='0.6'/%3E%3Cpath d='M-40 634.6Q-18 617.8 -7 610.2Q4 602.5 15 595.8Q26 589.2 37 583.4Q48 577.6 59 572.5Q70 567.5 81 562.9Q92 558.3 103 553.9Q114 549.5 125 544.9Q136 540.3 147 535.4Q158 530.4 169 524.9Q180 519.5 191 513.5Q202 507.5 213 501.1Q224 494.8 235 488.2Q246 481.7 257 475.3Q268 468.9 279 462.8Q290 456.7 301 451.1Q312 445.5 323 440.4Q334 435.3 345 430.6Q356 426 367 421.5Q378 417 389 412.5Q400 407.9 411 402.9L422 397.9L422 678.1L400 690L378 703.1L356 717.7L334 734.4L312 753.2L290 774L268 796.4L246 819.6L224 842.8L202 865.1L180 885.6L158 903.9L136 919.4L114 932.4L92 943.1L70 952.1L48 960L26 967.4L4 974.9L-18 982.6L-40 990.6Z' fill='url(%23g)'/%3E%3Cpath d='M-40 631.2Q-18 615.6 -7 609Q4 602.4 15 596.8Q26 591.1 37 586Q48 580.8 59 575.7Q70 570.7 81 565.4Q92 560.1 103 554.6Q114 549.1 125 543.5Q136 538 147 532.5Q158 527 169 521.8Q180 516.5 191 511.3Q202 506.2 213 500.9Q224 495.7 235 490.1Q246 484.4 257 478.4Q268 472.3 279 465.8Q290 459.3 301 452.8Q312 446.2 323 440Q334 433.9 345 428.4Q356 422.9 367 418.3Q378 413.7 389 409.6Q400 405.6 411 401.6L422 397.6' fill='none' stroke='rgba(255,255,255,0.64)' stroke-width='1.9'/%3E%3Cpath d='M-40 644Q-18 629.1 -7 622.1Q4 615 15 608.4Q26 601.7 37 595.5Q48 589.4 59 583.7Q70 578 81 572.8Q92 567.7 103 563Q114 558.3 125 553.9Q136 549.4 147 544.9Q158 540.3 169 535.3Q180 530.3 191 524.5Q202 518.7 213 512.1Q224 505.6 235 498.3Q246 491.1 257 483.7Q268 476.3 279 469.1Q290 462 301 455.7Q312 449.3 323 443.9Q334 438.6 345 434.1Q356 429.7 367 425.7Q378 421.7 389 417.7Q400 413.6 411 408.8L422 404.1' fill='none' stroke='rgba(255,255,255,0.70)' stroke-width='1.6'/%3E%3Cpath d='M-40 650.8Q-18 637.7 -7 631.8Q4 625.9 15 620.2Q26 614.5 37 608.8Q48 603 59 597.2Q70 591.3 81 585.5Q92 579.6 103 574Q114 568.4 125 563.1Q136 557.9 147 553Q158 548 169 543.1Q180 538.2 191 533Q202 527.7 213 521.6Q224 515.6 235 508.6Q246 501.6 257 493.8Q268 486.1 279 478.2Q290 470.2 301 462.7Q312 455.2 323 448.7Q334 442.2 345 437.1Q356 431.9 367 427.8Q378 423.7 389 420.2Q400 416.6 411 412.6L422 408.6' fill='none' stroke='rgba(255,255,255,0.48)' stroke-width='1.3'/%3E%3Cpath d='M-40 661.2Q-18 645.3 -7 638.4Q4 631.5 15 625.8Q26 620.1 37 615.3Q48 610.6 59 606.4Q70 602.1 81 597.9Q92 593.7 103 589Q114 584.3 125 578.9Q136 573.5 147 567.4Q158 561.2 169 554.4Q180 547.6 191 540.5Q202 533.4 213 526.3Q224 519.1 235 512Q246 505 257 498.2Q268 491.3 279 484.7Q290 478.1 301 471.7Q312 465.2 323 459Q334 452.8 345 446.8Q356 440.8 367 435.2Q378 429.5 389 424.1Q400 418.7 411 413.4L422 408.2' fill='none' stroke='rgba(255,255,255,0.44)' stroke-width='1.1'/%3E%3Cpath d='M-40 669.7Q-18 657 -7 651.3Q4 645.5 15 640.1Q26 634.7 37 629.3Q48 624 59 618.6Q70 613.3 81 607.8Q92 602.4 103 597Q114 591.5 125 586.1Q136 580.6 147 575.1Q158 569.7 169 563.9Q180 558.2 191 551.9Q202 545.6 213 538.7Q224 531.7 235 524Q246 516.3 257 508.1Q268 499.9 279 491.7Q290 483.4 301 475.6Q312 467.9 323 461Q334 454.2 345 448.4Q356 442.7 367 438Q378 433.2 389 429Q400 424.7 411 420.3L422 415.8' fill='none' stroke='rgba(255,255,255,0.38)' stroke-width='1.2'/%3E%3Cpath d='M-40 682.7Q-18 669.1 -7 662.3Q4 655.6 15 649.1Q26 642.7 37 636.9Q48 631.1 59 626Q70 620.9 81 616.4Q92 611.9 103 607.6Q114 603.4 125 598.9Q136 594.5 147 589.2Q158 584 169 577.6Q180 571.2 191 563.6Q202 556 213 547.5Q224 538.9 235 529.9Q246 520.9 257 512.1Q268 503.3 279 495.3Q290 487.2 301 480.3Q312 473.3 323 467.4Q334 461.6 345 456.4Q356 451.3 367 446.4Q378 441.5 389 436.4Q400 431.2 411 425.5L422 419.8' fill='none' stroke='rgba(255,255,255,0.42)' stroke-width='1'/%3E%3Cpath d='M-40 692.2Q-18 676.8 -7 669.6Q4 662.3 15 656.2Q26 650 37 645Q48 640.1 59 636.2Q70 632.4 81 629Q92 625.6 103 621.8Q114 618.1 125 613.3Q136 608.5 147 602.2Q158 595.8 169 588Q180 580.2 191 571.3Q202 562.4 213 553.1Q224 543.9 235 534.9Q246 526 257 517.8Q268 509.7 279 502.5Q290 495.3 301 488.9Q312 482.5 323 476.5Q334 470.5 345 464.6Q356 458.6 367 452.5Q378 446.3 389 439.9Q400 433.4 411 426.9L422 420.4' fill='none' stroke='rgba(255,255,255,0.27)' stroke-width='0.8'/%3E%3Cpath d='M-40 695.6Q-18 683.3 -7 678.2Q4 673.2 15 669Q26 664.9 37 661Q48 657.1 59 653Q70 648.9 81 644Q92 639.2 103 633.4Q114 627.6 125 621Q136 614.4 147 607.2Q158 600.1 169 592.7Q180 585.2 191 577.7Q202 570.2 213 562.6Q224 555 235 547.1Q246 539.3 257 531.1Q268 523 279 514.5Q290 506.1 301 497.5Q312 489 323 480.8Q334 472.6 345 465.2Q356 457.7 367 451.3Q378 444.9 389 439.6Q400 434.2 411 429.5L422 424.8' fill='none' stroke='rgba(255,255,255,0.24)' stroke-width='0.8'/%3E%3Cpath d='M-40 707Q-18 693 -7 687.1Q4 681.2 15 676.6Q26 672 37 668.4Q48 664.8 59 661.5Q70 658.3 81 654.6Q92 651 103 646.2Q114 641.4 125 635.1Q136 628.9 147 621.2Q158 613.5 169 604.9Q180 596.3 191 587.3Q202 578.3 213 569.4Q224 560.5 235 552Q246 543.6 257 535.6Q268 527.5 279 519.8Q290 512.1 301 504.4Q312 496.7 323 489Q334 481.4 345 473.8Q356 466.2 367 458.9Q378 451.7 389 445Q400 438.4 411 432.5L422 426.6' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.9'/%3E%3Cpath d='M-40 714.8Q-18 703.3 -7 698.5Q4 693.7 15 689.7Q26 685.7 37 682Q48 678.3 59 674.4Q70 670.5 81 665.8Q92 661.2 103 655.5Q114 649.9 125 643.3Q136 636.6 147 629.1Q158 621.7 169 613.7Q180 605.6 191 597.3Q202 589 213 580.4Q224 571.9 235 563.2Q246 554.5 257 545.6Q268 536.7 279 527.7Q290 518.7 301 509.8Q312 500.9 323 492.3Q334 483.8 345 476Q356 468.2 367 461.4Q378 454.6 389 448.8Q400 443 411 437.9L422 432.9' fill='none' stroke='rgba(255,255,255,0.18)' stroke-width='0.6'/%3E%3Cpath d='M-40 723.4Q-18 714.6 -7 710.8Q4 707 15 703.3Q26 699.5 37 695.4Q48 691.3 59 686.5Q70 681.6 81 676Q92 670.3 103 664.1Q114 657.8 125 651.1Q136 644.4 147 637.4Q158 630.5 169 623.2Q180 616 191 608.3Q202 600.6 213 592.2Q224 583.8 235 574.5Q246 565.2 257 555.2Q268 545.1 279 534.7Q290 524.3 301 514.2Q312 504.1 323 495Q334 485.9 345 478.3Q356 470.6 367 464.6Q378 458.5 389 453.6Q400 448.7 411 444.3L422 439.9' fill='none' stroke='rgba(255,255,255,0.14)' stroke-width='0.8'/%3E%3Cpath d='M-40 737.2Q-18 728.6 -7 724Q4 719.3 15 714.3Q26 709.3 37 704Q48 698.7 59 693.4Q70 688.1 81 682.9Q92 677.7 103 672.6Q114 667.4 125 662.1Q136 656.8 147 650.8Q158 644.9 169 637.7Q180 630.6 191 621.9Q202 613.3 213 603.2Q224 593.1 235 582Q246 570.9 257 559.4Q268 548 279 537.2Q290 526.4 301 516.8Q312 507.3 323 499.3Q334 491.4 345 484.9Q356 478.5 367 473Q378 467.5 389 462.3Q400 457.2 411 451.6L422 446.1' fill='none' stroke='rgba(255,255,255,0.14)' stroke-width='0.6'/%3E%3Cpath d='M-40 744.7Q-18 737 -7 733.1Q4 729.2 15 724.9Q26 720.6 37 715.9Q48 711.2 59 706.1Q70 700.9 81 695.5Q92 690 103 684.3Q114 678.6 125 672.7Q136 666.7 147 660.2Q158 653.6 169 646.2Q180 638.8 191 630.2Q202 621.6 213 611.7Q224 601.9 235 590.9Q246 579.9 257 568.5Q268 557 279 545.7Q290 534.5 301 524.2Q312 513.9 323 505.1Q334 496.4 345 489.2Q356 482 367 476.1Q378 470.3 389 465.1Q400 460 411 454.8L422 449.7' fill='none' stroke='rgba(255,255,255,0.09)' stroke-width='0.6'/%3E%3Cpath d='M-40 756.8Q-18 745.7 -7 740.2Q4 734.8 15 729.9Q26 725.1 37 721Q48 717 59 713.5Q70 710.1 81 706.7Q92 703.3 103 699.1Q114 695 125 689.3Q136 683.7 147 676.2Q158 668.6 169 659.2Q180 649.7 191 638.8Q202 627.9 213 616.3Q224 604.8 235 593.3Q246 581.8 257 571.1Q268 560.4 279 550.7Q290 541.1 301 532.4Q312 523.7 323 515.8Q334 507.8 345 500.2Q356 492.6 367 485.2Q378 477.8 389 470.5Q400 463.2 411 456.2L422 449.2' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.6'/%3E%3Cpath d='M-40 761.8Q-18 753.5 -7 749.9Q4 746.2 15 742.8Q26 739.5 37 736.1Q48 732.7 59 728.9Q70 725 81 720.3Q92 715.7 103 709.9Q114 704.2 125 697.2Q136 690.3 147 682.3Q158 674.3 169 665.3Q180 656.3 191 646.5Q202 636.7 213 626.3Q224 615.9 235 605.1Q246 594.2 257 583.2Q268 572.2 279 561.3Q290 550.3 301 539.9Q312 529.4 323 519.7Q334 510 345 501.4Q356 492.8 367 485.4Q378 478 389 471.7Q400 465.3 411 459.8L422 454.2' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.6'/%3E%3Cpath d='M-40 773.8Q-18 765.6 -7 761.5Q4 757.4 15 753.3Q26 749.2 37 745.3Q48 741.3 59 737.4Q70 733.4 81 729.1Q92 724.8 103 719.8Q114 714.8 125 708.6Q136 702.5 147 694.8Q158 687.2 169 678.1Q180 668.9 191 658.3Q202 647.7 213 636.1Q224 624.6 235 612.5Q246 600.5 257 588.6Q268 576.8 279 565.6Q290 554.4 301 544.2Q312 534 323 524.9Q334 515.9 345 507.8Q356 499.7 367 492.5Q378 485.2 389 478.6Q400 471.9 411 465.6L422 459.2' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.6'/%3E%3Cpath d='M-40 782.7Q-18 774.6 -7 770.6Q4 766.6 15 762.9Q26 759.1 37 755.6Q48 752.1 59 748.5Q70 744.9 81 740.9Q92 736.8 103 731.8Q114 726.8 125 720.4Q136 713.9 147 705.8Q158 697.7 169 688Q180 678.2 191 667.2Q202 656.1 213 644.2Q224 632.2 235 620.1Q246 607.9 257 596Q268 584.1 279 572.9Q290 561.6 301 551.3Q312 540.9 323 531.5Q334 522.1 345 513.6Q356 505 367 497.3Q378 489.5 389 482.4Q400 475.3 411 468.8L422 462.3' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.8'/%3E%3Cpath d='M-40 788.1Q-18 782.5 -7 780.1Q4 777.8 15 775.4Q26 773 37 770.1Q48 767.3 59 763.4Q70 759.5 81 754.4Q92 749.3 103 742.8Q114 736.4 125 728.7Q136 721.1 147 712.5Q158 703.9 169 694.5Q180 685.1 191 674.9Q202 664.8 213 653.9Q224 643 235 631.4Q246 619.7 257 607.6Q268 595.4 279 583.1Q290 570.8 301 558.8Q312 546.8 323 535.8Q334 524.9 345 515.3Q356 505.8 367 498Q378 490.1 389 483.8Q400 477.5 411 472.3L422 467.1' fill='none' stroke='rgba(255,255,255,0.07)' stroke-width='0.7'/%3E%3C/svg%3E") center bottom / cover no-repeat;
  opacity: .7;
  animation: as-flow-back 9s ease-in-out infinite alternate;
}
/* คลื่นเงินชั้นหน้า — สว่างที่สุด สันคลื่นกวาดจากล่างซ้ายขึ้นขวาบนแบบภาพอ้างอิง ไหลสวนทางชั้นหลัง
   สองชั้นไหลคนละทางคือสิ่งที่ทำให้มันอ่านเป็น "ของไหล" ไม่ใช่ลายเส้นแผ่นเดียว
   หรี่ไว้ .78 — สันคลื่นที่สว่างที่สุดอยู่หลังแถวไทล์กับแถบล่าง ตัวหนังสือต้องยังชนะ */
:root[data-theme="astral"] .fx-g {
  z-index: 4;
  inset: 0 -72px;
  transform-origin: 50% 100%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 860' preserveAspectRatio='xMidYMax slice'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(10,10,10)' stop-opacity='.92'/%3E%3Cstop offset='.5' stop-color='rgb(3,3,3)' stop-opacity='.97'/%3E%3Cstop offset='1' stop-color='rgb(0,0,0)'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M-40 773.4Q-18 753.5 -7 742Q4 730.4 15 717.7Q26 705 37 691.6Q48 678.2 59 664.8Q70 651.3 81 638.4Q92 625.5 103 613.7Q114 601.8 125 591.5Q136 581.1 147 572.4Q158 563.7 169 556.7Q180 549.6 191 544Q202 538.4 213 533.8Q224 529.2 235 525.3Q246 521.4 257 517.7Q268 514 279 510.3Q290 506.5 301 502.4Q312 498.4 323 494.1Q334 489.8 345 485.3Q356 480.8 367 476.4Q378 471.9 389 467.9Q400 463.8 411 460.4L422 456.9L422 839.3L400 858.3L378 877.3L356 895.3L334 911.4L312 924.9L290 935.3L268 942.5L246 947.1L224 949.6L202 951.1L180 952.9L158 955.8L136 960.9L114 968.7L92 979.2L70 992.2L48 1007.2L26 1023.3L4 1039.8L-18 1056L-40 1071.5Z' fill='url(%23g)'/%3E%3Cpath d='M-40 772.2Q-18 753.7 -7 742.9Q4 732.1 15 719.7Q26 707.3 37 693.8Q48 680.3 59 666.2Q70 652.2 81 638.5Q92 624.9 103 612.4Q114 600 125 589.4Q136 578.8 147 570.4Q158 561.9 169 555.5Q180 549.1 191 544.2Q202 539.3 213 535.3Q224 531.3 235 527.5Q246 523.7 257 519.6Q268 515.6 279 511.1Q290 506.7 301 501.9Q312 497.1 323 492.3Q334 487.5 345 483.1Q356 478.6 367 474.6Q378 470.7 389 467.4Q400 464 411 461.3L422 458.5' fill='none' stroke='rgba(255,255,255,0.83)' stroke-width='1.7'/%3E%3Cpath d='M-40 775.8Q-18 757 -7 746.3Q4 735.6 15 723.7Q26 711.8 37 699Q48 686.2 59 672.9Q70 659.7 81 646.6Q92 633.5 103 621.4Q114 609.3 125 598.8Q136 588.3 147 579.7Q158 571.2 169 564.6Q180 558.1 191 553.3Q202 548.5 213 544.8Q224 541 235 537.7Q246 534.4 257 530.9Q268 527.4 279 523.3Q290 519.2 301 514.5Q312 509.8 323 504.8Q334 499.7 345 494.6Q356 489.5 367 484.9Q378 480.2 389 476.3Q400 472.3 411 469.2L422 466' fill='none' stroke='rgba(255,255,255,0.87)' stroke-width='1.6'/%3E%3Cpath d='M-40 781.3Q-18 760.6 -7 749.3Q4 737.9 15 725.9Q26 714 37 701.8Q48 689.6 59 677.6Q70 665.5 81 653.9Q92 642.2 103 631.2Q114 620.2 125 610.2Q136 600.2 147 591.5Q158 582.8 169 575.6Q180 568.4 191 562.8Q202 557.3 213 553.1Q224 548.9 235 545.8Q246 542.6 257 539.8Q268 537 279 534Q290 530.9 301 527.1Q312 523.3 323 518.6Q334 513.9 345 508.5Q356 503.1 367 497.4Q378 491.7 389 486.4Q400 481.1 411 476.7L422 472.4' fill='none' stroke='rgba(255,255,255,0.67)' stroke-width='1.4'/%3E%3Cpath d='M-40 789.5Q-18 770.1 -7 758.3Q4 746.6 15 733.5Q26 720.5 37 707Q48 693.6 59 680.7Q70 667.8 81 656.3Q92 644.7 103 634.8Q114 625 125 616.8Q136 608.6 147 601.7Q158 594.9 169 589Q180 583.1 191 577.8Q202 572.4 213 567.5Q224 562.6 235 558Q246 553.5 257 549.3Q268 545.1 279 541.3Q290 537.5 301 533.9Q312 530.3 323 526.6Q334 523 345 518.9Q356 514.9 367 510.3Q378 505.7 389 500.6Q400 495.6 411 490.4L422 485.2' fill='none' stroke='rgba(255,255,255,0.70)' stroke-width='1.3'/%3E%3Cpath d='M-40 790.7Q-18 770.5 -7 759.4Q4 748.2 15 736.5Q26 724.8 37 712.9Q48 701 59 689.5Q70 677.9 81 667Q92 656 103 645.9Q114 635.9 125 626.8Q136 617.8 147 610Q158 602.2 169 595.8Q180 589.3 191 584.2Q202 579.1 213 575.2Q224 571.2 235 568.1Q246 564.9 257 562Q268 559.2 279 556Q290 552.9 301 549.1Q312 545.3 323 540.5Q334 535.8 345 530.3Q356 524.7 367 518.8Q378 512.8 389 506.9Q400 501.1 411 495.9L422 490.7' fill='none' stroke='rgba(255,255,255,0.62)' stroke-width='1.1'/%3E%3Cpath d='M-40 798.1Q-18 779.1 -7 767.7Q4 756.3 15 743.8Q26 731.2 37 718.3Q48 705.5 59 693.3Q70 681.1 81 670.2Q92 659.4 103 650.3Q114 641.1 125 633.6Q136 626.1 147 619.9Q158 613.8 169 608.4Q180 603.1 191 598.3Q202 593.5 213 589Q224 584.5 235 580.2Q246 576 257 572Q268 568 279 564.2Q290 560.4 301 556.7Q312 553 323 549.1Q334 545.1 345 540.7Q356 536.2 367 531.1Q378 526 389 520.3Q400 514.6 411 508.8L422 502.9' fill='none' stroke='rgba(255,255,255,0.55)' stroke-width='1.2'/%3E%3Cpath d='M-40 797.9Q-18 778.2 -7 767.6Q4 757.1 15 746.3Q26 735.5 37 724.7Q48 713.8 59 703.2Q70 692.6 81 682.3Q92 672 103 662.4Q114 652.7 125 643.9Q136 635.1 147 627.6Q158 620.1 169 614Q180 608 191 603.5Q202 599 213 595.8Q224 592.6 235 590.2Q246 587.8 257 585.5Q268 583.2 279 580.2Q290 577.3 301 573.1Q312 569 323 563.6Q334 558.2 345 551.8Q356 545.4 367 538.6Q378 531.8 389 525.3Q400 518.8 411 513.2L422 507.6' fill='none' stroke='rgba(255,255,255,0.52)' stroke-width='1'/%3E%3Cpath d='M-40 804.8Q-18 784.4 -7 773.3Q4 762.2 15 750.8Q26 739.4 37 728.3Q48 717.3 59 707Q70 696.7 81 687.3Q92 678 103 669.5Q114 661 125 653.3Q136 645.7 147 638.9Q158 632.1 169 626.2Q180 620.3 191 615.4Q202 610.6 213 606.8Q224 602.9 235 600Q246 597 257 594.5Q268 592 279 589.3Q290 586.6 301 583.1Q312 579.7 323 575Q334 570.3 345 564.3Q356 558.4 367 551.4Q378 544.5 389 537.3Q400 530.1 411 523.4L422 516.7' fill='none' stroke='rgba(255,255,255,0.37)' stroke-width='1.1'/%3E%3Cpath d='M-40 808.9Q-18 791 -7 780.8Q4 770.5 15 759.4Q26 748.2 37 736.7Q48 725.2 59 714.1Q70 702.9 81 692.8Q92 682.7 103 674.1Q114 665.4 125 658.4Q136 651.3 147 645.7Q158 640.1 169 635.7Q180 631.3 191 627.7Q202 624 213 620.8Q224 617.5 235 614.3Q246 611.1 257 607.7Q268 604.2 279 600.4Q290 596.5 301 592.2Q312 587.8 323 582.8Q334 577.8 345 572.2Q356 566.6 367 560.5Q378 554.4 389 548Q400 541.7 411 535.4L422 529' fill='none' stroke='rgba(255,255,255,0.33)' stroke-width='0.9'/%3E%3Cpath d='M-40 810.4Q-18 793.9 -7 784.8Q4 775.7 15 765.6Q26 755.5 37 744.8Q48 734 59 723.1Q70 712.2 81 701.7Q92 691.3 103 682Q114 672.8 125 665.3Q136 657.7 147 652.2Q158 646.6 169 642.8Q180 639 191 636.4Q202 633.8 213 631.7Q224 629.6 235 627.3Q246 624.9 257 621.8Q268 618.6 279 614.3Q290 610 301 604.7Q312 599.4 323 593.3Q334 587.3 345 580.9Q356 574.5 367 568.1Q378 561.7 389 555.6Q400 549.5 411 543.8L422 538.1' fill='none' stroke='rgba(255,255,255,0.32)' stroke-width='0.9'/%3E%3Cpath d='M-40 819.9Q-18 801.3 -7 790.5Q4 779.7 15 768.3Q26 756.8 37 745.6Q48 734.3 59 724.1Q70 713.9 81 705.3Q92 696.6 103 689.6Q114 682.5 125 676.9Q136 671.2 147 666.5Q158 661.7 169 657.5Q180 653.3 191 649.4Q202 645.5 213 641.8Q224 638.1 235 634.6Q246 631 257 627.7Q268 624.4 279 621.1Q290 617.8 301 614.1Q312 610.5 323 606.1Q334 601.6 345 596.1Q356 590.6 367 583.9Q378 577.2 389 569.6Q400 562 411 554.2L422 546.3' fill='none' stroke='rgba(255,255,255,0.31)' stroke-width='0.8'/%3E%3Cpath d='M-40 817.6Q-18 800.2 -7 791.3Q4 782.4 15 773.4Q26 764.3 37 755Q48 745.8 59 736.5Q70 727.2 81 718Q92 708.9 103 700.3Q114 691.8 125 684.3Q136 676.9 147 671Q158 665.1 169 661Q180 656.9 191 654.4Q202 651.9 213 650.4Q224 648.9 235 647.6Q246 646.3 257 644.2Q268 642.2 279 638.8Q290 635.3 301 630.2Q312 625.1 323 618.4Q334 611.8 345 604.1Q356 596.5 367 588.6Q378 580.8 389 573.4Q400 565.9 411 559.4L422 552.8' fill='none' stroke='rgba(255,255,255,0.30)' stroke-width='0.8'/%3E%3Cpath d='M-40 823.1Q-18 806.6 -7 797.9Q4 789.1 15 779.8Q26 770.5 37 761Q48 751.4 59 741.8Q70 732.3 81 723.3Q92 714.2 103 706.2Q114 698.2 125 691.6Q136 685.1 147 680.1Q158 675.2 169 671.9Q180 668.6 191 666.5Q202 664.4 213 662.8Q224 661.3 235 659.5Q246 657.8 257 655.2Q268 652.7 279 648.8Q290 645 301 639.8Q312 634.5 323 628.1Q334 621.7 345 614.4Q356 607.2 367 599.7Q378 592.1 389 584.8Q400 577.4 411 570.4L422 563.5' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.9'/%3E%3Cpath d='M-40 825.7Q-18 810.8 -7 802.9Q4 795.1 15 786.5Q26 778 37 768.8Q48 759.6 59 750Q70 740.4 81 731Q92 721.6 103 713.2Q114 704.9 125 698.2Q136 691.6 147 687.1Q158 682.5 169 680Q180 677.5 191 676.4Q202 675.3 213 674.6Q224 673.9 235 672.6Q246 671.4 257 668.7Q268 666 279 661.6Q290 657.2 301 651.2Q312 645.1 323 638Q334 630.8 345 623.2Q356 615.5 367 608.1Q378 600.6 389 593.5Q400 586.5 411 580L422 573.4' fill='none' stroke='rgba(255,255,255,0.22)' stroke-width='0.6'/%3E%3Cpath d='M-40 832.3Q-18 818.3 -7 810.3Q4 802.3 15 793.2Q26 784.1 37 774.2Q48 764.3 59 754.4Q70 744.4 81 735.2Q92 726 103 718.4Q114 710.9 125 705.5Q136 700.1 147 696.8Q158 693.6 169 692Q180 690.4 191 689.5Q202 688.6 213 687.6Q224 686.5 235 684.5Q246 682.4 257 678.9Q268 675.5 279 670.6Q290 665.7 301 659.8Q312 653.8 323 647.2Q334 640.6 345 633.8Q356 626.9 367 620Q378 613 389 606Q400 599 411 591.9L422 584.7' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.8'/%3E%3Cpath d='M-40 836.8Q-18 818.8 -7 809.7Q4 800.6 15 791.9Q26 783.1 37 775Q48 766.9 59 759.4Q70 751.9 81 745Q92 738.2 103 731.9Q114 725.7 125 720.2Q136 714.7 147 710.1Q158 705.5 169 702Q180 698.5 191 696.1Q202 693.7 213 692.2Q224 690.7 235 689.5Q246 688.4 257 686.9Q268 685.4 279 682.8Q290 680.1 301 675.7Q312 671.2 323 664.8Q334 658.4 345 650.2Q356 642 367 632.8Q378 623.6 389 614.1Q400 604.7 411 595.9L422 587.1' fill='none' stroke='rgba(255,255,255,0.13)' stroke-width='0.5'/%3E%3Cpath d='M-40 843.2Q-18 824.8 -7 815.3Q4 805.8 15 796.7Q26 787.5 37 779.2Q48 770.9 59 763.7Q70 756.4 81 750.3Q92 744.2 103 739Q114 733.7 125 729.2Q136 724.7 147 720.8Q158 717 169 713.7Q180 710.4 191 707.8Q202 705.2 213 703.3Q224 701.3 235 699.7Q246 698.2 257 696.5Q268 694.8 279 692.3Q290 689.8 301 685.8Q312 681.8 323 675.9Q334 670 345 662.2Q356 654.4 367 645.1Q378 635.8 389 625.8Q400 615.8 411 606.1L422 596.4' fill='none' stroke='rgba(255,255,255,0.15)' stroke-width='0.7'/%3E%3Cpath d='M-40 844.7Q-18 829.6 -7 821.8Q4 813.9 15 805.8Q26 797.7 37 789.4Q48 781.2 59 773.2Q70 765.2 81 757.8Q92 750.5 103 744.3Q114 738 125 733.3Q136 728.6 147 725.5Q158 722.4 169 720.8Q180 719.1 191 718.3Q202 717.6 213 717Q224 716.5 235 715.4Q246 714.2 257 711.9Q268 709.6 279 705.7Q290 701.8 301 696.2Q312 690.6 323 683.6Q334 676.6 345 668.5Q356 660.4 367 651.7Q378 643.1 389 634.3Q400 625.5 411 616.9L422 608.3' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.6'/%3E%3Cpath d='M-40 849Q-18 834.3 -7 826.7Q4 819 15 811.1Q26 803.2 37 795.2Q48 787.2 59 779.5Q70 771.7 81 764.7Q92 757.6 103 751.8Q114 745.9 125 741.6Q136 737.2 147 734.5Q158 731.8 169 730.5Q180 729.2 191 728.8Q202 728.3 213 728Q224 727.6 235 726.6Q246 725.6 257 723.3Q268 721 279 717.1Q290 713.1 301 707.4Q312 701.8 323 694.6Q334 687.4 345 679.2Q356 671 367 662.1Q378 653.3 389 644.3Q400 635.2 411 626.3L422 617.4' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.5'/%3E%3Cpath d='M-40 853.9Q-18 839.6 -7 832.1Q4 824.6 15 816.7Q26 808.8 37 800.8Q48 792.9 59 785.2Q70 777.6 81 770.9Q92 764.1 103 758.8Q114 753.4 125 749.6Q136 745.9 147 743.8Q158 741.7 169 740.9Q180 740 191 739.8Q202 739.6 213 739.3Q224 739.1 235 737.9Q246 736.8 257 734.4Q268 731.9 279 727.8Q290 723.8 301 718Q312 712.3 323 705.2Q334 698.1 345 690Q356 681.8 367 672.9Q378 664.1 389 654.8Q400 645.6 411 636.3L422 627' fill='none' stroke='rgba(255,255,255,0.08)' stroke-width='0.7'/%3E%3Cpath d='M-40 857.5Q-18 842.3 -7 834.8Q4 827.3 15 820Q26 812.6 37 805.6Q48 798.5 59 791.9Q70 785.3 81 779.4Q92 773.4 103 768.5Q114 763.5 125 759.7Q136 756 147 753.5Q158 751.1 169 749.9Q180 748.7 191 748.4Q202 748.1 213 748.1Q224 748 235 747.6Q246 747.1 257 745.4Q268 743.7 279 740.2Q290 736.8 301 731.3Q312 725.8 323 718.4Q334 711 345 702.1Q356 693.2 367 683.3Q378 673.5 389 663.5Q400 653.4 411 643.6L422 633.7' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.8'/%3E%3Cpath d='M-40 863.8Q-18 850.1 -7 842.7Q4 835.3 15 827.4Q26 819.6 37 811.7Q48 803.9 59 796.7Q70 789.4 81 783.4Q92 777.4 103 773.1Q114 768.8 125 766.2Q136 763.7 147 762.7Q158 761.6 169 761.6Q180 761.6 191 761.8Q202 762 213 761.7Q224 761.5 235 760.2Q246 758.9 257 756.2Q268 753.5 279 749.3Q290 745.1 301 739.5Q312 733.9 323 726.9Q334 720 345 711.9Q356 703.8 367 694.7Q378 685.7 389 675.9Q400 666.2 411 655.9L422 645.7' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.7'/%3E%3C/svg%3E") center bottom / cover no-repeat;
  opacity: .78;
  animation: as-flow-front 7s ease-in-out infinite alternate;
}
/* แสงวิ่งไปตามเส้นคลื่นชั้นหน้า — เจ้าของ: "ทำให้เส้นมันขยับให้เห็นชัดกว่านี้"
   การแกว่งทั้งชั้นอย่างเดียวยังอ่านว่า "ภาพเลื่อน" · แสงที่ไหลไปตามเส้นต่างหากที่อ่านว่า "เส้นกำลังไหล"
   หน้ากากคือเส้นชุดเดียวกับชั้นหน้าแต่ไม่มีพื้นดำ (สร้างจาก seed เดิม ตำแหน่งตรงกันเป๊ะ)
   แสงจึงติดเฉพาะตัวเส้น ไม่ใช่ทั้งก้อนคลื่น · เป็นลูกของ .fx-g จึงแกว่งไปพร้อมกับเส้นของมันเอง */
:root[data-theme="astral"] .fx-g::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.5) 46%, #fff 50%, rgba(255,255,255,.5) 54%, transparent 62%)
    0 0 / 320% 100% no-repeat;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 860' preserveAspectRatio='xMidYMax slice'%3E%3Cpath d='M-40 772.2Q-18 753.7 -7 742.9Q4 732.1 15 719.7Q26 707.3 37 693.8Q48 680.3 59 666.2Q70 652.2 81 638.5Q92 624.9 103 612.4Q114 600 125 589.4Q136 578.8 147 570.4Q158 561.9 169 555.5Q180 549.1 191 544.2Q202 539.3 213 535.3Q224 531.3 235 527.5Q246 523.7 257 519.6Q268 515.6 279 511.1Q290 506.7 301 501.9Q312 497.1 323 492.3Q334 487.5 345 483.1Q356 478.6 367 474.6Q378 470.7 389 467.4Q400 464 411 461.3L422 458.5' fill='none' stroke='rgba(255,255,255,0.83)' stroke-width='1.7'/%3E%3Cpath d='M-40 775.8Q-18 757 -7 746.3Q4 735.6 15 723.7Q26 711.8 37 699Q48 686.2 59 672.9Q70 659.7 81 646.6Q92 633.5 103 621.4Q114 609.3 125 598.8Q136 588.3 147 579.7Q158 571.2 169 564.6Q180 558.1 191 553.3Q202 548.5 213 544.8Q224 541 235 537.7Q246 534.4 257 530.9Q268 527.4 279 523.3Q290 519.2 301 514.5Q312 509.8 323 504.8Q334 499.7 345 494.6Q356 489.5 367 484.9Q378 480.2 389 476.3Q400 472.3 411 469.2L422 466' fill='none' stroke='rgba(255,255,255,0.87)' stroke-width='1.6'/%3E%3Cpath d='M-40 781.3Q-18 760.6 -7 749.3Q4 737.9 15 725.9Q26 714 37 701.8Q48 689.6 59 677.6Q70 665.5 81 653.9Q92 642.2 103 631.2Q114 620.2 125 610.2Q136 600.2 147 591.5Q158 582.8 169 575.6Q180 568.4 191 562.8Q202 557.3 213 553.1Q224 548.9 235 545.8Q246 542.6 257 539.8Q268 537 279 534Q290 530.9 301 527.1Q312 523.3 323 518.6Q334 513.9 345 508.5Q356 503.1 367 497.4Q378 491.7 389 486.4Q400 481.1 411 476.7L422 472.4' fill='none' stroke='rgba(255,255,255,0.67)' stroke-width='1.4'/%3E%3Cpath d='M-40 789.5Q-18 770.1 -7 758.3Q4 746.6 15 733.5Q26 720.5 37 707Q48 693.6 59 680.7Q70 667.8 81 656.3Q92 644.7 103 634.8Q114 625 125 616.8Q136 608.6 147 601.7Q158 594.9 169 589Q180 583.1 191 577.8Q202 572.4 213 567.5Q224 562.6 235 558Q246 553.5 257 549.3Q268 545.1 279 541.3Q290 537.5 301 533.9Q312 530.3 323 526.6Q334 523 345 518.9Q356 514.9 367 510.3Q378 505.7 389 500.6Q400 495.6 411 490.4L422 485.2' fill='none' stroke='rgba(255,255,255,0.70)' stroke-width='1.3'/%3E%3Cpath d='M-40 790.7Q-18 770.5 -7 759.4Q4 748.2 15 736.5Q26 724.8 37 712.9Q48 701 59 689.5Q70 677.9 81 667Q92 656 103 645.9Q114 635.9 125 626.8Q136 617.8 147 610Q158 602.2 169 595.8Q180 589.3 191 584.2Q202 579.1 213 575.2Q224 571.2 235 568.1Q246 564.9 257 562Q268 559.2 279 556Q290 552.9 301 549.1Q312 545.3 323 540.5Q334 535.8 345 530.3Q356 524.7 367 518.8Q378 512.8 389 506.9Q400 501.1 411 495.9L422 490.7' fill='none' stroke='rgba(255,255,255,0.62)' stroke-width='1.1'/%3E%3Cpath d='M-40 798.1Q-18 779.1 -7 767.7Q4 756.3 15 743.8Q26 731.2 37 718.3Q48 705.5 59 693.3Q70 681.1 81 670.2Q92 659.4 103 650.3Q114 641.1 125 633.6Q136 626.1 147 619.9Q158 613.8 169 608.4Q180 603.1 191 598.3Q202 593.5 213 589Q224 584.5 235 580.2Q246 576 257 572Q268 568 279 564.2Q290 560.4 301 556.7Q312 553 323 549.1Q334 545.1 345 540.7Q356 536.2 367 531.1Q378 526 389 520.3Q400 514.6 411 508.8L422 502.9' fill='none' stroke='rgba(255,255,255,0.55)' stroke-width='1.2'/%3E%3Cpath d='M-40 797.9Q-18 778.2 -7 767.6Q4 757.1 15 746.3Q26 735.5 37 724.7Q48 713.8 59 703.2Q70 692.6 81 682.3Q92 672 103 662.4Q114 652.7 125 643.9Q136 635.1 147 627.6Q158 620.1 169 614Q180 608 191 603.5Q202 599 213 595.8Q224 592.6 235 590.2Q246 587.8 257 585.5Q268 583.2 279 580.2Q290 577.3 301 573.1Q312 569 323 563.6Q334 558.2 345 551.8Q356 545.4 367 538.6Q378 531.8 389 525.3Q400 518.8 411 513.2L422 507.6' fill='none' stroke='rgba(255,255,255,0.52)' stroke-width='1'/%3E%3Cpath d='M-40 804.8Q-18 784.4 -7 773.3Q4 762.2 15 750.8Q26 739.4 37 728.3Q48 717.3 59 707Q70 696.7 81 687.3Q92 678 103 669.5Q114 661 125 653.3Q136 645.7 147 638.9Q158 632.1 169 626.2Q180 620.3 191 615.4Q202 610.6 213 606.8Q224 602.9 235 600Q246 597 257 594.5Q268 592 279 589.3Q290 586.6 301 583.1Q312 579.7 323 575Q334 570.3 345 564.3Q356 558.4 367 551.4Q378 544.5 389 537.3Q400 530.1 411 523.4L422 516.7' fill='none' stroke='rgba(255,255,255,0.37)' stroke-width='1.1'/%3E%3Cpath d='M-40 808.9Q-18 791 -7 780.8Q4 770.5 15 759.4Q26 748.2 37 736.7Q48 725.2 59 714.1Q70 702.9 81 692.8Q92 682.7 103 674.1Q114 665.4 125 658.4Q136 651.3 147 645.7Q158 640.1 169 635.7Q180 631.3 191 627.7Q202 624 213 620.8Q224 617.5 235 614.3Q246 611.1 257 607.7Q268 604.2 279 600.4Q290 596.5 301 592.2Q312 587.8 323 582.8Q334 577.8 345 572.2Q356 566.6 367 560.5Q378 554.4 389 548Q400 541.7 411 535.4L422 529' fill='none' stroke='rgba(255,255,255,0.33)' stroke-width='0.9'/%3E%3Cpath d='M-40 810.4Q-18 793.9 -7 784.8Q4 775.7 15 765.6Q26 755.5 37 744.8Q48 734 59 723.1Q70 712.2 81 701.7Q92 691.3 103 682Q114 672.8 125 665.3Q136 657.7 147 652.2Q158 646.6 169 642.8Q180 639 191 636.4Q202 633.8 213 631.7Q224 629.6 235 627.3Q246 624.9 257 621.8Q268 618.6 279 614.3Q290 610 301 604.7Q312 599.4 323 593.3Q334 587.3 345 580.9Q356 574.5 367 568.1Q378 561.7 389 555.6Q400 549.5 411 543.8L422 538.1' fill='none' stroke='rgba(255,255,255,0.32)' stroke-width='0.9'/%3E%3Cpath d='M-40 819.9Q-18 801.3 -7 790.5Q4 779.7 15 768.3Q26 756.8 37 745.6Q48 734.3 59 724.1Q70 713.9 81 705.3Q92 696.6 103 689.6Q114 682.5 125 676.9Q136 671.2 147 666.5Q158 661.7 169 657.5Q180 653.3 191 649.4Q202 645.5 213 641.8Q224 638.1 235 634.6Q246 631 257 627.7Q268 624.4 279 621.1Q290 617.8 301 614.1Q312 610.5 323 606.1Q334 601.6 345 596.1Q356 590.6 367 583.9Q378 577.2 389 569.6Q400 562 411 554.2L422 546.3' fill='none' stroke='rgba(255,255,255,0.31)' stroke-width='0.8'/%3E%3Cpath d='M-40 817.6Q-18 800.2 -7 791.3Q4 782.4 15 773.4Q26 764.3 37 755Q48 745.8 59 736.5Q70 727.2 81 718Q92 708.9 103 700.3Q114 691.8 125 684.3Q136 676.9 147 671Q158 665.1 169 661Q180 656.9 191 654.4Q202 651.9 213 650.4Q224 648.9 235 647.6Q246 646.3 257 644.2Q268 642.2 279 638.8Q290 635.3 301 630.2Q312 625.1 323 618.4Q334 611.8 345 604.1Q356 596.5 367 588.6Q378 580.8 389 573.4Q400 565.9 411 559.4L422 552.8' fill='none' stroke='rgba(255,255,255,0.30)' stroke-width='0.8'/%3E%3Cpath d='M-40 823.1Q-18 806.6 -7 797.9Q4 789.1 15 779.8Q26 770.5 37 761Q48 751.4 59 741.8Q70 732.3 81 723.3Q92 714.2 103 706.2Q114 698.2 125 691.6Q136 685.1 147 680.1Q158 675.2 169 671.9Q180 668.6 191 666.5Q202 664.4 213 662.8Q224 661.3 235 659.5Q246 657.8 257 655.2Q268 652.7 279 648.8Q290 645 301 639.8Q312 634.5 323 628.1Q334 621.7 345 614.4Q356 607.2 367 599.7Q378 592.1 389 584.8Q400 577.4 411 570.4L422 563.5' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.9'/%3E%3Cpath d='M-40 825.7Q-18 810.8 -7 802.9Q4 795.1 15 786.5Q26 778 37 768.8Q48 759.6 59 750Q70 740.4 81 731Q92 721.6 103 713.2Q114 704.9 125 698.2Q136 691.6 147 687.1Q158 682.5 169 680Q180 677.5 191 676.4Q202 675.3 213 674.6Q224 673.9 235 672.6Q246 671.4 257 668.7Q268 666 279 661.6Q290 657.2 301 651.2Q312 645.1 323 638Q334 630.8 345 623.2Q356 615.5 367 608.1Q378 600.6 389 593.5Q400 586.5 411 580L422 573.4' fill='none' stroke='rgba(255,255,255,0.22)' stroke-width='0.6'/%3E%3Cpath d='M-40 832.3Q-18 818.3 -7 810.3Q4 802.3 15 793.2Q26 784.1 37 774.2Q48 764.3 59 754.4Q70 744.4 81 735.2Q92 726 103 718.4Q114 710.9 125 705.5Q136 700.1 147 696.8Q158 693.6 169 692Q180 690.4 191 689.5Q202 688.6 213 687.6Q224 686.5 235 684.5Q246 682.4 257 678.9Q268 675.5 279 670.6Q290 665.7 301 659.8Q312 653.8 323 647.2Q334 640.6 345 633.8Q356 626.9 367 620Q378 613 389 606Q400 599 411 591.9L422 584.7' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.8'/%3E%3Cpath d='M-40 836.8Q-18 818.8 -7 809.7Q4 800.6 15 791.9Q26 783.1 37 775Q48 766.9 59 759.4Q70 751.9 81 745Q92 738.2 103 731.9Q114 725.7 125 720.2Q136 714.7 147 710.1Q158 705.5 169 702Q180 698.5 191 696.1Q202 693.7 213 692.2Q224 690.7 235 689.5Q246 688.4 257 686.9Q268 685.4 279 682.8Q290 680.1 301 675.7Q312 671.2 323 664.8Q334 658.4 345 650.2Q356 642 367 632.8Q378 623.6 389 614.1Q400 604.7 411 595.9L422 587.1' fill='none' stroke='rgba(255,255,255,0.13)' stroke-width='0.5'/%3E%3Cpath d='M-40 843.2Q-18 824.8 -7 815.3Q4 805.8 15 796.7Q26 787.5 37 779.2Q48 770.9 59 763.7Q70 756.4 81 750.3Q92 744.2 103 739Q114 733.7 125 729.2Q136 724.7 147 720.8Q158 717 169 713.7Q180 710.4 191 707.8Q202 705.2 213 703.3Q224 701.3 235 699.7Q246 698.2 257 696.5Q268 694.8 279 692.3Q290 689.8 301 685.8Q312 681.8 323 675.9Q334 670 345 662.2Q356 654.4 367 645.1Q378 635.8 389 625.8Q400 615.8 411 606.1L422 596.4' fill='none' stroke='rgba(255,255,255,0.15)' stroke-width='0.7'/%3E%3Cpath d='M-40 844.7Q-18 829.6 -7 821.8Q4 813.9 15 805.8Q26 797.7 37 789.4Q48 781.2 59 773.2Q70 765.2 81 757.8Q92 750.5 103 744.3Q114 738 125 733.3Q136 728.6 147 725.5Q158 722.4 169 720.8Q180 719.1 191 718.3Q202 717.6 213 717Q224 716.5 235 715.4Q246 714.2 257 711.9Q268 709.6 279 705.7Q290 701.8 301 696.2Q312 690.6 323 683.6Q334 676.6 345 668.5Q356 660.4 367 651.7Q378 643.1 389 634.3Q400 625.5 411 616.9L422 608.3' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.6'/%3E%3Cpath d='M-40 849Q-18 834.3 -7 826.7Q4 819 15 811.1Q26 803.2 37 795.2Q48 787.2 59 779.5Q70 771.7 81 764.7Q92 757.6 103 751.8Q114 745.9 125 741.6Q136 737.2 147 734.5Q158 731.8 169 730.5Q180 729.2 191 728.8Q202 728.3 213 728Q224 727.6 235 726.6Q246 725.6 257 723.3Q268 721 279 717.1Q290 713.1 301 707.4Q312 701.8 323 694.6Q334 687.4 345 679.2Q356 671 367 662.1Q378 653.3 389 644.3Q400 635.2 411 626.3L422 617.4' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.5'/%3E%3Cpath d='M-40 853.9Q-18 839.6 -7 832.1Q4 824.6 15 816.7Q26 808.8 37 800.8Q48 792.9 59 785.2Q70 777.6 81 770.9Q92 764.1 103 758.8Q114 753.4 125 749.6Q136 745.9 147 743.8Q158 741.7 169 740.9Q180 740 191 739.8Q202 739.6 213 739.3Q224 739.1 235 737.9Q246 736.8 257 734.4Q268 731.9 279 727.8Q290 723.8 301 718Q312 712.3 323 705.2Q334 698.1 345 690Q356 681.8 367 672.9Q378 664.1 389 654.8Q400 645.6 411 636.3L422 627' fill='none' stroke='rgba(255,255,255,0.08)' stroke-width='0.7'/%3E%3Cpath d='M-40 857.5Q-18 842.3 -7 834.8Q4 827.3 15 820Q26 812.6 37 805.6Q48 798.5 59 791.9Q70 785.3 81 779.4Q92 773.4 103 768.5Q114 763.5 125 759.7Q136 756 147 753.5Q158 751.1 169 749.9Q180 748.7 191 748.4Q202 748.1 213 748.1Q224 748 235 747.6Q246 747.1 257 745.4Q268 743.7 279 740.2Q290 736.8 301 731.3Q312 725.8 323 718.4Q334 711 345 702.1Q356 693.2 367 683.3Q378 673.5 389 663.5Q400 653.4 411 643.6L422 633.7' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.8'/%3E%3Cpath d='M-40 863.8Q-18 850.1 -7 842.7Q4 835.3 15 827.4Q26 819.6 37 811.7Q48 803.9 59 796.7Q70 789.4 81 783.4Q92 777.4 103 773.1Q114 768.8 125 766.2Q136 763.7 147 762.7Q158 761.6 169 761.6Q180 761.6 191 761.8Q202 762 213 761.7Q224 761.5 235 760.2Q246 758.9 257 756.2Q268 753.5 279 749.3Q290 745.1 301 739.5Q312 733.9 323 726.9Q334 720 345 711.9Q356 703.8 367 694.7Q378 685.7 389 675.9Q400 666.2 411 655.9L422 645.7' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.7'/%3E%3C/svg%3E") center bottom / cover no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 860' preserveAspectRatio='xMidYMax slice'%3E%3Cpath d='M-40 772.2Q-18 753.7 -7 742.9Q4 732.1 15 719.7Q26 707.3 37 693.8Q48 680.3 59 666.2Q70 652.2 81 638.5Q92 624.9 103 612.4Q114 600 125 589.4Q136 578.8 147 570.4Q158 561.9 169 555.5Q180 549.1 191 544.2Q202 539.3 213 535.3Q224 531.3 235 527.5Q246 523.7 257 519.6Q268 515.6 279 511.1Q290 506.7 301 501.9Q312 497.1 323 492.3Q334 487.5 345 483.1Q356 478.6 367 474.6Q378 470.7 389 467.4Q400 464 411 461.3L422 458.5' fill='none' stroke='rgba(255,255,255,0.83)' stroke-width='1.7'/%3E%3Cpath d='M-40 775.8Q-18 757 -7 746.3Q4 735.6 15 723.7Q26 711.8 37 699Q48 686.2 59 672.9Q70 659.7 81 646.6Q92 633.5 103 621.4Q114 609.3 125 598.8Q136 588.3 147 579.7Q158 571.2 169 564.6Q180 558.1 191 553.3Q202 548.5 213 544.8Q224 541 235 537.7Q246 534.4 257 530.9Q268 527.4 279 523.3Q290 519.2 301 514.5Q312 509.8 323 504.8Q334 499.7 345 494.6Q356 489.5 367 484.9Q378 480.2 389 476.3Q400 472.3 411 469.2L422 466' fill='none' stroke='rgba(255,255,255,0.87)' stroke-width='1.6'/%3E%3Cpath d='M-40 781.3Q-18 760.6 -7 749.3Q4 737.9 15 725.9Q26 714 37 701.8Q48 689.6 59 677.6Q70 665.5 81 653.9Q92 642.2 103 631.2Q114 620.2 125 610.2Q136 600.2 147 591.5Q158 582.8 169 575.6Q180 568.4 191 562.8Q202 557.3 213 553.1Q224 548.9 235 545.8Q246 542.6 257 539.8Q268 537 279 534Q290 530.9 301 527.1Q312 523.3 323 518.6Q334 513.9 345 508.5Q356 503.1 367 497.4Q378 491.7 389 486.4Q400 481.1 411 476.7L422 472.4' fill='none' stroke='rgba(255,255,255,0.67)' stroke-width='1.4'/%3E%3Cpath d='M-40 789.5Q-18 770.1 -7 758.3Q4 746.6 15 733.5Q26 720.5 37 707Q48 693.6 59 680.7Q70 667.8 81 656.3Q92 644.7 103 634.8Q114 625 125 616.8Q136 608.6 147 601.7Q158 594.9 169 589Q180 583.1 191 577.8Q202 572.4 213 567.5Q224 562.6 235 558Q246 553.5 257 549.3Q268 545.1 279 541.3Q290 537.5 301 533.9Q312 530.3 323 526.6Q334 523 345 518.9Q356 514.9 367 510.3Q378 505.7 389 500.6Q400 495.6 411 490.4L422 485.2' fill='none' stroke='rgba(255,255,255,0.70)' stroke-width='1.3'/%3E%3Cpath d='M-40 790.7Q-18 770.5 -7 759.4Q4 748.2 15 736.5Q26 724.8 37 712.9Q48 701 59 689.5Q70 677.9 81 667Q92 656 103 645.9Q114 635.9 125 626.8Q136 617.8 147 610Q158 602.2 169 595.8Q180 589.3 191 584.2Q202 579.1 213 575.2Q224 571.2 235 568.1Q246 564.9 257 562Q268 559.2 279 556Q290 552.9 301 549.1Q312 545.3 323 540.5Q334 535.8 345 530.3Q356 524.7 367 518.8Q378 512.8 389 506.9Q400 501.1 411 495.9L422 490.7' fill='none' stroke='rgba(255,255,255,0.62)' stroke-width='1.1'/%3E%3Cpath d='M-40 798.1Q-18 779.1 -7 767.7Q4 756.3 15 743.8Q26 731.2 37 718.3Q48 705.5 59 693.3Q70 681.1 81 670.2Q92 659.4 103 650.3Q114 641.1 125 633.6Q136 626.1 147 619.9Q158 613.8 169 608.4Q180 603.1 191 598.3Q202 593.5 213 589Q224 584.5 235 580.2Q246 576 257 572Q268 568 279 564.2Q290 560.4 301 556.7Q312 553 323 549.1Q334 545.1 345 540.7Q356 536.2 367 531.1Q378 526 389 520.3Q400 514.6 411 508.8L422 502.9' fill='none' stroke='rgba(255,255,255,0.55)' stroke-width='1.2'/%3E%3Cpath d='M-40 797.9Q-18 778.2 -7 767.6Q4 757.1 15 746.3Q26 735.5 37 724.7Q48 713.8 59 703.2Q70 692.6 81 682.3Q92 672 103 662.4Q114 652.7 125 643.9Q136 635.1 147 627.6Q158 620.1 169 614Q180 608 191 603.5Q202 599 213 595.8Q224 592.6 235 590.2Q246 587.8 257 585.5Q268 583.2 279 580.2Q290 577.3 301 573.1Q312 569 323 563.6Q334 558.2 345 551.8Q356 545.4 367 538.6Q378 531.8 389 525.3Q400 518.8 411 513.2L422 507.6' fill='none' stroke='rgba(255,255,255,0.52)' stroke-width='1'/%3E%3Cpath d='M-40 804.8Q-18 784.4 -7 773.3Q4 762.2 15 750.8Q26 739.4 37 728.3Q48 717.3 59 707Q70 696.7 81 687.3Q92 678 103 669.5Q114 661 125 653.3Q136 645.7 147 638.9Q158 632.1 169 626.2Q180 620.3 191 615.4Q202 610.6 213 606.8Q224 602.9 235 600Q246 597 257 594.5Q268 592 279 589.3Q290 586.6 301 583.1Q312 579.7 323 575Q334 570.3 345 564.3Q356 558.4 367 551.4Q378 544.5 389 537.3Q400 530.1 411 523.4L422 516.7' fill='none' stroke='rgba(255,255,255,0.37)' stroke-width='1.1'/%3E%3Cpath d='M-40 808.9Q-18 791 -7 780.8Q4 770.5 15 759.4Q26 748.2 37 736.7Q48 725.2 59 714.1Q70 702.9 81 692.8Q92 682.7 103 674.1Q114 665.4 125 658.4Q136 651.3 147 645.7Q158 640.1 169 635.7Q180 631.3 191 627.7Q202 624 213 620.8Q224 617.5 235 614.3Q246 611.1 257 607.7Q268 604.2 279 600.4Q290 596.5 301 592.2Q312 587.8 323 582.8Q334 577.8 345 572.2Q356 566.6 367 560.5Q378 554.4 389 548Q400 541.7 411 535.4L422 529' fill='none' stroke='rgba(255,255,255,0.33)' stroke-width='0.9'/%3E%3Cpath d='M-40 810.4Q-18 793.9 -7 784.8Q4 775.7 15 765.6Q26 755.5 37 744.8Q48 734 59 723.1Q70 712.2 81 701.7Q92 691.3 103 682Q114 672.8 125 665.3Q136 657.7 147 652.2Q158 646.6 169 642.8Q180 639 191 636.4Q202 633.8 213 631.7Q224 629.6 235 627.3Q246 624.9 257 621.8Q268 618.6 279 614.3Q290 610 301 604.7Q312 599.4 323 593.3Q334 587.3 345 580.9Q356 574.5 367 568.1Q378 561.7 389 555.6Q400 549.5 411 543.8L422 538.1' fill='none' stroke='rgba(255,255,255,0.32)' stroke-width='0.9'/%3E%3Cpath d='M-40 819.9Q-18 801.3 -7 790.5Q4 779.7 15 768.3Q26 756.8 37 745.6Q48 734.3 59 724.1Q70 713.9 81 705.3Q92 696.6 103 689.6Q114 682.5 125 676.9Q136 671.2 147 666.5Q158 661.7 169 657.5Q180 653.3 191 649.4Q202 645.5 213 641.8Q224 638.1 235 634.6Q246 631 257 627.7Q268 624.4 279 621.1Q290 617.8 301 614.1Q312 610.5 323 606.1Q334 601.6 345 596.1Q356 590.6 367 583.9Q378 577.2 389 569.6Q400 562 411 554.2L422 546.3' fill='none' stroke='rgba(255,255,255,0.31)' stroke-width='0.8'/%3E%3Cpath d='M-40 817.6Q-18 800.2 -7 791.3Q4 782.4 15 773.4Q26 764.3 37 755Q48 745.8 59 736.5Q70 727.2 81 718Q92 708.9 103 700.3Q114 691.8 125 684.3Q136 676.9 147 671Q158 665.1 169 661Q180 656.9 191 654.4Q202 651.9 213 650.4Q224 648.9 235 647.6Q246 646.3 257 644.2Q268 642.2 279 638.8Q290 635.3 301 630.2Q312 625.1 323 618.4Q334 611.8 345 604.1Q356 596.5 367 588.6Q378 580.8 389 573.4Q400 565.9 411 559.4L422 552.8' fill='none' stroke='rgba(255,255,255,0.30)' stroke-width='0.8'/%3E%3Cpath d='M-40 823.1Q-18 806.6 -7 797.9Q4 789.1 15 779.8Q26 770.5 37 761Q48 751.4 59 741.8Q70 732.3 81 723.3Q92 714.2 103 706.2Q114 698.2 125 691.6Q136 685.1 147 680.1Q158 675.2 169 671.9Q180 668.6 191 666.5Q202 664.4 213 662.8Q224 661.3 235 659.5Q246 657.8 257 655.2Q268 652.7 279 648.8Q290 645 301 639.8Q312 634.5 323 628.1Q334 621.7 345 614.4Q356 607.2 367 599.7Q378 592.1 389 584.8Q400 577.4 411 570.4L422 563.5' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.9'/%3E%3Cpath d='M-40 825.7Q-18 810.8 -7 802.9Q4 795.1 15 786.5Q26 778 37 768.8Q48 759.6 59 750Q70 740.4 81 731Q92 721.6 103 713.2Q114 704.9 125 698.2Q136 691.6 147 687.1Q158 682.5 169 680Q180 677.5 191 676.4Q202 675.3 213 674.6Q224 673.9 235 672.6Q246 671.4 257 668.7Q268 666 279 661.6Q290 657.2 301 651.2Q312 645.1 323 638Q334 630.8 345 623.2Q356 615.5 367 608.1Q378 600.6 389 593.5Q400 586.5 411 580L422 573.4' fill='none' stroke='rgba(255,255,255,0.22)' stroke-width='0.6'/%3E%3Cpath d='M-40 832.3Q-18 818.3 -7 810.3Q4 802.3 15 793.2Q26 784.1 37 774.2Q48 764.3 59 754.4Q70 744.4 81 735.2Q92 726 103 718.4Q114 710.9 125 705.5Q136 700.1 147 696.8Q158 693.6 169 692Q180 690.4 191 689.5Q202 688.6 213 687.6Q224 686.5 235 684.5Q246 682.4 257 678.9Q268 675.5 279 670.6Q290 665.7 301 659.8Q312 653.8 323 647.2Q334 640.6 345 633.8Q356 626.9 367 620Q378 613 389 606Q400 599 411 591.9L422 584.7' fill='none' stroke='rgba(255,255,255,0.20)' stroke-width='0.8'/%3E%3Cpath d='M-40 836.8Q-18 818.8 -7 809.7Q4 800.6 15 791.9Q26 783.1 37 775Q48 766.9 59 759.4Q70 751.9 81 745Q92 738.2 103 731.9Q114 725.7 125 720.2Q136 714.7 147 710.1Q158 705.5 169 702Q180 698.5 191 696.1Q202 693.7 213 692.2Q224 690.7 235 689.5Q246 688.4 257 686.9Q268 685.4 279 682.8Q290 680.1 301 675.7Q312 671.2 323 664.8Q334 658.4 345 650.2Q356 642 367 632.8Q378 623.6 389 614.1Q400 604.7 411 595.9L422 587.1' fill='none' stroke='rgba(255,255,255,0.13)' stroke-width='0.5'/%3E%3Cpath d='M-40 843.2Q-18 824.8 -7 815.3Q4 805.8 15 796.7Q26 787.5 37 779.2Q48 770.9 59 763.7Q70 756.4 81 750.3Q92 744.2 103 739Q114 733.7 125 729.2Q136 724.7 147 720.8Q158 717 169 713.7Q180 710.4 191 707.8Q202 705.2 213 703.3Q224 701.3 235 699.7Q246 698.2 257 696.5Q268 694.8 279 692.3Q290 689.8 301 685.8Q312 681.8 323 675.9Q334 670 345 662.2Q356 654.4 367 645.1Q378 635.8 389 625.8Q400 615.8 411 606.1L422 596.4' fill='none' stroke='rgba(255,255,255,0.15)' stroke-width='0.7'/%3E%3Cpath d='M-40 844.7Q-18 829.6 -7 821.8Q4 813.9 15 805.8Q26 797.7 37 789.4Q48 781.2 59 773.2Q70 765.2 81 757.8Q92 750.5 103 744.3Q114 738 125 733.3Q136 728.6 147 725.5Q158 722.4 169 720.8Q180 719.1 191 718.3Q202 717.6 213 717Q224 716.5 235 715.4Q246 714.2 257 711.9Q268 709.6 279 705.7Q290 701.8 301 696.2Q312 690.6 323 683.6Q334 676.6 345 668.5Q356 660.4 367 651.7Q378 643.1 389 634.3Q400 625.5 411 616.9L422 608.3' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.6'/%3E%3Cpath d='M-40 849Q-18 834.3 -7 826.7Q4 819 15 811.1Q26 803.2 37 795.2Q48 787.2 59 779.5Q70 771.7 81 764.7Q92 757.6 103 751.8Q114 745.9 125 741.6Q136 737.2 147 734.5Q158 731.8 169 730.5Q180 729.2 191 728.8Q202 728.3 213 728Q224 727.6 235 726.6Q246 725.6 257 723.3Q268 721 279 717.1Q290 713.1 301 707.4Q312 701.8 323 694.6Q334 687.4 345 679.2Q356 671 367 662.1Q378 653.3 389 644.3Q400 635.2 411 626.3L422 617.4' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.5'/%3E%3Cpath d='M-40 853.9Q-18 839.6 -7 832.1Q4 824.6 15 816.7Q26 808.8 37 800.8Q48 792.9 59 785.2Q70 777.6 81 770.9Q92 764.1 103 758.8Q114 753.4 125 749.6Q136 745.9 147 743.8Q158 741.7 169 740.9Q180 740 191 739.8Q202 739.6 213 739.3Q224 739.1 235 737.9Q246 736.8 257 734.4Q268 731.9 279 727.8Q290 723.8 301 718Q312 712.3 323 705.2Q334 698.1 345 690Q356 681.8 367 672.9Q378 664.1 389 654.8Q400 645.6 411 636.3L422 627' fill='none' stroke='rgba(255,255,255,0.08)' stroke-width='0.7'/%3E%3Cpath d='M-40 857.5Q-18 842.3 -7 834.8Q4 827.3 15 820Q26 812.6 37 805.6Q48 798.5 59 791.9Q70 785.3 81 779.4Q92 773.4 103 768.5Q114 763.5 125 759.7Q136 756 147 753.5Q158 751.1 169 749.9Q180 748.7 191 748.4Q202 748.1 213 748.1Q224 748 235 747.6Q246 747.1 257 745.4Q268 743.7 279 740.2Q290 736.8 301 731.3Q312 725.8 323 718.4Q334 711 345 702.1Q356 693.2 367 683.3Q378 673.5 389 663.5Q400 653.4 411 643.6L422 633.7' fill='none' stroke='rgba(255,255,255,0.10)' stroke-width='0.8'/%3E%3Cpath d='M-40 863.8Q-18 850.1 -7 842.7Q4 835.3 15 827.4Q26 819.6 37 811.7Q48 803.9 59 796.7Q70 789.4 81 783.4Q92 777.4 103 773.1Q114 768.8 125 766.2Q136 763.7 147 762.7Q158 761.6 169 761.6Q180 761.6 191 761.8Q202 762 213 761.7Q224 761.5 235 760.2Q246 758.9 257 756.2Q268 753.5 279 749.3Q290 745.1 301 739.5Q312 733.9 323 726.9Q334 720 345 711.9Q356 703.8 367 694.7Q378 685.7 389 675.9Q400 666.2 411 655.9L422 645.7' fill='none' stroke='rgba(255,255,255,0.11)' stroke-width='0.7'/%3E%3C/svg%3E") center bottom / cover no-repeat;
  animation: as-shimmer 5.5s linear infinite;
}
/* คลื่นสองชั้นจางลงช่วงกลางจอ เต็มแรงเฉพาะครึ่งล่าง (ตรงกับภาพอ้างอิงที่คลื่นหนักอยู่ล่าง)
   กลางจอคือที่ที่ข้อความวางบนพื้นตรง ๆ ไม่มีการ์ดรอง (เช่น "วันนี้ยังไม่มีงาน") —
   เส้นเงินบาง ๆ วิ่งตัดตัวหนังสือสีเทาคือตัวหนังสือที่อ่านยาก แม้ค่าเฉลี่ยความต่างจะผ่าน */
:root[data-theme="astral"] :is(.fx-a, .fx-g) {
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.3) 0%, rgba(0,0,0,.38) 58%, #000 84%);
          mask-image: linear-gradient(180deg, rgba(0,0,0,.3) 0%, rgba(0,0,0,.38) 58%, #000 84%);
}
/* ไม่มีดาวตกในธีมนี้โดยตั้งใจ (เจ้าของสั่งถอด) — .fx-shoot ไม่มีขนาดไม่มีพื้น จึงไม่โผล่เอง
   ดาวประกายสี่แฉกสองดวงบนฟ้า */
:root[data-theme="astral"] :is(.fx-e, .fx-f) {
  z-index: 5;
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  background:
    radial-gradient(circle, #fff 0 1.4px, rgba(235,235,235,.75) 2.4px, transparent 5.5px),
    linear-gradient(90deg, transparent 0 46%, rgba(255,255,255,.75) 50%, transparent 54%) center / 100% 1px no-repeat,
    linear-gradient(0deg, transparent 0 46%, rgba(255,255,255,.75) 50%, transparent 54%) center / 1px 100% no-repeat;
  animation: as-glint 4.8s ease-in-out infinite;
}
:root[data-theme="astral"] .fx-e { left: 82%; top: 22%; }
:root[data-theme="astral"] .fx-f { left: 40%; top: 9%; animation-delay: -2.4s; }
/* ขอบจอจมลงดำ + แสงจางจากขอบบน */
:root[data-theme="astral"] .fx-h {
  z-index: 6;
  inset: 0;
  background:
    radial-gradient(60% 40% at 50% 0%, rgba(255,255,255,.06), transparent 70%),
    radial-gradient(120% 90% at 50% 45%, transparent 55%, rgba(0,0,0,.8) 100%);
}
@keyframes as-drift-b { to { transform: translateY(-320px); } }
@keyframes as-drift-c { to { transform: translateY(-420px); } }
@keyframes as-twinkle { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
@keyframes as-glint   { 0%, 100% { opacity: .15; transform: scale(.45); } 50% { opacity: 1; transform: scale(1); } }
@keyframes as-float   { from { transform: translateY(0); } to { transform: translateY(8px); } }
@keyframes as-flow-back  { from { transform: translateX(-42px) scaleY(.97); } to { transform: translateX(42px) translateY(-10px) scaleY(1.04); } }
@keyframes as-flow-front { from { transform: translateX(50px) scaleY(1.03); } to { transform: translateX(-50px) translateY(12px) scaleY(.96); } }
@keyframes as-shimmer { from { background-position: 115% 0; } to { background-position: -15% 0; } }
@media (prefers-reduced-motion: reduce) {
  :root[data-theme="astral"] :is(.fx-a, .fx-b, .fx-c, .fx-d, .fx-e, .fx-f, .fx-g) { animation: none; }
  :root[data-theme="astral"] .fx-g::after { display: none; }
}

/* ---------- ช่องสีตัวอย่าง ----------
   เจ้าของ: "หน้าปกธีมเป็นแค่ดำตัดขาวก็พอ" — ทรงเดียวกับธีมอื่น (เฉียง 135° สองสี) ไม่ต้องวาดฉากย่อ
   ใช้ทั้งในจอเลือกธีม (.th-grid .sw) และไทล์ "ธีมสี" ในแท็บฉัน (.shw-sw) — เดิมเขียนแค่ตัวแรก
   ไทล์ในแท็บฉันจึงเป็นช่องว่างตอนใช้ธีมนี้ · (0,2,0) โดยตั้งใจ — .sw ตัวเดียวเคยทับช่องสีทั้งตารางมาแล้ว */
:is(.th-grid .sw, .shw-sw).sw-astral { background: linear-gradient(135deg, #000000 50%, #FFFFFF 50%); }
/* ตัวเลือกธีมที่ไม่ได้ใช้เป็น "เส้นขอบอย่างเดียว" ตามดีไซน์เดิม — บนดำสนิทมันอ่านเป็นช่องว่าง
   ใส่พื้นเงินจาง ๆ กับเส้นขอบสว่างขึ้นนิดเดียว (ยังไม่ใช่กระจก อันที่ใช้อยู่ยังเด่นกว่าชัด) */
:root[data-theme="astral"] .phone #themePick button:not(.active) {
  background: rgba(255,255,255,.05) !important;
  border-color: rgba(255,255,255,.16) !important;
}
.th-grid .th-astral .nm { font-family: 'Cinzel', serif; font-weight: 700; font-size: 10.5px; letter-spacing: .06em; }

/* ============================================================
   1C40 · Astral Black ขาว–ดำ–เทาล้วน
   ------------------------------------------------------------
   เจ้าของ: "ทำให้สีพวก ui ในธีมนี้มีแค่ ขาว ดำ เทา" — รอบก่อนยังเก็บแดง/เหลือง/เขียวไว้ให้ป้ายความสำคัญ
   รอบนี้ไม่มีสีอิ่มเหลือเลย ความต่างระดับย้ายจาก "สี" ไปเป็น "ความสว่าง":
     ด่วน/อันตราย = ขาวสว่างสุด · ปานกลาง = เทากลาง · ไม่ด่วน/เรียบร้อย = เทาเข้ม
   ไม่แตะ (ไม่ใช่สีของ UI): ช่องสีตัวอย่างธีมอื่นในจอเลือกธีม (เทาหมดแล้วแยกธีมไม่ออก) ·
   สีผนัง/ของแต่งในห้องของฉัน (ผู้ใช้เลือกสีเอง) · โลโก้ Google · รูปถ่าย · น้องไซ
   ============================================================ */
:root[data-theme="astral"] {
  /* สีสถานะ — ใช้เป็น "ตัวหนังสือบนพื้นมืด" เป็นหลัก จึงเป็นเทาสว่างไล่ระดับ */
  --alert:#FFFFFF; --alert-soft:rgba(255,255,255,.18);
  --warn:#CFCFCF;  --warn-soft:rgba(255,255,255,.12);
  --good:#A8A8A8;  --good-soft:rgba(255,255,255,.09); --fire:#FFFFFF;
  /* ระดับความสำคัญ: ทึบใช้กับแถบ/จุด/ป้าย · soft+text ใช้กับชิป */
  --pri-red:#F2F2F2;    --pri-red-soft:rgba(255,255,255,.24);  --pri-red-text:#FFFFFF;
  --pri-yellow:#A6A6A6; --pri-yellow-soft:rgba(255,255,255,.14); --pri-yellow-text:#D6D6D6;
  --pri-green:#5E5E5E;  --pri-green-soft:rgba(255,255,255,.07);  --pri-green-text:#A3A3A3;
  /* ทอง = "ทำสำเร็จแล้ว" ตามกฎของแอป → เงินสว่าง */
  --gold:#E6E6E6; --gold-soft:rgba(255,255,255,.14); --gold-text:#EDEDED; --on-gold:#0A0A0A;
  --grad-gold:linear-gradient(152deg,#F5F5F5 0%,#A8A8A8 100%);
  /* ระดับความหายากของการสุ่ม */
  --r-legend:#FFFFFF; --r-rare:#B5B5B5; --r-common:#6E6E6E;
  /* หัวตั๋ว "ตอนนี้" เปลี่ยนสีตามความด่วน + ตัวหนังสือขาวทับ → เทาเข้มไล่ระดับ (ขาวทับได้ 6:1 ขึ้นไป) */
  --sig-red:#5A5A5A; --sig-amber:#454545; --sig-green:#303030; --sig-blue:#3A3A3A;
}

/* ตัวหนังสือขาวที่วางบนก้อนสีสถานะ — ก้อนพวกนี้เป็นเทาสว่างแล้ว ตัวหนังสือต้องกลับเป็นดำ */
:root[data-theme="astral"] :is(.tl-next.late .tile, .wg-pill.red, .wg-pill.yellow, .mt-ct.hot, .tab-badge,
    .tk-live, .fd-scope-n, .sp.lv5.active, .sp.lv4.active, .sp.lv3.active,
    .tt-ck.on, .wk-go.on, .runbar, .rc-check.on, .tk-sb.on .sb-box, .wc-tick:active,
    .ib2-hero.clear .ib2-hero-ic, .rank.red, .rank.yellow, .rank.green, .pe-shop .pe-ic,
    .nt-ic-b, .an-bd.got .ab-mark) {
  color: #0A0A0A !important;
}
/* pseudo-element อยู่ใน :is() ไม่ได้ (ทั้งรายการจะเป็นโมฆะ) — แยกบรรทัด */
:root[data-theme="astral"] .fd-people.has-req::after { color: #0A0A0A !important; }
/* ป้ายตัวเลขแดงบนไทล์หน้าแรก ("!") — ขาวทึบ ตัวดำ ยังเป็นของที่สว่างที่สุดตรงนั้น */
:root[data-theme="astral"] .tg-ct.hot { background: #F2F2F2; color: #0A0A0A; }

/* ---------- ของที่ระบายสีตายตัว (ไม่ผ่านโทเคน) ---------- */
/* แสงฮาโลของช่องพิมพ์น้องไซ (ชมพู/ม่วง/ฟ้า) → แสงเงิน */
:root[data-theme="astral"] .hs-b1 { background: linear-gradient(90deg, #FFFFFF, #8A8A8A, #E0E0E0, #5A5A5A) !important; }
:root[data-theme="astral"] .hs-b2 { background: linear-gradient(90deg, #BDBDBD, #FFFFFF, #7A7A7A) !important; }
:root[data-theme="astral"] .hs-b3 { background: linear-gradient(90deg, #6E6E6E, #F0F0F0, #9A9A9A) !important; }
:root[data-theme="astral"] .phone .sai-bar.hs-focus {
  box-shadow: 0 0 0 1px rgba(255,255,255,.38), 0 8px 22px -10px rgba(255,255,255,.3) !important;
}
/* เส้นกวาดตอนสแกน (เงาฟ้า) */
:root[data-theme="astral"] .tt-sweep { background: #FFFFFF; box-shadow: 0 0 14px 2px rgba(255,255,255,.55); }
/* เงาอมกรมของปุ่มกลมในสวิตช์ — ชุดกระจกตั้งไว้ด้วย !important จึงต้องทับแบบเดียวกัน */
:root[data-theme="astral"] :is(.tg .tg-k, .ctx-sw i) {
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 2px rgba(0,0,0,.14), 0 0 0 .5px rgba(0,0,0,.25), 0 3px 8px -2px rgba(0,0,0,.6) !important;
}
/* ปุ่มนำสีทอง (สุ่ม 10 ใบ · รับรางวัลเช็คอิน) — ทองเขียนตายตัวในชุดกระจก → เงินขัดเงา ตัวดำ */
:root[data-theme="astral"] :is(.gc-go.lead, .ck-cta) {
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.6) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0) 50%, rgba(0,0,0,.06)),
    linear-gradient(135deg, #F2F2F2, #A0A0A0) !important;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.8), inset 0 -2px 4px rgba(0,0,0,.18), inset 0 0 18px rgba(255,255,255,.14),
    0 0 0 .5px rgba(0,0,0,.3), 0 13px 28px -12px rgba(255,255,255,.28) !important;
  color: #0A0A0A !important;
}
:root[data-theme="astral"] .gc-go.lead i { color: #2A2A2A !important; }
/* แถบความคืบหน้าเช็คอิน (ไล่ทองตายตัว) · ติ๊ก "มีแล้ว" ในร้าน + ปุ่มติ๊กงานเสร็จ (เขียวตายตัว) ·
   ตัวหนังสือน้ำตาลบนป้าย "ยังไม่เปิดขาย" */
:root[data-theme="astral"] .tk-track i { background: linear-gradient(90deg, #8A8A8A, #F2F2F2); }
:root[data-theme="astral"] :is(.tb-ok, .tb-row.own .tb-bd i, .tn-ib.done) { color: #D0D0D0; }
:root[data-theme="astral"] .pe-wip { color: #0A0A0A; }
:root[data-theme="astral"] .tk-cta .tile.deck { color: #0A0A0A; }
/* ไฟเรืองของการ์ดสุ่มที่หงายได้ของดี (ฟ้า/ส้ม) → แสงขาว */
:root[data-theme="astral"] .gc.lit-rare { filter: drop-shadow(0 0 12px rgba(255,255,255,.35)); }
:root[data-theme="astral"] .gc.lit-legendary { filter: drop-shadow(0 0 18px rgba(255,255,255,.6)); }
/* แสงวูบเต็มจอตอนหงายของหายาก (ฟ้า/ทอง) → แสงขาว ระดับต่างกันที่ความแรง */
:root[data-theme="astral"] .gc-flash.rare {
  background: radial-gradient(130% 90% at 50% 42%, rgba(255,255,255,.12), transparent 70%);
  box-shadow: inset 0 0 90px 24px rgba(255,255,255,.5), inset 0 0 0 2px rgba(255,255,255,.55);
}
:root[data-theme="astral"] .gc-flash.secret {
  background: radial-gradient(130% 90% at 50% 42%, rgba(255,255,255,.2), transparent 70%);
  box-shadow: inset 0 0 120px 34px rgba(255,255,255,.75), inset 0 0 0 2px rgba(255,255,255,.8);
}
:root[data-theme="astral"] .gc-aura.rare { box-shadow: inset 0 0 70px 12px rgba(255,255,255,.35), inset 0 0 0 1.5px rgba(255,255,255,.45); }
:root[data-theme="astral"] :is(.gc-aura.legendary, .gc-aura.secret) {
  box-shadow: inset 0 0 90px 18px rgba(255,255,255,.55), inset 0 0 0 1.5px rgba(255,255,255,.65);
}
:root[data-theme="astral"] .gc-flash.legendary {
  background: radial-gradient(130% 90% at 50% 42%, rgba(255,255,255,.2), transparent 70%);
  box-shadow: inset 0 0 120px 34px rgba(255,255,255,.75), inset 0 0 0 2px rgba(255,255,255,.8);
}
/* ภาพประกอบที่วาดด้วยสีเต็ม (เหรียญตรา · หน้าการ์ดสุ่ม · การ์ดสกิน · หัวข้อไล่สี ·
   วงรอบรูปคนที่ออนไลน์) — ลดเป็นขาวดำทั้งชิ้น ดีกว่าไล่เขียนสีใหม่ทีละชิ้นแล้วตกหล่น
   12 ต.ค. 69 · เหรียญโทเคน (.tok) ถอดออกจากรายชื่อนี้ — เป็นสีเดิมทุกธีม
   เจ้าของส่งภาพชิป "+100" (เหรียญสีทอง) คู่กับกระดานอันดับในธีมนี้ (เหรียญเทา) แล้วถามว่า "ไหนอะ"
   เหรียญเทาบนป้ายเทากลืนหายจนดูไม่ออกว่าเป็นโทเคน · และในธีมเดียวกันมีบางที่เป็นทอง บางที่เป็นเทา
   เหรียญโทเคนคือโลโก้ของเงินในแอป — ข้อยกเว้นแบบเดียวกับโลโก้ Google ที่ธีมนี้ไม่แตะอยู่แล้ว */
:root[data-theme="astral"] :is(.bg-mark, .bg-nm.fancy, .gc-face, .gc-title, .tk-skin, .tk-aura,
    .fd-on-ring, .an-tile, .ab-mark) {
  filter: grayscale(1);
}
/* รูปย่อของคนที่ไม่มีรูป (ตัวอักษรบนพื้นสีประจำตัว — สีมาจาก JS เป็น style ในบรรทัด)
   12 ต.ค. 69 · ยกเว้น .ch-face.ghost (ที่ว่างแทนรูปในฟองที่ไม่ใช่ฟองสุดท้ายของก้อน) — เดิมโดนทาเทาด้วย
   ห้องแชทในธีมนี้จึงมีวงกลมเทาว่าง ๆ หน้าข้อความ (เจอตอนทำตัวอย่างห้องแชทแบบ IG) */
:root[data-theme="astral"] :is(.ch-face, .dm-av, .ep-av, .fd-av, .fr-av, .ig-av, .nt-av, .tp-av):not(img):not(.src):not(.ghost) {
  background: #2B2B2B !important; color: #F0F0F0 !important;
}
/* บรรทัดบนหัวจอ (วัน · วันที่ · เวลาว่าง / ค้างกี่งาน) กับแท็บโหมด "วันนี้ / สัปดาห์ / รายการ"
   เจ้าของ: "ทำให้ข้อความนี้ชัดขึ้นทั้งสามข้อความ" — เดิมเป็น --faint #8E8E8E หนัก 600 ขนาด 12px
   บนพื้นดำที่มีเส้นคลื่นวิ่งผ่าน ตัวเล็กสีเทากลางเลยจมไปกับลาย
   ยกเป็นหมึกเกือบเต็ม + หนาขึ้น + เงาดำบาง ๆ แยกตัวหนังสือออกจากเส้นคลื่น · ยังเบากว่าหัวข้อจอหนึ่งขั้น */
:root[data-theme="astral"] .eyebrow { color: var(--ink); font-weight: 700; }
/* รอบสอง — เจ้าของส่งภาพเดิมมาอีกครั้ง: ตัวขาว + เงาฟุ้งยังโดนเส้นคลื่นวิ่งตัดกลางตัวหนังสือ
   และเงาฟุ้งทำให้ตัวดูเบลอ · แก้ที่ต้นเหตุ = อย่าให้เส้นผ่านหลังตัวหนังสือเลย
   บรรทัดบนหัวจอได้แคปซูลกระจกดำของตัวเอง (กว้างเท่าข้อความ) · ขาวเต็ม 13.5px ไม่มีเงาฟุ้ง */
:root[data-theme="astral"] .page-head .eyebrow {
  width: fit-content; max-width: 100%;
  padding: 3px 11px; margin: 0 0 4px -2px; border-radius: 999px;
  background: rgba(0,0,0,.66);
  border: 1px solid rgba(255,255,255,.16);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: #FFFFFF; font-size: 13.5px; letter-spacing: .02em;
}
/* รางแท็บโหมด: กระจกเงินโปร่ง 8.6% เห็นเส้นคลื่นกับดาวเคราะห์ทะลุมาหลังคำ "สัปดาห์ / รายการ"
   → กระจกดำเกือบทึบ ขอบเงินเดิม · ตัวที่ไม่ได้เลือกขาวเต็ม หนา 700
   (ต้องผ่าน #scr-tasks เพราะชุดกระจกใส่ !important ไว้ด้วยตัวเลือกที่จำเพาะกว่า .tk-modes เดี่ยว ๆ) */
:root[data-theme="astral"] #scr-tasks .tk-modes {
  background-color: rgba(10,10,10,.84) !important;
  background-image: linear-gradient(180deg, rgba(255,255,255,.1), rgba(255,255,255,.02) 60%) !important;
}
:root[data-theme="astral"] .tk-mode { font-size: 14px; font-weight: 700; }
:root[data-theme="astral"] .tk-mode:not(.on) { color: #FFFFFF; }

/* ============================================================
   1C40 · แชทน้องไซหน้าตาแบบแอปแชท AI (Claude · ChatGPT · Grok)
   ------------------------------------------------------------
   เจ้าของ: "แก้ตรงแชทกับน้องไซให้มันคล้ายกับแชทเราคุยกัน เช่น claude chatgpt grok"
   • ข้อความเรา = ฟองเทาชิดขวา ไม่มีรูป · คำตอบน้องไซ = ตัวหนังสือเต็มความกว้าง ไม่มีฟอง
     มีป้ายชื่อเล็ก ๆ ข้างบน และปุ่มคัดลอกข้างล่าง
   • จอว่าง = คำทักตัวใหญ่ + การ์ดคำถามสำเร็จรูป 2×2
   • กล่องพิมพ์ = กล่องมนใหญ่ ตัวหนังสืออยู่บน แถวปุ่มอยู่ล่าง ปุ่มส่งวงกลมทึบตอนมีตัวหนังสือ
   ชุดกระจก/ฮาโลเดิมตั้ง .phone .sai-bar ไว้ด้วย !important → ที่นี่ทับด้วย #aiBody (ความจำเพาะสูงกว่า)
   ============================================================ */

/* ---------- หัวจอ ---------- */
#aiBody .sai-head { padding-bottom: 4px; }
#aiBody .sai-head .ai-av.big { width: 34px; height: 34px; }
#aiBody .sh-name { font-size: 18px; }
.sh-new {
  flex: none; width: 40px; height: 40px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: none; color: var(--ink); cursor: pointer;
}
.sh-new svg { width: 19px; height: 19px; }
.sh-new:active { background: var(--card2); }

/* ---------- บทสนทนา ---------- */
#aiBody .at-in { gap: 22px; padding: 6px 0 12px; }
#aiBody .ai-msg.me { justify-content: flex-end; }
#aiBody .ai-msg.me .ai-bub {
  max-width: 82%;
  padding: 10px 15px;
  border: 0; border-radius: 22px 22px 6px 22px;
  background: var(--card2); color: var(--ink);
  font-size: 15px; line-height: 1.55;
  box-shadow: inset 0 0 0 1px var(--line);
}
#aiBody .ai-msg.sai { display: block; }
.am-head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.am-head .ai-av { width: 24px; height: 24px; margin: 0; }
.am-head b { font-size: 13.5px; font-weight: 700; color: var(--ink); letter-spacing: -.01em; }
.am-text {
  font-size: 15px; line-height: 1.72; color: var(--ink);
  overflow-wrap: anywhere;
}
.am-text p { margin: 0 0 10px; }
.am-text > :last-child { margin-bottom: 0; }
.am-text :is(ul, ol) { margin: 2px 0 10px; padding-left: 22px; }
.am-text li { margin: 4px 0; padding-left: 2px; }
.am-text li::marker { color: var(--muted); }
.am-text b { font-weight: 700; }
.am-text code {
  font-family: 'Space Mono', ui-monospace, monospace; font-size: 13px;
  padding: 1px 6px; border-radius: 6px; background: var(--card2);
}
.am-text.err { color: var(--alert); }
/* เคอร์เซอร์ระหว่างพิมพ์ตอบ — บอกว่า "ยังพิมพ์อยู่" ไม่ใช่ตอบจบแล้ว */
.am-caret {
  display: inline-block; width: 8px; height: 1.05em; margin-left: 2px; vertical-align: -.15em;
  border-radius: 2px; background: var(--ink); animation: am-caret 1s steps(2, start) infinite;
}
@keyframes am-caret { to { visibility: hidden; } }
.am-text.ai-live > p:last-of-type { display: inline; }
.am-act { display: flex; gap: 2px; margin: 6px 0 0 -8px; }
.am-act button {
  width: 32px; height: 32px; display: grid; place-items: center;
  border: 0; border-radius: 10px; background: none; color: var(--faint); cursor: pointer;
}
.am-act button svg { width: 16px; height: 16px; }
.am-act button:active { background: var(--card2); color: var(--ink); }
#aiBody .ai-typing { height: 24px; padding-left: 2px; }
#aiBody .ai-offer { margin-top: 2px; }

/* ---------- จอว่าง ---------- */
#aiBody .at-hello { gap: 14px; }
.ai-hello { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 8px 6px 4px; }
.ai-hello .ai-av.hello { width: 64px; height: 64px; margin: 0 0 12px; box-shadow: var(--shadow); }
.ai-hello h2 { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); line-height: 1.3; }
.ai-hello p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); max-width: 320px; }
#aiBody .at-hello .sai-day { margin-top: 0; }
.ai-starters { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ai-st {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0;
  padding: 12px 13px; border: 1px solid var(--line); border-radius: 18px;
  background: var(--card); color: var(--ink); text-align: left; font-family: inherit; cursor: pointer;
  transition: transform .2s cubic-bezier(.3,1.6,.5,1);
}
.ai-st svg { width: 17px; height: 17px; color: var(--fill); margin-bottom: 2px; }
.ai-st b { font-size: 13.5px; font-weight: 700; }
.ai-st span {
  font-size: 11.5px; line-height: 1.45; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ai-st:active { transform: scale(.97); }
.ai-st:disabled { opacity: .5; }
#aiBody .at-hello .ai-priv { margin-top: 0; }

/* ---------- กล่องพิมพ์ ---------- */
.phone #aiBody .sai-bar.sai-cmp {
  display: flex !important; flex-direction: column !important; align-items: stretch !important; gap: 4px !important;
  margin-top: 10px; padding: 10px 10px 8px 16px !important; min-height: 0 !important;
  border-radius: 26px !important;
  border: 1px solid var(--line) !important;
  background: var(--card) !important;
  box-shadow: 0 10px 30px -16px rgba(0,0,0,.45), inset 0 1px 0 color-mix(in srgb, var(--ink) 6%, transparent) !important;
}
.phone #aiBody .sai-bar.sai-cmp:focus-within { border-color: color-mix(in srgb, var(--ink) 22%, transparent) !important; }
.phone #aiBody .sai-bar.sai-cmp .ai-in {
  width: 100%; padding: 4px 0 2px !important; min-height: 26px !important;
  font-size: 15px; line-height: 1.5; max-height: 160px;
}
.cmp-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.phone #aiBody .sai-bar.sai-cmp .sb-mic {
  display: grid !important; width: 34px; height: 34px; margin-left: -6px;
  background: none; color: var(--muted);
}
.phone #aiBody .sai-bar.sai-cmp .sb-send {
  width: 36px !important; height: 36px !important; position: relative;
  border: 0 !important; border-radius: 50% !important;
  background: var(--card2) !important; color: var(--faint) !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
  transition: background-color .15s ease, color .15s ease, transform .15s ease;
}
/* มีตัวหนังสือแล้ว = ปุ่มส่งทึบด้วยสีหมึก (ดำบนธีมสว่าง · ขาวบนธีมมืด) แบบแอปแชท AI */
.phone #aiBody .sai-bar.sai-cmp.has-text .sb-send {
  background: var(--ink) !important; color: var(--scr) !important;
}
.phone #aiBody .sai-bar.sai-cmp .sb-send svg { width: 18px; height: 18px; stroke-width: 2.6; }
.phone #aiBody .sai-bar.sai-cmp .sb-send:active { transform: scale(.92); }
@media (prefers-reduced-motion: reduce) { .am-caret { animation: none; } }

/* ============================================================
   QA 6 ต.ค. 69 · แก้ตามรายงานตรวจก่อนเผยแพร่ (20 จุด)
   รวมไว้ท้ายไฟล์ก้อนเดียว เพราะหลายข้อต้องชนะชั้นกระจก 1C40 ที่อยู่ข้างบน
   ห้ามแตะ style.css (กฎของโปรเจกต์) — ข้อที่ต้นเหตุอยู่ในนั้นจึง override จากตรงนี้
   ============================================================ */

/* #16 · ตัวหนังสือไม่โดน Safari แนวนอนขยายเอง · ป้ายเล็กสุดไม่ต่ำกว่า 11px */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
.phone .tabbar .tab { font-size: 11px; }
/* ตัวเลขเล็กกว่า 10px ที่เป็นข้อความอ่านจริง (ไม่ใช่แบดจ์) ยกขึ้นเป็น 10.5px */
.ck-node em, .cal-more, .tltime .d, .dn-mid i, .ab-ds { font-size: 10.5px; }

/* #8 · ข้อความผิดใต้ช่องแปะข้อความ (แทน alert) */
.paste-err { display: block; margin: 6px 4px 0; }
.paste-err[hidden] { display: none; }
#pasteText[aria-invalid="true"], #fDetail[aria-invalid="true"] { outline: 2px solid var(--alert); outline-offset: 2px; border-radius: 12px; }

/* #17 · ปุ่มย้อนในแผ่นเพิ่มงาน (หน้าตัวเชื่อม) เป็น <button> แล้ว — ล้างหน้าตาปุ่มของเบราว์เซอร์ */
button.as-back { background: none; border: 0; font: inherit; color: inherit; width: 100%;
  text-align: inherit; cursor: pointer; }

/* #17 · วงโฟกัสคีย์บอร์ดที่เห็นได้ทุกปุ่ม ทุกธีม — เฉพาะตอนใช้คีย์บอร์ด (ไม่ขึ้นตอนแตะนิ้ว) */
.phone :is(button, a, [role="button"], [tabindex], input, textarea, select, label.scan-tile):focus-visible,
#addSheet :focus-visible, #checkin :focus-visible, #focusWrap :focus-visible,
#soonSheet :focus-visible, #daySheet :focus-visible, #aiSheet :focus-visible {
  outline: 2.5px solid var(--blue) !important; outline-offset: 2px !important;
}

/* #12 · ปุ่มที่ใช้ไม่ได้ต้องดูออกว่าใช้ไม่ได้ · และมีสถานะชี้บนจอที่มีเมาส์ */
.phone button:disabled, .phone button[aria-disabled="true"] { opacity: .5; cursor: not-allowed; filter: saturate(.6); }
@media (hover: hover) and (pointer: fine) {
  .phone :is(.fm-save, .tc-cta, .sai-cta, .ck-cta, .as-row, .tg-t, .dr-row, .soon-go, .ai-read, .manual):not(:disabled):hover {
    filter: brightness(1.06);
  }
  .phone :is(.as-row, .dr-row):not(:disabled):hover { background-color: color-mix(in srgb, var(--blue) 6%, transparent); }
}

/* #11 · เป้ากดเล็กกว่า 44px — คงขนาดที่เห็นไว้ แต่ขยายพื้นที่รับนิ้วด้วยชั้นล่องหน */
/* :where() = ความเจาะจง 0 — ปุ่มที่ตั้ง position ไว้เองแล้ว (เช่น .top-friends เป็น absolute) ชนะเสมอ
   ใส่ relative เฉพาะตัวที่ยังเป็น static เพื่อให้ชั้นล่องหนข้างล่างเกาะตัวมันเอง */
:where(.phone) :where(.chk, .wc-tick, .tk-tick, .dm-find-x, .wz-x, .cp-img-x, .fr-x, .ctx-del, .ch-emo-btn,
  .ig-set, .th-bell, .fd-people, .bg-del, .top-friends) { position: relative; }
.phone :is(.chk, .wc-tick, .tk-tick, .dm-find-x, .wz-x, .cp-img-x, .fr-x, .ctx-del, .ch-emo-btn,
  .ig-set, .th-bell, .fd-people, .bg-del, .top-friends)::before {
  /* ::before ไม่ใช่ ::after — .fd-people.has-req ใช้ ::after เป็นจุดแดงอยู่แล้ว */
  content: ''; position: absolute; inset: -10px; border-radius: 50%;
}
.phone .wc-tick { width: 24px; height: 24px; }
.phone .dm-find-x { width: 32px; height: 32px; }

/* #6 · ปุ่มเพื่อนมุมขวาบน (z 91) ลอยทับชั้นมืดของเช็คอิน/แผ่นต่าง ๆ — หลบเมื่อมีชั้นไหนเปิดอยู่ */
body:has(#checkin:not([hidden]), #addSheet:not([hidden]), #soonSheet:not([hidden]), #daySheet:not([hidden]),
  #planRowSheet:not([hidden]), #aiSheet:not([hidden]), #reportSheet:not([hidden])) .top-friends,
body.focus-on .top-friends { visibility: hidden; }

/* #5 · จอ "เสร็จแล้ว" ของโหมดโฟกัสเลื่อนแนวนอนได้ 32px (อวตารน้องไซยื่นออกขอบการ์ด) */
.fc-sheet.done { overflow-x: hidden; }
.fc-sheet.done .fw-hero { max-width: 100%; }

/* #4 · หน้าแรกต้องพอดี 375×812 — ไทล์ไม่ต้องเป็นสี่เหลี่ยมจัตุรัสบนจอแคบ (ประหยัด ~40px)
   และช่องไฟระหว่างบล็อกลดจาก 22 → 16 · จอกว้างกว่า 620 ใช้กติกาเดิมใน today.css */
@media (max-width: 619px) {
  /* 12 ต.ค. 69 · เจ้าของ (ส่งภาพเทียบสองรูป): "ทำให้ปุ่มพวกนี้ไม่เปลี่ยนรูปไปเอง คงรูปเดิมแบบรูปสอง"
     เดิมสูง 60 แต่กว้างเต็มช่อง (width 100% จาก today.css) — จอ 375 ได้ไทล์ 79×60 ทรงผืนผ้าแบน
     และทรงเปลี่ยนตามความกว้างจอเอง (จอยิ่งกว้างยิ่งแบน · เกิน 620 กลับเป็นจัตุรัส)
     ตอนนี้จัตุรัส 60×60 ทุกความกว้าง — สูงเท่าเดิมเป๊ะ หน้าแรกจึงไม่ยาวขึ้นแม้แต่พิกเซลเดียว
     ต้องมี .tg-grid นำหน้า: today.css โหลดหลังไฟล์นี้ width: 100% ของมันจึงชนะตัวเลือกที่แรงเท่ากัน */
  .tg-ic { height: 60px; border-radius: 17px; }
  .tg-grid .tg-ic { width: 60px; aspect-ratio: 1; }
  .tg-ic svg { width: 21px; height: 21px; padding: 7px; }
  .tg-grid { gap: 10px 6px; }
  .tg-lb2 { min-height: 2.5em; }
  #menuBody .td-tiles, #menuBody .td-railwrap { margin-top: 16px; }
}
@media (max-width: 619px) {
  #menuBody .saih { margin-bottom: 0; }
  #menuBody .td-stats { margin-top: 10px; gap: 8px; }
  /* แถบตัวเลขแบบบรรทัดเดียว: ไอคอนซ้าย ตัวเลข+ป้ายขวา — สูง ~52 แทน 103 */
  #menuBody .ts { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 8px;
    align-items: center; padding: 9px 10px; border-radius: 16px; }
  #menuBody .ts-ic { grid-row: span 2; margin: 0; width: 28px; height: 28px; }
  #menuBody .ts b { font-size: 17px; }
  #menuBody .ts i { margin-top: 1px; font-size: 11px; }
  #menuBody > .td-ask { margin: 10px 0 0; }
  #menuBody > .td-now, #menuBody > .td-empty { margin-top: 12px; }
  #menuBody { padding-bottom: 12px; }
}

/* สำเนาทดลอง: คำเตือนของแผนใช้สีความหมายเดิม และอยู่ติดปุ่มลงมือ */
.tn-plan-note { display: flex; align-items: center; gap: 6px; width: 100%; padding: 7px 8px;
  margin: 0 0 8px; border: 0; border-radius: 10px; background: var(--card2); color: var(--muted);
  font: inherit; font-size: 12px; text-align: left; line-height: 1.45; cursor: pointer; }
.tn-plan-note svg { width: 15px; height: 15px; flex: 0 0 15px; }
.tn-plan-note svg:last-child { margin-left: auto; }
.tn-plan-note.warn { background: var(--alert-soft); color: var(--alert); }
.fm-score-help { margin: 8px 0 0; color: var(--muted); font-size: 12px; line-height: 1.6; }

/* บนมือถือสั้น ตัวเลขซ้ำกับหัวจอหลบให้ปุ่มใช้งาน แต่ไทล์ทั้งแปดใบยังอยู่ครบ */
@media (max-width: 619px) and (max-height: 860px) {
  :root:not([data-nav="side"]) body:not(.login-mode) .screens > #scr-menu.screen { padding-bottom: var(--tb-under); }
  .phone #menuBody { gap: 4px; padding-bottom: 10px; }
  .phone #menuBody .td-stats { display: none; }
  .phone #menuBody .saih { min-height: 0; height: 56px; padding: 6px 12px; }
  .phone #menuBody .saih-stage { width: 44px; height: 44px; flex: 0 0 44px; }
  .phone #menuBody .saih-face { width: 44px; height: 44px; }
  .phone #menuBody .saih-go { font-size: 11px; }
  .phone #menuBody:has(.td-railwrap) .saih { display: none; }
  .phone #menuBody .td-railwrap { margin-top: 8px; }
  .phone #menuBody .rl-lb { min-height: 0; height: 20px; line-height: 20px; margin-bottom: 4px; }
  .phone #menuBody .rl-lb b { font-size: 14px; line-height: 20px; }
  .phone #menuBody .td-rail { max-height: 80px; overflow-y: auto; }
  .phone #menuBody .dr-row.end { display: none; }
  .phone #menuBody > .td-now, .phone #menuBody > .td-empty { margin-top: 12px; }
  .phone #menuBody .td-tiles { margin-top: 12px; }
}

/* #14 · ปุ่มส่งของช่องพิมพ์น้องไซจางเกิน (≈2.2:1 ในธีมมืด) — ไอคอนต้องได้ 3:1 ขึ้นไป */
.phone .sai-bar .sb-send, .phone #aiBody .sai-bar.sai-cmp .sb-send { color: var(--muted) !important; }
:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch],[data-theme=astral])
  .phone :is(.sai-bar .sb-send, #aiBody .sai-bar.sai-cmp .sb-send) { color: var(--ink) !important; }
/* #14 · Genesis: --faint 2.16:1 บนพื้นจอ → เข้มขึ้นจนได้ ≥4.5:1 บนการ์ดและพื้นจอ */
:root[data-theme="genesis"] { --faint: #2E3566; }

/* #15 · ปุ่มทองใช้โทเคนทองของธีม ไม่ใช่สีดิบ — Astral จึงได้ "เงิน" ตามที่ตั้งใจ */
:root :is(.gc-go.lead, .ck-cta) {
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.5) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0) 50%, rgba(0,0,0,.06)),
    var(--grad-gold) !important;
  color: var(--on-gold) !important;
}
/* #15 · Astral = ขาว ดำ เทา ล้วน — แถบล่างไม่อมน้ำเงินตามชุดธีมมืดรวม */
:root[data-theme="astral"] .phone .tabbar {
  background: linear-gradient(180deg, rgba(38,38,38,.66), rgba(18,18,18,.55)) !important;
  border-color: rgba(255,255,255,.22) !important;
}

/* #8 · การ์ดผลพลาดของการสแกน (แทน alert) */
.scan-err { display: grid; gap: 4px; margin: 10px 0 0; padding: 12px 14px; border-radius: 16px;
  background: var(--alert-soft); border: 1px solid color-mix(in srgb, var(--alert) 30%, transparent);
  text-align: left; }
.scan-err b { font-size: 14px; color: var(--ink); }
.scan-err span { font-size: 13px; line-height: 1.45; color: var(--ink); opacity: .85; }
.scan-err small { font-size: 11px; color: var(--muted); }

/* #15 · โทเคนสเกลตัวอักษร / ระยะห่าง / มุมโค้ง — ดู alt/DESIGN.md
   ของใหม่ใช้ตัวพวกนี้ · ของเก่าย้ายเมื่อแตะจอนั้นอยู่แล้ว (ไม่รื้อ 1,100 จุดรวดเดียว) */
:root {
  --fs-xs: 11px; --fs-sm: 12.5px; --fs-md: 14px; --fs-base: 15.5px;
  --fs-lg: 18px; --fs-xl: 22px; --fs-2xl: 28px;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;
  --r-pill: 999px;
}
/* #15 · ปุ่มหลักทุกจอใช้คู่สีเดียวกัน (--fill/--on-fill) — เดิมธีมมืดได้ฟ้าอ่อน+ตัวดำที่ฟอร์ม
   แต่น้ำเงิน+ตัวขาวที่การ์ดหน้าแรก อ่านเหมือนสองแบรนด์ · ชั้นประกายกระจกเป็น background-image จึงยังอยู่ */
.phone :is(.btn.primary, .fm-save, .ai-read, .tc-cta, .sai-cta, .ep-save) {
  background-color: var(--fill) !important; color: var(--on-fill) !important;
}
.phone :is(.tc-cta, .fr-go, .gc-go) { border-radius: var(--r-pill) !important; }

/* ============================================================
   จอเข้าสู่ระบบ — รอบ "ดูง่ายและไม่รก"
   ------------------------------------------------------------
   ชิปสามใบกับบรรทัดเหตุผลใต้ปุ่มล็อกอินถูกถอดจาก markup แล้ว · สามข้อของแอปเหลือบรรทัดเดียว
   style.css ตั้ง .lf-ic ให้คร่อมสองแถว (หัวข้อ + บรรทัดรอง) — ไม่มีบรรทัดรองแล้ว ต้องคืนเป็นแถวเดียว
   ไม่งั้นหัวข้อลอยชิดบนของไอคอนแทนที่จะอยู่กลาง
   ระยะจากใบพระเอกเพิ่มเป็น 38px — เดิมชิปคั่นอยู่ น้องไซที่คร่อมขอบล่างใบจะชนแถวแรก
   ============================================================ */
.lg-feats { margin-top: 38px; gap: 16px; }
.lg-feat .lf-ic { grid-row: auto; }
.lg-feat b { font-size: 15px; }

/* ============================================================
   หน้าแรกจอกว้าง — ทุกก้อนกว้างเท่ากัน
   ------------------------------------------------------------
   เจ้าของ: "ทำให้ความยาวมันเท่า ๆ กัน" — today.css คุม max-width 620px ไว้ทีละคลาส
   (หัวจอ · ช่องถาม · ไทล์ · การ์ดตอนนี้ ฯลฯ) แต่ก้อนที่เพิ่มทีหลัง (การ์ดน้องไซ · แถวตัวเลข ·
   การ์ด "วันนี้ยังไม่มีงาน") ไม่อยู่ในรายชื่อ เลยยืดเต็มคอลัมน์ 680px ขอบขวาเลยแหว่งเป็นฟันปลา
   คุมที่ลูกทุกตัวของ .menu-body แทนการไล่เติมรายชื่อ — บล็อกใหม่ที่ตามมาจะกว้างเท่ากันเอง
   ============================================================ */
@media (min-width: 720px) {
  #scr-menu .menu-body > * { max-width: 620px; }
}

/* ============================================================
   แท็บโหมด วันนี้ · สัปดาห์ · รายการ — ก้อนเลื่อนด้วยสปริง (แบบ HaloToggleGroup)
   ------------------------------------------------------------
   ก้อนเป็นของชิ้นเดียว (.tk-thumb ดูสปริงใน app.js) ปุ่มที่เลือกเหลือแค่สีตัวหนังสือ
   ตำแหน่งมาจาก --il / --ir (ลำดับช่องของขอบซ้าย/ขวา ทศนิยมได้) กับ --n (จำนวนช่อง)
   ช่องหนึ่งกว้าง (100% − padding 6px − ช่องไฟ 3px × (n−1)) ÷ n — ตรงกับ grid ของ .tk-modes เป๊ะ
   ฮาโล = แสงสีธีมฟุ้งใต้ก้อน ตามชื่อต้นแบบ (Halo) · มีแค่ตอนมีก้อน (.has-thumb) —
   ถ้า JS ไม่ได้วาดก้อน ปุ่มที่เลือกยังเป็นก้อนทึบแบบเดิม ไม่หายเงียบ
   ============================================================ */
.tk-modes.has-thumb { position: relative; isolation: isolate; }
.tk-modes.has-thumb .tk-mode { position: relative; z-index: 1; transition: color .2s ease .08s; }
/* สีตัวหนังสือเปลี่ยนช้ากว่าก้อนนิดหนึ่ง — ขาวทันทีตอนก้อนยังวิ่งมาไม่ถึง = ขาวบนพื้นราง อ่านไม่ออกชั่วครู่ */
.tk-modes.has-thumb .tk-mode.on {
  background: transparent !important; background-image: none !important;
  border-color: transparent !important; box-shadow: none !important;
}
.tk-thumb {
  --cell: calc((100% - 6px - (var(--n, 3) - 1) * 3px) / var(--n, 3));
  position: absolute; top: 3px; bottom: 3px; z-index: 0; pointer-events: none;
  left: calc(3px + var(--il, 0) * (var(--cell) + 3px));
  width: calc((var(--ir, 0) - var(--il, 0)) * (var(--cell) + 3px) + var(--cell));
  border-radius: 999px;
  background-color: var(--fill);
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.46) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,0) 50%, rgba(0,0,0,.08));
  border: 1px solid rgba(255,255,255,.4);
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.6), inset 0 -1.5px 3px rgba(0,0,0,.14),
    inset 0 0 12px rgba(255,255,255,.12), 0 0 0 .5px var(--lgb-edge, transparent);
}
.tk-thumb::after {
  content: ''; position: absolute; z-index: -1;
  left: 12%; right: 12%; bottom: -7px; height: 14px; border-radius: 50%;
  background: var(--fill); filter: blur(10px); opacity: .55;
}

/* ============================================================
   ก้อนเลื่อนของแถวชิป "เตือนให้ทำตอน" (#doPick · doThumb ใน app.js) · 31 ต.ค. 69
   เจ้าของ: "ทำอนิเมชั่นหน่อย" — หน้าตาเดียวกับก้อนแท็บโหมดจองาน (.tk-thumb · แบบ HaloToggleGroup)
   ตำแหน่ง/ความกว้างเป็นพิกเซลจาก JS (ชิปกว้างไม่เท่ากัน) · ชิปที่เลือกเหลือแค่สีตัวหนังสือ ก้อนเป็นตัววาดพื้น
   ถ้า JS ไม่ได้วาดก้อน (ไม่มี .has-thumb) ชิปที่เลือกยังเป็นก้อนทึบแบบเดิม ไม่หายเงียบ
   ============================================================ */
#doPick.has-thumb { position: relative; isolation: isolate; }
#doPick.has-thumb .sp { position: relative; z-index: 1; transition: color .2s ease .06s, transform .42s cubic-bezier(.3, 1.6, .5, 1); }
#doPick.has-thumb .sp.active {
  background: transparent !important; background-image: none !important;
  border-color: transparent !important; box-shadow: none !important;
}
.do-thumb {
  position: absolute; left: 0; top: 0; z-index: 0; pointer-events: none; will-change: transform, width;
  border-radius: 999px;
  background-color: var(--fill);
  background-image:
    radial-gradient(120% 100% at 18% -8%, rgba(255,255,255,.46) 0%, rgba(255,255,255,.1) 42%, transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,0) 50%, rgba(0,0,0,.08));
  border: 1px solid rgba(255,255,255,.4);
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.6), inset 0 -1.5px 3px rgba(0,0,0,.14),
    inset 0 0 12px rgba(255,255,255,.12), 0 6px 14px -8px var(--fill);
}
@media (prefers-reduced-motion: reduce) { #doPick.has-thumb .sp { transition: none; } }

/* ============================================================
   Deep Ocean — ไทล์หน้าแรกสีอ่อนลง (เฉพาะธีมนี้)
   ------------------------------------------------------------
   เจ้าของ: "ทำให้แค่ในธีมนี้สีอ่อนลง" — กรอบไทล์ใช้ --fill ทึบ (#38BDF8 ฟ้าสด) แปดก้อนบนทะเลมืด
   จ้าจนแย่งสายตาจากปุ่มหลัก · เหลือฟ้า 55% โปร่งให้ทะเลข้างหลังลอดขึ้นมา เป็นกระจกฟ้าแทนก้อนฟ้าทึบ
   ลองที่ 34% แล้ว — กลายเป็นเทาอมเขียว ไม่อ่านเป็นสีฟ้าแล้ว (บทเรียน 1B25: จางกว่าพื้นขั้นเดียว = พื้นผิว)
   ============================================================ */
/* ถอนแล้ว — เจ้าของ: "สีปุ่มข้างล่างหายไปไหน เอากลับมา" · ฟ้าโปร่ง 55% บนทะเลมืดอ่านเป็นกระจกเทา ไม่ใช่ปุ่มสีฟ้า
   กลับไปใช้ --fill ทึบเหมือนธีมอื่น (กฎ .tg-t ใน today.css) · ถ้าจะทำให้อ่อนลงอีก ต้องผสมขาว ไม่ใช่ทำให้โปร่ง */
/* การ์ด "ไม่มีอะไรค้าง" กับแถบตัวเลขสามช่องบนจองาน (โหมดวันนี้) — เจ้าของ: "ให้มันมีขอบสว่างหน่อย"
   แล้วต่อมา "ทำให้มีขอบสว่างในทุกธีม" · พื้นเป็น --card ไม่มีขอบไม่มีเงา จึงจมหายไปกับพื้นจอ
   ขอบสีเน้นของธีม 40% (ชุดเดียวกับการ์ด "ยังไม่รู้ตารางเรียน" ที่อยู่เหนือมัน) + ประกายบนบาง ๆ
   + เรืองสีธีมจางรอบนอก · ใช้เงาด้านในแทน border — ไม่เพิ่มความหนา 1px ให้ผังขยับ
   (เริ่มที่ Deep Ocean ธีมเดียว แล้วขยายเป็นทุกธีมตามคำสั่ง — สีมาจาก --fill ของแต่ละธีมเอง) */
:root :is(.tb-focus.flat, .tb-strip) {
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--fill) 40%, transparent),
    inset 0 1px 0 rgba(255,255,255,.1),
    0 0 18px -6px color-mix(in srgb, var(--fill) 35%, transparent);
}

/* ============================================================
   หัวจองาน — ชื่อจอกับบรรทัดวัน/เวลาว่างอยู่บรรทัดเดียวกัน
   ------------------------------------------------------------
   เจ้าของ: "ลองเอามาไว้หลังคำว่าวันนี้" · ชื่อจอซ้าย บรรทัดวันต่อท้ายขวา กึ่งกลางแนวตั้ง
   flex-wrap: ชื่อจอยาว + บรรทัดยาว (สัปดาห์นี้ · 6–12 ต.ค. · ว่างรวม ... · ค้าง N) ไม่พอดี 375px
   ก็ปัดบรรทัดวันลงไปใต้ชื่อจอเอง ไม่ตัดคำ ไม่ล้นขอบ
   ============================================================ */
/* เว้นขวา 34px ให้ปุ่มเพื่อนที่ลอยอยู่มุมขวาบน (.top-friends) — บรรทัดวันยาวกว่านี้ต้องปัดลงก่อนถึงปุ่ม ไม่ใช่ลอดใต้ปุ่ม */
#scr-tasks .tk-head-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; padding-right: 34px; }
#scr-tasks .tk-head-row .page-title { margin: 0; }
#scr-tasks .tk-head-row .eyebrow { margin: 0; min-width: 0; }

/* ============================================================
   แคปซูลรอบบรรทัดวัน/เวลาว่างบนหัวจอ — ทุกธีม
   ------------------------------------------------------------
   เจ้าของ: "เอากรอบที่ครอบรอบ อ 6 ต.ค. ไปใส่ในทุกธีม" · เดิมมีเฉพาะ Astral Black (ดำโปร่ง ตัวขาว)
   ธีมอื่นใช้สีของธีมเอง: พื้นการ์ดโปร่ง 78% · ขอบสีเน้น 32% (ชุดเดียวกับขอบการ์ดบนจองาน) · หมึกหนา 700
   ธีมสว่างจะได้แคปซูลขาวขอบสี ไม่ใช่ก้อนดำที่หนักเกินจอ · Astral ยังใช้กฎของตัวเอง (จำเพาะกว่า)
   ============================================================ */
.page-head .eyebrow {
  width: fit-content; max-width: 100%;
  padding: 3px 11px; margin: 0 0 4px -2px; border-radius: 999px;
  background: color-mix(in srgb, var(--card) 78%, transparent);
  border: 1px solid color-mix(in srgb, var(--fill) 32%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: var(--ink); font-size: 13px; font-weight: 700; letter-spacing: .02em;
}

/* ============================================================
   ปุ่ม + — อนิเมชันตอนกด (เจ้าของ: "สร้าง animation เมื่อกดตรงเพิ่ม")
   ------------------------------------------------------------
   1) ก้อนยุบ 0.8 แล้วเด้งเกิน 1.12 กลับมาที่ 1 (สปริงแบบ iOS) — .pop ใส่ด้วย plusTap() ใน app.js
   2) วงแหวนสีธีมสองวงกระจายออกจากก้อน ห่างกัน 0.12 วิ แล้วจาง (::before / ::after)
   3) เครื่องหมาย + หมุน 135° กลายเป็น × ตลอดที่แผ่นเพิ่มงานเปิด (body.as-open) แล้วหมุนกลับตอนปิด
   4) ของในแผ่นลอยขึ้นทีละชิ้น: หัวข้อ → ไทล์ใหญ่สามใบ → "หรือใส่เอง" → รายการ (.as-card.intro)
      ไอคอนในไทล์ใหญ่เด้งตามจังหวะไทล์ของตัวเอง
   ทุกท่าปิดเมื่อเครื่องตั้งลดการเคลื่อนไหว · ใช้แค่ transform/opacity ไม่ไปขยับผัง
   ============================================================ */
.tab.scan .scan-dot { position: relative; }
.tab.scan .scan-dot svg { transition: transform .5s cubic-bezier(.34, 1.56, .64, 1); }
body.as-open .tab.scan .scan-dot svg { transform: rotate(135deg); }
.tab.scan.pop .scan-dot { animation: plus-pop .5s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes plus-pop {
  0%   { transform: scale(1); }
  28%  { transform: scale(.8); }
  62%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}
.tab.scan .scan-dot::before,
.tab.scan .scan-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  border: 2px solid color-mix(in srgb, var(--fill) 70%, #fff);
  opacity: 0;
}
.tab.scan.pop .scan-dot::before { animation: plus-ring .62s ease-out; }
.tab.scan.pop .scan-dot::after  { animation: plus-ring .62s ease-out .12s; }
@keyframes plus-ring {
  0%   { opacity: .9; transform: scale(1); }
  100% { opacity: 0;  transform: scale(2.3); }
}

@keyframes as-in {
  from { opacity: 0; transform: translateY(16px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes as-ic-pop {
  0%   { transform: scale(.4) rotate(-20deg); }
  70%  { transform: scale(1.12) rotate(4deg); }
  100% { transform: none; }
}
.as-card.intro :is(.as-h, .as-hero, .as-or),
.as-card.intro > .as-row { animation: as-in .44s cubic-bezier(.22, 1, .36, 1) both; }
.as-card.intro .as-hero .as-hero-ic { animation: as-ic-pop .55s cubic-bezier(.34, 1.56, .64, 1) both; animation-delay: inherit; }
.as-card.intro .as-h { animation-delay: .05s; }
.as-card.intro .as-hero:nth-of-type(1) { animation-delay: .1s; }
.as-card.intro .as-hero:nth-of-type(2) { animation-delay: .15s; }
.as-card.intro .as-hero:nth-of-type(3) { animation-delay: .2s; }
.as-card.intro .as-or { animation-delay: .24s; }
.as-card.intro > .as-row:nth-of-type(1) { animation-delay: .27s; }
.as-card.intro > .as-row:nth-of-type(2) { animation-delay: .3s; }
.as-card.intro > .as-row:nth-of-type(3) { animation-delay: .33s; }
.as-card.intro > .as-row:nth-of-type(4) { animation-delay: .36s; }
.as-card.intro > .as-row:nth-of-type(n+5) { animation-delay: .39s; }
@media (prefers-reduced-motion: reduce) {
  .tab.scan.pop .scan-dot, .tab.scan.pop .scan-dot::before, .tab.scan.pop .scan-dot::after,
  .as-card.intro :is(.as-h, .as-hero, .as-or, .as-hero-ic), .as-card.intro > .as-row { animation: none; }
  .tab.scan .scan-dot svg { transition: none; }
}

/* ============================================================
   เมนูเลือกวิชาแบบ HaloSelect (ปุ่ม "ดูวิชาทั้งหมด" ในฟอร์มเพิ่มงาน)
   ------------------------------------------------------------
   ปุ่ม = ตัวเรียก: ข้อความซ้าย ลูกศรขวา หมุนกลับหัวตอนเปิด
   แผ่น = กระจกฝ้าโปร่ง (พื้นการ์ด 78% + เบลอ) ลอยทับฟอร์มลงมาจากใต้ปุ่ม ไม่ดันอะไรเลื่อน
          ขยายจากขอบบน + จางเข้า · รายการไหลเข้าทีละแถว (--i) · สูงสุด 300px แล้วเลื่อนในแผ่น
   เลือก = แถบที่เลือกเป็นสีเน้นจาง มีเครื่องหมายถูก · ตอนกดวาบสีเน้นหนึ่งครั้ง (.flash)
           แถวในฟอร์มกับตัวปุ่มวาบตามหลังแผ่นปิด ให้ตาตามไปเจอว่าค่าไปลงที่ไหน
   ============================================================ */
.hsel-trig { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; }
/* 31 ต.ค. 69 · เจ้าของ (ภาพปุ่ม "ดูวิชาทั้งหมด"): "ปรับพวกปุ่มให้ตรง" — .fs-alt เดิมจัดตัวหนังสือกลาง จึงไม่เคยมี padding
   (style.css ล้างเป็น 0) · ตัวเลือกนี้ดันชื่อไปซ้าย ลูกศรไปขวา แล้วกฎทรงแคปซูลทำมุมเป็น 999px → ตัวหนังสือชิดขอบโค้ง
   ล้นออกนอกเส้นขอบ ลูกศรชนขอบขวา · เว้นในให้พ้นส่วนโค้ง (สูง 44 = รัศมี 22) */
.hsel-trig { padding-inline: 18px 16px; }
.hsel-trig .hsel-val { flex: 1; min-width: 0; text-align: left; }
.hsel-trig .hsel-ind { flex: none; transform: rotate(90deg); transition: transform .32s cubic-bezier(.34, 1.56, .64, 1); }
.hsel-trig.hsel-open .hsel-ind { transform: rotate(-90deg); }
/* ตำแหน่ง left/top/width ใส่จาก hselOpen() เทียบกับ .screen ที่เลื่อนอยู่ · เหนือปุ่มบันทึกที่ติดขอบล่าง */
.hsel-pop {
  position: absolute; z-index: 45;
  max-height: 300px; overflow-y: auto; overscroll-behavior: contain;
  padding: 6px; border-radius: 18px;
  background: color-mix(in srgb, var(--card) 78%, transparent);
  -webkit-backdrop-filter: blur(22px) saturate(180%); backdrop-filter: blur(22px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--fill) 26%, var(--line));
  box-shadow: 0 18px 40px -16px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.18);
  transform-origin: 50% 0; transform: translateY(-6px) scale(.96); opacity: 0;
  /* 31 ต.ค. 69 · เจ้าของ: "ให้อนิเมชั่นมันสมูดกว่านี้" — เดิมเด้งเกิน (.34,1.4) ทั้งขาเปิดและขาปิด และขาปิดยาว .26s
     แต่ hselClose() ถอดแผ่นทิ้งที่ 180ms = ท่าถูกตัดกลางทาง · ตอนนี้: ขาปิดสั้น .16s จบก่อนถูกถอด
     ขาเปิด .3s ease-out ไม่เด้ง (คลังของ React Bits: UI spring ~0.3 วิ ไม่เด้ง) */
  transition: transform .16s cubic-bezier(.4, 0, 1, 1), opacity .14s ease-in;
}
.hsel-pop.on { transform: none; opacity: 1; transition: transform .3s cubic-bezier(.23, 1, .32, 1), opacity .2s ease-out; }
.hsel-it {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  padding: 11px 12px; border: 0; border-radius: 12px; background: none;
  font: inherit; font-size: 14.5px; font-weight: 600; color: var(--ink); text-align: left; cursor: pointer;
  transition: background-color .15s ease;
}
.hsel-pop.on .hsel-it { animation: hsel-in .32s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--i, 0) * 18ms); }
@keyframes hsel-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.hsel-it svg { width: 17px; height: 17px; flex: none; color: var(--fill); opacity: 0; transform: scale(.6); transition: opacity .15s ease, transform .25s cubic-bezier(.34, 1.56, .64, 1); }
.hsel-it:hover, .hsel-it:focus-visible { background: color-mix(in srgb, var(--fill) 10%, transparent); outline: none; }
.hsel-it.on { background: color-mix(in srgb, var(--fill) 16%, transparent); color: var(--ink); }
.hsel-it.on svg { opacity: 1; transform: none; }
.hsel-it.flash { animation: hsel-flash .5s ease-out; }
@keyframes hsel-flash {
  0%   { background: color-mix(in srgb, var(--fill) 55%, transparent); }
  100% { background: color-mix(in srgb, var(--fill) 16%, transparent); }
}
/* แถวในบล็อก "รายละเอียด" ที่เป็นเมนู: ลูกศรกลับหัว + ชื่อแถวเป็นสีเน้นตอนเปิด (แบบแถวที่กางอยู่เดิม) */
.fm-row > summary.hsel-open .rw-l { color: var(--blue-deep); }
.fm-row > summary.hsel-open .rw-v::after { transform: rotate(-135deg) translate(-1px, -1px); }
.fm-row > summary { border-radius: 12px; }
/* แถวในฟอร์มกับตัวเรียกวาบตามหลังแผ่นปิด — วงแสงสีธีมจางออก */
:is(.pick-rows .pk, .hsel-trig, .fm-row > summary).flash { animation: hsel-glow .75s ease-out; }
@keyframes hsel-glow {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--fill) 55%, transparent); }
  100% { box-shadow: 0 0 0 10px color-mix(in srgb, var(--fill) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .hsel-pop, .hsel-trig .hsel-ind, .hsel-it svg { transition: none; }
  .hsel-pop.on .hsel-it, .hsel-it.flash, :is(.pick-rows .pk, .hsel-trig, .fm-row > summary).flash { animation: none; }
}

/* ============================================================
   แถบโหลดแบบ HaloProgress — จอสแกนใบงาน (#ocrBarWrap)
   ------------------------------------------------------------
   เจ้าของ: "เอามาใช้ตอนโหลด" (ตัวอย่าง HaloProgress) · ป้ายขั้นซ้าย ตัวเลขใหญ่สีเน้นขวา
   แถบ: ไล่สีแบรนด์ของธีม + แสงวาบวิ่งผ่านตลอด (ไม่นิ่งแม้ตัวเลขยังไม่ขยับ) + หัวเรืองที่ปลายแถบ (ฮาโล)
   ไม่รู้ว่านานแค่ไหน (.indet) = ท่อนแถบวิ่งวนซ้ายไปขวา ไม่มีตัวเลข ไม่มีหัวเรือง
   ความยาวแถบมาจาก width ที่ ocrHalo() ใส่ · หัวเรืองตามตำแหน่งผ่าน --p
   ============================================================ */
.hprog { margin: 12px 2px 6px; }
.hprog[hidden] { display: none; }
.hp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 9px; }
.hp-lbl {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13.5px; font-weight: 700; color: var(--ink);
}
.hp-val { flex: none; font-size: 15px; font-weight: 800; color: var(--fill); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.hp-track {
  position: relative; height: 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.12);
}
.hp-fill {
  position: relative; height: 100%; width: 0; border-radius: inherit; overflow: hidden;
  background: var(--grad-brand, var(--fill));
  box-shadow: 0 0 14px 1px color-mix(in srgb, var(--fill) 55%, transparent);
  transition: width .5s cubic-bezier(.22, 1, .36, 1);
}
.hp-fill::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform: translateX(-100%); animation: hp-shine 1.5s ease-in-out infinite;
}
@keyframes hp-shine { to { transform: translateX(100%); } }
.hp-track::after {
  content: ''; position: absolute; top: 50%; left: calc(var(--p, 0) * 1%);
  width: 14px; height: 14px; border-radius: 50%; transform: translate(-50%, -50%);
  background: color-mix(in srgb, var(--fill) 55%, #fff);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fill) 25%, transparent), 0 0 16px 4px color-mix(in srgb, var(--fill) 60%, transparent);
  transition: left .5s cubic-bezier(.22, 1, .36, 1);
}
.hprog.indet .hp-track { overflow: hidden; }
.hprog.indet .hp-track::after { display: none; }
.hprog.indet .hp-fill { width: 38% !important; animation: hp-indet 1.25s cubic-bezier(.65, 0, .35, 1) infinite; transition: none; }
@keyframes hp-indet { from { transform: translateX(-105%); } to { transform: translateX(265%); } }
@media (prefers-reduced-motion: reduce) {
  .hp-fill::after { animation: none; display: none; }
  .hprog.indet .hp-fill { animation: none; transform: none; }
  .hp-fill, .hp-track::after { transition: none; }
}

/* ============================================================
   หัวฟอร์มเพิ่มงาน — ชื่อจออยู่แค่บนสุด กากบาทลอยอยู่ซ้ายตลอด (คู่กับ .stuck ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "มันอยู่แค่ข้างบน พอเลื่อนลงมาจะไม่เจอ ส่วนปุ่มกากบาทให้ไปอยู่ด้านซ้าย"
   รอบก่อนใส่พื้นกระจกฝ้าให้หัวจอทั้งแถบติดขอบบน — ผิดทาง: ชื่อจอไม่ต้องตามลงมา
   ตอนนี้พอเลื่อนพ้นบนสุด ชื่อจอจางหายไป เหลือปุ่มกากบาท (ก้อนกระจกกลม มีเงาอยู่แล้ว) ลอยมุมซ้ายบน
   ปิดฟอร์มได้จากทุกตำแหน่งที่เลื่อนไป · แถบหัวจอโปร่งและไม่รับการแตะ ยกเว้นตัวปุ่ม
   (ไม่งั้นแถบใส ๆ สูง 66px จะบังการแตะของในฟอร์มที่เลื่อนลอดอยู่ข้างใต้)
   ============================================================ */
#scr-form .fm-top #formTitle { transition: opacity .18s ease, transform .18s ease; }
#scr-form .fm-top.stuck { pointer-events: none; }
#scr-form .fm-top.stuck .fm-x { pointer-events: auto; }
#scr-form .fm-top.stuck #formTitle { opacity: 0; transform: translateY(-6px); }
/* 31 ต.ค. 69 · ป้าย "ขั้น 2/2" (มาทีหลังกติกาข้างบน 16 ต.ค.) ไม่ได้จางตามชื่อจอ — เลื่อนลงแล้วมันค้างลอยต่ำกว่ากากบาท 11px
   ทับแถววิชาโดยไม่มีพื้น (เจ้าของ: "ปรับพวกปุ่มให้ตรง") · จางไปพร้อมชื่อจอ เหลือกากบาทลอยตัวเดียวตามที่ตกลงไว้ */
#scr-form .fm-top .fm-step { transition: opacity .18s ease, transform .18s ease; }
#scr-form .fm-top.stuck .fm-step { opacity: 0; transform: translateY(-6px); }
/* จอกว้าง (แถบเมนูซ้าย): กากบาทออกไปอยู่ในช่องว่างซ้ายของคอลัมน์ฟอร์ม ไม่ทับขอบการ์ด
   เจ้าของวาดลูกศรชี้ให้ย้ายไปทางซ้าย — ตอนลอยอยู่ (.stuck) มันไปนั่งบนแถว "การบ้าน" ของการ์ดแรก
   ขอบขวาของปุ่มห่างขอบการ์ด 14px (หัวจอมี padding 20px → left: 20 − 42 − 14 = −36px)
   หลุดออกจากแถวหัวจอ ชื่อจอจึงเลื่อนไปชิดแนวเดียวกับหัวข้อในการ์ด · มือถือไม่มีที่ว่างข้าง ๆ คงเดิม */
:root[data-nav="side"] #scr-form .fm-top .fm-x { position: absolute; left: -36px; top: 12px; }

/* ============================================================
   1C41b · แผ่นเช็คอินรายวันแบบใหม่ (.ck2) — ดู openDailyCheck / claimDailyFromSheet
   ------------------------------------------------------------
   เจ้าของ: "ปรับพวก UI กับทำ animation ตอนกดหน่อย"
   ลำดับสายตา: เหรียญวันนี้ในวงแสง (ใหญ่สุด) → จำนวน → ปฏิทินเจ็ดช่อง → ปุ่มรับ
   สีทองใช้กับ "ที่รับไปแล้ว" (ตราประทับ) กับปุ่มรับตามเดิม · ช่องวันนี้ใช้สีเน้นของธีม ไม่ใช่ทอง
   (กฎของแอป: ทองแปลว่าสำเร็จแล้ว — ของที่ยังไม่ได้รับจะทองไม่ได้)
   ============================================================ */
.ck2 { position: relative; overflow: visible; padding: 20px 18px 14px; }
.ck2 .ck-head { position: relative; }
.ck2 .ck-ttl { font-size: 20px; font-weight: 800; }
.ck2 .ck-sub { margin-top: 3px; }
.ck-streak {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 9px;
  padding: 4px 10px 4px 8px; border-radius: 999px;
  background: color-mix(in srgb, #F97316 14%, transparent); color: #EA580C;
  font-size: 11.5px; font-weight: 700;
}
.ck-streak svg { width: 13px; height: 13px; }
.ck-streak b { font-size: 12.5px; display: inline-block; }
.ck-streak b.ck-bump { animation: ck-bump .5s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes ck-bump { 0% { transform: scale(1); } 40% { transform: scale(1.6); } 100% { transform: scale(1); } }

/* ---- เหรียญวันนี้ในวงแสง ---- */
.ck-hero { position: relative; height: 92px; margin-top: 8px; display: grid; place-items: center; }
.ck-halo {
  position: absolute; width: 132px; height: 132px; border-radius: 50%;
  background:
    radial-gradient(circle, color-mix(in srgb, var(--gold, #F5B83D) 34%, transparent) 0%, transparent 62%),
    repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--gold, #F5B83D) 22%, transparent) 0deg 8deg, transparent 8deg 24deg);
  -webkit-mask: radial-gradient(circle, #000 30%, transparent 70%); mask: radial-gradient(circle, #000 30%, transparent 70%);
  animation: ck-rays 14s linear infinite;
}
@keyframes ck-rays { to { transform: rotate(360deg); } }
.ck-medal { position: relative; display: grid; place-items: center; animation: ck-float 3s ease-in-out infinite; }
.ck-medal .tok { filter: drop-shadow(0 8px 14px rgba(0,0,0,.28)); }
.ck-medal.gift { width: 60px; height: 60px; color: var(--fill); }
.ck-medal.gift .ck-gift { width: 60px; height: 60px; filter: drop-shadow(0 8px 14px rgba(0,0,0,.28)); }
@keyframes ck-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
.ck-medal.ck-pop { animation: ck-pop .55s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes ck-pop { 0% { transform: scale(1); } 35% { transform: scale(1.28) rotate(-8deg); } 100% { transform: scale(1); } }
.ck-plus {
  position: absolute; left: 50%; top: 4px; transform: translateX(-50%);
  font-size: 22px; font-weight: 800; color: var(--gold-text, #E9A93C); pointer-events: none;
  text-shadow: 0 2px 10px color-mix(in srgb, var(--gold, #F5B83D) 60%, transparent);
  animation: ck-plus 1s ease-out forwards;
}
@keyframes ck-plus {
  0%   { opacity: 0; transform: translate(-50%, 18px) scale(.7); }
  25%  { opacity: 1; transform: translate(-50%, 0) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -34px) scale(1); }
}
.ck-amt { display: flex; align-items: baseline; justify-content: center; gap: 7px; margin-top: 2px; }
.ck-amt b { font-size: 28px; font-weight: 800; line-height: 1.1; letter-spacing: -.03em; color: var(--ink); }
.ck-amt span { font-size: 12.5px; font-weight: 600; color: var(--muted); }

/* ---- ปฏิทินเจ็ดช่อง: 4 + (2 + วันที่ 7 กว้างสองช่อง) ---- */
.ck-cal { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-top: 14px; }
.ck-c {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 2px 7px; border-radius: 14px;
  background: var(--card2); border: 1px solid var(--line);
  animation: ck-cin .4s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(.12s + var(--i, 0) * 45ms);
}
@keyframes ck-cin { from { opacity: 0; transform: translateY(10px) scale(.92); } to { opacity: 1; transform: none; } }
.ck-c.d7 { grid-column: span 2; flex-direction: row; justify-content: center; gap: 8px; padding: 8px 10px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--fill) 16%, var(--card2)), var(--card2)); }
.ck-c.d7 .ck-cd { position: absolute; top: 6px; left: 10px; }
.ck-c.d7 .ck-ci { margin-top: 8px; }
.ck-c.d7 .ck-cv { margin-top: 8px; }
.ck-cd { font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--faint); }
.ck-ci { display: grid; place-items: center; height: 26px; }
.ck-ci .ck-gift { width: 28px; height: 28px; color: var(--fill); }
.ck-cv { font-size: 12.5px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.ck-c.next { opacity: .62; }
.ck-c.next .tok { filter: grayscale(.6); }
/* วันนี้ — กรอบสีเน้นของธีม เรืองหายใจ · ยกขึ้นนิดหนึ่ง */
.ck-c.now {
  background: color-mix(in srgb, var(--fill) 14%, var(--card));
  border: 2px solid var(--fill); padding: 7px 1px 6px;
  box-shadow: 0 8px 18px -10px color-mix(in srgb, var(--fill) 80%, transparent);
  animation: ck-cin .4s cubic-bezier(.22, 1, .36, 1) both, ck-breathe 2.2s ease-in-out .6s infinite;
  animation-delay: calc(.12s + var(--i, 0) * 45ms), .7s;
}
.ck-c.now .ck-cd { color: var(--fill); }
@keyframes ck-breathe {
  0%, 100% { box-shadow: 0 8px 18px -10px color-mix(in srgb, var(--fill) 80%, transparent), 0 0 0 0 color-mix(in srgb, var(--fill) 35%, transparent); }
  50%      { box-shadow: 0 8px 18px -10px color-mix(in srgb, var(--fill) 80%, transparent), 0 0 0 5px color-mix(in srgb, var(--fill) 0%, transparent); }
}
/* รับแล้ว — ตราประทับถูกสีทองทับช่อง ของข้างใต้จางลง */
.ck-ok {
  position: absolute; inset: 0; display: grid; place-items: center; border-radius: inherit;
  color: var(--on-gold, #3A2404); opacity: 0; pointer-events: none;
}
.ck-ok svg {
  width: 26px; height: 26px; padding: 5px; border-radius: 50%; stroke-width: 3;
  background: var(--grad-gold, #F5B83D); box-shadow: 0 4px 10px -3px rgba(0,0,0,.35);
}
.ck-c.done { background: var(--gold-soft, var(--card2)); border-color: color-mix(in srgb, var(--gold, #F5B83D) 35%, transparent); }
.ck-c.done > :not(.ck-ok) { opacity: .35; }
.ck-c.done .ck-ok { opacity: 1; }
.ck-c.ck-stamp .ck-ok { animation: ck-stamp .45s cubic-bezier(.34, 1.56, .64, 1) both; }
@keyframes ck-stamp { 0% { opacity: 0; transform: scale(2.2) rotate(-25deg); } 60% { opacity: 1; transform: scale(.9) rotate(4deg); } 100% { opacity: 1; transform: none; } }

/* ---- ปุ่มรับ: ยุบ-เด้ง แล้วกลายเป็น "รับแล้ว" ---- */
.ck2 .ck-cta { margin-top: 14px; display: flex; align-items: center; justify-content: center; gap: 7px; position: relative; overflow: hidden; }
.ck2 .ck-cta::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.55) 50%, transparent 65%);
  transform: translateX(-120%); animation: ck-sheen 2.6s ease-in-out 1s infinite;
}
@keyframes ck-sheen { 0%, 60% { transform: translateX(-120%); } 100% { transform: translateX(120%); } }
.ck2 .ck-cta.ck-press { animation: ck-press .5s cubic-bezier(.34, 1.56, .64, 1); pointer-events: none; }
@keyframes ck-press { 0% { transform: scale(1); } 30% { transform: scale(.92); } 70% { transform: scale(1.04); } 100% { transform: scale(1); } }
.ck2 .ck-cta.ck-got { filter: saturate(.75); }
.ck2 .ck-cta.ck-got::after { animation: none; display: none; }
.ck2 .ck-cta svg { width: 18px; height: 18px; stroke-width: 3; }
.ck2 .ck-cta:disabled { cursor: default; }
.ck2 .ck-done { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 14px 0 2px; font-weight: 600; }
.ck2 .ck-done svg { width: 15px; height: 15px; color: var(--gold-text, var(--good)); }

/* ---- เหรียญบินจากปุ่มเข้าเหรียญใหญ่ ---- */
.ck-fly { position: absolute; z-index: 3; width: 18px; height: 18px; margin: -9px 0 0 -9px; pointer-events: none;
  animation: ck-fly .72s cubic-bezier(.45, 0, .55, 1) both; }
.ck-fly .tok { display: block; }
@keyframes ck-fly {
  0%   { opacity: 0; transform: translate(0, 0) scale(.5); }
  12%  { opacity: 1; }
  50%  { transform: translate(calc(var(--dx) * .45 + var(--sx)), calc(var(--dy) * .55 - 26px)) scale(1.15); }
  100% { opacity: .2; transform: translate(var(--dx), var(--dy)) scale(.45); }
}
@media (prefers-reduced-motion: reduce) {
  .ck-halo, .ck-medal, .ck-c, .ck-c.now, .ck2 .ck-cta::after, .ck-fly, .ck-plus { animation: none !important; }
}

/* ============================================================
   "น้องไซช่วยอะไรได้บ้าง" — จอว่างของแชท (คู่กับ sga* ใน app.js)
   ------------------------------------------------------------
   พอร์ตจาก GenerateAnything (cult-ui · tabs-illustration-vercel · MIT)
   จอกว้าง: แท็บซ้าย | เส้นคั่น | ฟองภาพขวา เหมือนต้นฉบับ
   จอแคบ (มือถือ): หัวข้อ → ฟองภาพ → แท็บ เรียงลง เพราะสองคอลัมน์บีบฟองจนดูไม่ออก
   สีทั้งหมดมาจากโทเคนของธีม · เส้นแสงบนลูกโลกไม่มีสีทอง (ทองสงวนไว้ให้ของที่ทำสำเร็จแล้ว)
   ============================================================ */
.sga {
  --sga-sf: var(--card2);
  --sga-bd: color-mix(in srgb, var(--ink) 9%, transparent);
  --sga-grid: color-mix(in srgb, var(--ink) 17%, transparent);
  --sga-ball: color-mix(in srgb, var(--ink) 4%, var(--card2));
  --sga-t1: var(--fill);
  --sga-t2: color-mix(in srgb, var(--fill) 45%, #ffffff);
  --sga-t3: color-mix(in srgb, var(--fill) 50%, #22d3ee);
  --sga-t4: color-mix(in srgb, var(--fill) 50%, #f472b6);
  container-type: inline-size;
  border: 1px solid var(--line); border-radius: 22px; background: var(--card);
  overflow: hidden;
}
.sga-in {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "h" "st" "tb";
  padding: 16px 16px 8px;
}
.sga-h { grid-area: h; margin: 0 0 12px; font-size: 15px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
.sga-dv { display: none; }
.sga-r { grid-area: st; display: flex; flex-direction: column; justify-content: flex-end; min-width: 0; padding: 0 2px 6px 0; }
.sga-tabs { grid-area: tb; display: flex; flex-direction: column; min-width: 0; padding-top: 4px; }

@container (min-width: 540px) {
  .sga-in {
    grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1.15fr);
    grid-template-rows: auto 1fr;
    grid-template-areas: "h dv st" "tb dv st";
    column-gap: 28px; padding: 28px 28px 22px;
  }
  .sga-h { margin-bottom: 18px; font-size: 18px; align-self: end; }
  .sga-dv { display: block; grid-area: dv; background: var(--line); }
  .sga-r { padding: 0; justify-content: center; }
  .sga-tabs { padding-top: 0; }
}

/* ---- แท็บ: ชื่อ + เส้นนับถอยหลัง + คำอธิบายที่กางออกเฉพาะแท็บที่เลือก ---- */
.sga-tb {
  all: unset; box-sizing: border-box; display: block; width: fit-content; padding: 7px 0 0;
  cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
}
.sga-tb:focus-visible { outline: 2px solid var(--fill); outline-offset: 3px; border-radius: 6px; }
.sga-tt {
  font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--muted);
  transition: color .2s cubic-bezier(.23, 1, .32, 1);
}
.sga-it.on .sga-tt { color: var(--ink); }
.sga-pg {
  display: block; height: 2px; margin-top: 5px; border-radius: 9px; overflow: hidden;
  background: transparent; transition: background .2s ease;
}
.sga-it.on .sga-pg { background: color-mix(in srgb, var(--ink) 12%, transparent); }
.sga-pg i { display: block; height: 100%; border-radius: inherit; background: var(--ink); transform: scaleX(0); transform-origin: left; }
.sga-it:not(.on) .sga-pg i { transform: scaleX(0) !important; }
.sga-dw {
  display: grid; grid-template-rows: 0fr; opacity: 0; visibility: hidden;
  transition: grid-template-rows .35s cubic-bezier(.23, 1, .32, 1), opacity .25s cubic-bezier(.23, 1, .32, 1), visibility 0s .35s;
}
.sga-it.on .sga-dw { grid-template-rows: 1fr; opacity: 1; visibility: visible; transition-delay: 0s; }
.sga-dc { min-height: 0; overflow: hidden; }
.sga-dc p { margin: 7px 0 9px; max-width: 400px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.sga-it.on .sga-dc > * { animation: sga-desc .4s cubic-bezier(.23, 1, .32, 1) both; }
.sga-it.on .sga-dc > .sga-ask { animation-delay: .06s; }
@keyframes sga-desc { from { opacity: 0; transform: translateY(4px); } }
.sga-ask {
  display: inline-flex; align-items: center; gap: 3px; margin: 0 0 8px; padding: 7px 10px 7px 13px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card2); color: var(--ink);
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
  transition: transform .2s cubic-bezier(.3, 1.6, .5, 1);
}
.sga-ask svg { width: 14px; height: 14px; color: var(--fill); }
.sga-ask:active { transform: scale(.95); }
.sga-ask:disabled { opacity: .5; }

/* ---- ฟองแชทของน้องไซที่ใส่ภาพ ----
   หางฟองซ้อนทับมุมล่างซ้ายของฟอง (ทับเส้นขอบให้ต่อกันเนียน) ของที่อยู่มุมล่างซ้ายจึงต้องเว้นซ้าย 22px */
.sga-stage { width: 100%; }
.sga-stage.in { animation: sga-in .4s cubic-bezier(.23, 1, .32, 1) both; }
@keyframes sga-in { from { opacity: 0; transform: scale(.97) translateY(6px); } }
.sga-chat { display: flex; align-items: flex-end; gap: 11px; padding-left: 0; }
.sga-av {
  flex: none; width: 30px; height: 30px; border-radius: 9px; overflow: hidden; background: var(--sga-sf);
  box-shadow: 0 0 0 1px var(--sga-bd), 0 1px 3px rgba(0,0,0,.08);
}
.sga-av .ai-av { width: 100%; height: 100%; margin: 0; border-radius: inherit; }
.sga-bw { position: relative; flex: 1; min-width: 0; }
.sga-bub {
  position: relative; z-index: 1; overflow: hidden; border-radius: 22px; background: var(--sga-sf);
  box-shadow: 0 0 0 1px var(--sga-bd), 0 1px 3px rgba(0,0,0,.08);
}
.sga-tail { position: absolute; z-index: 2; left: -7px; bottom: -2px; width: 24px; height: 24px; display: block; }
.sga-box { position: relative; aspect-ratio: 16 / 9; overflow: hidden; }

/* ข้อความไหล + เคอร์เซอร์ */
.sga-txb { padding: 15px 17px; }
.sga-tx {
  margin: 0; font-size: 13.5px; line-height: 1.65; color: var(--muted);
  -webkit-mask-image: linear-gradient(175deg, #000 40%, transparent 90%);
          mask-image: linear-gradient(175deg, #000 40%, transparent 90%);
}
.sga-caret {
  display: inline-block; width: 2px; height: 14px; margin-left: 1px; vertical-align: text-bottom;
  background: currentColor; animation: sga-blink 1s step-end infinite;
}
.sga-tx.done .sga-caret { display: none; }
@keyframes sga-blink { 50% { opacity: 0; } }

/* ลูกโลกโครงลวด + แถบโหลด */
.sga-glb svg { display: block; width: 100%; height: 100%; overflow: visible; }
.sga-ball { fill: var(--sga-ball); }
.sga-grid path { fill: none; stroke: var(--sga-grid); stroke-width: 1; vector-effect: non-scaling-stroke; }
.sga-tr { fill: none; stroke-width: 2; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.sga-bar { height: 4px; margin: 0 14px 10px 22px; border-radius: 9px; overflow: hidden; background: color-mix(in srgb, var(--ink) 10%, transparent); }
.sga-bar i { display: block; height: 100%; border-radius: inherit; background: var(--fill); transform: scaleX(0); transform-origin: left; }

/* ย่อหน้าโครง + ปากกาเน้นข้อความ */
.sga-nt { display: flex; flex-direction: column; gap: 10px; padding: 18px 18px 0; }
.sga-ln {
  position: relative; display: block; flex: none; width: var(--w); height: 7px; border-radius: 9px;
  background: color-mix(in srgb, var(--ink) 15%, transparent);
}
.sga-ln:not(.key) { animation: sga-dim .5s ease both; animation-delay: calc(var(--sga-e, 0ms) + 2.6s); }
@keyframes sga-dim { to { opacity: .3; } }
.sga-hl {
  position: absolute; left: var(--a); width: calc(var(--b) - var(--a)); top: -4px; bottom: -4px;
  border-radius: 5px; background: color-mix(in srgb, var(--fill) 45%, transparent);
  transform: scaleX(0); transform-origin: left;
  animation: sga-hl .55s cubic-bezier(.65, 0, .35, 1) both;
  animation-delay: calc(var(--sga-e, 0ms) + 400ms + var(--k) * 650ms);
}
@keyframes sga-hl { to { transform: scaleX(1); } }
.sga-sum {
  position: absolute; left: 22px; bottom: 12px; display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px 6px 9px; border-radius: 999px; background: var(--fill); color: var(--on-fill);
  font-size: 12px; font-weight: 700; box-shadow: 0 6px 16px -8px var(--fill);
  animation: sga-pop .45s cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: calc(var(--sga-e, 0ms) + 2.7s);
}
.sga-sum svg { width: 14px; height: 14px; }
@keyframes sga-pop { from { opacity: 0; transform: translateY(8px) scale(.9); } }

/* แท่งเวลาอ่าน + เส้นเวลา จ.→วันสอบ */
.sga-wv { display: grid; place-items: center; }
.sga-bars { display: flex; align-items: center; gap: 3px; height: 72px; margin-top: -14px; }
.sga-bars i { width: 5px; height: 10px; border-radius: 3px; background: var(--fill); opacity: .85; }
@supports (color: hsl(from red h s l)) {
  .sga-bars i { background: hsl(from var(--fill) calc(h + var(--hh, 0)) s l); }
}
.sga-tl {
  position: absolute; left: 22px; right: 14px; bottom: 10px; display: flex; align-items: center; gap: 8px;
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.sga-day { min-width: 2.2em; }
.sga-trk { flex: 1; height: 3px; border-radius: 9px; overflow: hidden; background: color-mix(in srgb, var(--ink) 12%, transparent); }
.sga-trk i { display: block; height: 100%; border-radius: inherit; background: color-mix(in srgb, var(--ink) 50%, transparent); transform: scaleX(0); transform-origin: left; }

/* Astral Black เป็นธีมขาวดำล้วน — ภาพในฟองต้องไม่มีสีหลุดมา */
[data-theme="astral"] .sga-stage { filter: grayscale(1); }

@media (prefers-reduced-motion: reduce) {
  .sga-stage.in, .sga-it.on .sga-dc > *, .sga-caret { animation: none; }
  .sga-hl, .sga-ln:not(.key), .sga-sum { animation-duration: 1ms; animation-delay: 0s; }
  .sga-pg { visibility: hidden; }
}

/* ฟองรอคำตอบ (sgaWait) — ใช้ฟองภาพชุดเดียวกับแผงแท็บ แต่ไม่มีการ์ดล้อม
   กว้างไม่เกิน 300px ให้อ่านเป็น "ฟองแชท" ไม่ใช่แบนเนอร์เต็มจอ */
#aiBody .ai-msg.sai:has(> .sga-wait) { display: block; }
.sga.sga-wait {
  container-type: normal; width: 100%; max-width: 300px;
  border: 0; border-radius: 0; background: none; overflow: visible;
}
.sga-cap {
  display: flex; align-items: center; gap: 3px; margin: 8px 0 0 41px;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.sga-cap i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; animation: sga-dot 1.2s ease-in-out infinite; }
.sga-cap i:first-of-type { margin-left: 2px; }
.sga-cap i:nth-of-type(2) { animation-delay: .15s; }
.sga-cap i:nth-of-type(3) { animation-delay: .3s; }
@keyframes sga-dot { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sga-cap i { animation: none; opacity: .6; } }

/* คำตอบของน้องไซไหลออกทีละตัว (aiReveal ใน app.js) — แบบ TextPanel ของ GenerateAnything
   เคอร์เซอร์เส้นบาง 2px กะพริบแบบ step-end เหมือนต้นฉบับ (เดิมเป็นแท่งหนา 8px)
   คำตอบใหม่เข้ามาด้วยท่า panelIn: ย่อ .97 ลอยขึ้น 6px แล้วเข้าที่ */
#aiBody .am-text.ai-live .am-caret {
  width: 2px; height: 1.15em; margin-left: 1px; border-radius: 1px; vertical-align: -.2em;
  background: currentColor; animation: sga-blink 1s step-end infinite;
}
#aiBody .ai-msg.sai.am-enter { transform-origin: 0 100%; animation: sga-in .4s cubic-bezier(.23, 1, .32, 1) both; }
@media (prefers-reduced-motion: reduce) {
  #aiBody .ai-msg.sai.am-enter, #aiBody .am-text.ai-live .am-caret { animation: none; }
}

/* ช่องพิมพ์ถามน้องไซ — ไม่มีกรอบสี่เหลี่ยมรอบตัวหนังสือตอนพิมพ์ (เจ้าของ: "เอาขอบนี้ออก")
   กรอบมาจากวงโฟกัสคีย์บอร์ดของชุด QA (#17) ซึ่ง textarea ติด :focus-visible ทุกครั้งแม้แตะด้วยนิ้ว
   กล่องพิมพ์ทั้งกล่องยังบอกว่ากำลังโฟกัสอยู่ด้วยขอบที่เข้มขึ้น (.sai-cmp:focus-within) */
.phone #aiBody .sai-bar .ai-in:is(:focus, :focus-visible) { outline: none !important; }

/* ช่องพิมพ์ถามน้องไซ — ข้อความยาวต้องเห็นครบทุกบรรทัด กล่องสูงขึ้นตาม (เจ้าของ: "ทำให้มันเหมือนรูปสอง")
   กฎเก่า .ai-in { flex: 1 } (สมัยกล่องเป็นแถวนอน) ยังติดมา พอกล่องเป็นแนวตั้ง (1C40)
   flex-basis 0 ชนะความสูงที่ autoGrow() ตั้ง ช่องจึงค้างสูงบรรทัดเดียว บรรทัดบนโดนตัดเหลือแต่หางสระ */
.phone #aiBody .sai-bar.sai-cmp .ai-in { flex: none; }

/* ============================================================
   แถวตัวเลือกในฟอร์ม (ประเภท · วิชา · กำหนดส่ง) แบบ FeaturePoll (cult-ui · MIT)
   ------------------------------------------------------------
   เจ้าของส่ง FeaturePoll มา "เอามาใช้ในหน้านี้ อนิเมชันอะ"
   แถวละกรอบมน มีช่องไฟระหว่างแถว (แทนเส้นคั่น) · แถวที่เลือก = ขอบสีเน้น + พื้นจาง ๆ + เงาบาง
   วงกลมหน้าแถวเติมสีแล้วมีเครื่องหมายถูก (เดิมเป็นวงแหวนหนา)
   ท่าตอนแตะ (.pk-in / .pk-out ใส่จาก app.js): สีกวาดจากซ้ายเต็มแถว · วงกลมเด้ง · ถูกเด้งตามมา · แถวเดิมจางออก
   ============================================================ */
#scr-form .pick-rows { gap: 7px; }
#scr-form .pick-rows > button {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 50px; padding: 6px 14px;
  border: 1.5px solid var(--line); border-radius: 14px; background: none; box-shadow: none;
  transition: border-color .2s ease-out, box-shadow .2s ease-out, transform .15s ease-out, color .14s ease;
}
#scr-form .pick-rows > button::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: color-mix(in srgb, var(--blue) 9%, transparent);
  transform: scaleX(0); transform-origin: left center; opacity: 0;
}
#scr-form .pick-rows > button:is(.on, .active) {
  border-color: var(--blue);
  box-shadow: 0 1px 2px rgba(0,0,0,.05), 0 6px 16px -10px color-mix(in srgb, var(--blue) 55%, transparent);
}
#scr-form .pick-rows > button:is(.on, .active)::before { transform: none; opacity: 1; }
#scr-form .pick-rows > button:active { transform: scale(.98); }
@media (hover: hover) and (pointer: fine) {
  #scr-form .pick-rows > button:not(.on):not(.active):hover {
    border-color: color-mix(in srgb, var(--blue) 50%, var(--line));
  }
  #scr-form .pick-rows > button:not(.on):not(.active):hover::before { transform: none; opacity: .45; }
}

/* วงกลม → วงทึบ + เครื่องหมายถูก (วาดด้วยขอบ ไม่ต้องเพิ่ม markup) */
#scr-form .pick-rows .pk-dot {
  position: relative; display: grid; place-items: center;
  width: 22px; height: 22px; border: 2px solid color-mix(in srgb, var(--ink) 22%, transparent);
  background: none; transition: background-color .2s ease-out, border-color .2s ease-out;
}
#scr-form .pick-rows .pk-dot::after {
  content: ''; width: 5px; height: 9px; margin-top: -2px;
  border: solid var(--on-accent, #fff); border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg) scale(0); transition: transform .2s cubic-bezier(.3, 1.6, .5, 1);
}
#scr-form .pick-rows > button:is(.on, .active) .pk-dot { border-width: 2px; border-color: var(--blue); background: var(--blue); }
#scr-form .pick-rows > button:is(.on, .active) .pk-dot::after { transform: rotate(45deg) scale(1); }

/* ท่าตอนแตะ */
#scr-form .pick-rows > button.pk-in::before { animation: pk-sweep .5s cubic-bezier(.22, 1, .36, 1) both; }
#scr-form .pick-rows > button.pk-in .pk-dot { animation: pk-dot .38s cubic-bezier(.3, 1.6, .5, 1) both; }
#scr-form .pick-rows > button.pk-in .pk-dot::after { animation: pk-check .32s .1s cubic-bezier(.3, 1.6, .5, 1) both; }
#scr-form .pick-rows > button.pk-out::before { animation: pk-fade .3s ease-out both; }
@keyframes pk-sweep { from { transform: scaleX(0); opacity: 1; } to { transform: scaleX(1); opacity: 1; } }
@keyframes pk-fade { from { transform: none; opacity: 1; } to { transform: none; opacity: 0; } }
@keyframes pk-dot { 0% { transform: scale(.55); } 100% { transform: scale(1); } }
@keyframes pk-check { from { transform: rotate(45deg) scale(0); } to { transform: rotate(45deg) scale(1); } }
@media (prefers-reduced-motion: reduce) {
  #scr-form .pick-rows > button, #scr-form .pick-rows .pk-dot, #scr-form .pick-rows .pk-dot::after { transition: none; }
  #scr-form .pick-rows > button:is(.pk-in, .pk-out)::before,
  #scr-form .pick-rows > button.pk-in .pk-dot, #scr-form .pick-rows > button.pk-in .pk-dot::after { animation: none; }
}

/* ============================================================
   เพิ่มวิชาของฉัน (แถวท้ายรายการวิชา + แผ่นใต้แถว) · 31 ต.ค. 69 · รอบสอง
   ------------------------------------------------------------
   เจ้าของ (ภาพแถว "+ วิชาใหม่" กับแผ่น): "ปรับใหม่ให้หมดเลย" — รอบแรกแถวเพิ่มได้ทรง FeaturePoll เต็ม ๆ (ขอบเทา พื้นใส)
   แค่ตัวหนังสือฟ้า บนพื้นมืดเลยดูเหมือนแถวที่กดไม่ได้ · ชิปลบเป็น × ตัวเล็กจาง · แผ่นลอยแยกจากแถวที่เปิดมันขึ้นมา
   ตอนนี้:
   • แถว = แถวแบบ FeaturePoll (cult-ui · MIT) ฉบับ "ปุ่มเพิ่ม": ขอบประสีธีม พื้นเจือสีธีม วงกลมทึบมีบวก ป้ายสีหมึก
     คำใบ้ขวา "ชุมนุม · ติว · วิชาเลือก" · เปิดแล้วบวกหมุนเป็นกากบาท แถวกับแผ่นต่อกันเป็นการ์ดเดียว (มุมรอยต่อ 4px)
   • ช่องชื่อ = HaloSearchInput (cult-ui · MIT) ฉบับนิ่ง: ขอบไล่สีวงรอบแคปซูล แสงฟุ้งตอนแตะ ปุ่ม "เพิ่ม" อยู่ในช่อง
     ไม่หมุนตลอด (กติกา: ของขยับไม่หยุดใช้ได้แค่ transform/opacity)
   • ผิด = แถวแดงมีไอคอน ! + ช่องสั่นหนึ่งที (ท่า error ของ Code Slots · React Bits)
   • วิชาของฉัน = ชิปมีจุดสีของวิชานั้น · × เป็นวงกลมเห็นชัด 26px พื้นที่กด 36px
   ท่าเคลื่อนไหวใช้ ease-out (.23,1,.32,1) ตามคลังของ React Bits · ลดการเคลื่อนไหว = จางอย่างเดียว
   ============================================================ */
#scr-form .pick-rows > button.pk-add {
  border-style: dashed; border-color: color-mix(in srgb, var(--blue) 50%, var(--line));
  background: color-mix(in srgb, var(--blue) 7%, transparent); color: var(--ink);
}
#scr-form .pick-rows > button.pk-add::before { display: none; }
@media (hover: hover) and (pointer: fine) {
  #scr-form .pick-rows > button.pk-add:not(.on):not(.active):hover {
    border-color: var(--blue); background: color-mix(in srgb, var(--blue) 12%, transparent);
  }
}
#scr-form .pick-rows > button.pk-add[aria-expanded="true"] {
  border-style: solid; border-color: var(--blue);
  border-bottom-left-radius: 4px; border-bottom-right-radius: 4px;
  background: color-mix(in srgb, var(--blue) 10%, transparent);
}
.pk-add-t { font-weight: 700; }
.pk-plus {
  position: relative; flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--blue); color: var(--on-accent, #fff);
  box-shadow: 0 3px 8px -3px color-mix(in srgb, var(--blue) 80%, transparent);
  transition: transform .22s cubic-bezier(.23, 1, .32, 1);
}
.pk-plus::before, .pk-plus::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 10px; height: 2px; margin: -1px 0 0 -5px;
  border-radius: 1px; background: currentColor;
}
.pk-plus::after { transform: rotate(90deg); }
#scr-form .pick-rows > button.pk-add[aria-expanded="true"] .pk-plus { transform: rotate(45deg); }
#scr-form .pick-rows .pk-add .pk-add-hint { font-weight: 600; color: var(--muted); transition: opacity .18s ease-out; }
#scr-form .pick-rows > button.pk-add[aria-expanded="true"] .pk-add-hint { opacity: 0; }
/* ป้าย "ของฉัน" ท้ายแถววิชาที่เพิ่มเอง — บอกว่าแถวนี้มาจากไหน (ลบได้ในแผ่นข้างล่าง) */
#scr-form .pick-rows .pk-mine {
  padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 700;
  color: var(--blue); background: color-mix(in srgb, var(--blue) 12%, transparent);
}

/* แผ่นใต้แถว — ต่อกับแถวเป็นการ์ดเดียว */
#scr-form .subj-add {
  margin-top: -7px; padding: 14px 12px 12px;   /* ส่วนนี้เป็น flex มี gap 10px → เหลือรอยต่อกับแถว 3px */
  border: 1.5px solid var(--blue); border-radius: 4px 4px 16px 16px;
  background: color-mix(in srgb, var(--blue) 6%, var(--card));
  box-shadow: 0 10px 24px -18px color-mix(in srgb, var(--blue) 80%, transparent);
  animation: sa-in .22s cubic-bezier(.23, 1, .32, 1) both;
}
#scr-form .subj-add[hidden] { display: none; }
@keyframes sa-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ช่องชื่อ (HaloSearchInput ฉบับนิ่ง) */
.sa-field { position: relative; }
.sa-field input {
  width: 100%; min-height: 50px; padding: 0 96px 0 18px;
  border: 2px solid transparent; border-radius: 999px; color: var(--ink);
  font: inherit; font-size: 15px; font-weight: 600;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    conic-gradient(from 210deg,
      color-mix(in srgb, var(--blue) 70%, transparent),
      color-mix(in srgb, var(--halo-2, var(--blue)) 55%, transparent),
      color-mix(in srgb, var(--halo-3, var(--blue)) 50%, transparent),
      color-mix(in srgb, var(--blue) 70%, transparent)) border-box;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 6%, transparent);
  transition: box-shadow .25s ease-out;
}
.sa-field input::placeholder { color: var(--faint); font-weight: 500; }
.sa-field input:focus {
  outline: none;
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--blue) 16%, transparent),
              0 12px 26px -14px color-mix(in srgb, var(--blue) 75%, transparent);
}
.phone #scr-form .sa-field input:focus-visible { outline: none !important; }
.sa-field .sa-go {
  position: absolute; top: 6px; right: 6px; bottom: 6px; padding: 0 20px;
  border: 0; border-radius: 999px; background: var(--fill); color: var(--on-fill);
  font: inherit; font-size: 14.5px; font-weight: 800; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 4px 12px -6px color-mix(in srgb, var(--fill) 80%, transparent);
  transition: transform .16s cubic-bezier(.23, 1, .32, 1);
}
.sa-field .sa-go:active { transform: scale(.95); }
.sa-field.sa-shake { animation: sa-shake .38s cubic-bezier(.36, .07, .19, .97); }
@keyframes sa-shake {
  0%, 100% { transform: none; } 15% { transform: translateX(-5px); } 30% { transform: translateX(5px); }
  48% { transform: translateX(-3px); } 66% { transform: translateX(3px); } 84% { transform: translateX(-1px); }
}

/* ข้อความผิด */
.sa-err { display: flex; align-items: center; gap: 7px; margin: 9px 6px 0; font-size: 12.5px; font-weight: 700; color: var(--alert); }
.sa-err:empty { display: none; }
.sa-err::before {
  content: "!"; flex: none; width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center;
  background: var(--alert); color: #fff; font-size: 11px; font-weight: 800; line-height: 1;
}

/* วิชาของฉัน */
.sa-mine { margin-top: 14px; padding-top: 12px; border-top: 1px dashed color-mix(in srgb, var(--blue) 28%, var(--line)); }
.sa-mine > small { display: flex; justify-content: space-between; gap: 8px; margin: 0 4px 9px; font-size: 12px; color: var(--muted); }
.sa-mine > small > span:first-child { font-weight: 800; color: var(--ink); }
.sa-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.sa-chip {
  display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 5px 0 12px;
  border-radius: 999px; border: 1px solid color-mix(in srgb, var(--sj, var(--blue)) 45%, var(--line));
  background: color-mix(in srgb, var(--sj, var(--blue)) 10%, var(--card));
  font-size: 13.5px; font-weight: 700; color: var(--ink);
}
.sa-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--sj, var(--blue)); }
/* วิชาที่ยังไม่มีงานยังไม่ได้สีจาก subjIndex (ได้เทาของ "อื่น ๆ") — ในชิปวิชาของฉันใช้สีธีมแทน ไม่งั้นดูเหมือนปิดใช้ */
.sa-chip.sj-0 { --sj: var(--blue); }
.sa-chip button {
  position: relative; flex: none; width: 26px; height: 26px; border: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: color-mix(in srgb, var(--ink) 10%, transparent); color: var(--ink);
  transition: background-color .15s ease-out, color .15s ease-out, transform .16s cubic-bezier(.23, 1, .32, 1);
}
.sa-chip button::after { content: ""; position: absolute; inset: -5px; }   /* พื้นที่กด 36px */
.sa-chip button svg { width: 14px; height: 14px; }
.sa-chip button:active { transform: scale(.9); background: color-mix(in srgb, var(--alert) 18%, transparent); color: var(--alert); }
@media (hover: hover) and (pointer: fine) {
  .sa-chip button:hover { background: color-mix(in srgb, var(--alert) 14%, transparent); color: var(--alert); }
}
.sa-empty { margin: 0 4px; font-size: 12.5px; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .pk-plus, #scr-form .pick-rows .pk-add .pk-add-hint, .sa-field input, .sa-field .sa-go, .sa-chip button { transition: none; }
  #scr-form .subj-add { animation: sa-fade .2s ease-out both; }
  .sa-field.sa-shake { animation: none; }
}
@keyframes sa-fade { from { opacity: 0; } to { opacity: 1; } }

/* ============================================================
   ปฏิทินเลือกวันในฟอร์มเพิ่มงาน (renderDueCal ใน app.js)
   ------------------------------------------------------------
   แทนป๊อปอัปของ <input type=date> ที่เบราว์เซอร์วาดเอง (เทาเข้ม ภาษาอังกฤษ ค.ศ. แต่งไม่ได้)
   เดือน/ปีไทย พ.ศ. · หัววันไทย อา–ส · วันนี้ = วงขอบ · วันที่เลือก = วงทึบสีเน้น
   วันที่ผ่านไปแล้วจาง (ยังกดได้ — แก้งานเก่าที่เลยกำหนดต้องเลือกวันเดิมได้)
   ท่า: กล่องเลื่อนลงตอนกาง · ตารางวันเลื่อนซ้าย/ขวาตอนเปลี่ยนเดือน · วงที่เพิ่งเลือกเด้งพร้อมคลื่นวง
   ============================================================ */
#scr-form .due-exact { padding: 0; background: none; }
#scr-form .due-exact.dcal-open { animation: dcal-open .32s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes dcal-open { from { opacity: 0; transform: translateY(-6px); } }
.dcal {
  padding: 12px 10px 10px; border-radius: 18px;
  border: 1.5px solid var(--line); background: var(--card2);
  overflow: hidden;
}
.fld.unsure .dcal { box-shadow: inset 0 0 0 1.5px var(--warn); background: var(--warn-soft); }
.dcal-head { display: flex; align-items: center; gap: 4px; padding: 0 4px 8px 8px; }
.dcal-t { flex: 1; min-width: 0; font-size: 15.5px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
.dcal-t.in { animation: dcal-fade .28s ease-out both; }
@keyframes dcal-fade { from { opacity: 0; } }
.dcal-nav {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 50%; background: var(--card); color: var(--ink); cursor: pointer;
  box-shadow: 0 0 0 1px var(--line); transition: transform .15s ease-out;
}
.dcal-nav svg { width: 17px; height: 17px; }
.dcal-nav.prev svg { transform: rotate(180deg); }
.dcal-nav:active { transform: scale(.9); }
.dcal-wk, .dcal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.dcal-wk { padding-bottom: 4px; }
.dcal-wk span { text-align: center; font-size: 11.5px; font-weight: 700; color: var(--faint); line-height: 22px; }
.dcal-wk span:first-child { color: color-mix(in srgb, var(--alert) 70%, var(--faint)); }
.dcal-grid { row-gap: 3px; }
.dcal-grid.in-r { animation: dcal-r .3s cubic-bezier(.22, 1, .36, 1) both; }
.dcal-grid.in-l { animation: dcal-l .3s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes dcal-r { from { opacity: 0; transform: translateX(22px); } }
@keyframes dcal-l { from { opacity: 0; transform: translateX(-22px); } }
.dcal-d {
  position: relative; justify-self: center; width: 38px; height: 38px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%; background: none;
  font-family: inherit; font-size: 14.5px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; cursor: pointer;
  transition: background-color .15s ease, transform .15s ease-out;
}
.dcal-d.past { color: var(--faint); font-weight: 500; }
.dcal-d.today { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--blue) 55%, transparent); font-weight: 800; color: var(--blue); }
.dcal-d:active { transform: scale(.9); }
@media (hover: hover) and (pointer: fine) {
  .dcal-d:not(.on):hover { background: color-mix(in srgb, var(--blue) 10%, transparent); }
  .dcal-nav:hover { background: color-mix(in srgb, var(--blue) 10%, var(--card)); }
}
.dcal-d.on {
  background: var(--blue); color: var(--on-accent, #fff); font-weight: 800; box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--blue) 70%, transparent);
}
.dcal-d.on.pop { animation: dcal-pop .38s cubic-bezier(.3, 1.6, .5, 1) both; }
.dcal-d.on.pop::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  animation: dcal-ring .55s ease-out both;
}
@keyframes dcal-pop { from { transform: scale(.6); } }
@keyframes dcal-ring {
  from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--blue) 45%, transparent); }
  to { box-shadow: 0 0 0 10px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  #scr-form .due-exact.dcal-open, .dcal-t.in, .dcal-grid.in-r, .dcal-grid.in-l,
  .dcal-d.on.pop, .dcal-d.on.pop::after { animation: none; }
}

/* ---- ปฏิทินเลือกวัน: ท่าตอนกด (เจ้าของ: "ทำอนิเมชันให้หน่อยตอนกด สักนิดสักหน่อยให้มันสวย") ----
   นิ้วแตะลง = วงจาง ๆ ขยายออกใต้ตัวเลข แล้วตัวเลขยุบนิดหนึ่ง
   เลือกแล้ว = วงสีเน้นไหลจากวันเดิมมาวันใหม่ (.dcal-glide · pickDueDate) ถึงแล้วมีคลื่นวงกระจายหนึ่งรอบ
   ปุ่มเดือน = ลูกศรขยับไปทางที่กด · ชื่อเดือนเลื่อนเข้าจากทิศเดียวกับตาราง */
.dcal-grid { position: relative; }
.dcal-d { z-index: 1; transition: background-color .15s ease, color .15s ease, transform .18s cubic-bezier(.3, 1.6, .5, 1); }
.dcal-d::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: color-mix(in srgb, var(--blue) 16%, transparent);
  transform: scale(.2); opacity: 0;
  transition: transform .28s cubic-bezier(.22, 1, .36, 1), opacity .2s ease;
}
.dcal-d:not(.on):active::before { transform: scale(1); opacity: 1; transition-duration: .12s, .08s; }
.dcal-d:active { transform: scale(.88); }
/* วงที่เลือกอยู่ห้ามค่อย ๆ เติมสี — ตอนวงลอยถึงที่แล้วถูกถอด พื้นของวันต้องขึ้นทันทีในเฟรมเดียวกัน ไม่งั้นกะพริบ */
.dcal-d.on { transition: color .15s ease, transform .18s cubic-bezier(.3, 1.6, .5, 1); }
.dcal-d.on.glide { background: transparent; box-shadow: none; }
.dcal-d.on.glide-ink { color: var(--ink); }
.dcal-glide {
  position: absolute; z-index: 0; width: 38px; height: 38px; border-radius: 50%; pointer-events: none;
  background: var(--blue); box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--blue) 70%, transparent);
}
.dcal-d.on.ring::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  animation: dcal-ring .55s ease-out both;
}
.dcal-nav svg { transition: transform .2s cubic-bezier(.3, 1.6, .5, 1); }
.dcal-nav:active svg { transform: translateX(3px); }
.dcal-nav.prev:active svg { transform: rotate(180deg) translateX(3px); }
.dcal-t.in-r { animation: dcal-tr .3s cubic-bezier(.22, 1, .36, 1) both; }
.dcal-t.in-l { animation: dcal-tl .3s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes dcal-tr { from { opacity: 0; transform: translateX(12px); } }
@keyframes dcal-tl { from { opacity: 0; transform: translateX(-12px); } }
@media (prefers-reduced-motion: reduce) {
  .dcal-d, .dcal-d::before, .dcal-nav svg { transition: none; }
  .dcal-d:active, .dcal-nav:active svg { transform: none; }
  .dcal-nav.prev:active svg { transform: rotate(180deg); }
  .dcal-d.on.ring::after, .dcal-t.in-r, .dcal-t.in-l { animation: none; }
}

/* ============================================================
   ปุ่มกลับ/กากบาทลอยตามจอทุกจอ (คู่กับตัวฟัง scroll ท้าย app.js)
   ------------------------------------------------------------
   เจ้าของส่งรูปกากบาทของฟอร์มเพิ่มงานที่ลอยอยู่มุมซ้ายบนตลอด: "ทำให้พวกปุ่มกากบาท ปุ่มออก ให้มันตามหน้าจอเหมือนในรูปนี้"
   จอที่ยังไม่ลอย: หัวแบบฝังในเนื้อจอ (.sh-inline — ตั้งค่า · ร้านค้า · Pro · สุ่มสกิน · เหรียญตรา · ห้อง ·
   ผลของฉัน · บริบท · สแกนตาราง · ถ่ายรูป · คนในห้อง · ตั้งค่าย่อย) ตั้ง position: static ไว้
   กับหัวจอเพื่อน (.fd-top) ที่ไม่เคย sticky — เลื่อนลงแล้วปุ่มหายไปกับเนื้อหา ต้องเลื่อนกลับขึ้นไปถึงจะออกได้
   ตอนนี้ทุกหัวติดขอบบน · เลื่อนพ้นบนสุด (.stuck) ชื่อจอจางหาย ตัวหัวโปร่งไม่รับการแตะ ยกเว้นปุ่ม
   ห้องคุย/ห้องการบ้าน/หัวข้อ (.ch-top/.hw-top/.tp-top) กับจอแชทน้องไซ อยู่กับที่ด้วยผังของมันอยู่แล้ว ไม่ต้องแตะ
   ============================================================ */
.phone .sticky-head.sh-inline { position: sticky; top: 6px; z-index: 4; }
.phone .fd-top { position: sticky; top: 6px; z-index: 4; }
.phone :is(.sticky-head, .fd-top) :is(.sh-title, .sh-sub, .fd-title) { transition: opacity .18s ease, transform .18s ease; }
.phone :is(.sticky-head, .fd-top).stuck { pointer-events: none; }
.phone :is(.sticky-head, .fd-top).stuck :is(button, a, input, select) { pointer-events: auto; }
.phone :is(.sticky-head, .fd-top).stuck :is(.sh-title, .sh-sub, .fd-title) { opacity: 0; transform: translateY(-6px); }
@media (prefers-reduced-motion: reduce) {
  .phone :is(.sticky-head, .fd-top) :is(.sh-title, .sh-sub, .fd-title) { transition: none; }
}

/* จอกว้าง (แถบเมนูซ้าย): ปุ่มออกไปนั่งในช่องว่างซ้ายของคอลัมน์ เหมือนกากบาทของฟอร์มเพิ่มงาน
   ไม่งั้นตอนลอยมันไปนั่งทับขอบการ์ดใบแรก (วัดที่ 976px: ทับไอคอนแถวแรกของจอตั้งค่า)
   ขอบขวาปุ่มห่างขอบเนื้อหา 14px · หัวปกติมี padding 20px → −36px · หัวฝัง (.sh-inline) กับหัวจอเพื่อนไม่มี → −56px
   ต้องมีช่องว่างข้างคอลัมน์อย่างน้อย ~60px (คอลัมน์ 720 + แถบซ้าย 106) — จอแคบกว่านั้นปุ่มอยู่ที่เดิม ไม่ล้นขอบจอ */
@media (min-width: 950px) {
  :root[data-nav="side"] .phone .sticky-head:not(.sh-inline):not(.fm-top) > .sh-btn { position: absolute; left: -36px; top: 12px; }
  :root[data-nav="side"] .phone .sticky-head.sh-inline > .sh-btn { position: absolute; left: -56px; top: 0; }
  :root[data-nav="side"] .phone .fd-top > .fd-back { position: absolute; left: -56px; top: 4px; }
}

/* ช่องพิมพ์ถามน้องไซชิดแถบเมนูล่าง (เจ้าของ: "ให้มันขึ้นมาหน่อย มันยังติดกัน")
   จอกว้างที่เลือกแถบล่าง (กรอบโทรศัพท์กลางจอ) — today.css เว้นล่าง 66px แต่แถบล่างสูง 58px + ระยะจากขอบ
   ขอบล่างกล่องพิมพ์จึงตรงกับขอบบนปุ่ม + พอดี (วัดที่ 976px: ห่าง 0px) · เพิ่มเป็น 86px ให้ห่าง ~20px
   เท่ากับบนมือถือ (มือถือ/แอปที่ติดตั้งแล้วใช้ 22px ของมันเหมือนเดิม — แถบอยู่นอกพื้นที่จอ) */
:root:not([data-nav="side"]) .phone #aiBody.scr-body { padding-bottom: 86px; }
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) .phone #aiBody.scr-body { padding-bottom: 22px; }
}

/* ============================================================
   แจ้งเตือนในแอปแบบ Dynamic Island ของ iPhone 15 (#appToast · showToast ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "ทำอนิเมชันแจ้งเตือนหน่อย คล้ายกับการแจ้งเตือนของ iPhone 15"
   เกิดเป็นเม็ดยาสีดำเล็ก ๆ กลางขอบบน → กางออกแบบสปริง (เด้งเกินนิดแล้วเข้าที่) เป็นแผ่นดำมุมมน
   → รูปแอปกับข้อความค่อย ๆ ชัดขึ้นจากเบลอ · ตอนหาย: ข้อความจางก่อน → หดกลับเป็นเม็ดยา → จางหาย
   กางด้วย clip-path (inset จากเม็ดยา 124×36 กลางขอบบน → เต็มกล่อง) ตัวกล่องจริงไม่ต้องเปลี่ยนขนาด
   ข้อความยาวแค่ไหนก็กางได้ถูก ไม่ต้องวัดความสูงก่อน
   สีดำ ตัวขาว ทุกธีม เหมือนเกาะของเครื่องจริง · กฎเดิมของ .toast (style.css) ยังอยู่ — id ชนะทุกบรรทัด
   ============================================================ */
#appToast.toast {
  --di-w: 124px; --di-h: 36px;
  left: 10px; right: 10px; top: calc(env(safe-area-inset-top) + 8px);
  max-width: 420px; margin-inline: auto;
  min-height: 64px; padding: 12px 14px 12px 12px; gap: 12px;
  background: #000; color: #fff;
  border: 0; border-radius: 30px; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  transform: none; opacity: 0; visibility: hidden;
  clip-path: inset(0 calc(50% - var(--di-w) / 2) calc(100% - var(--di-h)) calc(50% - var(--di-w) / 2) round calc(var(--di-h) / 2));
  transition: clip-path .42s cubic-bezier(.4, 0, .2, 1) .1s, opacity .2s ease .46s, visibility 0s .66s;
}
#appToast.toast.show {
  opacity: 1; visibility: visible;
  clip-path: inset(0 0 0 0 round 30px);
  transition: opacity .12s ease, visibility 0s, clip-path .66s cubic-bezier(.32, 1.3, .44, 1) .1s;
}
:root[data-nav="side"] #appToast.toast { left: 120px; }
#appToast > * {
  opacity: 0; filter: blur(6px); transform: scale(.92);
  transition: opacity .14s ease, filter .14s ease, transform .2s ease;
}
#appToast.show > * {
  opacity: 1; filter: none; transform: none;
  transition: opacity .3s ease .3s, filter .36s ease .3s, transform .5s cubic-bezier(.32, 1.3, .44, 1) .26s;
}
#appToast .tav { width: 40px; height: 40px; border-radius: 12px; padding: 4px; }
#appToast .tt { color: #fff; font-size: 14px; }
#appToast .tb { color: rgba(255, 255, 255, .68); font-size: 12.5px; }
#appToast .tu {
  border: 0; background: rgba(255, 255, 255, .16);
  color: color-mix(in srgb, var(--blue) 40%, #fff);
}
/* อันใหม่มาตอนเกาะกางอยู่ = เด้งรับ */
#appToast.show.bump { animation: di-bump .5s cubic-bezier(.32, 1.3, .44, 1); }
@keyframes di-bump {
  0% { transform: none; }
  30% { transform: scale(1.035, .965); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  #appToast.toast, #appToast.toast.show { clip-path: none; transition: opacity .2s ease, visibility 0s; }
  #appToast.toast:not(.show) { transition: opacity .2s ease, visibility 0s .2s; }
  #appToast > *, #appToast.show > * { filter: none; transform: none; transition: opacity .2s ease; }
  #appToast.show.bump { animation: none; }
}

/* หน้าแรกกลับมามีไทล์สองแถว (เจ้าของ: "เอาแถวล่างกลับมาด้วย") — ยังต้องพอดี 375×812
   ป้ายใต้ไทล์จองความสูงไว้สองบรรทัด (min-height 2.5em) ทั้งที่ป้ายทุกใบเป็นบรรทัดเดียว — เสียไปแถวละ ~13px
   ไม่ต้องจองแล้ว: ในกริด ไทล์แถวเดียวกันสูงเท่ากันเอง และไอคอนเริ่มที่บรรทัดเดียวกันเสมอ (ป้ายอยู่ใต้ไอคอน)
   ถ้าจอแคบจนป้ายยาวขึ้นสองบรรทัด แถวนั้นสูงขึ้นเอง ไอคอนยังตรงกัน · วัดแล้ว: ล้น 26px → 0px */
@media (max-width: 619px) { #menuBody .tg-lb2 { min-height: 0; } }

/* ใบ "ต่อเนื่อง" ในแท็บฉัน — สีไฟชุดเดียวกับช่องวันต่อเนื่องบนหน้าแรก (เจ้าของ: "เอามาเปลี่ยนในอันนี้ด้วย")
   เดิมเป็นพื้นทึบ --fire (ชมพูแดงบนธีมมืด) กับเปลวไฟเส้นสีการ์ด · ตอนนี้พื้นส้มจาง + ขอบส้มบาง
   เปลวไฟสองโทน (เส้นส้ม · แกนเหลืองอำพัน) ที่ไหวช้า ๆ จาก STAT_ART.streak · Astral Black ยังขาวดำ */
/* รอบแรกใช้พื้นส้มจาง 18% แบบหน้าแรก — เจ้าของ: "มองไม่เห็น" · บนการ์ดมืดมันจมหาย
   ขณะที่ใบข้าง ๆ (ห้อง · เหรียญ) เป็นพื้นทึบสีเต็ม · แถวนี้จึงต้องทึบเหมือนเพื่อนบ้าน:
   พื้นไล่ส้ม → ส้มเข้ม · เปลวไฟเส้นขาว · แกนเหลืองสด */
.shw-streak .shw-ic {
  background: linear-gradient(160deg, #FB923C, #EA580C);
  box-shadow: none;
  color: #fff; --ts-c2: #FDE047;
}
.shw-streak .shw-ic svg { width: 22px; height: 22px; }
:root[data-theme="astral"] .shw-streak .shw-ic { filter: grayscale(1); }

/* ============================================================
   ช่อง "ถามน้องไซ…" บนหน้าแรก — ไม่มีกรอบสี่เหลี่ยม + ตัวอักษรเคลื่อนไหว (คู่กับ .ha-mir ท้าย app.js)
   ------------------------------------------------------------
   เจ้าของ: "แก้เอาขอบออก กับทำให้มันมีอนิเมชันข้อความหน่อย"
   กรอบสี่เหลี่ยมสีเน้นคือวงโฟกัสคีย์บอร์ดของ QA #17 (ช่องพิมพ์ติด :focus-visible ทุกครั้งแม้แตะนิ้ว)
   แคปซูลทั้งอันยังบอกว่ากำลังพิมพ์อยู่ด้วยขอบสีเน้นของมันเอง (.td-ask:focus-within ใน today.css)
   ตัวอักษรจริงในช่องโปร่งใส เหลือเคอร์เซอร์ — ชั้นเงาวาดแทนทีละพยางค์ (ชัดขึ้นจากเบลอ)
   ============================================================ */
.phone #hmAsk:is(:focus, :focus-visible) { outline: none !important; }
.td-ask { position: relative; }
.ha-mir {
  position: absolute; z-index: 1; pointer-events: none; overflow: hidden;
  display: flex; align-items: center; white-space: pre; color: var(--ink);
}
.ha-line { white-space: pre; }
.ha-line span.in { animation: ha-in .34s ease-out both; }
@keyframes ha-in { from { opacity: 0; filter: blur(5px); } }
.ha-ph {
  position: absolute; left: 0; top: 0; bottom: 0; display: flex; align-items: center;
  white-space: pre; color: var(--faint); transition: opacity .24s ease, filter .24s ease;
}
.ha-ph.out { opacity: 0; filter: blur(4px); }
.ha-ph span { opacity: 0; animation: ha-ph-in .36s ease-out forwards; }
@keyframes ha-ph-in { from { opacity: 0; filter: blur(5px); } to { opacity: 1; filter: none; } }
.td-ask.ha-has .ha-ph { display: none; }
.td-ask.ha-on .tk-in { color: transparent; caret-color: var(--ink); }
.td-ask.ha-on .tk-in::placeholder { color: transparent; }
@media (prefers-reduced-motion: reduce) {
  .ha-line span.in, .ha-ph span { animation: none; opacity: 1; }
  .ha-ph { transition: none; }
}

/* จอสแกนตารางเรียนเลื่อนลงไปดูของท้ายจอไม่ได้ (เจ้าของ: "มันเลื่อนลงไม่ได้ ทำให้มันเลื่อนไปเห็นได้")
   .tt-body ตั้งเว้นล่างไว้แค่ 8px (ให้เวทีกล้องพอดีจอ) — บนจอกว้างแบบกรอบโทรศัพท์ แถบเมนูล่างลอยทับก้นจอ
   ชิปคำแนะนำ (วางให้ตรง · เห็นครบทั้งสัปดาห์ · ไฟสว่างพอ) กับบรรทัดท้ายเลยจมใต้แถบ เลื่อนได้แค่ 14px
   คืนระยะเท่าจออื่น (.scr-body) ให้เลื่อนพ้นแถบได้ · มือถือ/แอปที่ติดตั้ง แถบอยู่นอกพื้นที่จอ ใช้ 22px ของมันเหมือนเดิม */
:root:not([data-nav="side"]) .tt-body { padding-bottom: calc(100px + var(--tabgap)); }
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) .tt-body { padding-bottom: 22px; }
}

/* ============================================================
   การ์ดสัปดาห์ (แท็บงาน → สัปดาห์) — ตกแต่งใหม่ (เจ้าของ: "ลองจัดหรือตกแต่งให้สวยหน่อย")
   ------------------------------------------------------------
   • คอลัมน์วัน: ชื่อวันมีจุดสีประจำวันแบบไทย (อา แดง · จ เหลือง · อ ชมพู · พ เขียว · พฤ ส้ม · ศ ฟ้า · ส ม่วง)
     วันนี้ = แคปซูลทึบสีแบรนด์ ตัวขาว มีเงาเรือง (เดิมพื้นฟ้าจาง)
   • เส้นตั้งระหว่างวันกับงานกลายเป็นแกนเวลา: มีจุดหนึ่งจุดต่อวัน · จุดวันนี้สีเน้นมีวงเรือง
   • บรรทัดใต้งาน: ป้ายเล็กมีไอคอน — ว่าง = เขียวจาง (เวลาที่ยังใช้ได้) · เวลาเรียน/หมดเวลาว่าง = ป้ายกลาง
   • เส้นคั่นแถวจางลง ให้แกนเวลาเป็นเส้นหลักของการ์ด
   ============================================================ */
.wk-card .wk-row { border-bottom-color: color-mix(in srgb, var(--line) 55%, transparent); }
.wk-d { --dw: var(--muted); }
.wk-d.dw-0 { --dw: #EF4444; } .wk-d.dw-1 { --dw: #EAB308; } .wk-d.dw-2 { --dw: #EC4899; }
.wk-d.dw-3 { --dw: #22C55E; } .wk-d.dw-4 { --dw: #F97316; } .wk-d.dw-5 { --dw: #3B82F6; } .wk-d.dw-6 { --dw: #A855F7; }
.wk-d b { color: var(--ink); }
.wk-d i { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); }
.wk-d i::before {
  content: ''; flex: none; width: 5px; height: 5px; border-radius: 50%; background: var(--dw);
}
.wk-row.now .wk-d {
  padding: 6px 0 7px; background: var(--grad-brand, var(--fill));
  box-shadow: 0 6px 16px -8px var(--fill), inset 0 1px 0 rgba(255,255,255,.25);
}
.wk-row.now .wk-d b, .wk-row.now .wk-d i { color: var(--on-fill, #fff); }
.wk-row.now .wk-d i::before { background: currentColor; opacity: .8; }

/* แกนเวลา: จุดหนึ่งจุดบนเส้นตั้งของทุกวัน */
.wk-b { position: relative; }
.wk-b::before {
  content: ''; position: absolute; left: -4px; top: 9px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--card); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--ink) 28%, transparent);
}
.wk-row.empty .wk-b::before { top: 6px; }
.wk-row.now .wk-b::before {
  background: var(--fill); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fill) 25%, transparent);
  animation: wk-now 2.4s ease-in-out infinite;
}
@keyframes wk-now {
  50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--fill) 12%, transparent); }
}

/* ป้ายใต้งาน */
.wk-sub { display: flex; flex-wrap: wrap; gap: 5px; }
.wk-pill {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px 3px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 600; line-height: 1.4; color: var(--muted);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}
.wk-pill svg { width: 12px; height: 12px; flex: none; }
.wk-pill.free {
  color: color-mix(in srgb, var(--good) 85%, var(--ink));
  background: color-mix(in srgb, var(--good) 13%, transparent);
}
@media (prefers-reduced-motion: reduce) { .wk-row.now .wk-b::before { animation: none; } }
:root[data-theme="astral"] .wk-d i::before, :root[data-theme="astral"] .wk-pill.free { filter: grayscale(1); }

/* "ทำไมอันนี้ก่อน" บนการ์ด "ตอนนี้" — แคปซูลเล็กเหนือแถวปุ่ม (เจ้าของ: "ปรับหน่อย และเอาไปให้อยู่บนปุ่มสามปุ่ม")
   เดิมเป็นแถวเต็มกว้าง มีเส้นคั่นด้านบน อยู่ใต้ปุ่ม · ตอนนี้กว้างเท่าข้อความ พื้นสีเน้นจาง ไอคอนประกาย
   ยังเบากว่าปุ่ม "เริ่มทำเลย" หนึ่งระดับ (พื้นจาง 14% ไม่ใช่สีทึบ) — การ์ดยังมีจุดโฟกัสเดียว */
.td-now .tn-why-go {
  display: inline-flex; width: auto; gap: 5px; margin: 0 0 10px; padding: 6px 10px 6px 9px;
  border: 0; border-radius: 999px;
  background: color-mix(in srgb, var(--fill) 14%, transparent);
  color: color-mix(in srgb, var(--fill) 60%, var(--ink));
  font-size: 12.5px; font-weight: 600;
  transition: transform .15s ease, background .15s ease;
}
.td-now .tn-why-go svg { width: 14px; height: 14px; }
.td-now .tn-why-go svg:first-child { color: var(--fill); }
.td-now .tn-why-go svg:last-child { margin-left: 1px; opacity: .55; }
.td-now .tn-why-go:active { opacity: 1; transform: scale(.96); background: color-mix(in srgb, var(--fill) 22%, transparent); }

/* แผง "ทำไมอันนี้ก่อน" ในการ์ด "ตอนนี้" (เจ้าของ: "ลบดาวหน้าทำไม แล้วเอาหน้านี้ไปไว้บนสามปุ่ม")
   แคปซูลไม่มีไอคอนประกายแล้ว · ลูกศรหมุนลงตอนเปิด · แผงกาง/พับแบบลื่น (grid 0fr → 1fr) อยู่เหนือแถวปุ่ม
   เนื้อหา = สองช่องตัวเลข (ที่ต้องใช้ · เริ่มช้าสุด) + เหตุผลเป็นข้อ ๆ + ลิงก์ไปจอเทียบเต็ม */
.td-now .tn-why-go svg:last-child { transition: transform .25s cubic-bezier(.3, 1.4, .5, 1); }
.td-now .tn-why-go.open svg:last-child { transform: rotate(90deg); opacity: .8; }
.tn-why-pane {
  display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows .32s cubic-bezier(.22, 1, .36, 1), opacity .22s ease, margin .32s ease;
}
.tn-why-pane.open { grid-template-rows: 1fr; opacity: 1; margin-bottom: 10px; }
.tn-why-in { min-height: 0; overflow: hidden; }
.tn-why-pane.open .tn-why-in > * { animation: tw-in .36s cubic-bezier(.22, 1, .36, 1) both; }
.tn-why-pane.open .tn-why-in > :nth-child(2) { animation-delay: .05s; }
.tn-why-pane.open .tn-why-in > :nth-child(3) { animation-delay: .1s; }
@keyframes tw-in { from { opacity: 0; transform: translateY(-4px); } }
.tw-stats { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 8px; }
.tw-stats > div {
  padding: 9px 11px; border-radius: 14px;
  background: color-mix(in srgb, var(--fill) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 22%, transparent);
}
.tw-stats b { display: block; font-size: 16px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.tw-stats span { display: block; margin-top: 1px; font-size: 11px; color: var(--muted); }
.tw-rs { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tw-rs li { display: flex; align-items: flex-start; gap: 7px; font-size: 13px; line-height: 1.5; color: var(--ink); }
.tw-rs li svg { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--good); }
.tw-more {
  display: inline-flex; align-items: center; gap: 2px; margin-top: 8px; padding: 2px 0;
  border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer;
}
.tw-more svg { width: 13px; height: 13px; opacity: .6; }
@media (prefers-reduced-motion: reduce) {
  .tn-why-pane, .td-now .tn-why-go svg:last-child { transition: none; }
  .tn-why-pane.open .tn-why-in > * { animation: none; }
}

/* วงกลมขาวไอคอนเป้าบนการ์ด "ตอนนี้" — ไม่มีขอบดำ (เจ้าของ: "มันมีขอบดำ ๆ เอาออก")
   .tn-mark รับเงา --shadow ของธีม ซึ่งธีมมืดเป็นเงาดำหนัก (0 2px 8px ดำ 50% + 0 18px 40px ดำ 85%)
   บนหัวการ์ดสีสด เงานั้นอ่านเป็นวงแหวนดำรอบวงกลม · ไม่ต้องมีเงา วงกลมขาวบนสีสดชัดอยู่แล้ว */
.td-now .tn-mark { box-shadow: none; }

/* ============================================================
   ตารางวันนี้ (scr-dayfull) — อ่านง่ายขึ้น สีชัดขึ้น (คู่กับ renderDayFull ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "ปรับหน่อย มันดูไม่สวยเลย สีไม่ค่อยชัด แต่ต้องทำให้มันดูง่าย"
   หนึ่งแถว = เวลา (ตัวหนา) ซ้าย + การ์ดเล็กขวา · การ์ดอมสีของชนิด 12% ขอบซ้ายสีเต็ม 3px
   ป้ายชนิดเป็นคำ + ไอคอน — สีช่วยกวาด แต่การอ่านไม่พึ่งสี
   งาน = สีเน้นของธีม · เรียน = ฟ้า · กิจกรรม = ส้ม · กิจวัตร/พัก = เทา
   ============================================================ */
.df-list { gap: 8px; background: none; border-radius: 0; overflow: visible; }
.df-r { align-items: stretch; gap: 10px; padding: 0; color: inherit; }
.df-r + .df-r { border-top: 0; }
button.df-r:active { background: none; }
button.df-r:active .df-x { transform: scale(.985); }
.df-r.work { --k: var(--fill); }
.df-r.class { --k: #3B82F6; }
.df-r.ev { --k: #F97316; }
.df-r.rt { --k: var(--muted); }
.df-r.brk { --k: var(--faint); }
.df-t {
  width: 46px; display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-start;
  padding-top: 10px; font-family: inherit; font-variant-numeric: tabular-nums;
}
.df-t b { font-size: 15px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); }
.df-t i { font-style: normal; margin-top: 1px; font-size: 11px; color: var(--faint); }
.df-x {
  padding: 9px 12px 10px 14px; border-radius: 16px;
  background: color-mix(in srgb, var(--k) 12%, var(--card));
  box-shadow: inset 3px 0 0 var(--k), inset 0 0 0 1px color-mix(in srgb, var(--k) 22%, transparent);
  transition: transform .15s ease;
}
.df-k {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 700; color: color-mix(in srgb, var(--k) 70%, var(--ink));
}
.df-k svg { width: 12px; height: 12px; flex: none; }
.df-x b { margin-top: 2px; font-size: 15px; font-weight: 700; }
.df-x i { margin-top: 1px; font-size: 12px; }
.df-r.past { opacity: .45; }
.df-r.live .df-x {
  box-shadow: inset 3px 0 0 var(--k), 0 0 0 2px color-mix(in srgb, var(--k) 55%, transparent),
    0 10px 22px -12px var(--k);
}
/* เส้น "ตอนนี้" */
.df-now { display: flex; align-items: center; gap: 8px; margin: 2px 0; }
.df-now span {
  flex: none; padding: 2px 8px; border-radius: 999px;
  background: var(--alert); color: #fff; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.df-now i { flex: 1; height: 2px; border-radius: 2px; background: color-mix(in srgb, var(--alert) 70%, transparent); }
:root[data-theme="astral"] .df-r { filter: grayscale(1); }

/* เส้น "ตอนนี้" สีเข้มขึ้น (เจ้าของ: "ให้สีเข้มกว่านี้") — --alert บนธีมมืดเป็นชมพูอ่อน (ตั้งใจให้ตัวหนังสือแดงอ่านได้บนพื้นมืด)
   แต่ที่นี่เป็นพื้นป้าย/เส้น ไม่ใช่ตัวหนังสือ จึงใช้แดงเข้มตายตัวทุกธีม ตัวหนังสือขาว · เส้นทึบเต็ม ไม่โปร่ง */
.df-now span { background: #DC2626; box-shadow: 0 4px 12px -4px rgba(220, 38, 38, .6); }
.df-now i { background: #DC2626; }
:root[data-theme="astral"] .df-now span, :root[data-theme="astral"] .df-now i { background: #FFFFFF; color: #000; box-shadow: none; }

/* ============================================================
   ปุ่มกรองจอแจ้งเตือน (ทั้งหมด · ข้อความ · งาน) แบบ GradientButtonGroup (cult-ui · MIT)
   ------------------------------------------------------------
   เจ้าของส่งโค้ด GradientButtonGroup มา: "เอามาใช้ในหน้านี้"
   ชั้นจากล่างขึ้นบน: ถาดยุบลง (.gbg-tray) → แผงนูน (.gbg) → ตัวบอกปุ่มที่เลือก (.gbg-ind):
   หลุมจม → วงแหวนไล่สีหมุน (สีจากธีม · ต้นฉบับเป็นเขียวมิ้นต์ตายตัว) → ร่องมืดบาง ๆ → ป้ายปุ่มอยู่บนสุด
   ปุ่มกว้างเท่ากัน 84px ตัวบอกจึงเลื่อนด้วย translateX(--i × (84 + 6)) ได้ตรง ไม่ต้องวัด
   ============================================================ */
/* .nt-chips (inbox.css) โหลดทีหลัง alt.css และตั้ง display:flex ไว้ — ต้องจำเพาะกว่า ไม่งั้นถาดยืดเต็มจอ */
.nt-chips.gbg-tray {
  display: inline-flex; margin: 6px 0 4px; padding: 4px; border-radius: 22px;
  background: color-mix(in srgb, var(--ink) 7%, var(--scr));
  box-shadow: inset 0 2px 8px rgba(0,0,0,.35), inset 0 1px 2px rgba(0,0,0,.25), 0 1px 0 rgba(255,255,255,.05);
}
.gbg {
  --bw: 84px; --gp: 6px;
  position: relative; display: grid; grid-template-columns: repeat(3, var(--bw)); gap: var(--gp);
  padding: 5px; border-radius: 18px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--card) 88%, #fff) 0%, var(--card) 55%, color-mix(in srgb, var(--card) 92%, #000) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 2px rgba(0,0,0,.18);
}
.gbg-b {
  position: relative; z-index: 2; height: 40px; padding: 0; border: 0; border-radius: 14px; background: none;
  font: inherit; font-size: 13.5px; font-weight: 700; color: var(--muted); cursor: pointer;
  transition: color .25s ease, transform .15s ease;
}
.gbg-b.on { color: var(--ink); }
.gbg-b:active { transform: scale(.96); }
@media (hover: hover) and (pointer: fine) { .gbg-b:not(.on):hover { color: var(--ink); } }
.gbg-ind {
  position: absolute; z-index: 1; left: 5px; top: 5px; width: var(--bw); height: 40px; border-radius: 14px;
  transform: translateX(calc(var(--i, 0) * (var(--bw) + var(--gp))));
  transition: transform .5s cubic-bezier(.3, 1.3, .5, 1);
  background: color-mix(in srgb, var(--ink) 5%, var(--scr));
  box-shadow: inset 0 2px 6px rgba(0,0,0,.55), inset 0 0 4px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.06);
}
.gbg.gbg-hold .gbg-ind { transition: none; }
.gbg-ring { position: absolute; inset: 3px; overflow: hidden; border-radius: 11px; }
.gbg-ring::before {
  content: ''; position: absolute; inset: -60%;
  background: conic-gradient(from 220deg, var(--fill) 0%, color-mix(in srgb, var(--fill) 45%, #fff) 18%,
    color-mix(in srgb, var(--fill) 55%, var(--halo-3)) 36%, var(--fill) 52%, color-mix(in srgb, var(--fill) 55%, var(--halo-2)) 70%,
    color-mix(in srgb, var(--fill) 40%, #fff) 86%, var(--fill) 100%);
  animation: gbg-spin 3.2s linear infinite;
}
@keyframes gbg-spin { to { transform: rotate(360deg); } }
.gbg-gap {
  position: absolute; inset: 6px; border-radius: 9px;
  background: var(--card);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.6), inset 0 0 2px rgba(0,0,0,.35);
}
@media (prefers-reduced-motion: reduce) {
  .gbg-ind { transition: none; }
  .gbg-ring::before { animation: none; }
}
:root[data-theme="astral"] .gbg-ring { filter: grayscale(1); }

/* แผงกว้างเต็มแถว — ถาดถูกยืดเต็มความกว้างอยู่แล้ว (คอลัมน์ flex ของจอ) ปุ่มกว้างตายตัวเลยทิ้งที่ว่างด้านขวา
   ปุ่มแบ่งความกว้างเท่ากันสามช่อง · ตัวบอกกว้างหนึ่งช่อง เลื่อนทีละ (ความกว้างตัวเอง + ช่องไฟ) */
.nt-chips.gbg-tray { display: flex; }
.gbg { flex: 1; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gbg-ind {
  width: calc((100% - 10px - 2 * var(--gp)) / 3);
  transform: translateX(calc(var(--i, 0) * (100% + var(--gp))));
}

/* กล่องไอคอนในจอแจ้งเตือน (.nt-av.src) — รูปไม่อยู่กลางกล่อง และกล่องลอยสูงกว่ากลางแถว (เจ้าของ: "ปรับให้รูปมันตรง")
   คลาส .src ชนกับการ์ดแหล่งข้อมูลใน inbox.css (.src { padding: 14px; margin-bottom: 9px }) —
   padding ดันไอคอน 21px ไปมุมล่างขวาของกล่อง 44px (ซ้าย/บน 15 · ขวา/ล่าง 8) ส่วน margin ยกกล่องขึ้น ~5px
   ล้างสองค่านั้นเฉพาะกล่องไอคอน — การ์ดแหล่งข้อมูลจริงยังได้ค่าเดิม */
.nt-av.src { padding: 0; margin: 0; }

/* ============================================================
   ปุ่มตัวเลือกในหน้าตั้งค่าย่อย (แถบเมนู · ขนาดตัวอักษร · วิดเจ็ตหน้าแรก) แบบ NeumorphButton (cult-ui · MIT)
   ------------------------------------------------------------
   เจ้าของส่ง NeumorphButton มา: "ใช้กับพวกอันนี้"
   ปุ่มทึบ มีขอบล่างเข้มเป็นสันนูน (inset −2px) + เงาฟุ้งใต้ปุ่ม · อันที่เลือก = แบบ "primary" สีเน้นของธีม
   เงาเรืองสีเดียวกัน · กด = สันบางลง เงาสั้นลง ยุบ .98 · ชี้เมาส์ = นูนขึ้น 1.02 (สปริง)
   อันที่ยังไม่เลือก = แบบ "default" พื้นทึบจากสีการ์ด — ไม่ใช่กรอบเส้นบาง ๆ แบบเดิม
   ============================================================ */
.fs-grid button {
  border: 0; border-radius: 12px; color: var(--muted);
  background: color-mix(in srgb, var(--ink) 8%, var(--card2));
  box-shadow: inset 0 -2px 0 0 color-mix(in srgb, var(--ink) 18%, rgba(0,0,0,.35)), 0 1.2px 6px 0 rgba(0,0,0,.28);
  transition: box-shadow .2s ease, background-color .2s ease, color .2s ease, transform .3s cubic-bezier(.3, 1.6, .5, 1);
}
.fs-grid button.active {
  border: 0; color: var(--on-fill, #fff); background: var(--fill);
  box-shadow: inset 0 -2.1px 0 0 color-mix(in srgb, var(--fill) 55%, #000),
    0 1.2px 6.3px 0 color-mix(in srgb, var(--fill) 58%, transparent);
}
.fs-grid button:active {
  transform: scale(.98); transition: none;
  box-shadow: inset 0 -1.5px 0 0 color-mix(in srgb, var(--ink) 18%, rgba(0,0,0,.4)), 0 .5px 2px 0 rgba(0,0,0,.35);
}
.fs-grid button.active:active {
  background: color-mix(in srgb, var(--fill) 86%, #000);
  box-shadow: inset 0 -1.5px 0 0 color-mix(in srgb, var(--fill) 45%, #000), 0 .5px 2px 0 color-mix(in srgb, var(--fill) 70%, transparent);
}
@media (hover: hover) and (pointer: fine) {
  .fs-grid button:not(:active):hover { transform: scale(1.02); }
  .fs-grid button:not(.active):not(:active):hover { background: color-mix(in srgb, var(--ink) 12%, var(--card2)); color: var(--ink); }
}
@media (prefers-reduced-motion: reduce) { .fs-grid button { transition: none; } .fs-grid button:hover, .fs-grid button:active { transform: none; } }

/* ============================================================
   หน้าตั้งค่า · แถว "ผู้ช่วย AI" กับ "ใส่โค้ด" (เจ้าของ: "ปรับหน่อย มันไม่สวยเลย แต่ทำให้ดูง่าย")
   ------------------------------------------------------------
   ผู้ช่วย AI: หัวแถวกว้างเต็ม (คำอธิบายบรรทัดเดียว) · สองปุ่มเท่ากันแถวล่าง มีไอคอน ป้ายบอกครบ
   ปุ่มหน้าตาชุดเดียวกับปุ่มตัวเลือกในหน้าตั้งค่าย่อย (พื้นทึบ สันล่าง) · ล้างประวัติ = ตัวอักษรสีเตือน
   ใส่โค้ด: ช่องพิมพ์กับปุ่ม "ใช้" สูงเท่ากัน มุมเท่ากัน ตัวพิมพ์ปกติแทนตัวพิมพ์ดีด
   ============================================================ */
.set-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.set-btns button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 42px; padding: 0 10px; border: 0; border-radius: 12px;
  background: color-mix(in srgb, var(--ink) 8%, var(--card2)); color: var(--ink);
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  box-shadow: inset 0 -2px 0 0 color-mix(in srgb, var(--ink) 18%, rgba(0,0,0,.35)), 0 1.2px 6px 0 rgba(0,0,0,.22);
  transition: transform .2s cubic-bezier(.3, 1.6, .5, 1), background-color .2s ease;
}
.set-btns button svg { width: 15px; height: 15px; flex: none; color: var(--fill); }
.set-btns button.warn { color: var(--alert); }
.set-btns button.warn svg { color: currentColor; }
.set-btns button:active { transform: scale(.97); box-shadow: inset 0 -1px 0 0 rgba(0,0,0,.35), 0 .5px 2px 0 rgba(0,0,0,.3); }
.set-row .code-tools input[type=text] {
  min-height: 42px; border-radius: 999px; padding: 0 16px; font-family: inherit; letter-spacing: .01em;
}
/* ปุ่ม "ใช้" เป็นแคปซูลตามกฎปุ่มหลักทั้งแอป (:root .btn.primary { border-radius: 999px !important })
   ช่องพิมพ์จึงเป็นแคปซูลตามปุ่ม แทนการไปฝืนกฎนั้น */
.code-tools .btn { min-height: 42px; padding: 0 20px; }

/* แท็บ "ฉัน" — ค่าชิดขวาของแต่ละแถว (ยังไม่ได้เลือก · ไม่มีข้อความใหม่ · รู้จัก 0% · เร็ว ๆ นี้ …) ชัดขึ้น
   เจ้าของ: "ปรับให้ชัดหน่อย" — ตัวอักษรขาว 80% บนพื้นการ์ดมืดยังอ่านเป็นของจาง
   ตอนนี้เป็นแคปซูลเล็ก: ตัวอักษรเต็มความเข้ม พื้นจางสีหมึก 8% · ลูกศรท้ายแถวเข้มขึ้นจาก --faint
   แถวเช็คอินรายวัน (.pe-daily) มีหน้าตาของตัวเอง ไม่แตะ */
.phone .pe:not(.pe-daily) .pe-v:not(:empty) {
  padding: 3px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  color: var(--ink); font-size: 12.5px; font-weight: 700; font-style: normal;
}
.phone .pe .pe-go { color: color-mix(in srgb, var(--ink) 55%, transparent); }

/* ============================================================
   กราฟ "งานที่ติ๊กเสร็จ 7 วันล่าสุด" (แท็บฉัน) — จัดให้ตรงและสวยขึ้น (เจ้าของ: "จัดหน่อย มีอันไม่ตรง และทำให้สวยขึ้นหน่อย")
   เดิม: ความสูงแท่งเป็น % ของทั้งคอลัมน์ (ซึ่งรวมตัวเลข + ชื่อวันด้วย) และตัวเลขอยู่ "ใต้" แท่ง
   ตัวเลขกับฐานแท่งจึงลอยคนละระดับทุกคอลัมน์ · ตอนนี้: ตัวเลขบนแท่ง → รางสูงคงที่ 70px → ชื่อวัน
   ทุกแท่งตั้งบนเส้นฐานเดียวกัน · รางว่างเป็นแถบจางเต็มความสูง (เห็นว่ามีเจ็ดช่อง) · วันนี้ไล่สีแบรนด์ + เรือง
   ============================================================ */
.st-card .st-bars { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; height: auto; align-items: end; margin-top: 4px; }
.st-card .st-bar { display: flex; flex-direction: column; align-items: center; gap: 5px; height: auto; min-width: 0; }
.st-bar .n { order: 0; min-height: 14px; font-size: 11px; font-weight: 700; color: var(--ink); line-height: 14px; }
.st-bar .trk {
  order: 1; position: relative; display: flex; align-items: flex-end; width: 100%; max-width: 30px; height: 70px;
  border-radius: 9px; background: color-mix(in srgb, var(--ink) 6%, transparent); overflow: hidden;
}
.st-card .st-bar .bar {
  width: 100%; min-height: 0; border-radius: 9px; margin: 0;
  background: color-mix(in srgb, var(--fill) 70%, transparent);
  transition: height .5s cubic-bezier(.22, 1, .36, 1);
}
.st-card .st-bar.now .bar { background: var(--grad-brand, var(--fill)); box-shadow: 0 0 14px -2px color-mix(in srgb, var(--fill) 70%, transparent); }
.st-card .st-bar .d { order: 2; font-size: 11px; color: var(--faint); line-height: 1.2; }
.st-card .st-bar.now .d { color: var(--fill); font-weight: 800; }

/* ปุ่มคัดลอกใต้คำตอบน้องไซ — แบบ CopyButton ของ animate-ui (เจ้าของส่งโค้ดมา)
   ไอคอนคัดลอกกับเครื่องหมายถูกซ้อนกัน · .ok = คัดลอกหมุนย่อหาย ถูกเด้งขึ้นสีเขียว · ครบ 1.5 วินาทีสลับกลับ */
.am-act .cpb { position: relative; }
.cpb > span { position: absolute; inset: 0; display: grid; place-items: center;
  transition: transform .35s cubic-bezier(.3, 1.5, .5, 1), opacity .2s ease; }
.cpb .cpb-b { opacity: 0; transform: scale(.4) rotate(-45deg); color: var(--good); }
.cpb.ok .cpb-a { opacity: 0; transform: scale(.4) rotate(45deg); }
.cpb.ok .cpb-b { opacity: 1; transform: none; }
.cpb.ok { background: color-mix(in srgb, var(--good) 14%, transparent); }
@media (prefers-reduced-motion: reduce) { .cpb > span { transition: opacity .15s ease; } }

/* ปุ่มคัดลอกโดนตัดขอบซ้าย (เจ้าของส่งรูปเครื่องหมายถูกที่พื้นเขียวเหลือครึ่งเดียว: "แก้ด้วย")
   แถวปุ่มใต้คำตอบดึงซ้าย −8px ให้ไอคอนตรงแนวตัวหนังสือ — ตอนปุ่มไม่มีพื้นก็ไม่มีใครเห็น
   แต่กล่องแชทตัดของที่ล้นขอบซ้าย พอปุ่มมีพื้น (สถานะคัดลอกแล้ว) พื้นเลยโดนตัดครึ่ง · เลิกดึงซ้าย */
#aiBody .am-act { margin-left: 0; }

/* ============================================================
   จอแผนราคา — อนิเมชันตอนสลับสองราคา (คู่กับ proSelect ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "ทำอนิเมชั่นตอนเลื่อนไประหว่างสองราคาให้หน่อย … ทำให้ดูมินิมอลนะ"
   • กรอบเลือกเป็นชิ้นเดียว (.pro-ind) วางทับการ์ด เลื่อนไปหาใบใหม่ — มีแต่เส้นขอบ ไม่มีพื้น
     (พื้นอมสีของใบที่เลือกยังเป็นของการ์ดเอง แค่ค่อย ๆ จางเข้าออก) จึงไม่บังตัวหนังสือ
   • ใบที่เลือกไม่หนาขอบ/ไม่เปลี่ยน padding แล้ว — ตัวหนังสือไม่ขยับตอนสลับ
   • รายการของแผน: ข้อใหม่ไล่ขึ้นทีละข้อ (ห่างกัน 40ms) จากฝั่งที่เลื่อนไป · ความสูงยืด/หดลื่น
   ============================================================ */
.pro-grid { position: relative; }
.pro-card, .pro-card.on { border: 1px solid var(--line); padding: 12px 13px; }
.pro-card { transition: background .3s ease, transform .15s ease; }
.pro-card:active { transform: scale(.98); }
.pro-name { transition: background .3s ease, color .3s ease; }
.pro-ind {
  position: absolute; z-index: 2; top: 0; left: 0; bottom: 0; pointer-events: none;
  width: calc((100% - 9px) / 2); border-radius: 14px;
  box-shadow: inset 0 0 0 2px var(--blue);
  transform: translateX(calc(var(--i, 0) * (100% + 9px)));
  transition: transform .42s cubic-bezier(.32, .72, 0, 1);
}
.pro-feats { overflow: hidden; transition: height .34s cubic-bezier(.32, .72, 0, 1); }
.pro-feats.swap .pro-f { animation: pro-f-in .34s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--k, 0) * 40ms); }
.pro-feats[data-dir="l"] { --dx: -10px; }
.pro-feats[data-dir="r"] { --dx: 10px; }
@keyframes pro-f-in { from { opacity: 0; transform: translateX(var(--dx, 0)); } }
@media (prefers-reduced-motion: reduce) {
  .pro-ind, .pro-feats { transition: none; }
  .pro-feats.swap .pro-f { animation: none; }
}

/* แจ้งเตือนแบบเกาะ: ปัดขึ้นเพื่อปิด (คู่กับ toastSwipe ใน app.js)
   touch-action: none = นิ้วที่ลากบนการ์ดไม่ไปเลื่อนจอข้างใต้ · ไม่ให้เลือกข้อความตอนลาก */
#appToast.toast { touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; }
#appToast.toast:active { cursor: grabbing; }

/* กราฟแท่ง 7 วัน — แท่งงอกขึ้นจากฐานตอนเพิ่งเข้าจอ (คู่กับ growBars ใน app.js)
   เจ้าของ: "เมื่อสลับมาหน้านี้ ให้มีอนิเมชั่นของแท่งเทียนหน่อย"
   ยืดจากฐาน (scaleY 0 → 1) ทีละวันห่างกัน 55ms · ตัวเลขบนแท่งจางขึ้นตามหลังแท่งของมันนิดหนึ่ง
   ใช้ transform ไม่ใช่ height — ไม่ดันเลย์เอาต์ และไม่ชนกับ transition ของ height ที่มีอยู่ */
.st-bars.grow .bar { transform-origin: 50% 100%; animation: st-grow .7s cubic-bezier(.22, 1, .36, 1) both; }
.st-bars.grow .n { animation: st-n-in .35s ease both; }
.st-bars.grow .st-bar:nth-child(1) { --sd: 0ms; }
.st-bars.grow .st-bar:nth-child(2) { --sd: 55ms; }
.st-bars.grow .st-bar:nth-child(3) { --sd: 110ms; }
.st-bars.grow .st-bar:nth-child(4) { --sd: 165ms; }
.st-bars.grow .st-bar:nth-child(5) { --sd: 220ms; }
.st-bars.grow .st-bar:nth-child(6) { --sd: 275ms; }
.st-bars.grow .st-bar:nth-child(7) { --sd: 330ms; }
.st-bars.grow .st-bar .bar { animation-delay: calc(var(--sd, 0ms) + 120ms); }
.st-bars.grow .st-bar .n { animation-delay: calc(var(--sd, 0ms) + 420ms); }
@keyframes st-grow { from { transform: scaleY(0); } }
@keyframes st-n-in { from { opacity: 0; transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .st-bars.grow .bar, .st-bars.grow .n { animation: none; } }

/* ============================================================
   ช่อง "ถามน้องไซ…" บนหน้าแรก — แบบเรียบหรู (คู่กับ askBar + .ha-mir ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "ให้มันดูชิค ๆ กว่านี้" — เดิมตัวอย่างคำถามโผล่ทีละตัวจากเบลอ ตัวท้าย ๆ ยังมัวอยู่ตอนอ่าน ดูเลอะ
   • ตัวอย่างคำถาม: แต่ละพยางค์ลอยขึ้นจากล่างเร็ว ๆ แบบคม ไม่เบลอ · อันเก่าเลื่อนขึ้นจางหาย (เหมือนป้ายหมุน)
   • (เคอร์เซอร์ปลอมกะพริบท้ายตัวอย่างคำถามถูกถอดออกแล้ว — เจ้าของ: "ลบตรงขีดด้านหลังออก")
   • ตัวที่พิมพ์เอง: จางเข้าเร็ว ๆ ไม่เบลอ
   • แคปซูล: เส้นขอบบางมีไฮไลต์ด้านบน พื้นกระจก · ปุ่มส่งเป็นวงกลมทึบสีหมึก ลูกศรขึ้นเส้นบาง
     พิมพ์แล้วปุ่มเปลี่ยนเป็นสีเน้นของธีม (ยังเบากว่าการ์ด "ตอนนี้" ตอนยังไม่ได้แตะ)
   กฎกระจกของปุ่มกลม (:root :is(… .tk-go …) !important) มี .ig-btns button:not(.pri) อยู่ในรายการ ทำให้หนัก 0,3,1
   ต้องหนักกว่า จึงเขียน :root .td-ask .tk-go.tk-go (0,4,0)
   ============================================================ */
.td-ask {
  min-height: 48px; padding: 5px 5px 5px 16px;
  border: 1px solid color-mix(in srgb, var(--ink) 9%, transparent);
  background: color-mix(in srgb, var(--card) 72%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 6px 20px -14px rgba(0,0,0,.35);
  -webkit-backdrop-filter: blur(16px) saturate(160%); backdrop-filter: blur(16px) saturate(160%);
  transition: border-color .25s ease, box-shadow .25s ease, background .25s ease;
}
.td-ask:focus-within {
  border-color: color-mix(in srgb, var(--fill) 45%, transparent);
  background: var(--card);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 0 0 4px color-mix(in srgb, var(--fill) 10%, transparent),
    0 10px 24px -14px color-mix(in srgb, var(--fill) 60%, transparent);
}
.td-ask .tk-in { font-size: 14px; letter-spacing: -.005em; }

/* ตัวอย่างคำถาม: ป้ายหมุน */
.ha-ph { color: color-mix(in srgb, var(--ink) 42%, transparent); transition: opacity .22s ease, transform .26s cubic-bezier(.4, 0, .2, 1); }
.ha-ph.out { opacity: 0; filter: none; transform: translateY(-7px); }
.ha-ph span { display: inline-block; white-space: pre; animation-name: ha-rise; animation-duration: .42s; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
@keyframes ha-rise { from { opacity: 0; transform: translateY(.55em); } to { opacity: 1; transform: none; } }
.ha-line span.in { animation: ha-fade .22s ease-out both; }
@keyframes ha-fade { from { opacity: 0; } }

/* ปุ่มส่ง */
:root .td-ask .tk-go.tk-go {
  width: 38px; height: 38px; border: 0 !important; border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 88%, transparent) !important; background-image: none !important;
  color: var(--scr, #fff) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 4px 10px -4px rgba(0,0,0,.35) !important;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  transition: background-color .25s ease, transform .42s cubic-bezier(.3, 1.6, .5, 1) !important;
}
:root .td-ask .tk-go.tk-go .ha-up { width: 17px; height: 17px; transform: none; transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); }
:root .td-ask:is(:focus-within, .ha-has) .tk-go.tk-go { background: var(--fill) !important; color: var(--on-fill) !important; }
:root .td-ask.ha-has .tk-go.tk-go .ha-up { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) {
  .ha-ph span, .ha-line span.in { animation: none; opacity: 1; }
}

/* การ์ด "ทำก่อน" บนจอ "ทำไมอันนี้ก่อน" — พื้นแบบเดียวกับหัวการ์ด "ตอนนี้" บนหน้าแรก
   เจ้าของ: "เอาให้หน้าของรูปที่สองใช้สีพื้นหลังเหมือนหน้าในรูปหนึ่ง"
   ไล่สี 140° (สว่างมุมซ้ายบน → สีเน้น → เข้มมุมขวาล่าง) + วงกลมขาวจางสองวงซ้อนหลัง — ค่าเดียวกับ .td-now .tn-head (today.css)
   เป็นงานชิ้นเดียวกันที่เพิ่งแตะมาจากการ์ดนั้น หน้าตาต้องต่อกัน */
.wy2-hero {
  position: relative; overflow: hidden;
  background: linear-gradient(140deg,
    color-mix(in srgb, var(--fill) 78%, #fff) 0%,
    var(--fill) 55%,
    color-mix(in srgb, var(--fill) 78%, #000) 100%);
}
.wy2-hero::after {
  content: ''; position: absolute; right: -44px; top: -54px;
  width: 168px; height: 168px; border-radius: 50%;
  background: rgba(255, 255, 255, .11); pointer-events: none;
}
.wy2-hero::before {
  content: ''; position: absolute; right: 18px; bottom: -66px;
  width: 124px; height: 124px; border-radius: 50%;
  background: rgba(255, 255, 255, .07); pointer-events: none;
}
.wy2-hero > * { position: relative; z-index: 2; }

/* จอ "ทำไมอันนี้ก่อน" — ตัวหนังสือจางให้ชัดขึ้น (เจ้าของ: "ทำให้ข้อความที่ดูจาง ๆ ชัดขึ้น")
   หัวการ์ด (เหตุผล · ลำดับทั้งหมด) · เหตุผลสั้นท้ายแถวลำดับ · บรรทัดท้ายการ์ด · เลขลำดับที่ไม่ใช่อันดับหนึ่ง
   เดิมเป็น --faint ซึ่งบนพื้นการ์ดสีอ่อนของธีมสว่างจางเกินอ่าน → ผสม --ink ให้เข้มขึ้น ยังเบากว่าชื่องานหนึ่งระดับ */
/* รอบสอง (เจ้าของส่งรูปเดิมมาอีกครั้ง: ยังจางอยู่) — 62% ยังไม่พอบนพื้นการ์ดกระจก → 85% + หนาขึ้น
   เลขลำดับที่ไม่ใช่อันดับหนึ่งได้พื้นอมสีเน้นเข้มขึ้นด้วย เดิมพื้นชมพูจางจนเลขลอย */
.wy2-cap { color: color-mix(in srgb, var(--ink) 85%, transparent); font-weight: 800; }
.wy2-line i { color: color-mix(in srgb, var(--ink) 85%, transparent); font-weight: 600; }
.wy2-more { color: color-mix(in srgb, var(--ink) 80%, transparent); }
.wy2-row:not(.top) .wy2-n {
  color: color-mix(in srgb, var(--fill) 75%, var(--ink));
  background: color-mix(in srgb, var(--fill) 18%, var(--card));
}

/* ============================================================
   ที่เก็บงานที่ทำเสร็จ (แท็บงาน → เสร็จแล้ว) — ติ๊กสีสด + อนิเมชันตอนกด (คู่กับ doneView · toggleDone)
   ------------------------------------------------------------
   เจ้าของ: "ทำให้เครื่องหมายถูกสีดูสดขึ้น … และให้มีอนิเมชันเมื่อกดตรงแต่ละงานที่เสร็จแล้วด้วย"
   • ติ๊ก: วงกลมเขียวสดทึบ (ไล่สีบนลงล่าง) ติ๊กขาวเส้นหนา มีเงาเขียวเรือง — เดิมพื้นเขียวจาง ๆ ติ๊กเขียวเข้ม
     แล้วทั้งการ์ดจาง 60% ซ้ำอีกชั้น ติ๊กจึงซีด · ตอนนี้ความจางย้ายไปอยู่ที่ตัวหนังสือแทน ติ๊กสดเต็มที่
     เขียวคงที่ทุกธีม (ไม่ใช่ --good ซึ่งบางธีมเป็นเขียวหม่น) · Astral Black ขาวดำ
   • กดการ์ด: การ์ดยุบลงนิด ติ๊กเด้งขยาย มีวงแหวนเขียวแผ่ออก · ชี้เมาส์ = การ์ดลอยขึ้นนิดหนึ่ง
   • กดติ๊ก (เอากลับเป็นงานค้าง): ติ๊กหมุนหดหาย การ์ดจางและเลื่อนออกทางขวาแล้วยุบ (.undo)
   ============================================================ */
.tk-done { opacity: 1; transition: transform .35s cubic-bezier(.3, 1.4, .5, 1), box-shadow .25s ease; }
.tk-done .tk-bd, .tk-done .tk-got { opacity: .7; }
.tk-done .tk-ttl { color: var(--ink); }
.tk-done .tk-tick.on {
  position: relative; inset: auto; width: 26px; height: 26px; border: 0;   /* inset: auto — ล้าง top/right ของ .tk-tick ตัวหลัก */
  background: linear-gradient(180deg, #34D399, #10B981 55%, #059669);
  box-shadow: 0 3px 10px -3px rgba(16, 185, 129, .7), inset 0 1px 0 rgba(255, 255, 255, .45);
  transition: transform .4s cubic-bezier(.3, 1.6, .5, 1), opacity .2s ease;
}
.tk-done .tk-tick.on svg { width: 14px; height: 14px; color: #fff; stroke-width: 3; }
.tk-done .tk-tick.on::after {
  content: ''; position: absolute; inset: -2px; border-radius: 50%; pointer-events: none;
  box-shadow: 0 0 0 0 rgba(16, 185, 129, .55); opacity: 0;
}
/* กดการ์ด */
.tk-done:active { transform: scale(.975); transition-duration: .12s; }
.tk-done:active .tk-tick.on { transform: scale(1.18); }
.tk-done:active .tk-tick.on::after { animation: tk-ring .55s ease-out; }
@keyframes tk-ring {
  0% { opacity: 1; box-shadow: 0 0 0 0 rgba(16, 185, 129, .55); }
  100% { opacity: 0; box-shadow: 0 0 0 12px rgba(16, 185, 129, 0); }
}
.tk-done .tk-go { transition: transform .3s cubic-bezier(.3, 1.4, .5, 1); }
@media (hover: hover) and (pointer: fine) {
  .tk-done:hover { transform: translateY(-2px); }
  .tk-done:hover .tk-go { transform: translateX(3px); }
}
/* กดติ๊ก = เอากลับเป็นงานค้าง */
.tk-done.undo { animation: tk-undo .3s cubic-bezier(.4, 0, .2, 1) forwards; pointer-events: none; }
.tk-done.undo .tk-tick.on { transform: scale(0) rotate(-90deg); opacity: 0; }
@keyframes tk-undo {
  40% { opacity: 1; }
  100% { opacity: 0; transform: translateX(40px); }
}
:root[data-theme="astral"] .tk-done .tk-tick.on { filter: grayscale(1); }
@media (prefers-reduced-motion: reduce) {
  .tk-done, .tk-done .tk-tick.on, .tk-done .tk-go { transition: none; }
  .tk-done:active .tk-tick.on::after { animation: none; }
}

/* ============================================================
   ผลของฉัน ฉบับเต็ม (scr-stats · #statFull) — มีสีสันขึ้นแต่ยังเรียบ + อนิเมชันตอนเข้าจอ
   ------------------------------------------------------------
   เจ้าของ: "ทำให้มันดูสวยและมีสีสันขึ้นกว่านี้หน่อย แต่ให้ดูง่ายและมินิมอล ทำอนิเมชันตอนกดเข้ามาให้ด้วย"
   • ไทล์บนสุด: ไทล์ละหนึ่งสี — ไอคอนอยู่ในวงกลมทึบสีนั้น ตัวเลขสีเดียวกัน พื้นอมสีจาง ๆ ไม่มีกรอบ
       ต่อเนื่อง = ทอง (ของที่ทำสำเร็จแล้ว ตามกฎทอง) · ส่งทัน = เขียว · ดีขึ้นจากสัปดาห์ก่อน = สีเน้นของธีม · แย่ลง = เทา
   • โดนัทวิชา: เส้นหนาขึ้น ปลายมน · "อื่น ๆ" ในจอนี้ใช้สีเน้นของธีมแทนเทา (มันไม่ใช่วิชาจริง จอทั้งจอเลยเทาไปหมด)
     ตัวเลขกลางวงใหญ่ขึ้น · แถบวิชาหนาขึ้น
   • การ์ดบรรทัดเดียว (เลื่อนงาน · จับเวลาอีก…): ไอคอนอยู่ในวงกลมอมสีเน้น ตัวเลขสีเน้น
   • เข้าจอ (.an-in จาก growBars): ไทล์เด้งขึ้นทีละใบ · การ์ดไล่ขึ้นทีละใบ · โดนัทวาดเส้นรอบวง · แถบวิชายืดจากซ้าย
   ============================================================ */
#statFull .an-tiles { gap: 9px; }
#statFull .an-tile {
  --tc: var(--muted);
  position: relative; overflow: hidden; padding: 13px 8px 12px; border: 0; border-radius: 18px;
  background: color-mix(in srgb, var(--tc) 11%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tc) 20%, transparent), 0 6px 16px -12px color-mix(in srgb, var(--tc) 70%, transparent);
}
#statFull .an-tile.gold { --tc: var(--gold); }
#statFull .an-tile.ok { --tc: #10B981; }
#statFull .an-tile.up { --tc: var(--fill); }
#statFull .an-tile .at-ic {
  width: 30px; height: 30px; margin: 0 auto; border-radius: 50%; display: grid; place-items: center;
  background: var(--tc); color: #fff;
  box-shadow: 0 4px 10px -4px var(--tc), inset 0 1px 0 rgba(255,255,255,.35);
}
#statFull .an-tile.gold .at-ic { color: var(--on-gold, #3F2D00); }
#statFull .an-tile .at-ic svg { width: 16px; height: 16px; }
#statFull .an-tile .at-v { margin-top: 8px; font-size: 22px; font-weight: 800; color: color-mix(in srgb, var(--tc) 75%, var(--ink)); }
#statFull .an-tile.gold .at-v { color: var(--gold-text); }
#statFull .an-tile .at-k { color: color-mix(in srgb, var(--ink) 62%, transparent); }
#statFull .an-tile.gold .at-k { color: var(--gold-text); opacity: .85; }

/* โดนัท + แถบวิชา */
#statFull .sj-0 { --sj: var(--fill); }
#statFull .an-donut circle { stroke-width: 12; stroke-linecap: round; }
#statFull .an-donut .dn-bg { stroke: color-mix(in srgb, var(--fill) 10%, var(--surface)); stroke-linecap: butt; }
#statFull .dn-mid b { font-size: 22px; font-weight: 800; color: color-mix(in srgb, var(--fill) 70%, var(--ink)); }
#statFull .dn-mid i { color: color-mix(in srgb, var(--ink) 55%, transparent); }
#statFull .lg-bar { height: 7px; background: color-mix(in srgb, var(--sj, var(--fill)) 14%, var(--surface)); }
#statFull .lg-dot { border-radius: 50%; }
#statFull .lg-pct { color: var(--ink); font-weight: 700; }
/* เจ้าของ: "ทำให้ข้อความข้างบนใหญ่หน่อย แล้วก็ข้อความข้างล่างชัด ใหญ่ขึ้นหน่อย" — หัวการ์ด 12 → 15px · บรรทัดรอง 11 → 12.5px เข้มขึ้น */
#statFull .st-h { color: var(--ink); font-size: 15px; font-weight: 800; letter-spacing: -.005em; margin-bottom: 4px; }
#statFull .st-foot { font-size: 12.5px; line-height: 1.5; color: color-mix(in srgb, var(--ink) 75%, transparent); }
#statFull .st-h + .st-bars { margin-top: 12px; }

/* การ์ดบรรทัดเดียว */
#statFull .st-card.soft {
  background: color-mix(in srgb, var(--fill) 7%, var(--card)); border-radius: 18px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 14%, transparent);
}
#statFull .st-card.soft .st-line { display: flex; align-items: center; gap: 10px; }
#statFull .st-card.soft .st-line > svg {
  flex: none; box-sizing: content-box; width: 15px; height: 15px; margin: 0; padding: 7px; border-radius: 50%;
  vertical-align: 0; color: var(--fill); background: color-mix(in srgb, var(--fill) 16%, transparent);
}
#statFull .st-line b { color: var(--fill); font-weight: 800; }

/* เข้าจอ */
#statFull.an-in > * { animation: an-up .5s cubic-bezier(.22, 1, .36, 1) both; }
#statFull.an-in > :nth-child(2) { animation-delay: .06s; }
#statFull.an-in > :nth-child(3) { animation-delay: .12s; }
#statFull.an-in > :nth-child(4) { animation-delay: .18s; }
#statFull.an-in > :nth-child(5) { animation-delay: .24s; }
#statFull.an-in > :nth-child(n+6) { animation-delay: .3s; }
#statFull.an-in .an-tile { animation: an-pop .5s cubic-bezier(.3, 1.4, .5, 1) both; }
#statFull.an-in .an-tile:nth-child(2) { animation-delay: .06s; }
#statFull.an-in .an-tile:nth-child(3) { animation-delay: .12s; }
#statFull.an-in .an-donut circle:not(.dn-bg) { animation: an-draw .9s cubic-bezier(.22, 1, .36, 1) .2s both; }
#statFull.an-in .lg-bar i { transform-origin: 0 50%; animation: an-grow-x .7s cubic-bezier(.22, 1, .36, 1) .25s both; }
@keyframes an-up { from { opacity: 0; transform: translateY(12px); } }
@keyframes an-pop { from { opacity: 0; transform: translateY(8px) scale(.92); } }
@keyframes an-draw { from { stroke-dasharray: 0 238.8; } }
@keyframes an-grow-x { from { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) {
  #statFull.an-in > *, #statFull.an-in .an-tile, #statFull.an-in .an-donut circle, #statFull.an-in .lg-bar i { animation: none; }
}
:root[data-theme="astral"] #statFull :is(.an-tile, .an-donut, .lg-bar, .lg-dot, .st-card.soft) { filter: grayscale(1); }

/* ============================================================
   ตั้งค่า → "นั่งทำงานไหวต่อวัน" — ตัวปรับแบบ − ตัวเลข + (คู่กับ stepFree ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "แก้ให้สวยกว่านี้" — เดิมช่องตัวเลขเปล่ามีลูกศรขึ้นลงเล็ก ๆ ของเบราว์เซอร์ติดขอบขวา
   แคปซูลพื้นอมสีเน้น · ปุ่มกลมสองข้าง (ลบ = พื้นการ์ด · บวก = สีเน้นทึบ) · ตัวเลขหนาตรงกลางมีหน่วย "ชม."
   ซ่อนลูกศรของเบราว์เซอร์ · กดแล้วตัวเลขเลื่อนตามทิศ · กฎ .set-row input เดิม (กว้าง 78px พื้นเทา) ถูกล้างในนี้
   ============================================================ */
.set-row .stp {
  flex: none; display: inline-flex; align-items: center; gap: 2px; padding: 3px;
  border-radius: 999px; background: color-mix(in srgb, var(--fill) 10%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 18%, transparent);
}
.stp-b {
  width: 30px; height: 30px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%;
  background: var(--card); color: var(--fill); cursor: pointer;
  box-shadow: 0 1px 3px rgba(0,0,0,.12), inset 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent);
  transition: transform .3s cubic-bezier(.3, 1.6, .5, 1), background .2s ease;
}
.stp-b:last-child { background: var(--fill); color: var(--on-fill); box-shadow: 0 3px 8px -3px var(--fill); }
.stp-b svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; }
.stp-b:active { transform: scale(.86); }
.stp-v { display: inline-flex; align-items: baseline; justify-content: center; gap: 3px; min-width: 58px; overflow: hidden; }
.set-row .stp-v input[type=number] {
  width: 32px; min-height: 0; padding: 0; border: 0 !important; border-radius: 0 !important; background: none !important;
  box-shadow: none !important; outline: none !important; text-align: right;
  font-size: 16px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums;
  -moz-appearance: textfield; appearance: textfield;
}
.stp-v input::-webkit-outer-spin-button, .stp-v input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stp-v i { font-style: normal; font-size: 11.5px; font-weight: 700; color: color-mix(in srgb, var(--ink) 60%, transparent); }
.stp:focus-within { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fill) 55%, transparent); }
.stp-v.up input { animation: stp-up .28s cubic-bezier(.22, 1, .36, 1); }
.stp-v.dn input { animation: stp-dn .28s cubic-bezier(.22, 1, .36, 1); }
@keyframes stp-up { from { opacity: 0; transform: translateY(8px); } }
@keyframes stp-dn { from { opacity: 0; transform: translateY(-8px); } }
@media (prefers-reduced-motion: reduce) { .stp-v.up input, .stp-v.dn input { animation: none; } .stp-b { transition: none; } }

/* ลูกศรขึ้นลงของเบราว์เซอร์ในช่องตัวเลขทุกช่องของแอป (คะแนนเก็บ · คะแนนที่ได้ · เต็ม …)
   เจ้าของ: "ตรงนี้อะ ปุ่มเลื่อนมันยังไม่สวย" — ลูกศรเทาเล็ก ๆ ติดขอบไม่เข้ากับธีมไหนเลย และกดยากบนมือถือ
   พิมพ์ตัวเลขเองได้เหมือนเดิม (มือถือขึ้นแป้นตัวเลขอยู่แล้ว) · ช่องที่ต้องกดปรับ ใช้ตัวปรับ − + (.stp) แทน */
.phone input[type=number] { -moz-appearance: textfield; appearance: textfield; }
.phone input[type=number]::-webkit-outer-spin-button,
.phone input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ตัวปรับ − + ให้กะทัดรัดขึ้น — ในกรอบมือถือแคบ แคปซูล 128px ดันชื่อแถว "นั่งทำงานไหวต่อวัน" ตัดเป็นสองบรรทัด
   ปุ่ม 30 → 26px · ช่องตัวเลข 58 → 46px · ชื่อแถวห้ามตัดกลางคำ (คำอธิบายใต้ชื่อยังตัดบรรทัดได้ตามปกติ) */
.stp-b { width: 26px; height: 26px; }
.stp-b svg { width: 13px; height: 13px; }
.stp-v { min-width: 46px; gap: 2px; }
.set-row .stp-v input[type=number] { width: 26px; font-size: 15px; }
.stp-v i { font-size: 11px; }
.set-row:has(.stp) .set-lb { min-width: 0; }
.set-row:has(.stp) .set-lb { white-space: normal; }
/* เคยมี .set-row:has(.stp) .set-lb::first-line { white-space: nowrap } ตรงนี้ — ถอดออก 11 ต.ค. 69
   white-space ใช้กับ ::first-line ไม่ได้อยู่แล้ว (วัดแล้ว ชื่อแถวตัดบรรทัดเหมือนเดิมเป๊ะทุกความกว้าง 280–360px)
   แต่ ::first-line คู่กับ :has() ทำให้ Chrome คิดสไตล์ใหม่ "ทั้งแอป" ทุกครั้งที่มีอะไรถูกใส่/ถอดออกจากหน้า
   วัดบนคอม: หน้าเสร็จแล้ว 800 ใบ ใส่ <span> ชิ้นเดียวในจอที่ซ่อนอยู่ = 70–118ms → ถอดแล้ว 2–5ms
   (renderAll ทั้งก้อน 366 → 196ms) · บนมือถือสเปคต่ำทุกการวาดใหม่หนักขึ้นตามจำนวนของบนจอ */

/* ============================================================
   ปุ่ม "เลือกรูป / เลือกภาพ" กับปุ่มถังขยะ (รูปโปรไฟล์ · ภาพวิดเจ็ต · พื้นหลัง) — ให้เห็นชัดว่าเป็นปุ่ม
   ------------------------------------------------------------
   เจ้าของ: "ปรับหน่อย เห็นปุ่มยังไม่ชัด" — ชั้นกระจก (:root :is(… .bg-pick, .bg-del …) !important) ทำให้ทั้งสองปุ่ม
   เป็นแผ่นขาวโปร่งบนการ์ดขาว ขอบแทบไม่มี จึงจมไปกับพื้น
   • เลือกรูป = แคปซูลพื้นอมสีเน้น ขอบสีเน้น ตัวหนังสือ/ไอคอนสีเน้นตัวหนา
   • ถังขยะ = วงกลมพื้นแดงอ่อน ขอบแดง ไอคอนแดง — สีเตือนบอกว่ากดแล้วลบ
   ต้องหนักกว่ากฎกระจก (0,3,1 + !important) จึงเขียน :root .bg-tools .bg-pick.bg-pick (0,4,0)
   ============================================================ */
:root .bg-tools .bg-pick.bg-pick {
  min-height: 36px; padding: 0 14px 0 11px; gap: 6px; border-radius: 999px !important;
  background: color-mix(in srgb, var(--fill) 13%, var(--card)) !important; background-image: none !important;
  border: 1.5px solid color-mix(in srgb, var(--fill) 45%, transparent) !important;
  color: color-mix(in srgb, var(--fill) 80%, var(--ink)) !important; font-weight: 700;
  box-shadow: 0 3px 8px -5px var(--fill) !important;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
:root .bg-tools .bg-pick.bg-pick svg { color: inherit; }
:root .bg-tools .bg-del.bg-del {
  width: 36px; height: 36px; border-radius: 50% !important;
  background: color-mix(in srgb, var(--alert) 12%, var(--card)) !important; background-image: none !important;
  border: 1.5px solid color-mix(in srgb, var(--alert) 40%, transparent) !important;
  color: var(--alert) !important; box-shadow: none !important;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}

/* ============================================================
   บริบทของฉัน (scr-context) — สวยขึ้นแต่ยังเรียบ (คู่กับ renderContext · ctxHeroHtml · ctxWeekBarsHtml)
   ------------------------------------------------------------
   เจ้าของ: "แก้ไขในหน้านี้ให้หน่อย ทำให้สวยแต่ยังดูง่ายและมินิมอล"
   • หัวการ์ด (ว่างวันนี้ · สัปดาห์นี้ · ข้อมูลของคุณ) เข้มขึ้น ตัวเลขชิดขวาเป็นป้ายแคปซูลอมสี
   • ตัวเลขใหญ่: เลขตัวโต 36px · หน่วยตัวเล็กจาง — อ่านเลขก่อน หน่วยทีหลัง
   • แท่งวัน: ทรงแคปซูลหนา 14px · ว่าง = ไล่สีเน้น · ไม่ว่าง = สีเน้นจาง · ช่วงที่ผ่านไปแล้วซีด
     เส้น "ตอนนี้" มีขอบขาวรอบ เห็นชัดทั้งบนช่วงว่างและไม่ว่าง
   • แท่งสัปดาห์: แต่ละวันมีรางจางเต็มความสูง (เห็นว่าเทียบกับอะไร) · วันที่เลือก = ไล่สีเต็ม มีเงา ชื่อวันตัวหนา
   • ข้อมูลของคุณ: แถบความคืบหน้าบาง ๆ ใต้หัว · ชิปพื้นอมสี ขอบประ มีวงกลม + สีเน้นนำหน้า
   • ปุ่มถ่ายรูปตารางเรียน: แคปซูลเตี้ยลง (เดิมเป็นปุ่มยักษ์ที่ดังกว่าตัวเลขของจอ)
   ============================================================ */
#ctxBody .cx2-card { border-radius: 22px; }
#ctxBody .cx2-cap { font-size: 12.5px; color: color-mix(in srgb, var(--ink) 70%, transparent); letter-spacing: .01em; }
#ctxBody .cx2-cap b {
  padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 800;
  background: color-mix(in srgb, var(--fill) 12%, transparent); color: color-mix(in srgb, var(--fill) 85%, var(--ink));
}
#ctxBody .cx2-pick {
  padding: 6px 10px; border-radius: 999px; font-weight: 700;
  background: color-mix(in srgb, var(--fill) 12%, var(--card)); color: color-mix(in srgb, var(--fill) 85%, var(--ink));
}

/* ตัวเลขใหญ่ */
#ctxBody .cx2-big { margin: 6px 0 14px; font-size: 15px; font-weight: 700; color: color-mix(in srgb, var(--ink) 55%, transparent); letter-spacing: 0; }
#ctxBody .cx2-big b { font-size: 36px; font-weight: 800; letter-spacing: -.03em; color: var(--ink); margin-right: 3px; }
#ctxBody .cx2-big b:not(:first-child) { margin-left: 6px; }

/* แท่งวัน */
#ctxBody .cx2-bar { height: 14px; gap: 3px; }
#ctxBody .cx2-bar > i { border-radius: 999px; }
#ctxBody .cx2-bar > .cb-free { background: linear-gradient(90deg, color-mix(in srgb, var(--fill) 75%, #fff), var(--fill)); }
#ctxBody .cx2-bar > .cb-busy { background: color-mix(in srgb, var(--fill) 16%, var(--card)); opacity: 1; box-shadow: none; }
#ctxBody .cx2-past { border-radius: 999px 0 0 999px; background: var(--card); opacity: .6; }
#ctxBody .cx2-now { top: -5px; bottom: -5px; width: 3px; margin-left: -1.5px; border-radius: 3px; background: var(--ink); box-shadow: 0 0 0 2px var(--card); }
#ctxBody .cx2-axis { font-size: 11px; font-weight: 600; color: color-mix(in srgb, var(--ink) 50%, transparent); }

/* แท่งสัปดาห์ */
#ctxBody .cx2-wk .cx2-week { height: 64px; gap: 7px; }
#ctxBody .cx2-day { gap: 6px; }
#ctxBody .cx2-day i {
  position: relative; border-radius: 10px; opacity: 1;
  background: color-mix(in srgb, var(--fill) 26%, var(--card));
  transition: transform .2s ease;
}
#ctxBody .cx2-day { position: relative; }
#ctxBody .cx2-day::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; bottom: 21px; border-radius: 10px;
  background: color-mix(in srgb, var(--fill) 7%, var(--card)); z-index: 0;
}
#ctxBody .cx2-day > * { position: relative; z-index: 1; }
#ctxBody .cx2-day.on i { background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 75%, #fff), var(--fill)); box-shadow: 0 6px 12px -6px var(--fill); }
#ctxBody .cx2-day span { font-size: 11.5px; font-weight: 600; color: color-mix(in srgb, var(--ink) 55%, transparent); }
#ctxBody .cx2-day.on span { color: var(--fill); font-weight: 800; }
#ctxBody .cx2-day.low i { background: color-mix(in srgb, var(--alert) 55%, var(--card)); }
#ctxBody .cx2-day:active i { transform: scaleY(.94); transform-origin: 50% 100%; }

/* ข้อมูลของคุณ */
.cx2-prog { height: 5px; margin-top: 10px; border-radius: 999px; overflow: hidden; background: color-mix(in srgb, var(--fill) 12%, var(--card)); }
.cx2-prog i { display: block; height: 100%; min-width: 5px; border-radius: 999px; background: var(--fill); transition: width .4s ease; }
#ctxBody .cx2-chips { gap: 6px; margin-top: 12px; }
:root #ctxBody .cx2-chip.cx2-chip:not(.done) {
  gap: 5px; padding: 6px 10px 6px 6px; border-radius: 999px !important; font-size: 12.5px; font-weight: 700;
  background: color-mix(in srgb, var(--fill) 7%, var(--card)) !important; background-image: none !important;
  border: 1.5px dashed color-mix(in srgb, var(--fill) 40%, transparent) !important; box-shadow: none !important;
  color: color-mix(in srgb, var(--fill) 80%, var(--ink)) !important;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.cx2-pl {
  width: 16px; height: 16px; flex: none; display: grid; place-items: center; border-radius: 50%;
  font-style: normal; font-size: 12px; font-weight: 800; line-height: 1;
  background: var(--fill); color: var(--on-fill);
}
#ctxBody .cx2-chip.done { color: color-mix(in srgb, var(--ink) 60%, transparent); }

/* ปุ่มถ่ายรูปตารางเรียน */
#ctxBody .cx2-scan { min-height: 46px; padding: 10px 16px; margin-top: 14px; font-size: 14px; }
#ctxBody .cx2-scan svg { width: 17px; height: 17px; }
:root[data-theme="astral"] #ctxBody :is(.cx2-bar, .cx2-week, .cx2-prog, .cx2-pl) { filter: grayscale(1); }

/* วงกลม + หน้าชิปไม่ตรงกลาง (เจ้าของ: "มันไม่ตรง") — ตัวอักษร "+" ของฟอนต์ไทยนั่งบนเส้นฐานที่สูงกว่ากลางวง
   วาดเป็นเส้น SVG สองเส้นแทน ตรงกลางเป๊ะทุกฟอนต์ */
/* สีต้องตั้งเอง — .cx2-chip svg (สีเน้น) ทับให้กากบาทสีเดียวกับวงจนหายไป */
.cx2-chip .cx2-pl svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 3.2; stroke-linecap: round; color: var(--on-fill); }

/* ชิป "ข้อมูลของคุณ" เรียงเป็นแถวเต็มความกว้างเท่ากันทุกอัน (เจ้าของ: "ยังไม่ตรงทุกอัน แก้ให้มันตรง")
   ในกรอบมือถือแคบ ชิปตกบรรทัดละอันแต่กว้างไม่เท่ากัน (139–162px) ขอบขวาจึงหยักเป็นฟันปลา
   เป็นคอลัมน์เดียวกว้างเต็ม = ขอบซ้ายขวาตรงแนวเดียวกันทุกแถว · ความสูงรวมเท่าเดิม (ในจอแคบมันเรียงบรรทัดละอันอยู่แล้ว) */
#ctxBody .cx2-chips { display: grid; grid-template-columns: 1fr; gap: 6px; }
#ctxBody .cx2-chip { width: 100%; justify-content: flex-start; text-align: left; }

/* บริบทของฉัน — สลับวัน (คู่กับ ctxPickDay) · เจ้าของ: "ตรงนี้ทำอนิเมชันให้หน่อย เมื่อกดปุ่มในแต่ละวัน"
   แท่งวันที่เลือกไถลมาจากวันเดิม (ทำใน JS) · หัว "ว่างวัน…" กับตัวเลขใหญ่เลื่อนเข้าจากฝั่งที่กดไป (--sx)
   แท่งเวลาของวันกวาดจากซ้ายไปขวา · กดค้างที่แท่งวัน = แท่งยุบลงนิด (มีอยู่แล้ว) */
#ctxBody .cx2-day i { z-index: 2; }
.cx2-swap > .cx2-cap > span, .cx2-swap .cx2-big { animation: cx2-in .38s cubic-bezier(.22, 1, .36, 1) both; }
.cx2-swap .cx2-big { animation-delay: .03s; }
.cx2-swap .cx2-bar > i { animation: cx2-wipe .5s cubic-bezier(.22, 1, .36, 1) .05s both; }
.cx2-swap .cx2-axis { animation: cx2-fade .3s ease .15s both; }
@keyframes cx2-in { from { opacity: 0; transform: translateX(var(--sx, 12px)); } }
@keyframes cx2-wipe { from { clip-path: inset(0 100% 0 0 round 999px); } to { clip-path: inset(0 0 0 0 round 999px); } }
@keyframes cx2-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .cx2-swap > .cx2-cap > span, .cx2-swap .cx2-big, .cx2-swap .cx2-bar > i, .cx2-swap .cx2-axis { animation: none; }
}

/* ============================================================
   บริบทของฉัน — เมนูเลือกวัน (คู่กับ ctxDdToggle) · เจ้าของ: "ปรับหน่อย ไม่สวยเลย มีอนิเมชันตอนกดด้วย"
   ------------------------------------------------------------
   ปุ่ม = แคปซูลอมสีเน้น ลูกศรหมุนลงตอนเปิด · เมนู = การ์ดลอยมุมมน เงานุ่ม กางแบบสปริงจากมุมขวาบน
   รายการไล่ขึ้นทีละบรรทัด · วันที่เลือกอยู่ = พื้นอมสีเน้น ตัวหนา มีเครื่องหมายถูก
   การ์ดนี้ต้องลอยเหนือการ์ดถัดไป (z-index) ไม่งั้นเมนูที่ยาวเลยขอบล่างโดนการ์ด "ข้อมูลของคุณ" ทับ
   ============================================================ */
#ctxBody .cx2-hero { position: relative; z-index: 5; }
.cx2-dd { position: relative; }
#ctxBody .cx2-pick {
  display: inline-flex; align-items: center; gap: 4px; padding: 6px 8px 6px 12px; border: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 700; transition: transform .3s cubic-bezier(.3, 1.6, .5, 1), box-shadow .2s ease;
}
#ctxBody .cx2-pick svg { width: 14px; height: 14px; transform: rotate(90deg); transition: transform .3s cubic-bezier(.3, 1.4, .5, 1); }
#ctxBody .cx2-pick:active { transform: scale(.94); }
.cx2-dd.open .cx2-pick { box-shadow: 0 0 0 3px color-mix(in srgb, var(--fill) 18%, transparent); }
.cx2-dd.open .cx2-pick svg { transform: rotate(-90deg); }
.cx2-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; min-width: 150px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px; border-radius: 18px;
  background: var(--card); box-shadow: 0 18px 40px -14px rgba(0,0,0,.35), 0 0 0 1px color-mix(in srgb, var(--fill) 14%, transparent);
  transform-origin: 90% 0; opacity: 0; visibility: hidden; transform: translateY(-6px) scale(.9);
  transition: opacity .16s ease, transform .2s ease, visibility 0s .2s;
}
.cx2-dd.open .cx2-menu {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .18s ease, transform .38s cubic-bezier(.3, 1.35, .5, 1), visibility 0s;
}
.cx2-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  padding: 9px 12px; border: 0; border-radius: 12px; background: none; cursor: pointer; text-align: left;
  font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink);
  transition: background .15s ease, transform .15s ease;
}
.cx2-opt svg { width: 15px; height: 15px; flex: none; color: var(--fill); stroke-width: 2.6; }
.cx2-opt.on { background: color-mix(in srgb, var(--fill) 13%, transparent); color: color-mix(in srgb, var(--fill) 85%, var(--ink)); font-weight: 800; }
.cx2-opt:active { transform: scale(.97); background: color-mix(in srgb, var(--fill) 9%, transparent); }
@media (hover: hover) and (pointer: fine) { .cx2-opt:not(.on):hover { background: color-mix(in srgb, var(--ink) 5%, transparent); } }
.cx2-dd.open .cx2-opt { animation: cx2-opt-in .3s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--k, 0) * 22ms + 40ms); }
@keyframes cx2-opt-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .cx2-menu, .cx2-dd.open .cx2-menu { transition: none; transform: none; }
  .cx2-dd.open .cx2-opt { animation: none; }
}

/* ============================================================
   ช่องถามน้องไซบนหน้าแรก — แบบ HaloSearchInput (เจ้าของส่งเดโมมา: "ใช้ในหน้านี้")
   ------------------------------------------------------------
   ได้มาแค่ไฟล์เดโม ไม่มีซอร์สของคอมโพเนนต์ — ทำตามที่เดโมบอกว่ามันทำอะไร:
   • วงรัศมี (halo): ไล่สีวนรอบแคปซูลช้า ๆ ฟุ้งออกนอกขอบ · พื้นแคปซูลเป็นกระจกฝ้า เห็นสีลอดเข้ามาจาง ๆ (frosted fill)
     ตอนพิมพ์ (โฟกัส) วงสว่างขึ้นและหมุนเร็วขึ้นนิดหนึ่ง
   • ปุ่ม × โผล่เมื่อมีตัวหนังสือ · กดแล้วตัวอักษรปลิวขึ้นหายทีละตัวจากท้าย (homeAskClear)
   • ไม่ได้ทำสถานะ "กำลังค้นหา…" — ช่องนี้กดส่งแล้วพาไปจอน้องไซทันที ไม่มีช่วงรอในช่องนี้ให้แสดง
   สีวงมาจากสีเน้นของธีม + ชมพู + ฟ้า (ผสมกับสีเน้น ไม่ใช่สีตายตัว) · Astral Black ขาวดำ
   ============================================================ */
@property --ha-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
#menuBody .td-ask { isolation: isolate; overflow: visible; }
#menuBody .td-ask::before {
  content: ''; position: absolute; inset: -3px; z-index: -1; border-radius: inherit; pointer-events: none;
  background: conic-gradient(from var(--ha-a),
    var(--fill), color-mix(in srgb, var(--fill) 45%, var(--halo-2)), color-mix(in srgb, var(--fill) 40%, var(--halo-3)),
    color-mix(in srgb, var(--fill) 60%, var(--halo-4)), var(--fill));
  filter: blur(8px); opacity: .7;
  /* steps ไม่ใช่ linear — มุมใน conic-gradient ขยับบน compositor ไม่ได้ ทุกครั้งที่ขยับคือวาดใหม่ + เบลอใหม่ทั้งวง
     และไอคอนกระจกฝ้าข้างล่าง (.tg-ic) ต้องเบลอพื้นหลังใหม่ตามด้วยเพราะแสงฟุ้งไปถึง
     linear = 60 ครั้ง/วิ ตลอดเวลาที่อยู่หน้าแรก → มือถือค้าง (เจ้าของ 8 ต.ค. 69) · 15 ครั้ง/วิ ตาแยกไม่ออกเพราะวงเบลออยู่แล้ว */
  animation: ha-spin 9s steps(135) infinite;
  transition: opacity .35s ease, filter .35s ease, inset .35s ease;
}
#menuBody .td-ask::after {
  /* พื้นกระจกฝ้าของแคปซูลอยู่ชั้นนี้ ไม่ใช่บนตัวกล่อง — ใน stacking context ลูกที่ z-index ติดลบวาดทับพื้นของตัวกล่อง
     ถ้าพื้นอยู่บนกล่อง วงรัศมี (::before) จะวาดทับข้างในจนตัวหนังสือจาง · ::after มาทีหลัง ::before จึงวาดทับวงได้ */
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  /* ไม่มี backdrop-filter — ของที่อยู่ข้างหลังชั้นนี้คือวงรัศมีที่หมุนอยู่ ทุกเฟรมที่วงขยับ กระจกฝ้าต้องเบลอใหม่ทั้งแคปซูล
     และวงก็เบลอ 8px มาแล้ว สีที่ลอดผ่านพื้น 84% จึงฟุ้งเหมือนกระจกฝ้าอยู่แล้วโดยไม่ต้องจ่ายซ้ำ */
  background: color-mix(in srgb, var(--card) 84%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px color-mix(in srgb, var(--fill) 22%, transparent);
  transition: background .3s ease, box-shadow .3s ease;
}
#menuBody .td-ask:focus-within::before { opacity: .95; filter: blur(11px); inset: -5px; animation-duration: 4.5s; animation-timing-function: steps(68); }
#menuBody .td-ask:focus-within::after { background: var(--card); box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px color-mix(in srgb, var(--fill) 40%, transparent); }
@keyframes ha-spin { to { --ha-a: 360deg; } }
#menuBody .td-ask, #menuBody .td-ask:focus-within { background: transparent; border-color: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }

/* ปุ่ม × */
.ha-x {
  flex: none; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; background: color-mix(in srgb, var(--ink) 8%, transparent); color: color-mix(in srgb, var(--ink) 65%, transparent);
  opacity: 0; transform: scale(.4) rotate(-90deg); pointer-events: none; width: 0; margin-right: -9px;
  transition: opacity .2s ease, transform .35s cubic-bezier(.3, 1.6, .5, 1), width .25s ease, margin .25s ease;
}
.ha-x svg { width: 13px; height: 13px; }
.td-ask.ha-has .ha-x { opacity: 1; transform: none; pointer-events: auto; width: 28px; margin-right: 0; }
.ha-x:active { transform: scale(.85); }
/* ตัวอักษรปลิวตอนกด × */
.ha-line span.out { display: inline-block; animation: ha-out .26s cubic-bezier(.4, 0, .6, 1) both; }
@keyframes ha-out { to { opacity: 0; transform: translateY(-9px) scale(.8); filter: blur(2px); } }

@media (prefers-reduced-motion: reduce) {
  #menuBody .td-ask::before { animation: none; }
  .ha-x { transition: none; }
}
:root[data-theme="astral"] #menuBody .td-ask::before { filter: grayscale(1) blur(9px); }

/* ============================================================
   จอเข้าสู่ระบบ — การ์ดแบบ TextureCard + ปุ่มแบบ TextureButton (cult-ui · MIT)
   ------------------------------------------------------------
   เจ้าของส่งเดโม TextureCardDemo มา: "ลองเอามาปรับใช้ในหน้านี้ดู" — ได้มาแค่เดโม ไม่มีซอร์สคอมโพเนนต์
   ทำตามหน้าตาของ cult-ui: ขอบการ์ดซ้อนสี่ชั้น (ขาวจาง · ดำจาง · ขาวจาง · ดำจาง) ทำด้วยเงาซ้อน ไม่เพิ่ม <div>
   เส้นคั่นเป็นเส้นคู่ (มืดบน สว่างล่าง) ให้ดูเป็นร่องบนผิว · ท้ายการ์ดเป็นแถบพื้นเข้มกว่าหนึ่งระดับ
   ปุ่มหลัก = ไล่สีเน้นจากสว่างลงเข้ม ขอบเข้ม ไฮไลต์ขาวขอบบน (accent) · ปุ่ม Google = ไล่ขาวลงเทาจาง ขอบบาง (icon)
   ไฮไลต์ขาวใช้ .35 ไม่ใช่ .6 ของเดโม — ธีมมืดของแอปใช้คลาสเดียวกัน ขาวเข้มกว่านี้เป็นเส้นสว่างบาดตาบนพื้นมืด
   ============================================================ */
.login-wrap .tx-card {
  margin-top: 26px; border-radius: 24px; overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--card) 94%, var(--ink)), var(--card) 40%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.35),
    inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent),
    inset 0 0 0 2px rgba(255,255,255,.35),
    inset 0 0 0 3px color-mix(in srgb, var(--ink) 6%, transparent),
    0 18px 36px -22px rgba(0,0,0,.35);
}
.tx-body { padding: 18px 18px 16px; }
.tx-card .lg-feats { margin-top: 0; gap: 12px; }
.tx-card .lg-actions { margin-top: 0; padding-top: 0; }
.tx-sep {
  height: 0; margin: 0 3px;
  border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-bottom: 1px solid rgba(255,255,255,.4);
}
.tx-foot {
  display: flex; justify-content: center; padding: 6px 12px 7px;
  background: color-mix(in srgb, var(--ink) 4%, var(--card));
  border-top: 1px solid color-mix(in srgb, var(--ink) 9%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35);
}
.tx-foot .login-what { margin: 0; }
.tx-card .lg-note:empty { display: none; }

/* TextureButton · accent */
.login-wrap .lg-opts .btn.lg-go {
  min-height: 52px; border-radius: 16px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 78%, #fff), var(--fill) 55%, color-mix(in srgb, var(--fill) 88%, #000));
  border: 1px solid color-mix(in srgb, var(--fill) 55%, #000);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -1px 0 rgba(0,0,0,.18),
    0 1px 2px rgba(0,0,0,.18), 0 8px 18px -10px var(--fill);
  text-shadow: 0 1px 0 rgba(0,0,0,.15);
  transition: transform .15s ease, filter .15s ease;
}
.login-wrap .lg-opts .btn.lg-go:active { transform: translateY(1px) scale(.99); filter: brightness(.96); }
/* TextureButton · icon (Google และเจ้าอื่นที่เป็นปุ่มเต็มแถว) */
.login-wrap .lg-opts .btn.lg-main {
  min-height: 50px; border-radius: 16px; gap: 10px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--card) 70%, #fff), var(--card));
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 2px rgba(0,0,0,.1), 0 6px 14px -10px rgba(0,0,0,.3);
  transition: transform .15s ease, filter .15s ease;
}
.login-wrap .lg-opts .btn.lg-main:active { transform: translateY(1px) scale(.99); filter: brightness(.97); }
.g-logo { width: 19px; height: 19px; flex: none; }
.tx-card .lg-alt { margin-top: 2px; }

/* การ์ดยืดเต็มที่ว่างที่เหลือของจอ — ปุ่มยังติดก้นจอในระยะนิ้วโป้ง (เหตุผลเดิมของ margin-top:auto ใน .lg-actions)
   สามบรรทัดว่าแอปทำอะไรอยู่กลางส่วนบนของการ์ด · จอเตี้ยที่ไม่เหลือที่ = การ์ดสูงเท่าเนื้อหา ไม่บีบ */
.login-wrap .tx-card { flex: 1 0 auto; display: flex; flex-direction: column; margin-bottom: 4px; }
.tx-card > .tx-body:first-child { flex: 1 0 auto; display: flex; flex-direction: column; justify-content: center; padding: 20px 20px; }
.tx-card .lg-feats { gap: 16px; }

/* toast ที่มีแค่หัวข้อ (ตัดคำอธิบายทิ้งแล้ว) — ไม่เหลือบรรทัดว่างใต้หัวข้อ */
.toast .tb:empty { display: none; }

/* ============================================================
   แผงลอย "วันนั้นทำงานอะไรเสร็จบ้าง" — แตะแท่งกราฟ 7 วัน (คู่กับ statDayOpen ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "เมื่อกดไปยังแท่งกราฟ ให้อธิบายด้วยว่าทำงานอะไรไปบ้าง" + เดโม FloatingPanel (motion-primitives)
   แผงงอกออกมาจากแท่งที่แตะ (FLIP ใน JS) · พื้นจอข้างหลังมืดลงและเบลอนิด ๆ · ตัวหนังสือในแผงโผล่หลังแผงกางเสร็จ
   แถวงานไล่ลงทีละแถว (ห่างกัน 45ms) · หัวแผง = วัน + "เสร็จ N งาน · ประเมินรวม …" · ท้ายแผงมีปุ่มปิด
   ============================================================ */
.st-card button.st-bar { border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.st-card button.st-bar .trk { transition: transform .2s ease, box-shadow .2s ease; }
.st-card button.st-bar:active .trk { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) { .st-card button.st-bar:hover .trk { box-shadow: 0 0 0 2px color-mix(in srgb, var(--fill) 30%, transparent); } }

.fp-scrim {
  position: absolute; inset: 0; z-index: 80; border-radius: inherit;
  background: rgba(10, 6, 20, .28); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; transition: opacity .3s ease;
}
.fp-scrim.open { opacity: 1; }
.fp {
  position: absolute; left: 14px; right: 14px; z-index: 81; max-height: 70%;
  display: flex; flex-direction: column; overflow: hidden; transform-origin: 0 0;
  border-radius: 24px; background: var(--card);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.45), 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent);
}
.fp-in { display: flex; flex-direction: column; min-height: 0; opacity: 0; transition: opacity .18s ease; }
.fp.open .fp-in { opacity: 1; }
.fp-h { display: flex; align-items: flex-start; gap: 10px; padding: 16px 12px 10px 18px; }
.fp-ht { flex: 1; min-width: 0; }
.fp-h b { display: block; font-size: 17px; font-weight: 800; color: var(--ink); }
/* 14 ต.ค. 69 · 62% → 70% — ต่ำกว่าเกณฑ์ 4.5:1 ของตัวหนังสือเล็กบนพื้นการ์ด */
.fp-h i { display: block; margin-top: 2px; font-style: normal; font-size: 12.5px; font-weight: 600; color: color-mix(in srgb, var(--ink) 70%, transparent); }
.fp-list { overflow-y: auto; padding: 2px 10px 12px; display: flex; flex-direction: column; gap: 2px; }
/* แถว = เวลา · ติ๊ก · ชื่องาน เรียงเป็นเส้นเวลา (Timeline ของ Aceternity ย่อเหลือแผงเดียว)
   ไม่มีพื้นสีรายแถวแล้ว — แถวเป็นลำดับเหตุการณ์ ไม่ใช่การ์ดเท่ากันสามใบ · พื้นโผล่ตอนชี้/กดเท่านั้น */
.fp-row {
  --fp-at: 40px;
  display: grid; grid-template-columns: var(--fp-at) 24px minmax(0, 1fr); align-items: center; column-gap: 10px;
  position: relative; width: 100%; min-height: 48px; padding: 8px 10px; border: 0; border-radius: 14px;
  background: transparent; font: inherit; text-align: left; color: var(--ink); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s ease, transform .15s ease;
}
@media (hover: hover) and (pointer: fine) { .fp-row:hover { background: color-mix(in srgb, var(--fill) 7%, transparent); } }
.fp-row:active { transform: scale(.98); background: color-mix(in srgb, var(--fill) 12%, transparent); }
.fp-row:focus-visible { outline: 2px solid var(--fill); outline-offset: -2px; }
/* เส้นต่อจากติ๊กนี้ลงไปติ๊กถัดไป (ศูนย์กลางถึงศูนย์กลาง) · แถวสุดท้ายไม่มี · ติ๊กวางทับเส้น */
.fp-tl .fp-row:not(:last-child)::before {
  content: ''; position: absolute; left: calc(10px + var(--fp-at) + 10px + 11px); top: 50%; width: 2px; height: calc(100% + 2px);
  border-radius: 2px; background: color-mix(in srgb, #10B981 32%, transparent); transform-origin: top; pointer-events: none;
}
.fp-ck { position: relative; z-index: 1; }
.fp.open .fp-row { animation: fp-row-in .38s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--k, 0) * 45ms + 60ms); }
@keyframes fp-row-in { from { opacity: 0; transform: translateY(-8px); } }
.fp-ck {
  width: 24px; height: 24px; flex: none; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(180deg, #34D399, #10B981 55%, #059669); color: #fff;
}
.fp-ck svg { width: 13px; height: 13px; stroke-width: 3; }
.fp-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fp-tx i {
  align-self: flex-start; font-style: normal; font-size: 10.5px; font-weight: 800; margin-bottom: 2px;
  padding: 1px 7px; border-radius: 99px; color: var(--sj, var(--fill));
  background: color-mix(in srgb, var(--sj, var(--fill)) 14%, transparent);
}
.fp-tx b { font-size: 14px; font-weight: 700; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* เวลาอยู่หน้าแถว ชิดขวาของช่องตัวเอง ตัวเลขกว้างเท่ากัน (แนวเวลาตรงกันทุกแถว) · 55% → 70% เหตุผลเดียวกับบรรทัดรองของหัวแผง */
.fp-at { font-size: 12px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; color: color-mix(in srgb, var(--ink) 70%, transparent); }
.fp-empty { margin: 4px 8px 8px; padding: 14px; border-radius: 14px; text-align: center; font-size: 13.5px; color: color-mix(in srgb, var(--ink) 62%, transparent); background: color-mix(in srgb, var(--fill) 6%, transparent); }
/* ปุ่มปิดกลมมุมขวาบน · ตัวปุ่ม 34px แต่พื้นที่กด 44px (::after ยื่นออกรอบละ 5px) */
.fp-x {
  position: relative; flex: none; width: 34px; height: 34px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%;
  cursor: pointer; color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent);
  -webkit-tap-highlight-color: transparent; transition: transform .16s cubic-bezier(.23, 1, .32, 1), background-color .15s ease;
}
.fp-x::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; }
.fp-x svg { width: 15px; height: 15px; }
@media (hover: hover) and (pointer: fine) { .fp-x:hover { background: color-mix(in srgb, var(--ink) 12%, transparent); } }
.fp-x:active { transform: scale(.92); }
.fp-x:focus-visible { outline: 2px solid var(--fill); outline-offset: 2px; }
/* เส้นเวลาวาดลงทีละช่วงหลังแถวของมันโผล่ (ช่วงที่ k วาดเมื่อแถว k ขึ้นมาแล้ว) — จังหวะเดียวของแผงนี้ */
.fp.open .fp-tl .fp-row:not(:last-child)::before { animation: fp-line .34s cubic-bezier(.23, 1, .32, 1) both; animation-delay: calc(var(--k, 0) * 45ms + 200ms); }
@keyframes fp-line { from { transform: scaleY(0); } }
@media (prefers-reduced-motion: reduce) {
  .fp-in, .fp-scrim { transition: none; }
  .fp.open .fp-row, .fp.open .fp-tl .fp-row::before { animation: none; }
}
:root[data-lite] .fp.open .fp-tl .fp-row::before { animation: none; }

/* ============================================================
   กล่องยืนยันของแอป (appConfirm ใน app.js) — แทน confirm() ของเบราว์เซอร์ที่ถูกปิดในบางที่
   แผ่นเลื่อนขึ้นจากล่างแบบสปริง · พื้นหลังมืดและเบลอนิด · ปุ่มยืนยันสีแดงเมื่อเป็นการลบ
   ============================================================ */
.ac-scrim {
  position: absolute; inset: 0; z-index: 120; border-radius: inherit;
  background: rgba(10, 6, 20, .34); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; transition: opacity .25s ease;
}
.ac-scrim.open { opacity: 1; }
.ac-sheet {
  position: absolute; left: 12px; right: 12px; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 121;
  padding: 20px 18px 14px; border-radius: 26px; background: var(--card); color: var(--ink);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.5), 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
  transform: translateY(calc(100% + 30px)); transition: transform .26s cubic-bezier(.4, 0, .6, 1);
}
.ac-sheet.open { transform: none; transition: transform .45s cubic-bezier(.3, 1.25, .45, 1); }
.ac-tx { text-align: center; padding: 0 6px; }
.ac-tx b { display: block; font-size: 17px; font-weight: 800; line-height: 1.35; }
.ac-tx p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.6; color: color-mix(in srgb, var(--ink) 68%, transparent); text-align: left; }
.ac-tx p:only-of-type { text-align: center; }
.ac-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; }
.ac-btns button {
  min-height: 48px; border: 0; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 800; transition: transform .15s ease;
}
.ac-btns button:active { transform: scale(.96); }
.ac-no { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }
.ac-ok { background: var(--fill); color: var(--on-fill); }
.ac-ok.danger { background: #DC2626; color: #fff; }
@media (prefers-reduced-motion: reduce) { .ac-sheet, .ac-sheet.open, .ac-scrim { transition: none; } }

/* ============================================================
   รายการแชทกับน้องไซ (ปุ่มดินสอบนหัวจอแชท · คู่กับ aiChatsOpen ใน app.js)
   ใช้แผงลอย .fp ชุดเดียวกับแผงของแท่งกราฟ — งอกจากปุ่ม หดกลับเข้าปุ่ม · แถวไล่ลงทีละแถว
   หน้าตาแบบแถบ "ล่าสุด" ของแอปแชท AI: ปุ่ม "แชทใหม่" บนสุด → หัวข้อ "ล่าสุด" → ชื่อแชท (คำถามแรก) + เวลา
   ============================================================ */
.ch-panel { max-height: 74%; }
.ch-new {
  display: flex; align-items: center; gap: 10px; margin: 0 10px 6px; padding: 12px 14px; border: 0; border-radius: 16px; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 800; text-align: left;
  background: color-mix(in srgb, var(--fill) 12%, var(--card)); color: color-mix(in srgb, var(--fill) 85%, var(--ink));
  transition: transform .15s ease;
}
.ch-new svg { width: 18px; height: 18px; }
.ch-new:active { transform: scale(.97); }
.ch-sec { padding: 8px 20px 4px; font-size: 12px; font-weight: 800; letter-spacing: .02em; color: color-mix(in srgb, var(--ink) 55%, transparent); }
.ch-list { gap: 2px; padding-bottom: 12px; }
.ch-row { background: none; padding: 10px 10px 10px 12px; gap: 8px; cursor: pointer; }
.ch-row:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.ch-row.on { cursor: default; background: color-mix(in srgb, var(--fill) 8%, transparent); }
.ch-row .fp-tx b { font-weight: 600; font-size: 14.5px; }
.ch-row.on .fp-tx b { font-weight: 800; }
.ch-row .fp-tx i { align-self: auto; padding: 0; margin: 2px 0 0; background: none; font-size: 11.5px; font-weight: 600; color: color-mix(in srgb, var(--ink) 50%, transparent); }
.ch-row .fp-tx i.ch-now { color: var(--fill); font-weight: 800; }
.ch-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--fill); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fill) 20%, transparent); }
.ch-del {
  width: 30px; height: 30px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: none; color: color-mix(in srgb, var(--ink) 40%, transparent); transition: background .15s ease, color .15s ease;
}
.ch-del svg { width: 14px; height: 14px; }
.ch-del:hover, .ch-del:focus-visible { background: color-mix(in srgb, #DC2626 12%, transparent); color: #DC2626; }

/* ============================================================
   แก้โปรไฟล์ — ช่องกรอกแบบ HaloField (เจ้าของส่งเดโม HaloFieldDemo มา: "เอามาใช้ในหน้านี้ดู")
   ------------------------------------------------------------
   ได้มาแค่เดโม ไม่มีซอร์สคอมโพเนนต์ — ทำตามที่เดโมบอก: "เปลือกกระจกฝ้า มีขอบเคลื่อนไหว" (frosted shell with an animated rim)
   • ขอบ = ไล่สีวน (สีเน้นของธีม · ชมพู · ฟ้า) ทำด้วยพื้นสองชั้น (padding-box ทึบ + border-box ไล่สี) ไม่ต้องเพิ่ม <div>
   • ปกติขอบจาง ๆ นิ่ง ๆ · แตะช่อง = ขอบเข้มขึ้น วนช้า ๆ มีแสงเรืองรอบช่อง · ไอคอน/@ นำหน้าเปลี่ยนเป็นสีเน้น
   • ช่องชื่อมีไอคอนคนนำหน้า (leadingSlot ของเดโม) · ช่องชื่อผู้ใช้มี @ อยู่แล้ว
   • ไม่ได้เพิ่มบรรทัดคำอธิบายใต้ช่อง (HaloFieldDescription) — เจ้าของเคยสั่งถอดคำใบ้ใต้ชื่อกับชื่อผู้ใช้ออกแล้ว
   social.css โหลดทีหลังไฟล์นี้ — ขึ้นต้นด้วย .ep เพื่อให้หนักกว่ากฎเดิมของมัน
   ============================================================ */
@property --hf-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.ep .ep-f > input[type="text"], .ep .ep-f > textarea, .ep .ep-at {
  --hf-c1: color-mix(in srgb, var(--fill) 28%, transparent);
  --hf-c2: color-mix(in srgb, var(--halo-2) 22%, transparent);
  --hf-c3: color-mix(in srgb, var(--halo-3) 22%, transparent);
  border: 1.5px solid transparent; border-radius: 16px;
  background:
    linear-gradient(color-mix(in srgb, var(--card) 88%, transparent), color-mix(in srgb, var(--card) 88%, transparent)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  -webkit-backdrop-filter: blur(12px) saturate(150%); backdrop-filter: blur(12px) saturate(150%);
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
  transition: box-shadow .3s ease, --hf-c1 .3s, --hf-c2 .3s, --hf-c3 .3s;
}
.ep .ep-f > input[type="text"]:focus, .ep .ep-f > textarea:focus, .ep .ep-at:focus-within {
  --hf-c1: var(--fill);
  --hf-c2: color-mix(in srgb, var(--fill) 45%, var(--halo-2));
  --hf-c3: color-mix(in srgb, var(--fill) 45%, var(--halo-3));
  outline: none; border-color: transparent;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fill) 12%, transparent), 0 10px 26px -14px color-mix(in srgb, var(--fill) 70%, transparent);
  animation: hf-spin 4s steps(60) infinite;
}
/* hf-spin ทุกที่ใช้ steps (~15 ครั้ง/วิ) ไม่ใช่ linear — เหตุผลเดียวกับ ha-spin บนหน้าแรก:
   มุมของ conic-gradient ขยับ = วาดใหม่ทั้งช่อง + กระจกฝ้า (backdrop-filter) ของช่องเบลอใหม่ทุกครั้ง
   linear คือ 60 ครั้ง/วิ ตลอดเวลาที่จออยู่ · ตัวไหนเปลี่ยนแค่ animation-duration ต้องใส่ steps ใหม่คู่กันด้วย */
@keyframes hf-spin { to { --hf-a: 360deg; } }
.ep .ep-f > input[type="text"], .ep .ep-f > textarea { padding: 13px 15px; }
.ep .ep-at { padding-left: 14px; gap: 4px; }
.ep .ep-at input { padding: 13px 15px 13px 4px !important; }
.ep .ep-at > span, .ep .ep-at > svg { flex: none; color: color-mix(in srgb, var(--ink) 45%, transparent); transition: color .25s ease; }
.ep .ep-at > svg { width: 17px; height: 17px; }
.ep .ep-at:focus-within > span, .ep .ep-at:focus-within > svg { color: var(--fill); }
.ep .hf-lead { gap: 8px; }
.ep .ep-f > label { font-size: 12.5px; font-weight: 800; }
.ep .ep-f:focus-within > label { color: var(--fill); }
.ep .ep-count { font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  .ep .ep-f > input[type="text"]:focus, .ep .ep-f > textarea:focus, .ep .ep-at:focus-within { animation: none; }
}

/* แก้โปรไฟล์ · HaloField รอบสอง — เจ้าของ: "เอามาใช้ในหน้านี้ดิ ไม่เห็นเปลี่ยนอะไรเลย"
   รอบแรกขอบจางเกินไปตอนไม่ได้แตะ (ไล่สี 22–28%) และวนเฉพาะตอนพิมพ์ — มองแวบเดียวเหมือนช่องเดิม
   ตอนนี้: ขอบไล่สีชัดและวนช้า ๆ ตลอด (12 วินาทีต่อรอบ) มีรัศมีจาง ๆ รอบช่อง · แตะ = สว่างขึ้น วนเร็วขึ้น แสงเรืองกว้างขึ้น
   + บรรทัดคำอธิบายใต้ช่อง (HaloFieldDescription) + ข้อผิดพลาดสีแดงของชื่อผู้ใช้ (HaloFieldError · epHandleCheck) */
.ep .ep-f > input[type="text"], .ep .ep-f > textarea, .ep .ep-at {
  --hf-c1: color-mix(in srgb, var(--fill) 70%, transparent);
  --hf-c2: color-mix(in srgb, var(--halo-2) 60%, transparent);
  --hf-c3: color-mix(in srgb, var(--halo-3) 55%, transparent);
  border-width: 2px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fill) 6%, transparent), 0 8px 22px -16px color-mix(in srgb, var(--fill) 60%, transparent);
  animation: hf-spin 12s steps(180) infinite;
}
.ep .ep-f > input[type="text"]:focus, .ep .ep-f > textarea:focus, .ep .ep-at:focus-within {
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--fill) 15%, transparent), 0 12px 30px -12px color-mix(in srgb, var(--fill) 75%, transparent);
  animation: hf-spin 3.5s steps(53) infinite;
}
/* ผิดกติกา: ขอบแดงทึบ ไม่วน · แสงรอบเป็นแดง */
.ep .ep-at.invalid, .ep .ep-at.invalid:focus-within {
  --hf-c1: #DC2626; --hf-c2: #EF4444; --hf-c3: #F87171;
  animation: none;
  box-shadow: 0 0 0 4px rgba(220, 38, 38, .14);
}
.ep .ep-at.invalid > span { color: #DC2626; }
.ep .hf-desc { margin: -1px 2px 0; font-size: 12px; line-height: 1.5; font-weight: 500; color: color-mix(in srgb, var(--ink) 58%, transparent); }
.ep .hf-err {
  display: flex; align-items: center; gap: 6px; margin: -2px 2px 0;
  font-size: 12.5px; font-weight: 700; color: #DC2626; animation: hf-err-in .25s ease;
}
.ep .hf-err::before {
  content: '!'; width: 16px; height: 16px; flex: none; border-radius: 50%; display: grid; place-items: center;
  background: #DC2626; color: #fff; font-size: 11px; font-weight: 900; line-height: 1;
}
.ep .hf-err[hidden] { display: none; }
@keyframes hf-err-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .ep .ep-f > input[type="text"], .ep .ep-f > textarea, .ep .ep-at { animation: none; }
}

/* แก้โปรไฟล์: กรอบซ้อนสองชั้นตอนพิมพ์ (เจ้าของ: "ยังไม่ถูกแก้ด้วย" — ส่งรูปช่องชื่อที่มีกรอบน้ำเงินมนอยู่ข้างในกรอบไล่สี)
   ตัวการคือวงโฟกัสคีย์บอร์ดทั้งแอป (.phone :is(… input …):focus-visible · outline 2.5px !important · QA #17)
   ช่องพิมพ์ติด :focus-visible ทุกครั้งแม้แตะด้วยนิ้ว วงจึงไปวาดรอบ <input> ตัวในของกรอบ @ / ไอคอน
   กรอบ HaloField ข้างนอกบอกโฟกัสอยู่แล้ว (สว่างขึ้น วนเร็วขึ้น มีแสงรอบ) — ปิดวงซ้ำเฉพาะช่องในจอนี้ */
.phone .ep .ep-at input:focus-visible,
.phone .ep .ep-f > input[type="text"]:focus-visible,
.phone .ep .ep-f > textarea:focus-visible { outline: none !important; }
.ep .ep-at input:focus { border: 0 !important; background: none !important; box-shadow: none !important; }

/* ใบตัวอย่างในจอเพื่อน — วงกลมเป็นรูปของวิชา (subjGlyph ใน social.js) · เจ้าของ: "ปรับตรงนี้ให้เป็นโลโก้ที่ตรงตามหัวข้อ"
   พื้นอมสีประจำวิชา ขอบสีเดียวกันจาง ๆ ไอคอนสีเต็ม · Astral Black ขาวดำ */
.so-av.so-glyph {
  background: color-mix(in srgb, var(--sg) 15%, var(--card)); color: var(--sg);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--sg) 30%, transparent), 0 6px 14px -8px var(--sg);
  border-style: solid; border-color: transparent;
}
.so-av.so-glyph svg { width: 22px; height: 22px; }
:root[data-theme="astral"] .so-av.so-glyph { filter: grayscale(1); }

/* แก้โปรไฟล์ — คำอธิบายใต้ช่องกับบรรทัดความเป็นส่วนตัวชัดขึ้น (เจ้าของวงแดงสี่จุด: "ทำให้ตรงที่วงกลมสีแดงชัดหน่อย")
   เดิม 12px สีหมึก 58% บนพื้นลวดลายสีพาสเทล — จมไปกับพื้น · ตอนนี้ 12.5px หนาขึ้น สีหมึก 78%
   บรรทัดความเป็นส่วนตัวเป็นแถบพื้นอมสีเน้น มีไอคอนกุญแจสีเน้น — อ่านออกเป็นข้อความเดียวที่ตั้งใจให้อ่าน */
.ep .hf-desc { font-size: 12.5px; font-weight: 600; color: color-mix(in srgb, var(--ink) 86%, transparent); }
.ep .ep-fine {
  padding: 10px 12px; border-radius: 14px; font-size: 12.5px; font-weight: 600; line-height: 1.55;
  color: color-mix(in srgb, var(--ink) 82%, transparent);
  color: var(--ink);
  background: color-mix(in srgb, var(--fill) 14%, var(--card));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fill) 30%, transparent);
}
.ep .ep-fine svg { color: var(--fill); width: 14px; height: 14px; }

/* แท็บฉัน · หัวโปรไฟล์ตอนยังไม่ล็อกอิน (เจ้าของ: "ทำให้ตรงที่วงกลมสีแดงชัดหน่อย และแก้ตรงหน้าเข้าสู่ระบบ ปุ่มมันยังดูลอย ๆ")
   • บรรทัด "ยังไม่ล็อกอิน — เพื่อนยังหาคุณไม่เจอ": เดิมตัวเอียงสีจาง → ป้ายแคปซูลพื้นอมสีส้ม มีจุดสถานะ ตัวหนา ตัวตรง
   (ส่วนปุ่ม "เข้าสู่ระบบ" ที่เคยแก้ในบล็อกนี้ ถูกถอดออกแล้วตามที่เจ้าของสั่ง — ดูท้ายบล็อก) */
.ig-id > i.ig-off {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 6px; padding: 4px 11px 4px 9px; border-radius: 999px;
  font-style: normal; font-size: 12.5px; font-weight: 700; color: color-mix(in srgb, #C2410C 85%, var(--ink));
  background: color-mix(in srgb, #F97316 13%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #F97316 28%, transparent);
}
.ig-id > i.ig-off::before {
  content: ''; width: 7px; height: 7px; flex: none; border-radius: 50%; background: #F97316;
  box-shadow: 0 0 0 3px color-mix(in srgb, #F97316 22%, transparent);
}
/* ปุ่ม "เข้าสู่ระบบ": เคยลองลดเงาแล้วทำเป็นปุ่มทึบ (ไม่ลอย) สองรอบ — เจ้าของสั่ง "เอากลับไปเหมือนเดิม" จึงถอดออก ปุ่มกลับเป็นปุ่มกระจกตามเดิม */
:root[data-theme="astral"] .ig-id > i.ig-off { filter: grayscale(1); }

/* กล่องข้อความ (scr-dm) — หัวจอไม่มีแถบขาวแล้ว (เจ้าของวงแดง: "ลบตรงสีขาวที่วงรอมอยู่")
   .ch-top เป็นแถบพื้นการ์ดทึบมีเส้นใต้ (social.css) — เหมาะกับห้องแชทที่ข้อความเลื่อนผ่านใต้หัว
   แต่กล่องข้อความเป็นรายการบนพื้นลวดลายของธีม แถบขาวทึบเลยตัดจอเป็นสองท่อน · ที่นี่เหลือแค่ปุ่มกลับกับคำว่า "ข้อความ" ลอยบนพื้น
   เฉพาะ #dmBody — ห้องแชท (scr-chat) ยังมีแถบเหมือนเดิม */
#dmBody .ch-top { background: transparent; border-bottom: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
#dmBody .ch-top .ch-who b { font-size: 18px; font-weight: 800; }

/* ============================================================
   กล่องข้อความ — ช่องค้นหาแบบ HaloSearchInput (เจ้าของส่งเดโมมา: "เอามาใช้ในตรงนี้")
   ------------------------------------------------------------
   • วงไล่สี (สีเน้น · ชมพู · ฟ้า) วนรอบช่องช้า ๆ ตลอด มีรัศมีจาง ๆ — ทำด้วยพื้นสองชั้นบนตัว <input> (padding-box ทึบ + border-box ไล่สี)
   • แตะช่อง = วงสว่าง วนเร็วขึ้น แสงกว้างขึ้น (ไม่มีวงโฟกัสคีย์บอร์ดซ้อนอีกชั้น)
   • กำลังค้นหา (.busy) = วงวนเร็ว + "กำลังค้นหา…" ไหลเป็นคลื่นทีละตัวที่ท้ายช่อง (แทนบรรทัด "กำลังค้นหา…" ในรายการ)
   • ปุ่ม × = ตัวหนังสือในช่องร่วงลงจางหาย (.clearing) แล้วค่อยล้าง
   ใช้ @property --hf-a ตัวเดียวกับช่องแก้โปรไฟล์ · social.css โหลดทีหลัง จึงขึ้นต้นด้วย #dmBody
   ============================================================ */
#dmBody .dm-find input {
  --hf-c1: color-mix(in srgb, var(--fill) 65%, transparent);
  --hf-c2: color-mix(in srgb, var(--halo-2) 55%, transparent);
  --hf-c3: color-mix(in srgb, var(--halo-3) 50%, transparent);
  padding: 12px 40px 12px 40px; border: 2px solid transparent; border-radius: 999px; color: var(--ink);
  background:
    linear-gradient(color-mix(in srgb, var(--card) 90%, transparent), color-mix(in srgb, var(--card) 90%, transparent)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  -webkit-backdrop-filter: blur(12px) saturate(150%); backdrop-filter: blur(12px) saturate(150%);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fill) 6%, transparent), 0 10px 26px -16px color-mix(in srgb, var(--fill) 60%, transparent);
  animation: hf-spin 12s steps(180) infinite; animation-delay: var(--hf-ph, 0s);
  transition: color .2s ease, transform .2s ease, box-shadow .3s ease;
}
#dmBody .dm-find input:focus {
  outline: none;
  --hf-c1: var(--fill);
  --hf-c2: color-mix(in srgb, var(--fill) 45%, var(--halo-2));
  --hf-c3: color-mix(in srgb, var(--fill) 45%, var(--halo-3));
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--fill) 14%, transparent), 0 12px 30px -12px color-mix(in srgb, var(--fill) 75%, transparent);
  animation-duration: 4s; animation-timing-function: steps(60);
}
.phone #dmBody .dm-find input:focus-visible { outline: none !important; }
#dmBody .dm-find-ic { left: 29px; z-index: 1; color: color-mix(in srgb, var(--ink) 55%, transparent); transition: color .25s ease; }
#dmBody .dm-find.busy .dm-find-ic { color: var(--fill); }
#dmBody .dm-find:focus-within .dm-find-ic { color: var(--fill); }
#dmBody .dm-find-x { right: 25px; background: color-mix(in srgb, var(--ink) 9%, transparent); animation: dmx-in .3s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes dmx-in { from { opacity: 0; transform: translateY(-40%) scale(.4) rotate(-90deg); } }

/* กำลังค้นหา */
#dmBody .dm-find.busy input {
  --hf-c1: var(--fill);
  --hf-c2: color-mix(in srgb, var(--fill) 40%, var(--halo-2));
  --hf-c3: color-mix(in srgb, var(--fill) 40%, var(--halo-3));
  animation-duration: 1.4s; animation-timing-function: steps(21);
}
.dm-find-load {
  position: absolute; right: 28px; top: 50%; transform: translateY(-40%); pointer-events: none;
  display: inline-flex; font-size: 12.5px; font-weight: 700; color: var(--fill); white-space: pre;
}
.dm-find-load span { display: inline-block; animation: dm-wave 1.3s ease-in-out infinite; animation-delay: calc(var(--i) * 44ms); }
@keyframes dm-wave {
  0%, 100% { opacity: .35; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-2.5px); }
}

/* ปุ่ม × — ตัวหนังสือร่วงหาย */
#dmBody .dm-find.clearing input { color: transparent; transform: translateY(1px); }
#dmBody .dm-find.clearing .dm-find-x { transform: translateY(-40%) scale(.6) rotate(90deg); opacity: 0; transition: transform .2s ease, opacity .2s ease; }

@media (prefers-reduced-motion: reduce) {
  #dmBody .dm-find input, #dmBody .dm-find-x, .dm-find-load span { animation: none; }
}
:root[data-theme="astral"] #dmBody .dm-find input { filter: grayscale(1); }

/* ============================================================
   ห้องแชทกับเพื่อน (scr-chat) + กล่องข้อความ (scr-dm) — รอบปรับตามรูปของเจ้าของ
   ------------------------------------------------------------
   เจ้าของ: "ทำให้มีปุ่มเมนูกลับมาข้างล่าง · ตรงปุ่มข้อความปรับให้สวย แล้วลบดาวออก · ข้างบนลบกรอบสีขาวออก
            · ใส่อนิเมชันตอนพิมพ์เหมือนตอนแชทกับน้องไซ · ในหน้าแชทปรับให้ข้อความเห็นชัดขึ้นหน่อย"
   1 แถบล่างกลับมา (go() ไม่ใส่ chat-mode ให้สองจอนี้แล้ว) · จอกว้างที่เป็นกรอบโทรศัพท์ แถบล่างลอยทับก้นจอ
     จึงยกช่องพิมพ์ขึ้นเท่ากับจอน้องไซ (มือถือจริงแถบอยู่นอกพื้นที่จอ ไม่ต้องยก)
   2 หัวจอ: ไม่มีแถบขาว เส้นใต้ — ปุ่มกลับ รูป ชื่อ ลอยบนพื้นของธีม
   3 แถบพิมพ์: ไม่มีพื้นขาว · ช่องพิมพ์เป็นแคปซูลกระจกขอบไล่สีวน (ชุดเดียวกับช่องค้นหาในกล่องข้อความ)
     ดาว (ปุ่มอิโมจิ) เป็นหน้ายิ้ม · ปุ่มส่งเป็นลูกศรขึ้นในวงกลมไล่สี
   4 ตัวที่พิมพ์ค่อย ๆ ชัดขึ้นทีละตัว (ชั้นเงา .ha-mir ตัวเดียวกับช่องถามน้องไซบนหน้าแรก)
   5 ฟองข้อความ: ฟองของอีกฝ่ายเป็นพื้นการ์ดทึบมีขอบและเงาบาง (เดิมเทาจางกลืนพื้น) ตัวหนังสือเข้ม
     ฟองของเราไล่สีเน้น · เวลาใต้ฟองกับป้ายวันเข้มขึ้น
   ============================================================ */
/* 1 · ยกช่องพิมพ์พ้นแถบล่าง (เฉพาะกรอบโทรศัพท์บนจอกว้าง — เลขเดียวกับจอน้องไซ) */
:root:not([data-nav="side"]) .phone #scr-chat .scr-body { bottom: 80px; }   /* วัดที่ 1050px: 64 ยังทับแถบ 3px · 80 = ห่าง ~13px */
/* มือถือ: แถบล่างลอยทับก้นจอเหมือนกัน (วัดที่ 375px: bottom 0 = ช่องพิมพ์จมใต้แถบ 54px) — ยกพ้นแถบ + safe-area ของเครื่อง */
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) .phone #scr-chat .scr-body { bottom: calc(66px + env(safe-area-inset-bottom, 0px)); }
}
#scr-chat .ch-bar { padding-bottom: 10px; }

/* 2 · หัวจอโปร่ง */
#chatBody .ch-top { background: transparent; border-bottom: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
#chatBody .ch-who-tx b { font-size: 16px; font-weight: 800; }

/* 3 · แถบพิมพ์ */
#chatBody .ch-bar { background: transparent; border-top: 0; align-items: center; }
#chatBody .ch-field {
  --hf-c1: color-mix(in srgb, var(--fill) 60%, transparent);
  --hf-c2: color-mix(in srgb, var(--halo-2) 50%, transparent);
  --hf-c3: color-mix(in srgb, var(--halo-3) 45%, transparent);
  position: relative; flex: 1; min-width: 0; padding: 3px 4px 3px 16px; border: 2px solid transparent; border-radius: 999px;
  background:
    linear-gradient(color-mix(in srgb, var(--card) 92%, transparent), color-mix(in srgb, var(--card) 92%, transparent)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  -webkit-backdrop-filter: blur(12px) saturate(150%); backdrop-filter: blur(12px) saturate(150%);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fill) 6%, transparent), 0 10px 24px -16px color-mix(in srgb, var(--fill) 60%, transparent);
  animation: hf-spin 12s steps(180) infinite;
  transition: box-shadow .3s ease;
}
#chatBody .ch-field:focus-within {
  --hf-c1: var(--fill);
  --hf-c2: color-mix(in srgb, var(--fill) 45%, var(--halo-2));
  --hf-c3: color-mix(in srgb, var(--fill) 45%, var(--halo-3));
  border-color: transparent;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--fill) 14%, transparent), 0 12px 28px -12px color-mix(in srgb, var(--fill) 70%, transparent);
  animation-duration: 4s; animation-timing-function: steps(60);
}
.phone #chatBody .ch-field input:focus-visible { outline: none !important; }
#chatBody .ch-field input { font-size: 15px; padding: 9px 0; color: var(--ink); }
#chatBody .ch-emo-btn {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: none; color: color-mix(in srgb, var(--ink) 50%, transparent); transition: color .2s ease, background .2s ease;
}
#chatBody .ch-emo-btn svg { width: 21px; height: 21px; }
#chatBody .ch-emo-btn:hover, #chatBody .ch-emo-btn:active { color: var(--fill); background: color-mix(in srgb, var(--fill) 10%, transparent); }
#chatBody .ch-send {
  width: 38px; height: 38px; background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill));
  box-shadow: 0 6px 14px -6px var(--fill); color: var(--on-fill);
}
#chatBody .ch-send svg { width: 18px; height: 18px; }
#chatBody .ch-plus {
  width: 44px; height: 44px; background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill));
  box-shadow: 0 8px 18px -8px var(--fill);
}

/* 4 · ชั้นเงาตัวอักษร (ตัวเดียวกับ .td-ask บนหน้าแรก) */
#chatBody .ch-field.ha-on #chatIn { color: transparent; caret-color: var(--ink); }
#chatBody .ch-field.ha-on #chatIn::placeholder { color: transparent; }
#chatBody .ch-field.ha-has .ha-ph { display: none; }
#chatBody .ch-field .ha-mir { color: var(--ink); }

/* 5 · ฟองข้อความชัดขึ้น */
#chatBody .ch-msg:not(.me) .ch-bub {
  background: var(--card); color: var(--ink); font-weight: 500;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent), 0 4px 12px -8px rgba(0,0,0,.25);
}
#chatBody .ch-msg.me .ch-bub {
  background: linear-gradient(160deg, color-mix(in srgb, var(--fill) 82%, #fff), var(--fill)); color: var(--on-fill); font-weight: 600;
  box-shadow: 0 6px 14px -8px var(--fill);
}
#chatBody .ch-bub { font-size: 15px; line-height: 1.5; padding: 10px 15px; }
#chatBody .ch-when { font-size: 11px; font-weight: 600; color: color-mix(in srgb, var(--ink) 62%, transparent); }
#chatBody .ch-unsend { color: color-mix(in srgb, var(--ink) 62%, transparent); }
#chatBody .ch-day span {
  background: color-mix(in srgb, var(--card) 88%, transparent); color: color-mix(in srgb, var(--ink) 75%, transparent);
  font-weight: 700; box-shadow: 0 0 0 1px color-mix(in srgb, var(--fill) 14%, transparent);
}
#chatBody .ch-img { border-radius: 18px; box-shadow: 0 8px 20px -12px rgba(0,0,0,.4); }
/* ฟองใหม่เด้งเข้ามา — 12 ต.ค. 69 ย้ายไปเป็นคลาส .in-me/.in-them (ท้ายไฟล์ · "ห้องแชทแบบ IG")
   เดิมผูกกับ :last-child ซึ่งเล่นซ้ำทุกครั้งที่วาดรายการใหม่ (รูปเพิ่งได้ลิงก์ · มีคนพิมพ์) ทั้งที่ไม่ใช่ข้อความใหม่ */
@media (prefers-reduced-motion: reduce) {
  #chatBody .ch-field { animation: none; }
}
:root[data-theme="astral"] #chatBody .ch-field { filter: grayscale(1); }

/* ============================================================
   6 · หน้าโปรไฟล์ — โพสต์เป็นตารางแบบ TweetGrid + หัวข้อไล่สีแบบ GradientHeading (คู่กับ tweetCard ใน feed.js)
   ============================================================ */
.twg-head {
  margin: 6px 2px 14px; font-size: 24px; font-weight: 900; letter-spacing: -.02em; line-height: 1.2;
  background: linear-gradient(180deg, var(--ink) 20%, color-mix(in srgb, var(--fill) 70%, var(--ink)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.twg-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: start; }
.twg-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.twg-card {
  margin: 0; padding: 12px; border-radius: 18px; cursor: pointer; min-width: 0;
  background: var(--card); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 7%, transparent), 0 8px 20px -14px rgba(0,0,0,.35);
  animation: twg-in .5s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--i, 0) * 50ms);
  transition: transform .2s ease;
}
.twg-card:active { transform: scale(.98); }
@keyframes twg-in { from { opacity: 0; transform: translateY(12px); } }
.twg-h { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.twg-av { width: 28px; height: 28px; flex: none; border-radius: 50%; object-fit: cover; display: grid; place-items: center; font-size: 12px; font-weight: 800; color: #fff; background: var(--fill); }
.twg-av.anon { background: color-mix(in srgb, var(--ink) 20%, transparent); }
.twg-who { min-width: 0; display: flex; flex-direction: column; }
.twg-who b { font-size: 12.5px; font-weight: 800; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.twg-who i { font-style: normal; font-size: 10.5px; color: color-mix(in srgb, var(--ink) 55%, transparent); }
.twg-subj {
  display: inline-block; margin-bottom: 6px; padding: 2px 8px; border-radius: 99px; font-size: 10.5px; font-weight: 800;
  color: var(--sj, var(--fill)); background: color-mix(in srgb, var(--sj, var(--fill)) 14%, transparent);
}
.twg-body {
  margin: 0; font-size: 13px; line-height: 1.55; color: var(--ink); white-space: pre-wrap; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden;
}
.twg-img { display: block; width: 100%; margin-top: 8px; border-radius: 12px; object-fit: cover; max-height: 220px; }
.twg-f { display: flex; align-items: center; gap: 5px; margin-top: 9px; font-size: 11px; font-weight: 700; color: color-mix(in srgb, var(--ink) 55%, transparent); }
.twg-f svg { width: 13px; height: 13px; }
@media (prefers-reduced-motion: reduce) { .twg-card { animation: none; } }

/* กล่องข้อความ: ปุ่มดินสอลอยมุมขวาล่างเคยวางชิดก้นจอ (18px) เพราะจอนี้ซ่อนแถบล่าง — แถบกลับมาแล้ว ปุ่มจมใต้แถบ 36px (วัดที่ 375px)
   ยกขึ้นพ้นแถบ + ช่องหายใจ ~12px · ไล่สีชุดเดียวกับปุ่มส่งในห้องแชท */
:root:not([data-nav="side"]) #dmBody .dm-fab { bottom: 96px; }   /* กรอบโทรศัพท์บนจอกว้าง (วัดที่ 1050px) */
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) #dmBody .dm-fab { bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
}
#dmBody .dm-fab { background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill)); color: var(--on-fill); box-shadow: 0 10px 22px -10px var(--fill); }

/* ============================================================
   หน้าโปรไฟล์ของคน (scr-user) — หัวจอโปร่ง + แท็บโพสต์/คำตอบแบบแคปซูลเลื่อน (คู่กับ renderUser · switchUserTab)
   ------------------------------------------------------------
   เจ้าของ: "แก้ตรงนี้ ลบสีขาวตรงที่วงไว้ และก็จัดตรงโพสต์กับคำตอบให้มันสวยกว่านี้ และมีอนิเมชันสักหน่อย"
   • หัวจอ (.cp-top): ไม่มีแถบขาว เส้นใต้ — ปุ่มกลับเป็นวงกลมกระจก ชื่อ @ ตัวหนา
   • แท็บ: รางแคปซูลอมสี · ก้อนสีเน้นเลื่อนแบบสปริงไปหาแท็บที่กด · ตัวเลขจำนวนเป็นป้ายเล็กข้างชื่อแท็บ
   • สลับแท็บ: เนื้อหาเลื่อนเข้าจากฝั่งที่กด · การ์ดโพสต์ไล่ขึ้นทีละใบ (มีอยู่แล้วใน .twg-card)
   • ไม่มีอะไรให้ดู: กล่องกลางจอมีไอคอนในวงกลม หัวข้อ และคำอธิบาย แทนบรรทัดเทาบรรทัดเดียว
   ============================================================ */
#userBody .cp-top { background: transparent; border-bottom: 0; box-shadow: none; padding: 12px 14px 4px; }
#userBody .cp-top > b { font-size: 16px; font-weight: 800; }
#userBody .cp-x {
  width: 38px; height: 38px; justify-content: center; padding: 0; border-radius: 50%;
  background: color-mix(in srgb, var(--card) 80%, transparent); color: var(--ink);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent), 0 4px 12px -6px rgba(0,0,0,.25);
}
#userBody .cp-x svg { width: 18px; height: 18px; }

#userBody .ig-tabs {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; margin: 18px 2px 4px; padding: 4px;
  border: 0; border-radius: 999px;
  background: color-mix(in srgb, var(--fill) 9%, var(--card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent);
}
#userBody .ig-tab-ind {
  position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: 999px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill));
  box-shadow: 0 6px 14px -6px var(--fill), inset 0 1px 0 rgba(255,255,255,.3);
  transform: translateX(calc(var(--i, 0) * 100%));
  transition: transform .45s cubic-bezier(.3, 1.3, .5, 1);
}
#userBody .ig-tabs.hold .ig-tab-ind { transition: none; }
#userBody .ig-tabs button {
  position: relative; z-index: 1; padding: 10px 0; border: 0; border-radius: 999px;
  font-size: 13.5px; font-weight: 800; color: color-mix(in srgb, var(--ink) 65%, transparent);
  transition: color .3s ease, transform .15s ease;
}
#userBody .ig-tabs button.on { color: var(--on-fill); border-bottom-color: transparent; }
#userBody .ig-tabs button:active { transform: scale(.96); }
#userBody .ig-tabs button svg { width: 15px; height: 15px; }
#userBody .ig-tabs button i {
  font-style: normal; margin-left: 2px; padding: 0 7px; border-radius: 99px; font-size: 11px; line-height: 18px;
  background: color-mix(in srgb, var(--fill) 14%, transparent); color: var(--fill); transition: background .3s, color .3s;
}
#userBody .ig-tabs button.on i { background: rgba(255,255,255,.25); color: var(--on-fill); }

#userBody .ig-tabbody { padding: 12px 2px 24px; }
#userBody .ig-tabbody.swap { animation: igt-in .4s cubic-bezier(.22, 1, .36, 1); }
#userBody .ig-tabbody[data-dir="r"] { --dx: 18px; }
#userBody .ig-tabbody[data-dir="l"] { --dx: -18px; }
@keyframes igt-in { from { opacity: 0; transform: translateX(var(--dx, 0)); } }

.ig-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px;
  margin: 8px 0; padding: 26px 20px; border-radius: 22px;
  background: color-mix(in srgb, var(--card) 70%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fill) 14%, transparent);
  animation: igt-pop .45s cubic-bezier(.3, 1.3, .5, 1) both;
}
.ig-empty > span {
  width: 52px; height: 52px; margin-bottom: 8px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--fill) 14%, var(--card)); color: var(--fill);
  animation: igt-bob 3s ease-in-out infinite;
}
.ig-empty > span svg { width: 24px; height: 24px; }
.ig-empty b { font-size: 15px; font-weight: 800; color: var(--ink); }
.ig-empty p { margin: 0; font-size: 13px; line-height: 1.6; color: color-mix(in srgb, var(--ink) 65%, transparent); }
@keyframes igt-pop { from { opacity: 0; transform: scale(.94) translateY(8px); } }
@keyframes igt-bob { 50% { transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  #userBody .ig-tab-ind { transition: none; }
  #userBody .ig-tabbody.swap, .ig-empty, .ig-empty > span { animation: none; }
}

/* ห้องแชท: ปุ่มส่งอยู่ท้ายช่องพิมพ์ตลอด (เจ้าของวาดลูกศรชี้ตรงที่ว่างท้ายช่อง)
   เดิมซ่อนจนกว่าจะมีตัวหนังสือ (social.css · "ปุ่มที่กดไปก็ไม่เกิดอะไรคือปุ่มที่สอนให้เลิกเชื่อปุ่ม")
   ตอนนี้ใช้ทางเดียวกับช่องถามน้องไซบนหน้าแรก: ว่าง = วงกลมสีหมึกจาง ๆ (กดได้แต่ไม่ส่งอะไร) · มีตัวหนังสือ = ไล่สีเน้นเต็ม ลูกศรขยับขึ้นนิด */
#chatBody .ch-send { transform: none; opacity: 1; pointer-events: auto; transition: background .25s ease, box-shadow .25s ease, transform .15s ease; }
#chatBody .ch-send:not(.on) { background: color-mix(in srgb, var(--ink) 12%, transparent); color: color-mix(in srgb, var(--ink) 55%, transparent); box-shadow: none; }
#chatBody .ch-send svg { transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); }
#chatBody .ch-send.on svg { transform: translateY(-1px); }
#chatBody .ch-send:active { transform: scale(.9); }

/* ============================================================
   แผ่นเพิ่มงาน → หน้า "ตัวเชื่อม" — หัวจัดตรง + อนิเมชันตอนกด (เจ้าของ: "ทำให้ตรงแล้วถูกต้อง ให้ดูสบายตาและมีอนิเมชันตอนกด")
   ------------------------------------------------------------
   ต้นเหตุที่หัวเละ: ปุ่มย้อนเคยมี aria-label "กลับไปเมนูเพิ่มงาน" กฎปุ่มกลับลอยของทุกจอจับไปเป็นวงกลมลอยทับคำว่า "ตัวเชื่อม"
   (แก้ที่ป้ายใน app.js) · หัวตอนนี้เป็นแถวเดียว: วงกลมลูกศร · "ตัวเชื่อม" ตัวหนา · ป้ายจำนวนชิดขวา แล้วคำอธิบายใต้
   • กดแถว = แถวยุบนิด พื้นอมสี · กดสวิตช์ = ปุ่มกลมไถลแบบสปริง แถวกะพริบพื้นอมสีหนึ่งที (.pulse)
   • สลับหน้าในแผ่น = ของเลื่อนเข้าจากฝั่งที่ไป (.swap)
   ============================================================ */
#addSheet .as-back { display: flex; align-items: center; gap: 10px; padding: 2px 0 0; margin-bottom: 2px; font-size: 18px; font-weight: 800; }
#addSheet .as-bk {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: 50%; transform: none;
  background: color-mix(in srgb, var(--fill) 10%, var(--card)); color: var(--ink);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent);
  transition: transform .2s ease, background .2s ease;
}
#addSheet .as-bk svg { width: 17px; height: 17px; transform: rotate(180deg); }
#addSheet .as-back:active .as-bk { transform: scale(.9); background: color-mix(in srgb, var(--fill) 18%, var(--card)); }
#addSheet .as-back .as-cnt { margin-left: auto; font-size: 11.5px; font-weight: 800; }
#addSheet .as-sub { margin: 4px 0 8px 44px; font-size: 12.5px; color: color-mix(in srgb, var(--ink) 65%, transparent); }

#addSheet .as-tgl { border-radius: 16px; padding-left: 8px; padding-right: 8px; transition: transform .15s ease, background .25s ease; }
#addSheet .as-tgl + .as-tgl, #addSheet .as-tgl + .as-more { border-top-color: color-mix(in srgb, var(--ink) 7%, transparent); }
#addSheet .as-tgl:active { transform: scale(.98); background: color-mix(in srgb, var(--fill) 8%, transparent); border-radius: 16px; }
#addSheet .as-tgl.pulse { animation: as-pulse .5s ease; }
@keyframes as-pulse { 30% { background: color-mix(in srgb, var(--fill) 12%, transparent); } }
#addSheet .as-tgl .as-ic { transition: background .3s ease, color .3s ease, transform .3s cubic-bezier(.3, 1.6, .5, 1); }
#addSheet .as-tgl.pulse .as-ic { transform: scale(1.1); }
#addSheet .as-more { border-radius: 16px; padding-left: 8px; padding-right: 8px; transition: transform .15s ease; }
#addSheet .as-more:active { transform: scale(.98); }
#addSheet .as-more .as-go { transition: transform .2s ease; }
#addSheet .as-more:active .as-go { transform: translateX(3px); }

#addSheet .as-card.swap > * { animation: as-swap .4s cubic-bezier(.22, 1, .36, 1) both; }
#addSheet .as-card.swap > :nth-child(3) { animation-delay: .03s; }
#addSheet .as-card.swap > :nth-child(4) { animation-delay: .06s; }
#addSheet .as-card.swap > :nth-child(5) { animation-delay: .09s; }
#addSheet .as-card.swap > :nth-child(n+6) { animation-delay: .12s; }
#addSheet .as-card[data-dir="r"] { --dx: 22px; }
#addSheet .as-card[data-dir="l"] { --dx: -22px; }
@keyframes as-swap { from { opacity: 0; transform: translateX(var(--dx, 0)); } }
#addSheet .as-card.swap > .as-grip { animation: none; }
@media (prefers-reduced-motion: reduce) {
  #addSheet .as-card.swap > *, #addSheet .as-tgl.pulse { animation: none; }
}

/* ============================================================
   โหมดเครื่องเบา — :root[data-lite] (ติดจาก liteProbe() ใน app.js · หรือแรม ≤2GB ใน <head>)
   ------------------------------------------------------------
   เจ้าของ 8 ต.ค. 69: "เอาบั๊กที่ทำให้เครื่องค้างออกไปสำหรับคนโทรศัพท์ไม่แรง"
   ถอดเฉพาะของที่กินการ์ดจอต่อเนื่อง — สี ธีม ตัวหนังสือ ปุ่ม เหมือนเดิมทุกอย่าง
   • กระจกฝ้า (backdrop-filter) ทุกชิ้น: เบลอสิ่งที่อยู่ข้างหลังใหม่ทุกครั้งที่ข้างหลังขยับหรือเลื่อนจอ
     หน้าแรกอย่างเดียวมี 11 ชิ้น (ไอคอนกริด 8 · แถบล่าง · กระดิ่ง · ช่องถามน้องไซ)
   • ฉากเคลื่อนไหวของธีม (.fx · .starfield) · วงแสงหมุน (ha/hf-spin) · น้องไซลอย — หยุดค้างไว้ที่เฟรมแรก
     ใช้ paused ไม่ใช่ none: ของที่เริ่มจากโปร่งใส/นอกจอในเฟรมแรกยังอยู่ที่เดิมที่ออกแบบไว้ ไม่โผล่มาผิดที่
   ที่ไม่แตะ: อนิเมชันที่บอกสถานะ (กำลังโหลด · กำลังอัดเสียง · จับเวลาอยู่) — หยุดแล้วคนจะคิดว่าแอปค้าง
   ============================================================ */
:root[data-lite] *, :root[data-lite] *::before, :root[data-lite] *::after {
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
:root[data-lite] .fx, :root[data-lite] .fx *, :root[data-lite] .fx *::before, :root[data-lite] .fx *::after,
:root[data-lite] .starfield, :root[data-lite] .starfield *, :root[data-lite] .starfield *::before, :root[data-lite] .starfield *::after,
:root[data-lite] #menuBody .td-ask::before,
:root[data-lite] .ep .ep-f > input[type="text"], :root[data-lite] .ep .ep-f > textarea, :root[data-lite] .ep .ep-at,
:root[data-lite] #dmBody .dm-find input, :root[data-lite] #chatBody .ch-field,
:root[data-lite] .saih-face, :root[data-lite] .saip-chibi {
  animation-play-state: paused !important;
}
/* จอเอฟเฟกต์งานเสร็จเคยเป็นกระจกฝ้าเต็มจอ (พื้น 90%) — ไม่มีเบลอแล้ว หน้าแรกข้างหลังจะลอดมาคม ๆ · ทึบไปเลย */
:root[data-lite] .hoop-ov { background: var(--scr) !important; }
/* ชิ้นกระจกที่ "มีของเลื่อนผ่านข้างหลัง" — ไม่มีเบลอแล้วตัวหนังสือข้างหลังลอดมาอ่านชนกัน (แถบล่างพื้น 30–62%)
   ทึบด้วยสีการ์ดของธีม · ชิ้นกระจกอื่น (ปุ่ม การ์ด) วางบนพื้นไล่สีเรียบ ๆ ไม่มีเบลอก็ดูเหมือนเดิม จึงไม่แตะ */
:root[data-lite] .tabbar, :root[data-lite] #checkin, :root[data-lite] #installGuide { background: var(--card) !important; }

/* ============================================================
   แผ่นเพิ่มงานด่วน (quickadd.js) — ปุ่มลัดของตัวเครื่อง
   วางไว้บนครึ่งบนของจอ ไม่ใช่ขอบล่างแบบ appConfirm โดยตั้งใจ:
   แผ่นนี้เปิดมาพร้อมคีย์บอร์ดเสมอ · ถ้าอยู่ขอบล่าง iPhone จะเอาคีย์บอร์ดทับช่องพิมพ์
   ============================================================ */
.qa-scrim {
  position: absolute; inset: 0; z-index: 120; border-radius: inherit;
  background: rgba(10, 6, 20, .38); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  opacity: 0; transition: opacity .22s ease;
}
.qa-scrim.open { opacity: 1; }
.qa-sheet {
  position: absolute; left: 12px; right: 12px; top: calc(env(safe-area-inset-top) + 72px); z-index: 121;
  padding: 12px; border-radius: 24px; background: var(--card); color: var(--ink);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.5), 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
  opacity: 0; transform: translateY(-14px) scale(.97);
  transition: opacity .2s ease, transform .2s ease;
}
.qa-sheet.open { opacity: 1; transform: none; transition: opacity .25s ease, transform .4s cubic-bezier(.3, 1.3, .45, 1); }
.qa-row { display: flex; gap: 8px; align-items: center; margin: 0; }
.qa-in {
  flex: 1; min-width: 0; height: 48px; padding: 0 14px; border-radius: 16px;
  border: 1.5px solid color-mix(in srgb, var(--fill) 70%, transparent);
  background: color-mix(in srgb, var(--ink) 4%, transparent); color: var(--ink);
  font: inherit; font-size: 16px; outline: none;
}
.qa-in:focus { border-color: var(--fill); }
.qa-in.bad { animation: qa-shake .32s ease; border-color: #DC2626; }
@keyframes qa-shake { 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.qa-go {
  flex: none; width: 48px; height: 48px; border: 0; border-radius: 16px; cursor: pointer;
  display: grid; place-items: center; background: var(--fill); color: var(--on-fill);
  transition: transform .15s ease;
}
.qa-go:active { transform: scale(.92); }
.qa-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.qa-chips:not(:empty) { margin-top: 10px; }
.qa-chip {
  font-size: 12.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--fill) 14%, transparent); color: var(--ink);
}
.qa-chip.warn { background: color-mix(in srgb, #F59E0B 20%, transparent); }
@media (prefers-reduced-motion: reduce) { .qa-sheet, .qa-sheet.open, .qa-scrim { transition: none; } .qa-in.bad { animation: none; } }

/* แผงตั้งค่าในจอตัวเชื่อม (แถว "ปุ่มลัดเพิ่มงาน") */
.qa-panel { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.qa-p { display: flex; flex-direction: column; gap: 6px; }
.qa-h { font-size: 12px; font-weight: 800; letter-spacing: .02em; color: color-mix(in srgb, var(--ink) 60%, transparent); }
.qa-p .src-in { font-size: 12px; }
.qa-try {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  min-height: 38px; padding: 0 14px; border: 0; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: 13.5px; font-weight: 700;
  background: color-mix(in srgb, var(--fill) 14%, transparent); color: var(--ink);
}
.qa-try svg { width: 16px; height: 16px; }
.qa-how { list-style: none; margin: 4px 0 0; padding: 10px 12px; border-radius: 14px; display: flex; flex-direction: column; gap: 8px;
  background: var(--card2); }
.qa-how li { display: flex; align-items: flex-start; gap: 9px; font-size: 13px; line-height: 1.55; color: var(--muted); }
.qa-how i { flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 50%; display: grid; place-items: center;
  font-style: normal; font-size: 11px; font-weight: 800; background: var(--blue-soft); color: var(--blue); }
.qa-how div { min-width: 0; overflow-wrap: anywhere; }
.qa-how b { font-weight: 800; color: var(--ink); }
.qa-install { align-self: stretch; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 46px; border: 0; border-radius: 999px; cursor: pointer; font: inherit; font-size: 15px; font-weight: 800;
  background: var(--fill); color: var(--on-fill); }
.qa-install svg { width: 17px; height: 17px; }
.qa-install:active { transform: scale(.97); }
.qa-install[disabled] { opacity: .5; }
.qa-mini { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 2px; }
.qa-mini button, .qa-mini a { border: 0; background: none; padding: 4px 0; cursor: pointer; font: inherit; font-size: 12.5px;
  font-weight: 700; color: var(--muted); text-decoration: none; }
.qa-mini button:last-child { color: var(--alert, #DC2626); }

/* ============================================================
   น้องไซ/น้องฮูกเล่าให้ฟังทีละข้อ — ปุ่มแบบ HaloButton + อนิเมชันเลื่อนระหว่างข้อ (คู่กับ renderSaiTour · saiTourGo ใน sai.js)
   ------------------------------------------------------------
   เจ้าของส่งเดโม HaloButton มา: "ลองอันนี้ไปใช้ ทำอนิเมชันเลื่อนให้หน่อย" — ได้มาแค่เดโม ทำตามที่มันบอก:
   • "ต่อไป" = พื้นทึบสีเน้น มีรัศมีไล่สี (สีเน้น · ชมพู · ฟ้า) วนช้า ๆ รอบปุ่มและฟุ้งออกนอกขอบ
   • "ออก/ก่อนหน้า" = แบบโปร่ง (translucent) กระจกฝ้า ขอบไล่สีบาง ๆ
   • ป้ายบนปุ่มไล่ขึ้นทีละตัว (string children stagger ของเดโม) ทุกครั้งที่ข้อเปลี่ยน — "ต่อไป" → "ดูแผนทั้งวัน" เห็นว่าเปลี่ยน
   • เปลี่ยนข้อ: กล่องคำพูดกับตัวมาสคอตเลื่อนเข้าจากฝั่งที่กด (ต่อไป = จากขวา · ก่อนหน้า = จากซ้าย) · ขีดความคืบหน้าข้อใหม่ยืดเต็ม
   ============================================================ */
/* ปุ่ม */
.st-nav .hb { position: relative; isolation: isolate; border-radius: 999px; padding: 14px; overflow: visible; transition: transform .2s cubic-bezier(.3, 1.5, .5, 1); }
.st-nav .hb:active { transform: scale(.96); }
.st-nav .st-next.hb {
  background: linear-gradient(180deg, color-mix(in srgb, var(--fill) 82%, #fff), var(--fill));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 10px 22px -12px var(--fill);
}
.st-nav .st-next.hb::before {
  content: ''; position: absolute; inset: -3px; z-index: -1; border-radius: inherit; pointer-events: none;
  background: conic-gradient(from var(--hf-a), var(--fill), color-mix(in srgb, var(--fill) 45%, var(--halo-2)),
    color-mix(in srgb, var(--fill) 40%, var(--halo-3)), color-mix(in srgb, var(--fill) 55%, var(--halo-4)), var(--fill));
  filter: blur(8px); opacity: .7; animation: hf-spin 6s linear infinite;
}
.st-nav .st-back.hb.hb-glass {
  --hf-c1: color-mix(in srgb, var(--fill) 45%, transparent);
  --hf-c2: color-mix(in srgb, var(--halo-2) 40%, transparent);
  --hf-c3: color-mix(in srgb, var(--halo-3) 35%, transparent);
  border: 1.5px solid transparent; color: color-mix(in srgb, var(--ink) 75%, transparent);
  background:
    linear-gradient(color-mix(in srgb, var(--card) 75%, transparent), color-mix(in srgb, var(--card) 75%, transparent)) padding-box,
    conic-gradient(from var(--hf-a), var(--hf-c1), var(--hf-c2), var(--hf-c3), var(--hf-c1)) border-box;
  -webkit-backdrop-filter: blur(12px) saturate(150%); backdrop-filter: blur(12px) saturate(150%);
  animation: hf-spin 10s linear infinite;
}
.hb-lb { display: inline-flex; white-space: pre; }
.hb-lb span { display: inline-block; animation: hb-in .42s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--k, 0) * 28ms + 60ms); }
@keyframes hb-in { from { opacity: 0; transform: translateY(6px); filter: blur(3px); } }
.st-nav .st-next svg { transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); }
.st-nav .st-next:active svg { transform: translateX(3px); }

/* เลื่อนระหว่างข้อ */
.st-mid[data-dir="1"] .st-say, .st-mid[data-dir="1"] .st-stage { animation: st-from-r .45s cubic-bezier(.22, 1, .36, 1) both; }
.st-mid[data-dir="-1"] .st-say, .st-mid[data-dir="-1"] .st-stage { animation: st-from-l .45s cubic-bezier(.22, 1, .36, 1) both; }
.st-mid[data-dir="1"] .st-stage, .st-mid[data-dir="-1"] .st-stage { animation-delay: .04s; }
@keyframes st-from-r { from { opacity: 0; transform: translateX(34px); } }
@keyframes st-from-l { from { opacity: 0; transform: translateX(-34px); } }
.st-dots i { transform-origin: 0 50%; }
.st-dots i.on:last-of-type, .st-dots i.on:has(+ i:not(.on)) { animation: st-dot .45s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes st-dot { from { transform: scaleX(.2); } }
@media (prefers-reduced-motion: reduce) {
  .st-nav .st-next.hb::before, .st-nav .st-back.hb.hb-glass, .hb-lb span,
  .st-mid[data-dir] .st-say, .st-mid[data-dir] .st-stage, .st-dots i.on { animation: none; }
}
:root[data-theme="astral"] .st-nav .st-next.hb::before { filter: grayscale(1) blur(8px); }

/* ============================================================
   แผนวันนี้ (scr-sai · renderSaiPlan) — สวยขึ้นและเป็นระเบียบ แต่ยังสบายตา
   ------------------------------------------------------------
   เจ้าของ: "ทำให้ในหน้ามีความสนใจมากกว่านี้ … ยังดูไม่ค่อยสวย ทำให้ดูมีความสวยและเป็นระเบียบนะ"
   ของที่เจ้าของเคาะไว้แล้วยังอยู่: ช่องว่างสีฟ้า (--sig-blue) · เวลาตัวหนาเด่นสุด · ไม่มีรางเส้นตั้ง
   • การ์ดมาสคอต: พื้นไล่สีอ่อนของธีม · คำพูดอยู่ในฟองมีหางชี้หามาสคอต · การ์ดพอดีตัว ไม่มีที่โหว่
   • ช่องว่าง: ฟ้าไล่ลึก มีเงาเรืองสีเดียวกันและแสงมุมบน · ป้าย "ว่าง" มีนาฬิกา · ตัวเลขเวลาว่างตัวใหญ่
   • ตื่น/นอน: ไอคอนพระอาทิตย์/พระจันทร์ในวงกลมเล็ก
   • เส้น "ตอนนี้": ป้ายเวลาแคปซูลแดงมีจุดกะพริบ เส้นไล่จาง
   • เปิดจอ: แถวไล่ขึ้นทีละแถว (ห่างกัน 40ms)
   ============================================================ */
#saiBody .sai-hi {
  grid-template-columns: 96px minmax(0, 1fr); gap: 12px; padding: 12px 16px 12px 8px; border: 0; border-radius: 26px;
  background:
    radial-gradient(120% 140% at 0% 100%, color-mix(in srgb, var(--fill) 16%, transparent), transparent 60%),
    linear-gradient(160deg, color-mix(in srgb, var(--card) 92%, var(--fill)), var(--card));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fill) 14%, transparent), 0 14px 32px -20px color-mix(in srgb, var(--fill) 60%, transparent);
}
#saiBody .sai-say { position: relative; }
#saiBody .sai-say > span {
  position: relative; display: block; padding: 13px 16px; border-radius: 18px 18px 18px 6px;
  background: var(--card); font-size: 15px; font-weight: 700; line-height: 1.55; color: var(--ink); text-wrap: pretty;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fill) 16%, transparent), 0 6px 16px -10px rgba(0,0,0,.25);
}
#saiBody .sai-say > span::before {
  content: ''; position: absolute; left: -7px; bottom: 10px; width: 14px; height: 14px; transform: rotate(45deg);
  background: var(--card); box-shadow: -1px 1px 0 color-mix(in srgb, var(--fill) 16%, transparent);
  border-radius: 0 0 0 3px;
}

/* หัวหมวด */
#saiBody .sec-label { margin-top: 18px; font-size: 14px; font-weight: 800; color: var(--ink); }

/* แถวไล่ขึ้นตอนเปิดจอ */
#saiBody .sd-r { animation: sd-in .45s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--n, 0) * 40ms); }
@keyframes sd-in { from { opacity: 0; transform: translateY(8px); } }

/* ช่องว่าง */
#saiBody .sd-free .sd-x {
  position: relative; overflow: hidden; border: 0; border-radius: 20px; padding: 14px 16px;
  background: linear-gradient(150deg, #3B82F6, var(--sig-blue) 55%, #1748A8);
  box-shadow: 0 14px 28px -16px rgba(27, 95, 208, .8), inset 0 1px 0 rgba(255,255,255,.25);
}
#saiBody .sd-free .sd-x::after {
  content: ''; position: absolute; inset: -40% -20% auto auto; width: 70%; height: 120%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255,255,255,.22), transparent 70%);
}
#saiBody .sd-free .sd-x > b { margin-top: 6px; font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
#saiBody .sd-free .sd-x > i { font-size: 12px; font-weight: 600; }
.sd-tag {
  display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  font-size: 11px; font-weight: 800; color: #fff; background: rgba(255,255,255,.18);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.25);
}
.sd-tag svg { width: 15px; height: 15px; }

/* ตื่น/นอน */
#saiBody .sd-wake .sd-x, #saiBody .sd-sleep .sd-x { display: flex; align-items: center; gap: 9px; padding: 4px 0 4px 6px; }
.sd-ic {
  width: 28px; height: 28px; flex: none; display: grid; place-items: center; border-radius: 50%;
  background: color-mix(in srgb, var(--card) 80%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
}
.sd-ic svg { width: 15px; height: 15px; }
.sd-wake .sd-ic { color: #F59E0B; }
.sd-sleep .sd-ic { color: #6366F1; }
#saiBody .sd-wake .sd-x > b, #saiBody .sd-sleep .sd-x > b { font-size: 14px; color: color-mix(in srgb, var(--ink) 70%, transparent); }

/* เส้น "ตอนนี้" */
#saiBody .sd-now span {
  justify-self: end; display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px 3px 7px; border-radius: 99px;
  font-size: 12.5px; color: #fff; background: var(--alert); box-shadow: 0 6px 14px -8px var(--alert);
}
#saiBody .sd-now span em { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: sd-blink 1.6s ease-in-out infinite; }
@keyframes sd-blink { 50% { opacity: .25; } }
#saiBody .sd-now i { height: 2px; background: linear-gradient(90deg, var(--alert), color-mix(in srgb, var(--alert) 10%, transparent)); }
#saiBody .sd-now { grid-template-columns: 64px minmax(0, 1fr); }

/* ปุ่มเล่าทีละข้อ */
#saiBody .sai-tour {
  border-style: solid; border-color: color-mix(in srgb, var(--fill) 35%, transparent); border-radius: 999px;
  background: color-mix(in srgb, var(--fill) 8%, var(--card)); transition: transform .15s ease, background .2s ease;
  color: color-mix(in srgb, var(--fill) 55%, var(--ink)); /* ผสมกับสีตัวหนังสือ — ธีมมืดสีเน้นล้วนจมพื้น */
}
#saiBody .sai-tour:active { background: color-mix(in srgb, var(--fill) 14%, var(--card)); }
@media (prefers-reduced-motion: reduce) {
  #saiBody .sd-r, #saiBody .sd-now span em { animation: none; }
}

/* ============================================================
   ไมค์ (scr-scan) — กล่องคำที่ได้ยินอยู่ใต้ปุ่มไมค์ + คลื่นเสียงสีรุ้ง (คู่กับ voiceWave/voiceWaveKick ใน app.js)
   ------------------------------------------------------------
   เจ้าของ: "ทำให้ขึ้นไปตรงตำแหน่งตามลูกศร และแก้เมื่อพูดให้ใช้อนิเมชันคล้ายกับรูปสอง"
   • แท่งมน 36 แท่ง สูงเป็นสามลูกคลื่น ไล่สีรุ้ง · แต่ละแท่งเต้นช้ากว่าแท่งข้าง ๆ 50ms → คลื่นวิ่งจากซ้ายไปขวา
   • ได้คำใหม่ทุกครั้ง คลื่นเด้งสูงขึ้นแวบหนึ่ง (.kick)
   • หยุดฟังแล้วคลื่นหายไป เหลือแต่ข้อความ (กฎ .voice-box.idle .wave เดิมใน style.css)
   ============================================================ */
@property --vw-amp { syntax: '<number>'; inherits: true; initial-value: 1; }
#voiceBox { margin-top: 0; animation: vw-box .4s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes vw-box { from { opacity: 0; transform: translateY(-6px) scale(.98); } }
#voiceBox .vw { height: 58px; gap: 3.5px; margin: 2px 0 10px; }
#voiceBox .vw i {
  width: 4.5px; flex: none; height: 100%; border-radius: 99px; background: var(--c); transform-origin: 50% 50%;
  transform: scaleY(calc(var(--h) * .5));
  animation: vw-bob 1.4s ease-in-out infinite; animation-delay: calc(var(--i) * -50ms);
  box-shadow: 0 0 10px -2px var(--c);
}
@keyframes vw-bob {
  0%, 100% { transform: scaleY(calc(var(--h) * .38 * var(--vw-amp))); }
  50%      { transform: scaleY(min(1, calc(var(--h) * .92 * var(--vw-amp)))); }
}
#voiceBox.kick { animation: vw-kick .5s ease-out; }
@keyframes vw-kick { 0% { --vw-amp: 1.25; } 100% { --vw-amp: 1; } }
#voiceBox .voice-text { text-align: center; }
#voiceBox.idle .voice-text { text-align: left; }
@media (prefers-reduced-motion: reduce) {
  #voiceBox, #voiceBox .vw i, #voiceBox.kick { animation: none; }
}

/* ============================================================
   เพื่อนร่วมห้อง · แก้โปรไฟล์ (scr-people · #matesBody) — เต็มจอ + การ์ดชื่อมีขอบสว่าง
   ------------------------------------------------------------
   เจ้าของ: "ทำให้มันเต็มหน้าจอ และตรงหน้ายังไม่มีผู้ใช้ให้มีขอบสว่างสักหน่อย"
   • จอกว้าง: #matesBody มี margin:0 auto อยู่ในกล่อง flex จึงหดเหลือกว้างเท่าเนื้อหา (~300px) — ให้กว้างเต็มคอลัมน์
   • การ์ดรูป/ชื่อ (.ep-face): ขอบไล่สีสว่างวนช้า ๆ (ชุดเดียวกับช่องกรอกแบบ HaloField) + แสงขาวขอบบน
   ============================================================ */
:root[data-nav="side"] #scr-people #matesBody { width: 100%; max-width: none; } /* #scr-people = ชนะ feed.css ที่โหลดทีหลัง */
.ep .ep-face {
  position: relative; isolation: isolate; border: 2px solid transparent; border-radius: 22px;
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--card) 86%, #fff), color-mix(in srgb, var(--card) 90%, var(--fill))) padding-box,
    conic-gradient(from var(--hf-a), color-mix(in srgb, var(--fill) 70%, #fff), var(--halo-2), var(--halo-3), var(--halo-4), color-mix(in srgb, var(--fill) 70%, #fff)) border-box;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55), 0 0 0 4px color-mix(in srgb, var(--fill) 8%, transparent),
    0 14px 30px -18px color-mix(in srgb, var(--fill) 70%, transparent);
  animation: hf-spin 8s linear infinite;
}
.ep .ep-face::after {
  content: ''; position: absolute; inset: -6px; z-index: -1; border-radius: 26px; pointer-events: none;
  background: conic-gradient(from var(--hf-a), color-mix(in srgb, var(--fill) 55%, transparent), rgba(249,168,212,.5), rgba(147,197,253,.5), color-mix(in srgb, var(--fill) 55%, transparent));
  filter: blur(12px); opacity: .45;
}
@media (prefers-reduced-motion: reduce) { .ep .ep-face { animation: none; } }

/* ============================================================
   จอเปิดแอปแบบไอจี (#boot ใน index.html · สคริปต์อยู่ใต้มัน)
   ------------------------------------------------------------
   เจ้าของ: "ทำโหลดแอปก่อนเข้าให้หน่อย เอาให้คล้ายตอนเข้าไอจี แต่ตอนโหลดให้ใช้อนิเมชันนี้" (HaloProgress)
   • พื้นเรียบสีธีม (สคริปต์ใส่ให้) · โลโก้กลางค่อนบน · "from" เทาเล็ก + "Masterpiece" ชิดล่างแบบ "from Meta"
   • แถบใช้ .hprog เดิมของจอสแกน (แสงวาบวิ่ง + หัวเรือง) แต่ไม่มี transition — สคริปต์ขยับให้ทุกเฟรมเอง
   • ออก: ทั้งจอจางหาย โลโก้ขยายนิดเดียว (0.42 วิ) และจอแรกของแอปเลื่อนขึ้นจางเข้า · ลดการเคลื่อนไหว = จางอย่างเดียว

   รอบสอง (เจ้าของ: "จัดการเลย" ต่อข้อเสนอให้ดูสบายตาขึ้น):
   • ตัดป้ายกับตัวเลข % เหลือแค่แถบ · แถบสั้นลง (160px) บางลง (4px)
   • หัวแถบเรืองเบาลงมาก — ในธีมชมพูมันเคยเป็นก้อนม่วงสว่างที่ดึงตาไปจากโลโก้
   • "Masterpiece" ใช้สีไล่ของธีม (--grad-brand) แทนฟ้าตายตัว ที่หลุดโทนบนพื้นชมพู
   • จอแรกของแอปค่อย ๆ โผล่ (:root.boot-reveal) แทนการโผล่มาทั้งจอทีเดียว
   ============================================================ */
.boot {
  position: fixed; inset: 0; z-index: 2147483000; display: grid; place-items: center;
  background: var(--bg, #F7FAFF); color: var(--ink);
  transition: opacity .42s ease, visibility 0s linear .42s;
}
.boot.out { opacity: 0; visibility: hidden; pointer-events: none; }
.boot-mid { display: grid; justify-items: center; gap: 40px; width: min(160px, 50vw); transform: translateY(-3vh); }
.boot-mark {
  width: 92px; height: 92px; object-fit: contain;
  animation: boot-in .6s cubic-bezier(.22, 1, .36, 1) both;
  transition: transform .42s cubic-bezier(.22, 1, .36, 1);
}
.boot.dark .boot-mark { filter: drop-shadow(0 0 18px rgba(96, 165, 250, .4)) brightness(1.15); }
.boot.out .boot-mark { transform: scale(1.08); }
@keyframes boot-in { from { opacity: 0; transform: scale(.92); } }
.boot .boot-bar { width: 100%; margin: 0; animation: boot-fade .5s .15s ease both; }
@keyframes boot-fade { from { opacity: 0; } }
.boot .hp-track { height: 4px; background: color-mix(in srgb, var(--ink) 8%, transparent); box-shadow: none; }
.boot .hp-fill { transition: none; box-shadow: 0 0 6px color-mix(in srgb, var(--fill) 30%, transparent); }
.boot .hp-fill::after { opacity: .55; }
.boot .hp-track::after {
  transition: none; width: 8px; height: 8px;
  background: color-mix(in srgb, var(--fill) 35%, #fff);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--fill) 12%, transparent), 0 0 8px 1px color-mix(in srgb, var(--fill) 28%, transparent);
}
.boot-from {
  position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + 30px); margin: 0;
  display: grid; justify-items: center; gap: 2px; line-height: 1.2;
  animation: boot-fade .5s .2s ease both;
}
.boot-from span { font-size: 13px; font-weight: 500; color: var(--muted); letter-spacing: .01em; }
.boot-from b {
  font-size: 16px; font-weight: 800; letter-spacing: .02em;
  background: var(--grad-brand, linear-gradient(90deg, #2563EB, #22D3EE)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* จอแรกของแอปโผล่ตามหลังจอเปิด — backwards = มีผลแค่ช่วงเริ่ม ไม่ค้าง transform ไว้บนจอหลังเล่นจบ */
:root.boot-reveal .screen.on { animation: boot-reveal .55s cubic-bezier(.22, 1, .36, 1) backwards; }
@keyframes boot-reveal { from { opacity: 0; transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) {
  .boot-mark, .boot .boot-bar, .boot-from { animation: none; }
  .boot.out .boot-mark { transform: none; }
  :root.boot-reveal .screen.on { animation: boot-fade .35s ease backwards; }
}

/* ============================================================
   เก็บงานทั้งแอปให้สบายตา + แอนิเมชันแบบ Cult UI (9 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "จัดการเลย เอาให้สวย ที่สวยเอาอนิเมชันจากเว็บ Cult UI ได้" (ต่อรายการที่เสนอหลังไล่ดู 12 จอ)
   ============================================================ */

/* หน้าแรก · ลิงก์เข้าห้องแผนใต้การ์ดจอว่าง (แทนการ์ดน้องฮูกใบที่สองที่พูดซ้ำ) */
.td-clear .tc-room {
  display: flex; align-items: center; justify-content: center; gap: 2px; width: 100%;
  margin-top: 8px; padding: 6px 0 2px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 700; color: color-mix(in srgb, var(--fill) 80%, var(--ink));
}
.td-clear .tc-room svg { width: 15px; height: 15px; transition: transform .25s cubic-bezier(.3, 1.5, .5, 1); }
.td-clear .tc-room:active svg { transform: translateX(3px); }

/* หน้าแรก · ปุ่มแปดปุ่มอ่อนลงหนึ่งระดับ
   ยังเป็นสีทึบ — ผสมกับสีการ์ดของธีม ไม่ได้ทำให้โปร่ง (บทเรียนในโค้ด: ปุ่มโปร่งบนทะเลมืดเคยอ่านเป็นกระจกเทา
   จนเจ้าของสั่ง "สีปุ่มข้างล่างหายไปไหน เอากลับมา") · ธีมสว่างได้สีอ่อนลง ธีมมืดได้สีหม่นลง ทั้งคู่เบาตากว่าเดิม
   สัญลักษณ์ยังอยู่บนชิปขาวเหมือนเดิม จึงอ่านชัดเท่าเดิม · อยากได้แบบเข้มคืน: ลบกฎนี้กฎเดียว */
.phone .tg-grid .tg-t { --tg-bg: color-mix(in srgb, var(--fill) 76%, var(--card)); }

/* แชทน้องฮูก · แถวปุ่มคำถามที่เลื่อนข้างได้ — ขอบขวาจางออก แทนการโดนตัดขาดกลางปุ่ม
   เผื่อที่ขวา 28px ให้ปุ่มสุดท้ายเลื่อนพ้นช่วงจางได้ */
.phone .sai-qa.sai-qa {
  padding-right: 28px !important;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 30px), transparent);
          mask-image: linear-gradient(90deg, #000 calc(100% - 30px), transparent);
}

/* ตัวเลขที่หมุน (rollNumbers) ใช้ตัวเลขความกว้างเท่ากัน — ไม่งั้นทั้งแถวสั่นระหว่างหมุน */
.td-stats .ts > b, #statFull .at-v { font-variant-numeric: tabular-nums; }

/* บริบทของฉัน · แถบเวลาวันนี้เปิดจากซ้ายไปขวา + แท่ง 7 วันงอกขึ้นทีละแท่ง */
.screen.fx-in .cx2-bar { animation: fx-wipe .8s cubic-bezier(.22, 1, .36, 1) backwards; }
@keyframes fx-wipe { from { clip-path: inset(-20px 100% -20px -20px); } to { clip-path: inset(-20px -20px -20px -20px); } }
.screen.fx-in .cx2-day i { transform-origin: 50% 100%; animation: fx-grow-y .7s cubic-bezier(.22, 1, .36, 1) backwards; }
.screen.fx-in .cx2-day:nth-child(2) i { animation-delay: .05s; }
.screen.fx-in .cx2-day:nth-child(3) i { animation-delay: .1s; }
.screen.fx-in .cx2-day:nth-child(4) i { animation-delay: .15s; }
.screen.fx-in .cx2-day:nth-child(5) i { animation-delay: .2s; }
.screen.fx-in .cx2-day:nth-child(6) i { animation-delay: .25s; }
.screen.fx-in .cx2-day:nth-child(7) i { animation-delay: .3s; }
@keyframes fx-grow-y { from { transform: scaleY(0); } }

/* เหรียญตรา · แถบความคืบหน้ายืด + เหรียญที่ได้แล้วเด้งพร้อมวงแสงหนึ่งครั้ง (Halo Badge) */
.screen.fx-in .bg-pg i { transform-origin: 0 50%; animation: fx-grow-x .9s .2s cubic-bezier(.22, 1, .36, 1) backwards; }
@keyframes fx-grow-x { from { transform: scaleX(0); } }
.screen.fx-in .bg-row.on .bg-mark { animation: fx-badge .9s .15s cubic-bezier(.3, 1.4, .5, 1) backwards, fx-halo 1.1s .35s ease-out; }
@keyframes fx-badge { from { transform: scale(.7); opacity: .4; } }
@keyframes fx-halo {
  from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--fill) 45%, transparent); }
  to   { box-shadow: 0 0 0 12px color-mix(in srgb, var(--fill) 0%, transparent); }
}

/* กล่องเข้า · แถวแหล่งงานไล่ขึ้นทีละแถว */
.screen.fx-in .ib2-list > * { animation: fx-up .5s cubic-bezier(.22, 1, .36, 1) backwards; }
.screen.fx-in .ib2-list > :nth-child(2) { animation-delay: .05s; }
.screen.fx-in .ib2-list > :nth-child(3) { animation-delay: .1s; }
.screen.fx-in .ib2-list > :nth-child(4) { animation-delay: .15s; }
.screen.fx-in .ib2-list > :nth-child(n+5) { animation-delay: .2s; }
@keyframes fx-up { from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
  .screen.fx-in :is(.cx2-bar, .cx2-day i, .bg-pg i, .bg-row.on .bg-mark, .ib2-list > *) { animation: none; }
}

/* ============================================================
   กล่องวางรูปพื้นหลัง (#bgZone · ตั้งค่า → พื้นหลังภาพ) — แบบ HaloDropzone ของ Cult UI
   ------------------------------------------------------------
   เจ้าของส่งเดโม HaloDropzone มา: "ลองเอามาปรับใช้ดู" (แทนปุ่ม "เลือกภาพ" เดิม)
   • กล่องมุมมนโปร่งแสง ขอบเส้นประบาง · แสงไล่สีฟุ้งที่ขอบล่างลอยไปมาช้า ๆ (ฮาโล) · ไอคอนอัปโหลดในวงกลมกลางกล่อง
   • .drag (ลากไฟล์ค้างอยู่): ขอบทึบสีเน้น แสงเข้มขึ้น ไอคอนลอยขึ้น
   • .busy (กำลังย่อรูป): แถบวิ่งบาง ๆ ชิดขอบล่าง — ไม่มีตัวเลข เพราะการย่อในเครื่องวัดความคืบหน้าไม่ได้
   • .ok (เพิ่งเสร็จ): ไอคอนเด้งเป็นเครื่องหมายถูก · .has (มีภาพแล้ว): ภาพนั้นเป็นพื้นกล่อง มีเงาไล่ให้อ่านตัวหนังสือออก
   ============================================================ */
.hdz {
  position: relative; isolation: isolate; overflow: hidden; display: grid; justify-items: center; align-content: center;
  gap: 4px; min-height: 148px; margin-top: 12px; padding: 20px 16px; border-radius: 20px; cursor: pointer; text-align: center;
  border: 1.5px dashed color-mix(in srgb, var(--fill) 38%, transparent);
  background: color-mix(in srgb, var(--card) 70%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: border-color .25s ease, transform .25s cubic-bezier(.22, 1, .36, 1), box-shadow .25s ease;
}
.hdz:active { transform: scale(.985); }
.hdz-halo {
  position: absolute; z-index: -1; left: -15%; right: -15%; bottom: -70%; height: 120%; pointer-events: none;
  background:
    radial-gradient(40% 55% at 22% 50%, color-mix(in srgb, #EC4899 70%, var(--fill)), transparent 70%),
    radial-gradient(40% 55% at 52% 55%, color-mix(in srgb, #3B82F6 70%, var(--fill)), transparent 70%),
    radial-gradient(40% 55% at 82% 50%, color-mix(in srgb, #F59E0B 70%, var(--fill)), transparent 70%);
  filter: blur(26px); opacity: .42;
  animation: hdz-drift 9s ease-in-out infinite alternate;
  transition: opacity .3s ease, transform .3s ease;
}
@keyframes hdz-drift { from { transform: translateX(-6%) scaleY(.95); } to { transform: translateX(6%) scaleY(1.08); } }
.hdz-ic {
  position: relative; width: 44px; height: 44px; margin-bottom: 6px; border-radius: 50%; display: grid; place-items: center;
  color: color-mix(in srgb, var(--fill) 85%, var(--ink));
  background: color-mix(in srgb, var(--card) 85%, var(--fill));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 22%, transparent), 0 6px 16px -10px var(--fill);
  transition: transform .35s cubic-bezier(.3, 1.5, .5, 1);
}
.hdz-ic svg { position: absolute; width: 20px; height: 20px; transition: opacity .2s ease, transform .35s cubic-bezier(.3, 1.5, .5, 1); }
.hdz-ok { opacity: 0; transform: scale(.4); }
.hdz b { font-size: 14px; font-weight: 800; color: var(--ink); }
.hdz-hint { font-size: 12px; font-style: normal; color: color-mix(in srgb, var(--ink) 60%, transparent); }
.hdz-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; overflow: hidden; opacity: 0; transition: opacity .2s ease; }
.hdz-bar i { display: block; width: 36%; height: 100%; border-radius: 99px; background: var(--grad-brand, var(--fill)); }

/* ลากค้าง */
.hdz.drag { border-style: solid; border-color: var(--fill); transform: scale(1.012);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--fill) 14%, transparent), 0 16px 34px -18px var(--fill); }
.hdz.drag .hdz-halo { opacity: .8; transform: scaleY(1.25); }
.hdz.drag .hdz-ic { transform: translateY(-4px) scale(1.08); }
/* กำลังย่อรูป */
.hdz.busy { pointer-events: none; }
.hdz.busy .hdz-bar { opacity: 1; }
.hdz.busy .hdz-bar i { animation: hdz-run 1.1s cubic-bezier(.65, 0, .35, 1) infinite; }
@keyframes hdz-run { from { transform: translateX(-105%); } to { transform: translateX(285%); } }
.hdz.busy .hdz-ic { animation: hdz-breathe 1.1s ease-in-out infinite; }
@keyframes hdz-breathe { 50% { transform: scale(.92); } }
/* เพิ่งเสร็จ */
.hdz.ok .hdz-up { opacity: 0; transform: scale(.4); }
.hdz.ok .hdz-ok { opacity: 1; transform: scale(1); }
.hdz.ok .hdz-ic { color: #fff; background: var(--fill); animation: hdz-pop .5s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes hdz-pop { 40% { transform: scale(1.18); } }
/* มีภาพแล้ว */
.hdz-prev { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; animation: hdz-fade .5s ease both; }
@keyframes hdz-fade { from { opacity: 0; transform: scale(1.04); } }
.hdz.has { border-style: solid; border-color: transparent; }
.hdz.has::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(0,0,0,.08), rgba(0,0,0,.5)); }
.hdz.has .hdz-halo { opacity: .25; }
.hdz.has b, .hdz.has .hdz-hint { color: #fff; text-shadow: 0 1px 6px rgba(0,0,0,.45); }
.hdz.has .hdz-ic { background: rgba(255,255,255,.88); }

/* เอาพื้นหลังออก — แถวใต้กล่อง */
.hdz-del {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-top: 8px; padding: 8px;
  border: 0; border-radius: 12px; background: none; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 700; color: var(--alert, #DC2626);
}
.hdz-del[hidden] { display: none; }
.hdz-del svg { width: 15px; height: 15px; }
.hdz-del:active { background: color-mix(in srgb, var(--alert, #DC2626) 10%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .hdz-halo, .hdz.busy .hdz-ic, .hdz.ok .hdz-ic, .hdz-prev { animation: none; }
  .hdz.busy .hdz-bar i { animation: none; width: 100%; opacity: .5; }
}

/* ============================================================
   แอนิเมชันรอบสอง (9 ต.ค. 69) — เจ้าของ: "จัดการเลย เอาอนิเมชันมาจากแอปเดิม หรือถ้าไม่ถูกใจลองสร้างขึ้นมาดู"
   ตัวไหนมีในแอปอยู่แล้วหยิบมาใช้ซ้ำ (สปริงของตัวเลขหมุน) · ที่ไม่มีสร้างใหม่ตามแบบ Cult UI
   ============================================================ */

/* ---- 1 · โหมดโฟกัส: วงแหวนรอบนาฬิกา (tickFocus) ---- */
.fc-dial {
  --p: 0; position: relative; display: grid; place-items: center;
  width: min(184px, 50vw, 26vh); aspect-ratio: 1; margin: 0 auto;
}
.fc-ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.fc-ring circle { fill: none; stroke-width: 6.5; }
.fr-bg { stroke: color-mix(in srgb, var(--ink) 8%, transparent); }
.fr-fg {
  stroke: var(--fill); stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: calc(100 - var(--p));
  transition: stroke-dashoffset 1s linear, stroke .4s ease;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--fill) 45%, transparent));
}
.fc-dial.intro .fr-fg { transition: stroke-dashoffset 1.2s cubic-bezier(.22, 1, .36, 1), stroke .4s ease; }
.fc-dial.over .fr-fg { stroke: var(--warn, #F59E0B); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--warn, #F59E0B) 45%, transparent)); }
/* แสงหายใจหลังตัวเลข — เฉพาะตอนนาฬิกาเดิน (พักอยู่ = นิ่ง) */
.fc-dial::before {
  content: ''; position: absolute; inset: 16%; border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, color-mix(in srgb, var(--fill) 30%, transparent), transparent 70%);
}
.fc-dial.run::before { animation: fc-breathe 4.2s ease-in-out infinite; }
.fc-dial.over::before { background: radial-gradient(circle, color-mix(in srgb, var(--warn, #F59E0B) 26%, transparent), transparent 70%); }
@keyframes fc-breathe { 0%, 100% { opacity: .3; transform: scale(.9); } 50% { opacity: .95; transform: scale(1.06); } }
/* หลักตัวเลข (rollClock) */
.fc-dial .fc-el { position: relative; font-size: 42px; line-height: 1.12; letter-spacing: -.02em; }
.fc-dial .fc-el.long { font-size: 32px; }
.fc-el .fd { position: relative; display: inline-block; overflow: hidden; height: 1.12em; vertical-align: top; }
.fc-el .fd i { display: block; font-style: normal; }
.fc-el .fd .in { animation: fd-in .34s cubic-bezier(.22, 1, .36, 1); }
.fc-el .fd .out { position: absolute; left: 0; right: 0; top: 0; animation: fd-out .34s cubic-bezier(.22, 1, .36, 1) forwards; }
@keyframes fd-in { from { transform: translateY(75%); opacity: 0; filter: blur(2px); } }
@keyframes fd-out { to { transform: translateY(-75%); opacity: 0; filter: blur(2px); } }
.fc-el .fc-colon { display: inline-block; vertical-align: top; opacity: .55; }
.fc-dial.run .fc-colon { animation: fc-blink 2s steps(1) infinite; }
@keyframes fc-blink { 50% { opacity: .2; } }
.fc-dial + .fc-target { margin-top: 10px; }

/* ---- 2 · เปลี่ยนธีม: วงกลมแผ่ออก (themeReveal) — ปิดการไขว้จางของเบราว์เซอร์ ให้วงกลมเป็นตัวเดียวที่ขยับ ---- */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ---- 3 · แท็บงาน: เนื้อหาเลื่อนเข้าจากฝั่งที่กด (setTaskView) ---- */
#taskList.tk-swap { overflow-x: clip; }
#taskList.tk-swap > :not(.page-head) { animation: tk-from-r .42s cubic-bezier(.22, 1, .36, 1) backwards; }
#taskList.tk-swap[data-swap="-1"] > :not(.page-head) { animation-name: tk-from-l; }
#taskList.tk-swap > :nth-child(3) { animation-delay: .03s; }
#taskList.tk-swap > :nth-child(n+4) { animation-delay: .06s; }
@keyframes tk-from-r { from { opacity: 0; transform: translateX(24px); } }
@keyframes tk-from-l { from { opacity: 0; transform: translateX(-24px); } }

/* ---- 4 · ฟอร์มจาก AI: ป้ายเด้งทีละอัน + ช่องงานกำลังพิมพ์ (typeInto) ---- */
.fm-chips.ai-in .chip { animation: chip-pop .45s cubic-bezier(.3, 1.5, .5, 1) backwards; animation-delay: calc(var(--k, 0) * 70ms + 140ms); }
.fm-ok.show { animation: chip-pop .45s cubic-bezier(.3, 1.5, .5, 1) backwards; }
@keyframes chip-pop { from { opacity: 0; transform: translateY(4px) scale(.75); } }
#fDetail.ai-typing { caret-color: transparent; outline: 2px solid color-mix(in srgb, var(--fill) 35%, transparent); outline-offset: 2px; }

/* ---- 6 · คำทักทาย (greetIn) ---- */
.th-greet .tw { display: inline-block; animation: tw-in .7s cubic-bezier(.22, 1, .36, 1) backwards; animation-delay: calc(var(--k, 0) * 90ms + 80ms); }
@keyframes tw-in { from { opacity: 0; filter: blur(6px); transform: translateY(8px); } }

@media (prefers-reduced-motion: reduce) {
  .fc-dial.run::before, .fc-dial.run .fc-colon, .fc-el .fd .in, .fc-el .fd .out,
  #taskList.tk-swap > *, .fm-chips.ai-in .chip, .fm-ok.show, .th-greet .tw { animation: none; }
  .fr-fg { transition: none; }
}

/* ============================================================
   โหมดเครื่องเบา — ของที่หลุดไป (ตรวจบั๊ก 9 ต.ค. 69: เปิดโหมดนี้แล้วนับแอนิเมชันที่ยังวิ่งไม่หยุด)
   ------------------------------------------------------------
   สี่กลุ่มนี้เป็นแสงเบลอ (filter: blur) ที่วิ่งตลอดเวลา = วาดเบลอใหม่ทุกเฟรม · หนักที่สุดสำหรับการ์ดจอเครื่องสเปคต่ำ
   ก้อนแสงในแชทน้องฮูก (.hs-b) · แสงในกล่องวางรูปพื้นหลัง (.hdz-halo) · ขอบวนการ์ดชื่อในหน้าแก้โปรไฟล์ (.ep-face)
   · รัศมีรอบปุ่มเล่าทีละข้อ (.st-nav .hb) — หยุดไว้ที่เฟรมแรก (paused) หน้าตายังอยู่ครบ แค่ไม่ขยับ
   ============================================================ */
:root[data-lite] .hs-b, :root[data-lite] .hdz-halo,
:root[data-lite] .ep .ep-face, :root[data-lite] .ep .ep-face::after,
:root[data-lite] .st-nav .hb, :root[data-lite] .st-nav .hb::before {
  animation-play-state: paused !important;
}

/* ============================================================
   ปุ่มของจอถ่ายรูปใบงาน / สแกนตารางเรียน ตอนใช้กล้องในแอปไม่ได้ (.tt-cta · .tt-2nd)
   ------------------------------------------------------------
   เจ้าของ: "แก้ให้มันสวยหน่อย มีขอบสว่าง ๆ"
   • ต้นเหตุขอบเทาเดิม: .tt-cta ไม่เคยล้าง border — ได้ขอบนูน 2px outset ของเบราว์เซอร์ติดมา
   • ปุ่มหลัก: พื้นไล่สีเน้นของธีม · ขอบไล่สีสว่าง (ขาวด้านบน → อมสีธีม) · ประกายขาวบาง ๆ ขอบบน · วงแสงจาง ๆ รอบนอก
   • ปุ่มรอง: พื้นอมสีธีมอ่อน · ขอบไล่สีสว่างแบบเดียวกัน · ตัวหนังสือสีเน้น
   • ไม่มีแอนิเมชันวนไม่หยุด (จอนี้เปิดตอนกล้องมีปัญหา เครื่องอาจกำลังหนักอยู่) — แค่ยุบนิดหนึ่งตอนกด
   ============================================================ */
.tt-cta {
  position: relative; min-height: 52px; padding: 13px 16px; border: 1.5px solid transparent; border-radius: 18px;
  font-family: inherit; font-size: 15px; font-weight: 800; color: var(--on-fill, #fff);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill)) padding-box,
    linear-gradient(180deg, color-mix(in srgb, #fff 92%, var(--fill)), color-mix(in srgb, var(--fill) 45%, #fff) 60%, color-mix(in srgb, #fff 70%, var(--fill))) border-box;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 0 0 4px color-mix(in srgb, var(--fill) 13%, transparent),
    0 12px 26px -14px var(--fill);
  transition: transform .22s cubic-bezier(.3, 1.5, .5, 1), box-shadow .22s ease;
}
.tt-cta svg { width: 18px; height: 18px; }
.tt-cta:active { transform: scale(.97); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 0 0 3px color-mix(in srgb, var(--fill) 18%, transparent), 0 6px 14px -10px var(--fill); }
.tt-2nd {
  min-height: 48px; margin-top: 10px; border: 1.5px solid transparent; border-radius: 16px;
  font-weight: 700; color: color-mix(in srgb, var(--fill) 72%, var(--ink));
  background:
    linear-gradient(color-mix(in srgb, var(--card) 86%, var(--fill)), color-mix(in srgb, var(--card) 93%, var(--fill))) padding-box,
    linear-gradient(135deg, color-mix(in srgb, #fff 92%, var(--fill)), color-mix(in srgb, var(--fill) 32%, #fff), color-mix(in srgb, #fff 85%, var(--fill))) border-box;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 6px 16px -12px color-mix(in srgb, var(--fill) 60%, transparent);
  transition: transform .2s cubic-bezier(.3, 1.5, .5, 1);
}
.tt-2nd svg { width: 17px; height: 17px; }
.tt-2nd:active { transform: scale(.975); }
@media (prefers-reduced-motion: reduce) { .tt-cta, .tt-2nd { transition: none; } }

/* ============================================================
   ตรวจ "เลือกไม่ได้ / กดไม่ติด" (9 ต.ค. 69) — ไล่ทุกปุ่มทุกจอ เช็กว่าจุดที่นิ้วแตะโดนตัวมันจริง
   ------------------------------------------------------------
   1) ฟอร์มเพิ่มงาน: ปุ่มบันทึกปักอยู่เหนือแถบล่าง (sticky · bottom: --tb-under) แต่จอไม่มีที่เผื่อให้เลื่อนพ้น
      แถวท้ายฟอร์ม ("ความคืบหน้า") จึงจมใต้ปุ่มบันทึกแม้เลื่อนสุดแล้ว — ใส่ระยะเท่าที่ปุ่มยกขึ้นไว้เหนือปุ่ม
   2) ปุ่มเล็กกว่า 30px ขยาย "พื้นที่กด" ด้วยชั้นล่องหนรอบตัว — หน้าตาเท่าเดิม แต่นิ้วแตะพลาดนิดหน่อยก็ยังโดน
      (ปุ่ม − / + ชั่วโมงในตั้งค่า · กล้องบนรูปโปรไฟล์ · "ดูทั้งหมด" · "จัดการ" · สวิตช์ตัวเชื่อม · แถบ "ยังไม่ได้ใส่ตารางเรียน")
   ============================================================ */
@media (max-width: 768px), (display-mode: standalone) {
  :root:not([data-nav="side"]) .fm-bar { margin-top: var(--tb-under); }
}
/* ============================================================
   จอเพิ่มงาน: ซ่อนแถบเมนูล่าง ปุ่ม "เสร็จ" ติดขอบล่างจอ · 31 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ (ภาพปุ่ม "เสร็จ" ลอยเหนือแถบเมนู): "ปรับให้มันอยู่ข้างล่าง" → เลือก "ซ่อนแถบเมนูตอนกรอก"
   ตอนกรอกฟอร์มไม่มีใครไปแท็บอื่น (ออกด้วย × มุมซ้ายบน) แถบเมนูจึงเป็นแค่ของกินที่ใต้ปุ่มบันทึก
   openForm() สลับจอเองไม่ผ่าน go() → จับด้วย :has(#scr-form.on) ไม่ต้องเพิ่มคลาส · ออกจากฟอร์มผ่าน go() = แถบกลับมาเอง
   เฉพาะตอนเมนูอยู่ล่าง (แถบข้างของจอกว้างไม่แตะ) · เบราว์เซอร์ที่ไม่รู้จัก :has = เหมือนเดิมทุกอย่าง
   ต้องแก้คู่กันสามที่: ซ่อนแถบ · .screens เลิกยื่นลงใต้แถบ (มือถือ: margin ติดลบเท่าแถบ ไม่งั้นท้ายจอหลุดขอบ)
   · แถบปุ่มฟอร์มเลิกยกตัวหลบแถบ (มือถือ --tb-under · แท็บเล็ต 90px ใน device-preview-controls.css) ลงไปติดขอบล่าง
   ============================================================ */
:root:not([data-nav="side"]) body:has(#scr-form.on) .tabbar { display: none !important; }
:root:not([data-nav="side"]) body:not(.login-mode):has(#scr-form.on) .screens { margin-bottom: 0; }
:root:not([data-nav="side"]) body:has(#scr-form.on) #scr-form .fm-bar {
  bottom: 0; margin-top: 0;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
:is(.stp-b, .ig-av-cam, .st-open-go, .an-grp > button, .ib2-sec > button, .tg, .tl-hint) { position: relative; }
:is(.stp-b, .ig-av-cam, .st-open-go, .an-grp > button, .ib2-sec > button, .tg)::after {
  content: ''; position: absolute; inset: -9px; border-radius: 12px;
}
.tl-hint::after { content: ''; position: absolute; inset: -8px 0; }

/* ============================================================
   หน้าโหลดขาวอย่างเดียว (#boot) — เจ้าของ: "แก้ให้มันเป็นหน้าโหลดขาวอย่างเดียว"
   ------------------------------------------------------------
   พื้นขาวทุกธีม · แถบโหลดกับ "Masterpiece" ใช้น้ำเงินของโลโก้ (ไล่ #2563EB → #22D3EE แบบตัว S) ทุกธีม
   ตั้งโทเคนสีใหม่ "ในตัว #boot" ไม่แตะของธีม — หน้าโหลดจึงหน้าตาเดียวกันทุกเครื่อง ไม่ว่าจะใช้ธีมไหน
   ============================================================ */
.boot {
  --fill: #2563EB; --grad-brand: linear-gradient(90deg, #2563EB, #22D3EE);
  --ink: #0F1E3D; --muted: #8592AD;
  background: #FFFFFF !important; color: var(--ink);
}
.boot .boot-mark { filter: none; }
.boot .hp-track { background: #E8EEF9; }
/* โลโก้อยู่กลางจอพอดีแบบไอจี (เจ้าของ: "แก้ให้มันตรง") — เดิมจัด "โลโก้ + แถบ" เป็นก้อนเดียวไว้กลางจอแล้วยกขึ้นอีก 3vh
   ตัวโลโก้จึงไม่อยู่กลางจริง · ตอนนี้ก้อนกลางสูงเท่าโลโก้ แถบโหลดลอยอยู่ใต้โลโก้ 34px (absolute) ไม่ดันโลโก้ขึ้น */
.boot .boot-mid { position: relative; gap: 0; transform: none; }
.boot .boot-bar { position: absolute; left: 0; right: 0; top: calc(100% + 34px); }

/* ============================================================
   คุมให้ลื่น 60fps (9 ต.ค. 69) — เจ้าของ: "ลองคุมให้ได้ 60 fps หน่อย จะได้ไม่ค้าง ต่อให้เครื่องจะไม่ดี"
   ------------------------------------------------------------
   • หน้าโหลด: แถบขยับด้วย transform (การ์ดจอทำเองบนเลเยอร์ของมัน) แทน width ที่ต้องคำนวณผังใหม่ทุกเฟรม
   • ของเบลอที่ขยับอยู่ตลอด (แสงฟุ้ง/ก้อนแสง) ให้มีเลเยอร์ของตัวเอง — ขยับแล้วไม่ต้องวาดเบลอใหม่
   • โหมดลื่น (data-lite): เดิมเป็นสวิตช์ในตั้งค่า — ตอนนี้คือระดับ "กลาง" ของปุ่มกราฟิก
   ============================================================ */
.boot .hp-fill { width: 100% !important; transform-origin: 0 50%; transform: scaleX(0); will-change: transform; }
.hdz-halo, .hs-b { will-change: transform; }
/* #liteBtn ถูกแทนด้วยปุ่มสามระดับ #gfxSeg (19 ต.ค. 69) — ดูบล็อก "ระดับกราฟิก" ท้ายไฟล์ */

/* ============================================================
   หน้า "เสร็จแล้ว" (doneView · แท็บงาน › เสร็จแล้ว) — แต่งให้สวย + อนิเมชันตอนกดเข้า
   ------------------------------------------------------------
   เจ้าของ: "ตกแต่งหน่อย แล้วก็ใส่อนิเมชันตอนกดเข้าไป"
   • การ์ดสรุปบนสุด: เหรียญเครื่องหมายถูกสีทอง · ตัวเลขรวมตัวใหญ่ · วันนี้ / 7 วันนี้ — ทองได้เพราะเป็นของที่ทำสำเร็จจริง
   • แต่ละวัน = ช่วงบนเส้นเวลา: จุดทองหน้าหัววัน · ป้ายจำนวนงาน · งานเรียงตามเส้นทองแนวตั้ง
   • กดเข้า (.dn-in · setFilter ใส่ให้รอบเดียว): การ์ดสรุปเด้ง เหรียญหมุนเข้าที่ ตัวเลขหมุนขึ้น
     → หัววันเลื่อนเข้า เส้นเวลาลากลง งานไล่ขึ้นทีละใบ (วันถัดไปช้ากว่าวันก่อนนิดหนึ่ง)
   ============================================================ */
.dn-hero {
  position: relative; display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; gap: 4px 14px; align-items: center;
  margin: 4px 0 18px; padding: 16px 16px 14px; border-radius: 22px; overflow: hidden;
  background:
    radial-gradient(120% 140% at 0% 0%, color-mix(in srgb, var(--gold) 22%, transparent), transparent 60%),
    linear-gradient(160deg, color-mix(in srgb, var(--card) 88%, var(--gold)), var(--card));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--gold) 35%, transparent), 0 14px 30px -20px color-mix(in srgb, var(--gold) 80%, transparent);
}
.dn-medal {
  grid-row: 1 / 3; width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  color: var(--on-gold, #3F2D00);
  background: radial-gradient(circle at 32% 28%, #FFF6D5 0%, var(--gold) 55%, color-mix(in srgb, var(--gold) 70%, #7A5200) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 0 0 4px color-mix(in srgb, var(--gold) 18%, transparent), 0 10px 20px -10px var(--gold);
}
.dn-medal svg { width: 26px; height: 26px; stroke-width: 3; }
.dn-tx { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.dn-n { font-size: 34px; font-weight: 900; line-height: 1; color: var(--gold-text); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.dn-tx > span { font-size: 13.5px; font-weight: 700; color: color-mix(in srgb, var(--ink) 75%, transparent); }
.dn-mini { display: flex; gap: 8px; }
.dn-mini span { display: inline-flex; align-items: baseline; gap: 5px; padding: 4px 11px; border-radius: 99px; font-size: 12px; font-weight: 700;
  color: color-mix(in srgb, var(--ink) 70%, transparent); background: color-mix(in srgb, var(--gold) 12%, var(--card)); }
.dn-mini b { font-size: 14px; font-weight: 900; color: var(--gold-text); font-variant-numeric: tabular-nums; }

.dn-day { margin-bottom: 16px; }
.dn-dh { display: flex; align-items: center; gap: 9px; margin: 0 2px 10px; font-size: 14px; font-weight: 800; color: var(--ink); }
.dn-dh i { flex: none; width: 11px; height: 11px; border-radius: 50%; background: var(--gold);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 20%, transparent), 0 0 12px color-mix(in srgb, var(--gold) 70%, transparent); }
.dn-dh em { margin-left: auto; padding: 3px 10px; border-radius: 99px; font-style: normal; font-size: 11.5px; font-weight: 800;
  color: var(--gold-text); background: color-mix(in srgb, var(--gold) 14%, var(--card)); }
.dn-list { position: relative; display: grid; gap: 9px; margin-left: 7px; padding-left: 16px; }
.dn-list::before { content: ''; position: absolute; left: -1px; top: 2px; bottom: 10px; width: 2px; border-radius: 2px;
  background: linear-gradient(color-mix(in srgb, var(--gold) 70%, transparent), color-mix(in srgb, var(--gold) 5%, transparent)); transform-origin: 50% 0; }
.dn-list > * { margin: 0; }

/* กดเข้า */
.dn-in .dn-hero { animation: dn-pop .55s cubic-bezier(.3, 1.35, .5, 1) backwards; }
.dn-in .dn-medal { animation: dn-medal .8s cubic-bezier(.3, 1.5, .5, 1) .12s backwards, dn-ring 1.1s ease-out .5s; }
.dn-in .dn-mini span { animation: dn-up .5s cubic-bezier(.22, 1, .36, 1) .25s backwards; }
.dn-in .dn-mini span + span { animation-delay: .32s; }
.dn-in .dn-dh { animation: dn-left .5s cubic-bezier(.22, 1, .36, 1) backwards; animation-delay: calc(var(--d, 0) * 90ms + 180ms); }
.dn-in .dn-list::before { animation: dn-draw .7s cubic-bezier(.22, 1, .36, 1) backwards; animation-delay: calc(var(--d, 0) * 90ms + 220ms); }
.dn-in .dn-list > * { animation: dn-up .5s cubic-bezier(.22, 1, .36, 1) backwards; animation-delay: calc(var(--d, 0) * 90ms + var(--c, 0) * 50ms + 260ms); }
.dn-list > :nth-child(2) { --c: 1; } .dn-list > :nth-child(3) { --c: 2; } .dn-list > :nth-child(4) { --c: 3; }
.dn-list > :nth-child(5) { --c: 4; } .dn-list > :nth-child(n+6) { --c: 5; }
@keyframes dn-pop { from { opacity: 0; transform: translateY(10px) scale(.94); } }
@keyframes dn-medal { from { opacity: 0; transform: scale(.4) rotate(-40deg); } }
@keyframes dn-ring { from { box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 0 0 0 color-mix(in srgb, var(--gold) 55%, transparent); }
  to { box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 0 0 16px color-mix(in srgb, var(--gold) 0%, transparent); } }
@keyframes dn-up { from { opacity: 0; transform: translateY(12px); } }
@keyframes dn-left { from { opacity: 0; transform: translateX(-12px); } }
@keyframes dn-draw { from { transform: scaleY(0); } }
@media (prefers-reduced-motion: reduce) {
  .dn-in .dn-hero, .dn-in .dn-medal, .dn-in .dn-mini span, .dn-in .dn-dh, .dn-in .dn-list::before, .dn-in .dn-list > * { animation: none; }
}

/* ============================================================
   หน้า "เสร็จแล้ว" บนเครื่องสเปคต่ำ/กลาง (11 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ในหน้านี้เมื่อใช้ในเครื่องที่มีสเปคค่อนข้างต่ำหรือกลาง มันจะค้างและกดไม่ได้ประมาณสองสามนาที"
   • ปุ่มดูต่อท้ายจอ (doneMore · วาดทีละช่วง ดู DONE_PAGE ใน app.js)
   • ลูกศรในการ์ด: กระจกซ้อนกระจก — การ์ดเบลอข้างหลังแล้ว ลูกศรเบลอซ้ำอีกชั้นข้างใน ตาเปล่าไม่เห็นต่าง
     (ข้างหลังลูกศรคือพื้นการ์ดที่เบลอแล้ว) แต่การ์ดจอต้องเรนเดอร์สองชั้นต่อใบ ทุกครั้งที่เลื่อนจอ
   • แอนิเมชันกดเข้า: เล่นแค่สามวันแรก (วันที่สี่ลงไปอยู่ใต้ขอบจอตอนกดเข้าอยู่แล้ว ไม่มีใครเห็น)
   • โหมดลื่น: ไม่มีลำดับเด้ง เข้าแล้วเห็นเลย
   ============================================================ */
.dn-more {
  display: block; width: 100%; margin: 2px 0 10px; padding: 13px 14px; border-radius: 16px;
  font: inherit; font-size: 13.5px; font-weight: 800; color: var(--gold-text); cursor: pointer;
  background: color-mix(in srgb, var(--gold) 10%, var(--card));
  border: 1.5px dashed color-mix(in srgb, var(--gold) 45%, transparent);
  transition: transform .3s cubic-bezier(.3, 1.4, .5, 1);
}
.dn-more:active { transform: scale(.98); transition-duration: .12s; }
#taskList .tk-done .tk-go { -webkit-backdrop-filter: none; backdrop-filter: none; }
.dn-in .dn-day:nth-child(n+5) .dn-dh,
.dn-in .dn-day:nth-child(n+5) .dn-list::before,
.dn-in .dn-day:nth-child(n+5) .dn-list > * { animation: none; }
:root[data-lite] .dn-in .dn-hero, :root[data-lite] .dn-in .dn-medal, :root[data-lite] .dn-in .dn-mini span,
:root[data-lite] .dn-in .dn-dh, :root[data-lite] .dn-in .dn-list::before, :root[data-lite] .dn-in .dn-list > * { animation: none; }

/* ============================================================
   เฟรมเรต · การแตะ (11 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ยังมีบัคอะไรที่เกี่ยวกับการใช้แอปอีกบ้าง เช่นพวกเฟรมเรต การกดแอป ความเสถียร"
   ตรวจทุกจอ (44 จอ · 375×812): หาแอนิเมชันวนไม่รู้จบที่ขยับด้วยค่าที่การ์ดจอทำแทนไม่ได้ (left/top)
   = เบราว์เซอร์ต้องคำนวณหน้าใหม่และวาดใหม่ทุกเฟรมตลอดเวลาที่อยู่จอนั้น · เปลี่ยนเป็น transform ให้การ์ดจอเลื่อนภาพเดิม
   ============================================================ */

/* แตะปุ่มบน Android แล้วมีกรอบสี่เหลี่ยมสีฟ้า/เทาของเบราว์เซอร์แวบขึ้นทับ — มุมเหลี่ยมทับปุ่มมน ดูเหมือนกดพลาดที่
   ทุกปุ่มในแอปมีท่าตอนกดของตัวเองอยู่แล้ว (ยุบ · สว่างขึ้น) จึงปิดของเบราว์เซอร์ทั้งแอป */
html { -webkit-tap-highlight-color: transparent; }

/* แสงสามก้อนใต้ช่องพิมพ์ในจอแชทน้องไซ — เดิมเลื่อนด้วย left
   = คำนวณตำแหน่งใหม่ + วาดก้อนเบลอ 16–24px ใหม่ 60 ครั้ง/วิ ตลอดเวลาที่เปิดแชท
   ระยะทางเท่าเดิม (cqw = % ของความกว้างแถบ เหมือน left %) · เบราว์เซอร์เก่าที่ไม่รู้จัก cqw = แสงนิ่งที่จุดเริ่ม ไม่พัง */
.hs-wrap { container-type: inline-size; }
.hs-b1 { left: -5%; } .hs-b2 { left: 65%; } .hs-b3 { left: 25%; }
@keyframes hsA { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(80cqw); } }
@keyframes hsB { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-55cqw); } }
@keyframes hsC { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(30cqw); } }

/* เส้นกวาดบนจอกล้อง (ถ่ายใบงาน · สแกนตารางเรียน) — เดิมเลื่อนด้วย top = คำนวณหน้าใหม่ทุกเฟรม
   ระหว่างที่กล้องเปิดภาพสดอยู่ ซึ่งเป็นช่วงที่เครื่องหนักที่สุดอยู่แล้ว
   ตอนนี้กล่องสูงเท่าระยะที่เส้นวิ่ง (12% → 84% ของเวที) ตัวเส้นอยู่ขอบบนของกล่อง (::before)
   แล้วเลื่อนทั้งกล่องลง 100% ของความสูงตัวเอง = เส้นผ่านจุดเดิมทุกจุด แต่การ์ดจอทำให้ทั้งหมด */
.tt-sweep { top: 12%; height: 72%; background: none; box-shadow: none; pointer-events: none; }
.tt-sweep::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--neon, #4DA3FF); box-shadow: 0 0 14px 2px rgba(77,163,255,.65);
}
:root[data-theme="astral"] .tt-sweep { background: none; box-shadow: none; }
:root[data-theme="astral"] .tt-sweep::before { background: #FFFFFF; box-shadow: 0 0 14px 2px rgba(255,255,255,.55); }
@keyframes ttSweep { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(100%); } }

/* ============================================================
   11 ต.ค. 69 · ชิปรางวัล "+100" บนแถว "ส่งฟีดแบ็ก" (แท็บฉัน) — เจ้าของ: "ขอสวยๆเท่ๆ"
   ไม่ใช้ทอง: ทองสงวนไว้ให้ของที่ทำสำเร็จแล้ว (Key Decisions) · ของที่ยังไม่ได้ทำใช้สีแบรนด์ของธีม
   เหรียญคือหน้าตาของโทเคนที่ร้านค้าใช้บอกราคาอยู่แล้ว ไม่ใช่ป้ายความสำเร็จ
   แสงวาบวิ่งผ่านชิปทุก 3.2 วิ · ปิดเองเมื่อเครื่องตั้งลดการเคลื่อนไหว หรือโหมดเครื่องเบา
   ============================================================ */
/* #scr-profile นำหน้า — กฎเดิม `#scr-profile .pf-entry .pe-v` (มี id) ทับสีตัวอักษรเป็นเทา */
#scr-profile .pf-entry .pe-v.pe-reward:not(:empty), .phone .pe .pe-v.pe-reward:not(:empty) {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 11px 3px 5px;
  background: var(--grad-brand, var(--fill)); color: #fff;
  box-shadow: 0 2px 10px color-mix(in srgb, var(--fill) 35%, transparent);
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
.phone .pe .pe-v.pe-reward .tok { filter: drop-shadow(0 1px 1px rgba(0,0,0,.25)); }
.phone .pe .pe-v.pe-reward::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.45) 50%, transparent 70%);
  transform: translateX(-120%); animation: peRewardSheen 3.2s ease-in-out infinite;
}
@keyframes peRewardSheen { 0%, 55% { transform: translateX(-120%); } 85%, 100% { transform: translateX(120%); } }
@media (prefers-reduced-motion: reduce) { .phone .pe .pe-v.pe-reward::after { animation: none; display: none; } }
:root[data-lite] .phone .pe .pe-v.pe-reward::after { animation: none; display: none; }

/* ============================================================
   11 ต.ค. 69 · การ์ดรางวัลฟีดแบ็กใต้หัวแท็บ "ฉัน" — เจ้าของ: "เห็นยากอยู่นะ" · "ขอสวยๆเท่ๆ"
   พื้นเป็นสีแบรนด์ของธีม (--grad-brand) + เงามืดมุมขวา + ลายจุดดาว + แสงวาบ · เหรียญลอยขยับ
   ไม่ใช้ทองกับตัวอักษร (ยังไม่ได้รับ) · เคลื่อนไหวหยุดเองเมื่อลดการเคลื่อนไหวหรือโหมดเครื่องเบา
   ============================================================ */
.phone .fb-promo {
  position: relative; overflow: hidden; isolation: isolate; width: 100%;
  display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 14px 14px 14px 12px; border: 0; border-radius: 20px; cursor: pointer;
  background: var(--grad-brand, var(--fill)); color: #fff; font-family: inherit;
  box-shadow: 0 10px 26px color-mix(in srgb, var(--fill) 32%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
}
.phone .fb-promo[hidden] { display: none; }
.phone .fb-promo::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(rgba(255,255,255,.5) 1px, transparent 1.4px) 0 0 / 14px 14px,
    radial-gradient(120% 120% at 100% 100%, rgba(0,0,0,.32), transparent 60%);
  -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.35), #000 70%); mask-image: linear-gradient(90deg, rgba(0,0,0,.35), #000 70%);
}
.phone .fb-promo::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.3) 50%, transparent 65%);
  transform: translateX(-110%); animation: fbpSheen 3.6s ease-in-out infinite;
}
@keyframes fbpSheen { 0%, 50% { transform: translateX(-110%); } 85%, 100% { transform: translateX(110%); } }
.phone .fb-promo .fbp-coin { flex: none; filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)); animation: fbpBob 3s ease-in-out infinite; }
@keyframes fbpBob { 0%, 100% { transform: translateY(0) rotate(-6deg); } 50% { transform: translateY(-3px) rotate(6deg); } }
.phone .fb-promo .fbp-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.phone .fb-promo .fbp-tx b { font-size: 21px; font-weight: 800; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.phone .fb-promo .fbp-tx span { font-size: 13px; font-weight: 600; opacity: .88; }
.phone .fb-promo .fbp-go {
  flex: none; font-size: 13.5px; font-weight: 700; color: var(--fill);
  background: #fff; border-radius: 999px; padding: 7px 14px; box-shadow: 0 3px 10px rgba(0,0,0,.18);
}
.phone .fb-promo:active { transform: scale(.985); }
@media (prefers-reduced-motion: reduce) { .phone .fb-promo::after, .phone .fb-promo .fbp-coin { animation: none; } .phone .fb-promo::after { display: none; } }
:root[data-lite] .phone .fb-promo::after, :root[data-lite] .phone .fb-promo .fbp-coin { animation: none; }
:root[data-lite] .phone .fb-promo::after { display: none; }

/* ============================================================
   จอว่างทั้งแอป (emptyState ใน app.js) — 12 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ลองแก้ไขหรือตกแต่งเพิ่มเติม อันไหนควรตกแต่งเพิ่ม ควรปรับให้พอดี"
   ใช้ที่: หน้างานโหมดวันนี้ · แผนวันนี้ · เสร็จแล้ว · ถังขยะ · จอเพื่อนตอนยังไม่เข้าบัญชี
   • กล่องไอคอน: ทรงเดียวกับจอแจ้งเตือนตอนว่าง (.nt-empty-ic ใน inbox.css) — แอปมีหน้าตาจอว่างแบบเดียว
   • ลายจุดจาง ๆ หลังไอคอน ไล่หายออกขอบ (Empty States ของ Aceternity) — ภาพนิ่ง ไม่วาดใหม่
   • เด้งเข้า: ไอคอนเด้ง → หัวข้อ → คำอธิบาย → ปุ่ม (stagger แบบ Text Animate ของ Cult UI)
     เฉพาะตอนเพิ่งเปิดจอ (.fx-in) · โหมดลื่น/ลดการเคลื่อนไหว = ไม่เด้ง
   ============================================================ */
.es {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 28px 20px 22px; border-radius: 24px;
  background: color-mix(in srgb, var(--card) 80%, transparent);
  border: 1px solid var(--line); box-shadow: var(--shadow);
}
.es::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(color-mix(in srgb, var(--ink) 16%, transparent) 1px, transparent 1.5px);
  background-size: 16px 16px; background-position: center 8px;
  -webkit-mask: radial-gradient(65% 55% at 50% 22%, #000 0%, transparent 78%);
          mask: radial-gradient(65% 55% at 50% 22%, #000 0%, transparent 78%);
}
.es-ic {
  width: 58px; height: 58px; margin-bottom: 14px; border-radius: 20px; flex: none;
  display: grid; place-items: center;
  background-color: var(--fill); color: var(--on-fill);
  background-image: radial-gradient(120% 90% at 22% -10%, rgba(255, 255, 255, .45), rgba(255, 255, 255, .06) 48%, transparent 66%);
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .55), inset 0 -2px 3px rgba(0, 0, 0, .12),
    0 12px 22px -10px color-mix(in srgb, var(--fill) 75%, transparent);
}
/* เรื่องสบาย ๆ: กล่องสีอ่อน ไอคอนสีหลัก — ไม่ตะโกนเท่าเรื่องที่ต้องลงมือ */
.es-ic.soft {
  background-color: color-mix(in srgb, var(--fill) 16%, var(--card2)); color: var(--fill);
  background-image: radial-gradient(120% 90% at 22% -10%, rgba(255, 255, 255, .28), transparent 62%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 0 0 1px color-mix(in srgb, var(--fill) 22%, transparent),
    0 10px 20px -12px color-mix(in srgb, var(--fill) 55%, transparent);
}
.es-ic svg { width: 28px; height: 28px; }
.es-t { margin: 0; font-size: 17px; font-weight: 800; line-height: 1.35; letter-spacing: -.02em; color: var(--ink); }
.es-p { margin: 6px auto 0; max-width: 30ch; font-size: 13px; line-height: 1.6; color: var(--muted); }
.es-list { list-style: none; margin: 14px 0 0; padding: 0; width: 100%; display: grid; gap: 7px; text-align: left; }
.es-list li {
  display: flex; align-items: center; gap: 11px; padding: 10px 13px; border-radius: 14px;
  background: color-mix(in srgb, var(--fill) 7%, var(--card2));
  font-size: 13px; font-weight: 700; line-height: 1.45; color: var(--ink);
}
.es-list li > svg { flex: none; width: 19px; height: 19px; color: var(--fill); }
.es-go {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; margin-top: 16px; padding: 0 22px; border: none; border-radius: 999px; cursor: pointer;
  background: var(--blue); color: var(--on-accent, #fff);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .2), rgba(255, 255, 255, 0) 60%);
  font: inherit; font-size: 14.5px; font-weight: 800; box-shadow: var(--shadow-brand);
  transition: transform .16s cubic-bezier(.23, 1, .32, 1);
}
.es-list + .es-go { align-self: stretch; }
.es-go.ghost {
  background: color-mix(in srgb, var(--blue) 12%, var(--card2)); background-image: none;
  color: var(--blue-deep, var(--blue)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--blue) 22%, transparent);
}
.es-go svg { width: 17px; height: 17px; }
.es-go:active { transform: scale(.97); }

/* เด้งเข้า — เฉพาะตอนเพิ่งเปิดจอ */
.fx-in .es > * { animation: es-up .45s cubic-bezier(.23, 1, .32, 1) backwards; }
.fx-in .es > .es-ic { animation: es-pop .55s cubic-bezier(.3, 1.5, .5, 1) backwards; }
.fx-in .es > :nth-child(2) { animation-delay: .06s; }
.fx-in .es > :nth-child(3) { animation-delay: .12s; }
.fx-in .es > :nth-child(4) { animation-delay: .18s; }
.fx-in .es > :nth-child(5) { animation-delay: .24s; }
@keyframes es-up { from { opacity: 0; transform: translateY(8px); } }
@keyframes es-pop { from { opacity: 0; transform: scale(.6); } }
:root[data-lite] .fx-in .es > * { animation: none; }
@media (prefers-reduced-motion: reduce) { .fx-in .es > * { animation: none; } }

/* ============================================================
   ตัวตนของแต่ละธีม — 12 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ลองแก้ไขหรือสร้าง UI ในแต่ละธีมให้มีความแตกต่างกัน ให้มีเอกลักษณ์ในแต่ละธีม แต่งให้สวย"
   ไล่ดูหน้าแรกครบ 15 ธีม: สีกับฉากหลังต่างกันอยู่แล้ว แต่ "รูปทรง" ของทุกอย่างเหมือนกันหมด
   (มุมการ์ด 22–26px · ไอคอนสี่เหลี่ยมมน · ปุ่มแคปซูล · แท็บก้อนมน) — ทุกธีมจึงดูเป็นแอปเดียวกันที่เปลี่ยนสี
   ตอนนี้แต่ละธีมมี "ภาษารูปทรง" ของตัวเองหกจุด ที่เห็นทุกจอ:
     ① ทรงกล่องไอคอน (กริดหน้าแรก · จอว่าง · จอแจ้งเตือนตอนว่าง)  ② ทรงปุ่มหลัก + ผิวของปุ่ม
     ③ ทรงแท็บที่เลือกอยู่บนแถบล่าง  ④ มุมการ์ด (--r-card/--r-tile)  ⑤ หัวข้อจอ  ⑥ ลายหลังไอคอนในจอว่าง
   ที่มาของแต่ละแบบ (ตามคลังที่เรียนไว้):
     ชมพู · หวานแหว = ปุ่ม 3 มิติแบบ Uiverse (ขอบล่างทึบ กดแล้วยุบลง) + ทรงเยลลี่ (Jelly Radio ของ React Bits)
     โลก · ต้นไม้โลก = ทรงใบไม้ (Organic Button ของ Cult UI)
     มหาสมุทร · ทะเลลึก = หยดน้ำ/ฟองอากาศ + แสงเรืองใต้น้ำ (Glow Button ของ Cult UI)
     อวกาศ · กาแล็กซี = วงโคจรรอบไอคอน · แสงเนบิวลา (Border Beam / Shine Border ของ Magic UI แบบนิ่ง)
     เวทมนตร์ = ทรงซุ้มประตูโค้ง + วงแหวนทองสองชั้น
     Crystal = ทรงเหลี่ยมเพชร (มุมสลับแหลม/มน) + ขอบปริซึม
     Metaverse = HUD: มุมเกือบเหลี่ยม เส้นนีออนบาง ตาราง (Grid/Scales ของ Aceternity)
     Glitch = มุมแหลม เงาแยกสีแดง/ฟ้า เส้นสแกน
   ไม่แตะ: สว่าง/มืด (ฐานของแอป แบบ Halo ของ Cult UI) · Astral Black (มีชุดของตัวเองครบแล้ว)
   ทุกอย่างเป็นภาพนิ่ง — ไม่มีแอนิเมชันวนเพิ่ม ไม่กินเครื่อง · ขนาดทุกชิ้นเท่าเดิม หน้าแรกไม่เลื่อนเหมือนเดิม
   ทรงทำด้วย border-radius เท่านั้น ไม่ใช้ clip-path — ป้ายตัวเลขบนไอคอน (.tg-ct) อยู่ในกล่อง จะโดนตัด
   ============================================================ */

/* ---------- โทเคนของแต่ละธีม ----------
   --id-tile  ทรงกล่องไอคอน        --id-chip  ทรงชิปขาวในกล่องไอคอน
   --id-btn   ทรงปุ่มหลัก          --id-tab   ทรงแท็บที่เลือกอยู่ */
:root[data-theme="warm"]      { --id-tile: 24px; --id-chip: 999px; --id-btn: 999px; --id-tab: 999px; --r-card: 28px; --r-tile: 20px; }
:root[data-theme="sweet"]     { --id-tile: 46% 54% 48% 52% / 52% 46% 54% 48%; --id-chip: 999px; --id-btn: 999px; --id-tab: 999px; --r-card: 30px; --r-tile: 22px; }
:root[data-theme="earth"]     { --id-tile: 24px 7px 24px 7px; --id-chip: 12px 4px 12px 4px; --id-btn: 22px 7px 22px 7px; --id-tab: 16px 5px 16px 5px; --r-card: 26px; --r-tile: 16px; }
:root[data-theme="earth2"]    { --id-tile: 7px 24px 7px 24px; --id-chip: 4px 12px 4px 12px; --id-btn: 7px 22px 7px 22px; --id-tab: 5px 16px 5px 16px; --r-card: 26px; --r-tile: 16px; }
:root[data-theme="ocean"]     { --id-tile: 50% 50% 50% 18%; --id-chip: 50%; --id-btn: 999px; --id-tab: 999px; --r-card: 26px; --r-tile: 20px; }
:root[data-theme="deepocean"] { --id-tile: 50%; --id-chip: 50%; --id-btn: 999px; --id-tab: 999px; --r-card: 28px; --r-tile: 20px; }
:root[data-theme="space"]     { --id-tile: 50%; --id-chip: 50%; --id-btn: 999px; --id-tab: 999px; --r-card: 20px; --r-tile: 14px; }
:root[data-theme="galaxy"]    { --id-tile: 22px; --id-chip: 50%; --id-btn: 999px; --id-tab: 999px; --r-card: 24px; --r-tile: 16px; }
:root[data-theme="magic"]     { --id-tile: 50% 50% 14px 14px / 42% 42% 14px 14px; --id-chip: 50% 50% 8px 8px / 44% 44% 8px 8px; --id-btn: 18px 18px 10px 10px; --id-tab: 14px 14px 6px 6px; --r-card: 22px; --r-tile: 14px; }
:root[data-theme="genesis"]   { --id-tile: 6px 22px 6px 22px; --id-chip: 4px 12px 4px 12px; --id-btn: 6px 18px 6px 18px; --id-tab: 4px 14px 4px 14px; --r-card: 20px; --r-tile: 12px; }
:root[data-theme="meta"]      { --id-tile: 10px; --id-chip: 6px; --id-btn: 10px; --id-tab: 8px; --r-card: 14px; --r-tile: 10px; }
:root[data-theme="glitch"]    { --id-tile: 5px; --id-chip: 3px; --id-btn: 4px; --id-tab: 3px; --r-card: 10px; --r-tile: 6px; }

/* ---------- ① ทรงกล่องไอคอน ---------- */
/* 12 ต.ค. 69 · เจ้าของ (ส่งภาพกริดแปดปุ่มหน้าแรก): "ในปุ่มนี้ให้มีรูปทรงแบบเดิมทุกธีม"
   ปุ่มกริดหน้าแรก (.tg-ic) ถอดออกจากชุดนี้ทั้งหมด — ทรง ชิปขาวข้างใน และวงรอบไอคอน (::after) กลับเป็นแบบเดิมทุกธีม
   ที่ยังเปลี่ยนตามธีม: ไอคอนในจอว่าง · จอแจ้งเตือนตอนว่าง · แถวตั้งค่า/แท็บฉัน (ดูรอบสองข้างล่าง) */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],
  [data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch])
  .phone :is(.es-ic, .nt-empty-ic) { border-radius: var(--id-tile) !important; }

/* ---------- ② ปุ่มหลัก: ทรง + ผิว ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],
  [data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch])
  .phone :is(.tc-cta, .btn.primary, .fm-save, .sai-cta, .ck-cta, .pro-cta, .ep-save, .ai-read, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go, .fr-go, .gc-go) {
  border-radius: var(--id-btn) !important;
}
/* ชมพู: นุ่มแบบหมอนอิง — ขอบบนสว่าง เงาชมพูฟุ้ง */
:root[data-theme="warm"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .6), inset 0 -2px 4px rgba(140, 20, 70, .18), 0 12px 24px -10px rgba(206, 63, 121, .6) !important;
}
/* หวานแหว: ปุ่มลูกอม 3 มิติ — ขอบล่างทึบ กดแล้วยุบลงจริง (แทนการหด) */
:root[data-theme="sweet"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .55), 0 5px 0 color-mix(in srgb, var(--fill) 58%, #4A1460), 0 12px 20px -8px color-mix(in srgb, var(--fill) 55%, transparent) !important;
}
:root[data-theme="sweet"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go):active {
  transform: translateY(4px) !important;
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .55), 0 1px 0 color-mix(in srgb, var(--fill) 58%, #4A1460) !important;
}
/* ทะเลลึก: เรืองแสงฟ้าใต้น้ำ */
:root[data-theme="deepocean"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 0 0 1px rgba(56, 189, 248, .45), 0 0 24px -4px rgba(56, 189, 248, .7) !important;
}
/* อวกาศ: แสงดาวขาวอมฟ้า */
:root[data-theme="space"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 0 0 1px rgba(200, 214, 255, .35), 0 0 26px -6px rgba(170, 190, 255, .7) !important;
}
/* กาแล็กซี: แสงเนบิวลาชมพูใต้ปุ่ม */
:root[data-theme="galaxy"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 0 0 1px rgba(255, 255, 255, .16), 0 12px 28px -8px rgba(236, 72, 153, .7) !important;
}
/* เวทมนตร์: วงแหวนทองสองชั้นรอบปุ่ม */
:root[data-theme="magic"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 0 0 2px var(--card), 0 0 0 3.5px rgba(232, 194, 90, .75), 0 14px 24px -10px rgba(139, 92, 246, .7) !important;
}
/* Crystal: ขอบปริซึม */
:root[data-theme="genesis"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .85), inset 0 0 0 1px rgba(183, 245, 255, .6), 0 12px 24px -10px rgba(76, 87, 201, .65) !important;
}
/* Metaverse: เส้นนีออน + ตัวอักษรห่างแบบหน้าจอ HUD */
:root[data-theme="meta"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  letter-spacing: .04em;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25), 0 0 0 1px rgba(56, 232, 255, .7), 0 0 20px -4px rgba(56, 232, 255, .6) !important;
}
/* Glitch: เงาแยกสี */
:root[data-theme="glitch"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  box-shadow: 3px 0 0 rgba(255, 45, 111, .85), -3px 0 0 rgba(45, 240, 255, .85) !important;
}

/* ---------- ③ แท็บที่เลือกอยู่บนแถบล่าง ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],
  [data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]):not([data-nav="side"])
  .phone .tabbar .tab.active:not(.scan) { border-radius: var(--id-tab); }
:root[data-theme="deepocean"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { box-shadow: 0 0 18px -2px rgba(56, 189, 248, .7) !important; }
:root[data-theme="meta"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { box-shadow: 0 0 0 1px rgba(56, 232, 255, .75), 0 0 16px -3px rgba(56, 232, 255, .65) !important; }
:root[data-theme="glitch"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { box-shadow: 2px 0 0 rgba(255, 45, 111, .85), -2px 0 0 rgba(45, 240, 255, .85) !important; }
:root[data-theme="sweet"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { box-shadow: inset 0 1.5px 0 rgba(255, 255, 255, .55), 0 3px 0 color-mix(in srgb, var(--fill) 58%, #4A1460) !important; }
:root[data-theme="magic"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { box-shadow: 0 0 0 1.5px rgba(232, 194, 90, .8) !important; }

/* ---------- ⑤ หัวข้อจอ ---------- */
/* ไล่สีบนตัวหนังสือ — ใช้กับหัวข้อจอ (ตัวหนังสือล้วน) เท่านั้น ไม่ใช้กับคำทักทายหน้าแรก
   คำทักทายแตกเป็นคำ ๆ ที่ลอยเข้าทีละคำ (greetIn) ไล่สีแบบตัดตามตัวหนังสือจะหลุดตอนคำลอย */
:root:is([data-theme=sweet],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=ocean],[data-theme=earth2])
  .phone :is(.page-title, .fd-title) {
  background-image: var(--id-title-ink); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
:root[data-theme="sweet"]   { --id-title-ink: linear-gradient(100deg, #E24FA6, #9B6BF0); }
:root[data-theme="galaxy"]  { --id-title-ink: linear-gradient(100deg, #F9A8D4, #C4B5FD 55%, #A855F7); }
:root[data-theme="magic"]   { --id-title-ink: linear-gradient(100deg, #F5DC96, #E8C25A 50%, #C9A7FF); }
:root[data-theme="genesis"] { --id-title-ink: linear-gradient(100deg, #4C57C9, #6F7FE8 50%, #38B6D0); }
:root[data-theme="ocean"]   { --id-title-ink: linear-gradient(100deg, #0A5170, #0E8FB8); }
:root[data-theme="earth2"]  { --id-title-ink: linear-gradient(100deg, #1E5B2E, #4F9A3A); }
/* 12 ต.ค. 69 · เจ้าของส่งภาพ "วันนี" "งานทังหมด" "สัปดาห์นี" — วรรณยุกต์กับสระบนหายไป ("มันหายไปแก้ด้วย")
   ต้นเหตุ: ไล่สีแบบตัดตามตัวหนังสือ (background-clip: text + ตัวอักษรโปร่ง) วาดสีได้แค่ในกรอบของหัวข้อ
   หัวข้อสูงบรรทัด 1.2–1.24 · ไม้โท/ไม้หันอากาศที่ซ้อนกัน (ทั้ง · นี้) ยื่นพ้นขอบบนของกรอบ → ตรงนั้นไม่มีสี = มองไม่เห็น
   แก้: ขยายกรอบขึ้น-ลง .3em ด้วย padding · ยกกลับขึ้น .3em ด้วย position: relative · คืนที่ด้วย margin-bottom −.6em
   ไม่แตะ margin-top เลย — รอบแรกหักคืนด้วย margin-top ติดลบ แล้วหัวข้อเลื่อนลง 4px ในจอที่มีป้ายเล็กข้างบน
   (margin 5px ของหัวข้อ "ยุบรวม" กับ 4px ของป้ายเป็น 5 · ค่าติดลบยุบรวมแบบบวกลบกัน ได้ไม่เท่าเดิม) — วัดเจอตอนเทสต์
   ด้านล่าง: margin ติดลบรวมกับ margin บวกของของถัดไปแบบบวกกันพอดี ของข้างล่างจึงอยู่ที่เดิม
   ธีมขาวดำ (หัวข้อโครเมียม ④ ข้างล่าง) ใช้เทคนิคเดียวกัน จึงอยู่ในรายชื่อนี้ด้วย */
:root:is([data-theme=sweet],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=ocean],[data-theme=earth2],[data-theme=astral])
  .phone :is(.page-title, .fd-title) { padding-block: .3em; position: relative; top: -.3em; margin-bottom: -.6em; }
/* หัวจองานตั้ง margin: 0 ด้วย id (แรงกว่ากฎข้างบน) — ต้องเขียนซ้ำด้วยความแรงเท่ากัน ไม่งั้นแถวหัวจอสูงขึ้น .6em */
:root:is([data-theme=sweet],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=ocean],[data-theme=earth2],[data-theme=astral])
  .phone #scr-tasks .tk-head-row .page-title { margin-bottom: -.6em; }
/* ตัวหนังสือไล่สีตัวอื่นที่เป็นไทยและบรรทัดชิด — บั๊กเดียวกัน ไล่ดูตอนแก้หัวข้อจอ (ทุกธีม ไม่ใช่เฉพาะชุดข้างบน)
   หัวจอสุ่มสกิน "แตะสำรับเพื่อเปิด" (.gc-title · ไล่สีทองทุกธีม) · หัวโพสต์ในโปรไฟล์ (.twg-head · margin ล่างเดิม 14px)
   ชื่อธีมตัวพิเศษในหน้าเลือกธีม (.bg-nm.fancy) */
.phone :is(.gc-title, .bg-nm.fancy) { padding-block: .3em; position: relative; top: -.3em; margin-bottom: -.6em; }
.phone .twg-head { padding-block: .3em; position: relative; top: -.3em; margin-bottom: calc(14px - .6em); }
/* แสงบนตัวหนังสือ — ใช้กับคำทักทายหน้าแรกได้ด้วย (text-shadow ตามไปกับทุกคำ) */
:root[data-theme="meta"] .phone :is(.page-title, .fd-title, .th-greet) { text-shadow: 0 0 14px rgba(56, 232, 255, .55); letter-spacing: .01em; }
:root[data-theme="glitch"] .phone :is(.page-title, .fd-title, .th-greet) { text-shadow: 1.5px 0 0 rgba(255, 45, 111, .8), -1.5px 0 0 rgba(45, 240, 255, .8); }
:root[data-theme="deepocean"] .phone :is(.page-title, .fd-title, .th-greet) { text-shadow: 0 0 16px rgba(56, 189, 248, .6); }
:root[data-theme="space"] .phone :is(.page-title, .fd-title, .th-greet) { text-shadow: 0 0 14px rgba(200, 214, 255, .5); }
:root[data-theme="galaxy"] .phone .th-greet { text-shadow: 0 0 16px rgba(236, 72, 153, .45); }
:root[data-theme="magic"] .phone .th-greet { text-shadow: 0 0 14px rgba(232, 194, 90, .45); }

/* ---------- ⑥ ลายหลังไอคอนในจอว่าง ---------- */
:root[data-theme="meta"] .es::before {
  background-image: linear-gradient(rgba(56, 232, 255, .22) 1px, transparent 1px), linear-gradient(90deg, rgba(56, 232, 255, .22) 1px, transparent 1px);
  background-size: 18px 18px;
}
:root[data-theme="glitch"] .es::before {
  background-image: repeating-linear-gradient(0deg, rgba(45, 240, 255, .14) 0 1px, transparent 1px 4px);
  background-size: auto;
}
:root[data-theme="sweet"] .es::before {
  background-image: repeating-linear-gradient(135deg, rgba(226, 79, 166, .14) 0 6px, transparent 6px 16px);
  background-size: auto;
}
:root:is([data-theme=space],[data-theme=galaxy]) .es::before {
  background-image: radial-gradient(rgba(255, 255, 255, .55) 1px, transparent 1.6px), radial-gradient(rgba(255, 255, 255, .3) .8px, transparent 1.3px);
  background-size: 34px 34px, 13px 13px; background-position: 4px 6px, 0 0;
}
:root[data-theme="ocean"] .es::before {
  background-image: radial-gradient(circle at 50% 100%, transparent 7px, rgba(14, 110, 146, .2) 7.5px, rgba(14, 110, 146, .2) 8.5px, transparent 9px);
  background-size: 20px 10px;
}
:root[data-theme="deepocean"] .es::before {
  background-image: radial-gradient(circle, transparent 2px, rgba(56, 189, 248, .35) 2.5px, transparent 3.2px), radial-gradient(circle, rgba(56, 189, 248, .25) 1px, transparent 1.6px);
  background-size: 26px 26px, 11px 11px; background-position: 3px 2px, 0 0;
}
:root:is([data-theme=earth],[data-theme=earth2]) .es::before {
  background-image: radial-gradient(ellipse 2.2px 1.2px, color-mix(in srgb, var(--fill) 45%, transparent) 99%, transparent);
  background-size: 15px 15px;
}
:root[data-theme="magic"] .es::before {
  background-image:
    radial-gradient(circle, rgba(232, 194, 90, .55) 1px, transparent 1.6px),
    radial-gradient(circle, rgba(201, 167, 255, .35) .8px, transparent 1.4px);
  background-size: 22px 22px, 9px 9px; background-repeat: repeat;
}
:root[data-theme="genesis"] .es::before {
  background-image: linear-gradient(45deg, rgba(111, 127, 232, .16) 1px, transparent 1px), linear-gradient(-45deg, rgba(111, 127, 232, .16) 1px, transparent 1px);
  background-size: 16px 16px;
}
:root[data-theme="warm"] .es::before {
  background-image: radial-gradient(circle, transparent 2.5px, rgba(206, 63, 121, .22) 3px, transparent 3.6px);
  background-size: 18px 18px;
}

/* ============================================================
   ตัวตนของแต่ละธีม รอบสอง: ทุกหน้า + ท่าเคลื่อนไหว — 12 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ออกแบบในหน้าอื่นด้วย พวกอนิเมชันก็ปรับแต่งด้วยนะ ออกแบบในทุกหน้า แต่ถ้าไหนควรต้องเหมือนกันก็ให้เหมือน"
   รอบแรกแต่งของบนหน้าแรก · รอบนี้แต่ง "ของที่ใช้ร่วมกันทุกหน้า" ภาษารูปทรงของธีมจึงตามไปทุกจอเอง:
     ปุ่มกลับ (มีแทบทุกจอย่อย) · กรอบแถบล่าง · ตัวบอกแท็บที่เลือก (วันนี้/สัปดาห์/รายการ · ตัวกรองแจ้งเตือน
     · ตัวสลับกระดาน) · ชิป · ช่องค้นหา/ช่องถามน้องฮูก/ช่องแชท · ไอคอนในแถวตั้งค่า แท็บฉัน และแผ่นเพิ่มงาน
   + ท่าเปลี่ยนจอของแต่ละธีม + ท่าตอนกดไอคอนของแต่ละธีม
   ที่ "ต้องเหมือนกัน" ทุกธีม (ไม่แตะโดยตั้งใจ):
     ผังจอ ระยะห่าง ขนาดตัวอักษร · สีบอกสถานะ (แดง=เลย/ลบ · เขียว=เสร็จ · ทอง=สำเร็จจริง) · ปุ่มติ๊กงาน · ดาวความสำคัญ
     · โหมดโฟกัส (จอนิ่งให้ใจจดจ่อ) · ฟอร์มเพิ่มงาน · แจ้งเตือนแบบ Dynamic Island (ดำทุกธีมโดยตั้งใจ เหมือนของเครื่องจริง)
     · ทิศของท่าเปลี่ยนจอ (เดินหน้า = เข้าจากขวา · ถอย = เข้าจากซ้าย) — ทิศคือข้อมูลว่ากำลังไปไหน ไม่ใช่ของตกแต่ง
   ทุกท่าใช้ transform/opacity · ลดการเคลื่อนไหว = ไม่ขยับ
   ============================================================ */
:root[data-theme="warm"]      { --id-bar: 30px; --id-back: 50%; --id-ctl: 999px; }
:root[data-theme="sweet"]     { --id-bar: 32px; --id-back: 46% 54% 48% 52% / 52% 46% 54% 48%; --id-ctl: 999px; }
:root[data-theme="earth"]     { --id-bar: 26px 10px 26px 10px; --id-back: 18px 6px 18px 6px; --id-ctl: 12px 4px 12px 4px; --id-in: 18px 6px 18px 6px; }
:root[data-theme="earth2"]    { --id-bar: 10px 26px 10px 26px; --id-back: 6px 18px 6px 18px; --id-ctl: 4px 12px 4px 12px; --id-in: 6px 18px 6px 18px; }
:root[data-theme="ocean"]     { --id-bar: 30px; --id-back: 50% 50% 50% 18%; --id-ctl: 999px; }
:root[data-theme="deepocean"] { --id-bar: 30px; --id-back: 50%; --id-ctl: 999px; }
:root[data-theme="space"]     { --id-bar: 30px; --id-back: 50%; --id-ctl: 999px; }
:root[data-theme="galaxy"]    { --id-bar: 28px; --id-back: 16px; --id-ctl: 999px; }
:root[data-theme="magic"]     { --id-bar: 24px 24px 14px 14px; --id-back: 50% 50% 12px 12px / 42% 42% 12px 12px; --id-ctl: 12px 12px 5px 5px; --id-in: 16px 16px 8px 8px; }
:root[data-theme="genesis"]   { --id-bar: 8px 26px 8px 26px; --id-back: 5px 16px 5px 16px; --id-ctl: 4px 12px 4px 12px; --id-in: 5px 16px 5px 16px; }
:root[data-theme="meta"]      { --id-bar: 12px; --id-back: 9px; --id-ctl: 7px; --id-in: 9px; }
:root[data-theme="glitch"]    { --id-bar: 5px; --id-back: 4px; --id-ctl: 3px; --id-in: 3px; }

/* ---------- ปุ่มกลับ (ทุกจอย่อย) — ปุ่ม "‹ กลับ" ของกระดานอันดับเป็นแคปซูลมีคำ คงไว้ (กฎ id ชนะ) ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],[data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { border-radius: var(--id-back) !important; }
:root[data-theme="meta"] .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { box-shadow: inset 0 0 0 1px rgba(56, 232, 255, .55), 0 0 12px -4px rgba(56, 232, 255, .5) !important; }
:root[data-theme="glitch"] .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { box-shadow: 2px 0 0 rgba(255, 45, 111, .7), -2px 0 0 rgba(45, 240, 255, .7) !important; }
:root[data-theme="deepocean"] .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { box-shadow: 0 0 0 1px rgba(56, 189, 248, .4), 0 0 14px -3px rgba(56, 189, 248, .55) !important; }
:root[data-theme="magic"] .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { box-shadow: 0 0 0 1px rgba(232, 194, 90, .7) !important; }

/* ---------- กรอบแถบล่าง ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],[data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone .tabbar { border-radius: var(--id-bar) !important; }
:root[data-theme="meta"] .phone .tabbar { border-color: rgba(56, 232, 255, .5) !important; }
:root[data-theme="glitch"] .phone .tabbar { border-color: rgba(45, 240, 255, .45) !important; }

/* ---------- ตัวบอกแท็บที่เลือก + ชิป (ของชิ้นเล็กที่เลือกได้) ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],[data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone :is(.tk-thumb, .tk-mode.on, .gbg-ind, .bd-seg-k, .fd-scope.on, .chip, .cp-chip, .so-chip, .cx2-chip, .sp) {
  border-radius: var(--id-ctl) !important;
}
:root:is([data-theme=earth],[data-theme=earth2],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone :is(.tk-modes, .gbg, .bd-seg) { border-radius: var(--id-ctl) !important; }
:root[data-theme="meta"] .phone :is(.tk-thumb, .gbg-ind, .bd-seg-k) { box-shadow: inset 0 0 0 1px rgba(56, 232, 255, .6), 0 0 12px -3px rgba(56, 232, 255, .55) !important; }
:root[data-theme="glitch"] .phone :is(.tk-thumb, .gbg-ind, .bd-seg-k) { box-shadow: 2px 0 0 rgba(255, 45, 111, .75), -2px 0 0 rgba(45, 240, 255, .75) !important; }

/* ---------- ช่องพิมพ์ (ธีมที่ตัวตนอยู่ที่รูปทรง) ---------- */
:root:is([data-theme=earth],[data-theme=earth2],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone :is(.fr-search, .sai-bar, #menuBody .td-ask, .ep .ep-f > input[type="text"], .set-row input[type="text"]) {
  border-radius: var(--id-in) !important;
}
:root[data-theme="meta"] .phone :is(.fr-search, .sai-bar) { box-shadow: inset 0 0 0 1px rgba(56, 232, 255, .45) !important; }

/* ---------- ไอคอนในแถว (ตั้งค่า · แท็บฉัน · แผ่นเพิ่มงาน · ทางเข้ากระดาน) — ทรงเดียวกับไอคอนหน้าแรก ---------- */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],[data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch]) .phone :is(.set-ic, .pe-ic, .as-ic, .tb-nd-ic, .soon-ic, .bd-entry-ic, .bd-guest-ic, .fd-blank-ic, .dm-blank-ic) {
  border-radius: var(--id-tile) !important;
}
:root[data-theme="meta"] .phone :is(.set-ic, .pe-ic, .as-ic) { box-shadow: inset 0 0 0 1px rgba(56, 232, 255, .55) !important; }
:root[data-theme="glitch"] .phone :is(.set-ic, .pe-ic, .as-ic) { box-shadow: 1.5px 0 0 rgba(255, 45, 111, .7), -1.5px 0 0 rgba(45, 240, 255, .7) !important; }
:root[data-theme="magic"] .phone :is(.set-ic, .pe-ic, .as-ic) { box-shadow: 0 0 0 1px rgba(232, 194, 90, .6) !important; }
:root[data-theme="deepocean"] .phone :is(.set-ic, .pe-ic, .as-ic) { box-shadow: 0 0 10px -2px rgba(56, 189, 248, .6) !important; }

/* ============================================================
   ท่าเปลี่ยนจอของแต่ละธีม
   ทิศเหมือนเดิมทุกธีม (--id-dx: เดินหน้า +26 · ถอย −22 · สลับแท็บ 0) — ต่างกันที่ "นิสัย" ของท่า
   12 ต.ค. 69 · เจ้าของ: "ตอนเปลี่ยนหน้าในเมนูหลัก มันมีอนิเมชันเปลี่ยน … มันรู้สึกเวียนหัว"
   รอบแรกหมุนทั้งจอ (กาแล็กซี) · ซูมเข้า 5% (อวกาศ) · หดเหลือ 90% (เวทมนตร์) · กระตุก 8px (Glitch)
   ทั้งจอขยับแบบนี้ทุกครั้งที่กดแท็บล่าง = เวียนหัวจริง (การหมุนกับซูมทั้งจอคือตัวกระตุ้นอาการเมารถบนจอที่รู้กัน)
   ตอนนี้: กดแท็บล่าง (lat) ใช้ท่าเดิม scr-lat เหมือนกันทุกธีม — ไปมาบ่อยที่สุด ต้องนิ่งที่สุด
   ท่าของธีมเหลือเฉพาะตอนเข้าจอย่อย/ถอยกลับ และเบาลงทุกท่า: ไม่หมุน · ซูมไม่เกิน 1–2.5% · กะพริบ/กระตุกเบา
   ============================================================ */
body[data-godir="fwd"]  { --id-dx: 26px; }
body[data-godir="back"] { --id-dx: -22px; }
body[data-godir="lat"]  { --id-dx: 0px; }
/* ชมพู: นุ่ม ช้าลงนิด */
:root[data-theme="warm"] body:not([data-godir="lat"]) .screen.on { animation: id-soft .4s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes id-soft { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .6), 10px, 0) scale(.99); } }
/* หวานแหว: เยลลี่ — เด้งเกินแล้วกลับเข้าที่ */
:root[data-theme="sweet"] body:not([data-godir="lat"]) .screen.on { animation: id-jelly .52s cubic-bezier(.3, 1, .4, 1) both; }
@keyframes id-jelly {
  0% { opacity: 0; transform: translate3d(var(--id-dx), 0, 0) scale(.975); }
  60% { opacity: 1; transform: translate3d(0, 0, 0) scale(1.005, .997); }
  100% { opacity: 1; transform: none; }
}
/* โลก · ต้นไม้โลก: งอกขึ้นจากพื้น */
:root:is([data-theme=earth],[data-theme=earth2]) body:not([data-godir="lat"]) .screen.on { animation: id-sprout .44s cubic-bezier(.22, 1, .36, 1) both; transform-origin: 50% 100%; }
@keyframes id-sprout { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .5), 8px, 0) scaleY(.99); } }
/* มหาสมุทร: ลอยขึ้นจากน้ำ */
:root[data-theme="ocean"] body:not([data-godir="lat"]) .screen.on { animation: id-float .5s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes id-float { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .5), 10px, 0); } }
/* ทะเลลึก: โผล่ขึ้นมาจากความลึก */
:root[data-theme="deepocean"] body:not([data-godir="lat"]) .screen.on { animation: id-emerge .5s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes id-emerge { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .4), 8px, 0) scale(.985); } }
/* อวกาศ: วาร์ป — ซูมเข้าหาจากไกล */
:root[data-theme="space"] body:not([data-godir="lat"]) .screen.on { animation: id-warp .38s cubic-bezier(.2, .9, .2, 1) both; }
@keyframes id-warp { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .4), 0, 0) scale(1.012); } }
/* กาแล็กซี: หมุนวนเข้ามานิดหนึ่ง */
:root[data-theme="galaxy"] body:not([data-godir="lat"]) .screen.on { animation: id-swirl .46s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes id-swirl { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .5), 6px, 0) scale(.985); } }
/* เวทมนตร์: เสก — โผล่จากเล็กแล้วเด้งเกินนิด */
:root[data-theme="magic"] body:not([data-godir="lat"]) .screen.on { animation: id-conjure .5s cubic-bezier(.3, 1, .4, 1) both; }
@keyframes id-conjure {
  0% { opacity: 0; transform: translate3d(calc(var(--id-dx) * .4), 0, 0) scale(.975); }
  60% { opacity: 1; transform: scale(1.004); }
  100% { opacity: 1; transform: none; }
}
/* Crystal: เข้าเร็ว คม */
:root[data-theme="genesis"] body:not([data-godir="lat"]) .screen.on { animation: id-crystal .26s cubic-bezier(.2, .9, .1, 1) both; }
@keyframes id-crystal { from { opacity: 0; transform: translate3d(calc(var(--id-dx) * .4), 0, 0) scale(.985); } }
/* Metaverse: เปิดจอ HUD — กะพริบสองจังหวะก่อนติดเต็ม */
:root[data-theme="meta"] body:not([data-godir="lat"]) .screen.on { animation: id-hud .34s linear both; }
@keyframes id-hud {
  0% { opacity: 0; transform: translate3d(calc(var(--id-dx) * .4), -3px, 0); }
  35% { opacity: .8; transform: translate3d(calc(var(--id-dx) * .15), -1px, 0); }
  50% { opacity: .62; }
  75% { opacity: 1; transform: none; }
  100% { opacity: 1; transform: none; }
}
/* Glitch: กระตุกซ้ายขวาก่อนเข้าที่ */
:root[data-theme="glitch"] body:not([data-godir="lat"]) .screen.on { animation: id-jitter .3s steps(1, end) both; }
@keyframes id-jitter {
  0% { opacity: 0; transform: translate3d(calc(var(--id-dx) * .3), 0, 0); }
  30% { opacity: 1; transform: translate3d(2px, 0, 0); }
  60% { transform: translate3d(-1.5px, 0, 0); }
  100% { opacity: 1; transform: none; }
}

/* ---------- ท่าตอนกดไอคอนหน้าแรก ---------- */
:root[data-theme="sweet"] .phone .tg-t:active .tg-ic { transform: scale(1.07, .88) !important; }
:root:is([data-theme=earth],[data-theme=earth2]) .phone .tg-t:active .tg-ic { transform: rotate(-4deg) scale(.95) !important; }
:root:is([data-theme=ocean],[data-theme=deepocean]) .phone .tg-t:active .tg-ic { transform: translateY(3px) scale(.95) !important; }
:root:is([data-theme=space],[data-theme=galaxy]) .phone .tg-t:active .tg-ic { transform: scale(.88) !important; }
:root[data-theme="magic"] .phone .tg-t:active .tg-ic { transform: rotate(3deg) scale(.93) !important; }
:root[data-theme="genesis"] .phone .tg-t:active .tg-ic { transform: scale(.93) rotate(-2deg) !important; }
:root[data-theme="meta"] .phone .tg-t:active .tg-ic { transform: scale(.95) !important; filter: brightness(1.3); }
:root[data-theme="glitch"] .phone .tg-t:active .tg-ic { transform: translateX(2px) scale(.95) !important; }

@media (prefers-reduced-motion: reduce) {
  :root[data-theme] body[data-godir] .screen.on { animation: none !important; }
  :root[data-theme] .phone .tg-t:active .tg-ic { transform: none !important; }
}
/* ตัวบอกตัวกรองบนจอแจ้งเตือน (.gbg-ind) มีวงแหวนสีกับช่องว่างซ้อนอยู่ข้างใน — ต้องเปลี่ยนทรงตามกรอบนอก
   ไม่งั้นได้วงแหวนมนอยู่ในกรอบเหลี่ยม (เจอใน Glitch กับเวทมนตร์) */
:root:is([data-theme=warm],[data-theme=sweet],[data-theme=earth],[data-theme=earth2],[data-theme=ocean],[data-theme=deepocean],
  [data-theme=space],[data-theme=galaxy],[data-theme=magic],[data-theme=genesis],[data-theme=meta],[data-theme=glitch])
  .phone .gbg-ind :is(.gbg-ring, .gbg-gap) { border-radius: inherit; }

/* ============================================================
   ตัวตนของ Astral Black (ธีมขาว–ดำ) — 12 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ในธีมที่มีแค่สีขาวกับดำ" (ต่อจากการแต่งตัวตนให้ทุกธีม ซึ่งรอบแรกเว้นธีมนี้ไว้)
   ยังเป็นขาว ดำ เทา ล้วนตามที่เจ้าของสั่งไว้ตั้งแต่ 1C40 — ไม่มีสีอิ่มเพิ่มแม้แต่จุดเดียว
   แนวของธีมนี้ (ภาพอ้างอิงเดิมของเจ้าของ): อวกาศขาวดำ · ดาวเคราะห์ · โลหะเงิน
     ① ไอคอนเป็นดาวเคราะห์กลม มีวงโคจรเส้นเงินบางรอบตัวกับ "ดวงจันทร์" จุดเดียวบนวง
        (ต่างจากอวกาศที่เป็นวงเส้นประ) — ใช้ทั้งหน้าแรก แถวตั้งค่า แท็บฉัน แผ่นเพิ่มงาน และจอว่าง
     ② ปุ่มหลักเป็นโลหะเงินขัดเงา (แบบ Metal Button ของ Cult UI · ไล่ขาว→เงิน→เทา + ขอบสะท้อนบน/ล่าง)
     ③ ปุ่มกลับกลม ขอบเส้นเงินบาง · แถบล่างขอบเส้นเงิน แท็บที่เลือกเป็นเงินขัดเงา
     ④ หัวข้อจอเป็นตัวหนังสือโครเมียม (ขาวไล่ลงเทา)
     ⑤ ลายหลังไอคอนในจอว่างเป็นวงโคจรซ้อนกันบาง ๆ
     ⑥ ท่าเปลี่ยนจอ "สุริยุปราคา" — ค่อย ๆ สว่างขึ้นจากดำ ช้าและนิ่งแบบภาพยนตร์ (ทิศเข้า/ถอยเหมือนทุกธีม)
   ============================================================ */
:root[data-theme="astral"] { --r-card: 18px; --r-tile: 12px; }

/* ① ดาวเคราะห์ + วงโคจรมีดวงจันทร์ */
:root[data-theme="astral"] .phone :is(.es-ic, .nt-empty-ic, .set-ic, .pe-ic, .as-ic, .tb-nd-ic, .soon-ic, .bd-entry-ic, .bd-guest-ic, .fd-blank-ic, .dm-blank-ic) { border-radius: 50% !important; }

/* ② ปุ่มหลักโลหะเงิน */
:root[data-theme="astral"] .phone :is(.tc-cta, .btn.primary, .fm-save, .fr-gate-go, .es-go:not(.ghost), .bd-guest-go) {
  border-radius: 999px !important;
  background: linear-gradient(180deg, #FFFFFF 0%, #DCDCDC 42%, #B4B4B4 58%, #E6E6E6 100%) !important;
  color: #0A0A0A !important;
  box-shadow: inset 0 1px 0 #FFFFFF, inset 0 -1px 0 rgba(0, 0, 0, .28), 0 0 0 1px rgba(255, 255, 255, .3),
    0 12px 26px -14px rgba(255, 255, 255, .4) !important;
}

/* ③ ปุ่มกลับ · แถบล่าง */
:root[data-theme="astral"] .phone :is(.sh-btn,.set-back,.ch-back,.hw-back,.tp-back,.sh-back,.lg-back,.rp-back,.back,.fc-x,button[aria-label^="กลับ"]) { border-radius: 50% !important; box-shadow: 0 0 0 1px rgba(255, 255, 255, .3) !important; }
:root[data-theme="astral"] .phone .tabbar { border-color: rgba(255, 255, 255, .26) !important; }
:root[data-theme="astral"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) {
  background-image: linear-gradient(180deg, #FFFFFF 0%, #DCDCDC 45%, #B9B9B9 100%) !important;
  color: #0A0A0A !important;
  box-shadow: inset 0 1px 0 #FFFFFF, inset 0 -1px 0 rgba(0, 0, 0, .25) !important;
}

/* ④ หัวข้อโครเมียม */
:root[data-theme="astral"] .phone :is(.page-title, .fd-title) {
  background-image: linear-gradient(180deg, #FFFFFF 30%, #A3A3A3 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
}

/* ⑤ จอว่าง: วงโคจรซ้อน */
:root[data-theme="astral"] .es::before {
  background-image: repeating-radial-gradient(circle at 50% 30%, transparent 0 15px, rgba(255, 255, 255, .09) 15px 16px);
  background-size: auto;
}

/* ⑥ ท่าเปลี่ยนจอ + ท่าตอนกด */
:root[data-theme="astral"] body:not([data-godir="lat"]) .screen.on { animation: id-eclipse .46s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes id-eclipse {
  0% { opacity: 0; transform: translate3d(calc(var(--id-dx) * .3), 0, 0) scale(.99); }
  40% { opacity: .55; }
  100% { opacity: 1; transform: none; }
}
:root[data-theme="astral"] .phone .tg-t:active .tg-ic { transform: scale(.92) !important; }

/* ============================================================
   ห้องแชทแบบ IG แต่เป็นของเราเอง (12 ต.ค. 69 · คู่กับ social.js หัวข้อเดียวกัน)
   ------------------------------------------------------------
   เจ้าของ (ส่งภาพห้องแชทในธีมดำ): "แก้ไขในหน้านี้หน่อยให้ดูแบบแชทคล้ายไอจี มีอนิเมชันคล้าย ๆ กันแต่อย่าเหมือนกัน"
   • รายการ: ไม่มีแถบเลื่อน (ภาพที่ส่งมามีแถบเลื่อนเทาพร้อมลูกศรกินขอบขวา) · ขอบบนจางใต้หัวจอแทนการตัดขาด
   • ฟองของเรา: ไล่สีตามตำแหน่งบนจอ — บนสุด = สีเน้นหมุนเฉด 48° · ล่างสุด = สีเน้นของธีม (social.js · chatPaint)
     IG ใช้ม่วง→น้ำเงินตายตัว ของเราเปลี่ยนตามธีม (น้ำเงิน→ม่วง · เขียว→เขียวอมฟ้า · ธีมขาวดำ = ขาว→เงิน)
   • อิโมจิล้วนไม่เกินสามตัว = ตัวใหญ่ไม่มีฟอง
   • ท่าเข้า: ของเขาโผล่จากฝั่งรูป ของเราลอยออกจากช่องพิมพ์ (JS) · สปริงเกินนิดเดียว (.2, 1.2, .32, 1)
   • กดค้าง: ฟองยุบ 4% ระหว่างรอ → จอหรี่ ฟองยกขึ้น เมนูเด้งออกจากมุมของฟอง
   • กำลังพิมพ์: จุดสามจุดเป็นคลื่นสีเน้นของธีม · ข้อความใหม่ตอนอ่านของเก่า = ป้ายลอยเหนือช่องพิมพ์
   โหมดลื่น: ไม่เบลอ ไม่มีขอบจาง ไม่ไล่สีตามตำแหน่ง · ลดการเคลื่อนไหว: จางเข้าอย่างเดียว
   ============================================================ */
#chatBody { position: relative; }
.ch-reqs { display: contents; }
#chatBody .ch-list {
  position: relative; scrollbar-width: none; overscroll-behavior: contain;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
  mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
}
#chatBody .ch-list::-webkit-scrollbar { display: none; }

/* ฟองกดค้างได้ — ปิดเมนูเลือกข้อความของเครื่อง (เมนูของเรามีปุ่มคัดลอกให้แทน) */
#chatBody :is(.ch-bub, .ch-img) {
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; touch-action: manipulation;
  transition: transform .2s cubic-bezier(.23, 1, .32, 1), opacity .2s ease;
}
#chatBody :is(.ch-bub, .ch-img).pressing { transform: scale(.96); }
#chatBody .ch-bub:focus-visible { outline: 2px solid var(--fill); outline-offset: 2px; }

@supports (color: oklch(from red l c h)) {
  #chatBody { --chg-top: oklch(from var(--fill) calc(l + .05) c calc(h + 48)); --chg-bot: var(--fill); }
  #chatBody .ch-msg.me .ch-bub:not(.ch-emoji) {
    background: linear-gradient(180deg,
      color-mix(in oklab, var(--chg-top), var(--chg-bot) var(--g0, 70%)),
      color-mix(in oklab, var(--chg-top), var(--chg-bot) var(--g1, 82%)));
  }
  /* ธีมขาวดำ: สีเน้นเป็นขาว หมุนเฉดไม่มีผล — ไล่ขาว → เงินแทน */
  :root[data-theme="astral"] #chatBody { --chg-top: #FFFFFF; --chg-bot: #BDBDBD; }
}

#chatBody .ch-bub.ch-emoji {
  background: none !important; box-shadow: none !important; border: 0;
  padding: 0 2px; font-size: 38px; line-height: 1.15; letter-spacing: 2px;
}
#chatBody .ch-msg.sending :is(.ch-bub, .ch-img) { opacity: .62; }

/* ---------- ท่าเข้า ---------- */
#chatBody .ch-msg.me .ch-col { transform-origin: 100% 100%; }
#chatBody .ch-msg:not(.me) .ch-col { transform-origin: 0 100%; }
#chatBody .ch-msg.in-them .ch-col { animation: chm-them .46s cubic-bezier(.2, 1.2, .32, 1) both; }
#chatBody .ch-msg.in-them > .ch-face:not(.ghost) { animation: chm-face .42s cubic-bezier(.2, 1.3, .32, 1) both; }
#chatBody .ch-msg.in-me .ch-col { animation: chm-me .42s cubic-bezier(.2, 1.2, .32, 1) both; }
@keyframes chm-them { from { opacity: 0; transform: translate3d(-14px, 10px, 0) scale(.88); } }
@keyframes chm-me { from { opacity: 0; transform: translate3d(14px, 10px, 0) scale(.88); } }
@keyframes chm-face { from { opacity: 0; transform: scale(.4); } }

/* ---------- อีกฝ่ายกำลังพิมพ์ ---------- */
#chatBody .ch-typing .ch-bub { display: inline-flex; align-items: center; gap: 4px; padding: 13px 15px; color: var(--fill); }
#chatBody .ch-typing .ch-bub i {
  width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .35;
  animation: chm-dot 1.1s ease-in-out infinite;
}
#chatBody .ch-typing .ch-bub i:nth-child(2) { animation-delay: .14s; }
#chatBody .ch-typing .ch-bub i:nth-child(3) { animation-delay: .28s; }
@keyframes chm-dot { 0%, 60%, 100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-4px); opacity: 1; } }
#chatBody .ch-typing.out .ch-col { animation: chm-out .2s ease forwards; }
@keyframes chm-out { to { opacity: 0; transform: scale(.8); } }

/* ---------- ป้าย "ข้อความใหม่" ---------- */
#chatBody .ch-bar { position: relative; }
#chatBody .ch-jump {
  position: absolute; left: 50%; bottom: calc(100% + 8px); z-index: 2;
  display: inline-flex; align-items: center; gap: 4px; padding: 7px 11px 7px 14px;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--fill); color: var(--on-fill, #fff); font: inherit; font-size: 12.5px; font-weight: 800;
  box-shadow: 0 8px 20px -8px var(--fill);
  transform: translateX(-50%); animation: chm-jump .34s cubic-bezier(.2, 1.3, .32, 1) both;
}
#chatBody .ch-jump svg { width: 14px; height: 14px; transform: rotate(90deg); }
@keyframes chm-jump { from { opacity: 0; transform: translate(-50%, 8px) scale(.85); } }

/* ---------- เมนูกดค้าง ---------- */
#chatBody .ch-hold { position: absolute; inset: 0; z-index: 30; }
#chatBody .ch-hold-dim {
  position: absolute; inset: 0; opacity: 0; transition: opacity .2s ease;
  background: color-mix(in srgb, #000 40%, transparent);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
#chatBody .ch-hold.on .ch-hold-dim { opacity: 1; }
#chatBody .ch-hold-row { position: absolute; margin: 0; pointer-events: none; }
#chatBody .ch-hold-row .ch-col { max-width: none; width: 100%; }
#chatBody .ch-hold-row :is(.ch-bub, .ch-img) { transition: transform .34s cubic-bezier(.2, 1.3, .32, 1), box-shadow .34s ease; }
#chatBody .ch-hold.on .ch-hold-row :is(.ch-bub, .ch-img) { transform: scale(1.04); box-shadow: 0 18px 36px -14px rgba(0, 0, 0, .6); }
#chatBody .ch-hold-menu {
  position: absolute; min-width: 196px; padding: 6px; border-radius: 18px;
  background: color-mix(in srgb, var(--card) 94%, transparent); color: var(--ink);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent), 0 18px 40px -16px rgba(0, 0, 0, .55);
  -webkit-backdrop-filter: blur(18px) saturate(160%); backdrop-filter: blur(18px) saturate(160%);
  opacity: 0; transform: scale(.82);
  transition: opacity .16s ease, transform .32s cubic-bezier(.2, 1.25, .32, 1);
}
#chatBody .ch-hold.on .ch-hold-menu { opacity: 1; transform: none; }
#chatBody .ch-hold-when {
  margin: 5px 10px 5px; font-size: 11.5px; font-weight: 700;
  color: color-mix(in srgb, var(--ink) 55%, transparent); font-variant-numeric: tabular-nums;
}
#chatBody .ch-hold-menu button {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; width: 100%;
  padding: 11px 12px; border: 0; border-radius: 12px; background: none; cursor: pointer;
  color: var(--ink); font: inherit; font-size: 14.5px; font-weight: 700; text-align: left;
}
#chatBody .ch-hold-menu button svg { width: 18px; height: 18px; flex: none; }
#chatBody .ch-hold-menu button:is(:hover, :focus-visible) { background: color-mix(in srgb, var(--ink) 8%, transparent); outline: none; }
#chatBody .ch-hold-menu button.bad { color: #EF4444; }

:root[data-lite] #chatBody .ch-list { -webkit-mask-image: none; mask-image: none; }
:root[data-lite] #chatBody :is(.ch-hold-dim, .ch-hold-menu) { -webkit-backdrop-filter: none; backdrop-filter: none; }
:root[data-lite] #chatBody .ch-hold-menu { background: var(--card); }
:root[data-lite] #chatBody .ch-typing .ch-bub i { animation-play-state: paused; opacity: .7; }
@media (prefers-reduced-motion: reduce) {
  #chatBody .ch-msg:is(.in-them, .in-me) .ch-col, #chatBody .ch-jump { animation: boot-fade .2s ease both; }
  #chatBody .ch-msg.in-them > .ch-face { animation: none; }
  #chatBody .ch-typing .ch-bub i { animation: none; opacity: .7; }
  #chatBody .ch-hold-menu, #chatBody .ch-hold.on .ch-hold-row :is(.ch-bub, .ch-img) { transform: none; }
}

/* ============================================================
   เมนูข้อความแบบ IG (ต่อจาก "ห้องแชทแบบ IG" ข้างบน · คู่กับ social.js chatHoldOpen)
   ------------------------------------------------------------
   เจ้าของส่งภาพแถบ หน้ายิ้ม / ตอบกลับ / ⋮ กับเมนู Edit · Forward · Copy · Translate · Pin · Unsend แล้วบอก "ใช้ระบบนี้ด้วย"
   • คอม: เอาเมาส์ชี้ฟอง = ปุ่มสามปุ่มโผล่ข้างฟอง (ฝั่งตรงข้ามกับที่ฟองชิด) · มือถือ: กดค้าง
   • เมนูเดิม (.ch-hold-menu) ได้ไอคอนเส้นตามแบบ IG · แถบปฏิกิริยาลอยเหนือฟอง
   • ตอบกลับ: ข้อความต้นทางเป็นฟองจางเหนือฟองตอบ · แถบ "ตอบกลับ…/กำลังแก้ไข…" เหนือช่องพิมพ์
   • ปักหมุด: แถบบนสุดของห้อง แตะแล้วเลื่อนไปหา · ปฏิกิริยา: เม็ดอิโมจิเกาะมุมล่างของฟอง
   ============================================================ */
/* ---------- ปุ่มข้างฟอง (เมาส์เท่านั้น) ---------- */
#chatBody .ch-tools { display: none; }
@media (hover: hover) and (pointer: fine) {
  #chatBody .ch-tools {
    display: inline-flex; align-self: center; gap: 2px; flex: none;
    opacity: 0; transition: opacity .15s ease;
  }
  #chatBody .ch-msg:hover > .ch-tools, #chatBody .ch-tools:focus-within { opacity: 1; }
  #chatBody .ch-tools button {
    width: 30px; height: 30px; display: grid; place-items: center; padding: 0;
    border: 0; border-radius: 50%; background: none; cursor: pointer;
    color: color-mix(in srgb, var(--ink) 55%, transparent);
    transition: background .15s ease, color .15s ease, transform .15s ease;
  }
  #chatBody .ch-tools button svg { width: 18px; height: 18px; }
  #chatBody .ch-tools button:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 9%, transparent); }
  #chatBody .ch-tools button:active { transform: scale(.9); }
}

/* ---------- แถบปฏิกิริยาเหนือฟอง ---------- */
#chatBody .ch-hold-rx {
  position: absolute; display: flex; gap: 2px; padding: 5px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--card) 94%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent), 0 14px 32px -14px rgba(0, 0, 0, .55);
  -webkit-backdrop-filter: blur(18px) saturate(160%); backdrop-filter: blur(18px) saturate(160%);
  opacity: 0; transform: scale(.7);
  transition: opacity .16s ease, transform .34s cubic-bezier(.2, 1.3, .32, 1);
}
#chatBody .ch-hold.on .ch-hold-rx { opacity: 1; transform: none; }
#chatBody .ch-hold-rx button {
  width: 40px; height: 40px; border: 0; border-radius: 50%; background: none; cursor: pointer;
  font-size: 24px; line-height: 1; display: grid; place-items: center; padding: 0;
  transition: transform .2s cubic-bezier(.2, 1.4, .32, 1), background .15s ease;
}
#chatBody .ch-hold-rx button:hover, #chatBody .ch-hold-rx button:focus-visible { transform: scale(1.22) translateY(-3px); outline: none; }
#chatBody .ch-hold-rx button.on { background: color-mix(in srgb, var(--ink) 12%, transparent); }
/* แต่ละอิโมจิเด้งเข้าไล่กัน (ตามท่า stagger ของ React Bits — 25ms ต่อตัว) */
#chatBody .ch-hold.on .ch-hold-rx button { animation: chm-rx .36s cubic-bezier(.2, 1.4, .32, 1) both; }
#chatBody .ch-hold.on .ch-hold-rx button:nth-child(2) { animation-delay: .025s; }
#chatBody .ch-hold.on .ch-hold-rx button:nth-child(3) { animation-delay: .05s; }
#chatBody .ch-hold.on .ch-hold-rx button:nth-child(4) { animation-delay: .075s; }
#chatBody .ch-hold.on .ch-hold-rx button:nth-child(5) { animation-delay: .1s; }
#chatBody .ch-hold.on .ch-hold-rx button:nth-child(6) { animation-delay: .125s; }
@keyframes chm-rx { from { opacity: 0; transform: translateY(8px) scale(.5); } }

/* ---------- ฟองที่เป็นการตอบกลับ ---------- */
#chatBody .ch-quote {
  display: flex; flex-direction: column; gap: 2px; max-width: 100%; margin: 0 0 -10px; padding: 0;
  border: 0; background: none; font: inherit; color: inherit; text-align: inherit; cursor: pointer;
}
#chatBody .ch-msg.me .ch-quote { align-items: flex-end; }
#chatBody .ch-quote:disabled { cursor: default; }
#chatBody .ch-quote i {
  display: inline-flex; align-items: center; gap: 4px; padding: 0 6px;
  font-style: normal; font-size: 11px; font-weight: 700; color: color-mix(in srgb, var(--ink) 58%, transparent);
}
#chatBody .ch-quote i svg { width: 12px; height: 12px; }
#chatBody .ch-quote span {
  max-width: 100%; padding: 8px 13px 18px; border-radius: 16px;
  background: color-mix(in srgb, var(--ink) 9%, transparent); color: color-mix(in srgb, var(--ink) 70%, transparent);
  font-size: 13px; line-height: 1.4; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
#chatBody .ch-quote + .ch-edited + .ch-bub, #chatBody .ch-quote + .ch-bub { position: relative; }
#chatBody .ch-edited {
  padding: 0 6px 2px; font-size: 11px; font-weight: 600; color: color-mix(in srgb, var(--ink) 50%, transparent);
}
#chatBody .ch-msg.flash .ch-col > :is(.ch-bub, .ch-img) { animation: chm-flash 1.4s ease; }
@keyframes chm-flash { 0%, 35% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--fill) 70%, transparent); } }

/* ---------- คำแปล ---------- */
#chatBody .ch-bub.tr { font-style: normal; }
#chatBody .ch-trsw {
  margin: 3px 4px 0; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 700; color: var(--fill);
}

/* ---------- เม็ดปฏิกิริยาใต้ฟอง ---------- */
#chatBody .ch-rx {
  position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 3px;
  margin: -9px 8px 0; padding: 2px 7px; border-radius: 999px; cursor: pointer;
  border: 2px solid var(--bg, #000); background: var(--card2, var(--card)); color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1.3;
  animation: chm-rxin .32s cubic-bezier(.2, 1.4, .32, 1) both;
}
#chatBody .ch-rx b { font-size: 11px; font-weight: 800; }
#chatBody .ch-rx.mine { box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--fill) 70%, transparent); }
@keyframes chm-rxin { from { transform: scale(.3); opacity: 0; } }
/* แตะสองที = หัวใจพองขึ้นกลางฟองแล้วจางไป */
#chatBody .ch-col { position: relative; }
#chatBody .ch-burst {
  position: absolute; left: 50%; top: 50%; z-index: 3; pointer-events: none;
  font-size: 44px; line-height: 1; transform: translate(-50%, -50%);
  animation: chm-burst .75s cubic-bezier(.2, 1.3, .32, 1) forwards;
}
@keyframes chm-burst {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.2); }
  35% { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  60% { transform: translate(-50%, -50%) scale(.95); }
  100% { opacity: 0; transform: translate(-50%, -80%) scale(1); }
}

/* ---------- แถบข้อความที่ปักหมุด ---------- */
#chatBody .ch-pinbar {
  display: flex; align-items: center; gap: 10px; margin: 0 12px 4px; padding: 8px 12px;
  border: 0; border-radius: 14px; cursor: pointer; text-align: left; flex: none;
  background: color-mix(in srgb, var(--card) 88%, transparent); color: var(--ink); font: inherit;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
#chatBody .ch-pinbar > svg { width: 16px; height: 16px; flex: none; color: var(--fill); }
#chatBody .ch-pinbar span { display: grid; min-width: 0; }
#chatBody .ch-pinbar b { font-size: 11.5px; font-weight: 800; color: var(--fill); }
#chatBody .ch-pinbar i { font-style: normal; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- แถบ ตอบกลับ / กำลังแก้ไข เหนือช่องพิมพ์ ---------- */
#chatBody .ch-ctx {
  display: flex; align-items: center; gap: 10px; flex: none; margin: 0 12px; padding: 8px 6px 8px 12px;
  border-radius: 14px 14px 0 0; background: color-mix(in srgb, var(--card) 90%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
  animation: chm-ctx .26s cubic-bezier(.2, 1.2, .32, 1) both;
}
#chatBody .ch-ctx[hidden] { display: none; }
@keyframes chm-ctx { from { opacity: 0; transform: translateY(10px); } }
#chatBody .ch-ctx-ic { color: var(--fill); display: grid; }
#chatBody .ch-ctx-ic svg { width: 18px; height: 18px; }
#chatBody .ch-ctx-tx { display: grid; min-width: 0; flex: 1; }
#chatBody .ch-ctx-tx b { font-size: 12px; font-weight: 800; color: var(--ink); }
#chatBody .ch-ctx-tx i {
  font-style: normal; font-size: 12.5px; color: color-mix(in srgb, var(--ink) 60%, transparent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#chatBody .ch-ctx-x {
  width: 32px; height: 32px; flex: none; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 50%; background: none; cursor: pointer; color: color-mix(in srgb, var(--ink) 60%, transparent);
}
#chatBody .ch-ctx-x svg { width: 16px; height: 16px; }
#chatBody .ch-ctx-x:hover { background: color-mix(in srgb, var(--ink) 9%, transparent); }

/* ---------- ส่งต่อ ---------- */
#chatBody .ch-fwd { position: absolute; inset: 0; z-index: 31; }
#chatBody .ch-fwd.on .ch-hold-dim { opacity: 1; }
#chatBody .ch-fwd-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; max-height: 72%; display: flex; flex-direction: column;
  padding: 14px 14px calc(14px + env(safe-area-inset-bottom, 0px)); border-radius: 22px 22px 0 0;
  background: var(--card); color: var(--ink); box-shadow: 0 -18px 40px -20px rgba(0, 0, 0, .5);
  transform: translateY(100%); transition: transform .34s cubic-bezier(.2, 1, .32, 1);
}
#chatBody .ch-fwd.on .ch-fwd-sheet { transform: none; }
#chatBody .ch-fwd-head { display: flex; align-items: center; justify-content: space-between; }
#chatBody .ch-fwd-head b { font-size: 16px; font-weight: 800; }
#chatBody .ch-fwd-msg {
  margin: 8px 0 10px; padding: 9px 12px; border-radius: 12px; font-size: 13px; line-height: 1.45;
  background: color-mix(in srgb, var(--ink) 7%, transparent); color: color-mix(in srgb, var(--ink) 75%, transparent);
}
#chatBody .ch-fwd-list { overflow-y: auto; display: grid; gap: 2px; }
#chatBody .ch-fwd-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; }
#chatBody .ch-fwd-av {
  width: 40px; height: 40px; flex: none; border-radius: 50%; object-fit: cover;
  display: grid; place-items: center; font-size: 15px; font-weight: 700; background: var(--card2); color: var(--muted);
}
#chatBody .ch-fwd-nm { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#chatBody .ch-fwd-go {
  padding: 7px 16px; border: 0; border-radius: 999px; cursor: pointer; font: inherit; font-size: 13px; font-weight: 800;
  background: var(--fill); color: var(--on-fill, #fff); transition: background .2s ease, color .2s ease;
}
#chatBody .ch-fwd-go.done, #chatBody .ch-fwd-go:disabled { background: color-mix(in srgb, var(--ink) 10%, transparent); color: var(--ink); cursor: default; }
#chatBody .ch-fwd-none { margin: 16px 0; text-align: center; font-size: 13px; color: var(--muted); }

:root[data-lite] #chatBody :is(.ch-hold-rx, .ch-pinbar) { -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (prefers-reduced-motion: reduce) {
  #chatBody .ch-hold-rx, #chatBody .ch-hold.on .ch-hold-rx button, #chatBody .ch-rx, #chatBody .ch-ctx { animation: none; transform: none; }
  #chatBody .ch-fwd-sheet { transition: none; }
}

/* ============================================================
   13 ต.ค. 69 · เก็บจอที่ "ยังไม่ค่อยสวยหรือดูแปลก" (ไล่ทุกจอที่ 375×812 แล้วส่งภาพให้เจ้าของดู)
   ============================================================ */
/* ① แถวเช็คอินรายวัน (แท็บฉัน) — ชื่อหักเป็น "เช็คอินราย / วัน" และค่าขวาถูกตัดเหลือ "วันที่ 3 · ได้ 3 โท…"
   ต้นเหตุ: ชื่อหดได้ (flex 1 1 · min-width 0) แต่ค่าห้ามตัดบรรทัด → ค่าแย่งที่จนชื่อเหลือ 78px
   แก้เป็นแถวสองบรรทัดแบบรายการของ Cult UI (FeaturePoll row ที่แอปใช้อยู่ในฟอร์ม): ชื่อบน · ค่าเล็กใต้ชื่อ · ป้ายขวาสุด
   ไม่แตะ HTML — จัดด้วย grid: ไอคอนกินสองแถว · ป้ายกินสองแถว · ชื่อกับค่าซ้อนกันตรงกลาง */
.phone .pe-daily {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "ic tx go" "ic v go"; column-gap: 13px; row-gap: 1px; align-items: center;
}
.phone .pe-daily .pe-ic { grid-area: ic; }
.phone .pe-daily .pe-tx { grid-area: tx; align-self: end; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.phone .pe-daily .pe-v { grid-area: v; align-self: start; text-align: left; }
.phone .pe-daily .pe-daily-go { grid-area: go; }

/* ② ชื่อธีมตัวพิเศษบนธีมมืด — สีเข้มตายตัว (#0E7BA8 · #1E7A3C) ออกแบบไว้สำหรับพื้นสว่าง
   บนพื้นมืดวัดได้ 3.1–3.5 : 1 (ต่ำกว่าเกณฑ์อ่านง่าย) · ธีมมืดใช้สีเดียวกันแบบสว่าง */
:root:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch])
  .bg-row.on.sea .bg-nm.fancy { color: #6FD0F5; }
:root:is([data-theme=dark],[data-theme=space],[data-theme=magic],[data-theme=galaxy],[data-theme=deepocean],[data-theme=meta],[data-theme=glitch])
  .bg-row.on.tree .bg-nm.fancy { color: #7DDB99; }

/* ③ ป้ายใต้ตัวเลขในการ์ดสถิติ — "ส่งทันกำหนด · 5/5 งาน" ตกบรรทัดเหลือ "งาน" คำเดียว · ให้สองบรรทัดยาวพอ ๆ กัน */
.at-k { text-wrap: balance; }

/* ============================================================
   แอปมีมิติ (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "มีอันไหนควรใส่อนิเมชันบ้าง แล้วจะดูมีมิติขึ้น" → เลือกหกจุด → "ลองทำดู เอาอนิเมชันหรือ UI จากที่เรียนมาปรับใช้"
   ① แผ่นล่างเปิด = จอข้างหลังยุบลง (Drawer ของ Cult UI · ท่าของ vaul)
   ② การ์ดบนสุดหน้าแรกเอียงตามนิ้ว + แสงสะท้อน + ลูกในลอยคนละระดับ (3D Card · Glare ของ Aceternity · Tilted Card ของ React Bits — JS ใน app.js)
   ③ ติ๊กงานเสร็จแบบ Spring Check (React Bits)
   ④ รายการไล่เข้าทีละแถว + เส้นเวลาลากลง (AnimatedList ของ React Bits)
   ⑤ ช่องโชว์ในแท็บฉันกดแล้วยุบแบบปุ่มนูน ไอคอนเด้งสวนขึ้น (ปุ่ม 3D ของ Uiverse)
   ⑥ เหรียญในร้านค้าพลิกเข้า + แสงวาบผ่านการ์ดยอด (Shine ของ Magic UI)
   transform/opacity ล้วน · โหมดลื่นปิดท่าหนัก · ลดการเคลื่อนไหวเหลือแค่จาง
   ============================================================ */

/* ① ใช้ scale/translate แยก ไม่ใช่ transform — ธีม Glitch ใช้ transform ของ .screens กระตุกจออยู่แล้ว สองอย่างต้องซ้อนกันได้
   จุดหมุนอยู่บนกลาง: จอหดเข้าหาหัวจอ แผ่นที่ขึ้นมาจากล่างจึงดูเหมือนอยู่ "หน้า" จอจริง ๆ
   ขอบจอมนตามตอนหด (.screens มี overflow: hidden อยู่แล้ว) · เห็นพื้นหลังของธีมรอบ ๆ = ชั้นลึกสุด */
.phone .screens {
  transform-origin: 50% 0;
  transition: scale .5s cubic-bezier(.32, .72, 0, 1), translate .5s cubic-bezier(.32, .72, 0, 1), border-radius .5s cubic-bezier(.32, .72, 0, 1);
}
body.sheet-up .phone .screens { scale: .94; translate: 0 12px; border-radius: 22px; }

/* ② */
#menuBody :is(.td-now, .td-clear).tilt-on {
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--ts, 1));
  will-change: transform;
}
#menuBody :is(.td-now, .td-clear).tilt-on::after {
  content: ''; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none;
  background: radial-gradient(55% 65% at var(--gx, 50%) var(--gy, 50%), rgba(255, 255, 255, .16), transparent 70%);
  opacity: var(--ga, 0);
}
#menuBody .td-clear.tilt-on .tc-art { translate: calc(var(--px, 0) * 7px) calc(var(--py, 0) * 6px); }
#menuBody .td-clear.tilt-on .tc-tx { translate: calc(var(--px, 0) * 3px) calc(var(--py, 0) * 2.5px); }
#menuBody .td-clear.tilt-on :is(.tc-cta, .tc-room, .tc-steps) { translate: calc(var(--px, 0) * -1.5px) calc(var(--py, 0) * -1px); }
#menuBody .td-now.tilt-on .tn-head { translate: calc(var(--px, 0) * 4px) calc(var(--py, 0) * 3px); }
#menuBody .td-now.tilt-on .tn-body { translate: calc(var(--px, 0) * 1.5px) calc(var(--py, 0) * 1px); }

/* ③ Spring Check — ติ๊กพองเกิน (1.24) แล้วยุบ · ถูกวาดเส้น · ชื่อถูกขีดฆ่า · การ์ดจางยุบ (ก่อนรายการวาดใหม่ 430ms) */
.phone :is(.tk-tick, .rc-check).pop { animation: sc-pop .5s cubic-bezier(.2, 1.6, .35, 1) both; }
@keyframes sc-pop { 0% { transform: scale(.72); } 45% { transform: scale(1.24); } 100% { transform: scale(1); } }
.phone :is(.tk-tick, .rc-check).pop svg { stroke-dasharray: 26; stroke-dashoffset: 26; animation: sc-draw .34s .1s cubic-bezier(.65, 0, .35, 1) forwards; }
@keyframes sc-draw { to { stroke-dashoffset: 0; } }
.phone :is(.tk, .rank-card).just-done :is(.tk-ttl, .rc-title) {
  text-decoration-line: line-through; text-decoration-thickness: 2px; text-decoration-color: transparent;
  animation: sc-strike .3s .12s ease-out forwards;
}
@keyframes sc-strike { to { text-decoration-color: color-mix(in srgb, currentColor 65%, transparent); opacity: .6; } }
.phone :is(.tk, .rank-card).just-done { animation: sc-card .4s .22s cubic-bezier(.4, 0, .2, 1) forwards; }
@keyframes sc-card { to { opacity: .5; transform: scale(.975); } }

/* ④ ไล่ทีละแถวตอนเพิ่งเปิดจอ (.fx-in มาจาก screenFx ใน go()) · 40ms ต่อแถว · แถวที่ 9 ขึ้นไปมาพร้อมกัน */
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow) { animation: fx-up .45s cubic-bezier(.22, 1, .36, 1) backwards; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(2) { animation-delay: .04s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(3) { animation-delay: .08s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(4) { animation-delay: .12s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(5) { animation-delay: .16s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(6) { animation-delay: .2s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(7) { animation-delay: .24s; }
.screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow):nth-child(n+8) { animation-delay: .28s; }
.screen.fx-in .dayrail::before { transform-origin: 50% 0; animation: fx-grow-y .8s cubic-bezier(.22, 1, .36, 1) backwards; }

/* ⑤ ปุ่มนูน: กด = ตัวการ์ดจมลง 2px เงาหด · ไอคอนสวนขึ้น — สองชั้นขยับคนละทางคือสิ่งที่ทำให้อ่านเป็นความลึก */
.phone .shw { transition: transform .16s cubic-bezier(.23, 1, .32, 1), box-shadow .16s ease; }
.phone .shw .shw-ic { transition: transform .26s cubic-bezier(.3, 1.6, .5, 1); }
.phone .shw:active { transform: translateY(2px) scale(.97); box-shadow: 0 1px 2px rgba(0, 0, 0, .2); }
.phone .shw:active .shw-ic { transform: translateY(-3px) scale(1.08); }
.screen.fx-in .shw .shw-ic { animation: es-pop .5s cubic-bezier(.3, 1.5, .5, 1) backwards; }
.screen.fx-in .shw:nth-child(2) .shw-ic { animation-delay: .05s; }
.screen.fx-in .shw:nth-child(3) .shw-ic { animation-delay: .1s; }
.screen.fx-in .shw:nth-child(4) .shw-ic { animation-delay: .15s; }

/* ⑥ เหรียญพลิกเข้าหนึ่งรอบครึ่งแล้วลงที่ · แสงวาบวิ่งผ่านการ์ดยอดหนึ่งครั้งตามหลัง */
.screen.fx-in .tk-hero .tk-top .tok { animation: coin-flip .95s .12s cubic-bezier(.3, 1.2, .5, 1) backwards; }
@keyframes coin-flip { from { opacity: 0; transform: perspective(320px) rotateY(-540deg) scale(.55); } 55% { opacity: 1; } }
.screen.fx-in .tk-hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, .2) 50%, transparent 65%);
  transform: translateX(-100%); animation: tk-shine 1.1s .45s cubic-bezier(.4, 0, .2, 1) forwards;
}
@keyframes tk-shine { to { transform: translateX(100%); } }

/* โหมดลื่น: ไม่เอียง ไม่ยุบจอ ไม่พลิกเหรียญ (ท่าที่กินแรงเครื่องที่สุดในชุดนี้) · ติ๊กกับไล่แถวยังอยู่ (เบา) */
:root[data-lite] .phone .screens { transition: none; }
:root[data-lite] body.sheet-up .phone .screens { scale: none; translate: none; border-radius: 0; }
:root[data-lite] .screen.fx-in .tk-hero .tk-top .tok, :root[data-lite] .screen.fx-in .tk-hero::after { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .phone .screens { transition: none; }
  body.sheet-up .phone .screens { scale: none; translate: none; border-radius: 0; }
  .phone :is(.tk-tick, .rc-check).pop, .phone :is(.tk-tick, .rc-check).pop svg { animation: none; stroke-dashoffset: 0; }
  .phone :is(.tk, .rank-card).just-done { animation: none; opacity: .6; }
  .screen.fx-in :is(#taskList > *, .wk-card > .wk-row, .dayrail > .dayrow) { animation: boot-fade .25s ease backwards; }
  .screen.fx-in .dayrail::before, .screen.fx-in .shw .shw-ic, .screen.fx-in .tk-hero .tk-top .tok, .screen.fx-in .tk-hero::after { animation: none; }
  .phone .shw:active, .phone .shw:active .shw-ic { transform: none; }
}

/* ============================================================
   Astral Black · ขาว–ดำ–เทาให้ครบ + ท่าประจำธีม (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ในธีม astral black ตกแต่งให้สวย UI อยู่ในแนว astral black deep black สร้างอนิเมชันให้เข้ากับธีม
            จัดการตกแต่งทั้งหมดและทุกปุ่ม แต่ถ้าปุ่มไม่ควรแก้ก็ปล่อยไป ให้มีแค่สีขาวกับดำและเทา ... ไม่เอาให้มันรกเกินไป"
   ไล่ทุกจอด้วยตัววัดสี (ตัวหนังสือ · พื้น · ขอบ · เงา · ไอคอน · ::before/::after · นับฟิลเตอร์ขาวดำของตัวแม่ด้วย)
   เหลือสีหลุดจริงไม่กี่จุด → เทาหมด · คงสีไว้เพราะสีคือความหมาย: โลโก้ Google · ช่องสีตัวอย่างธีมอื่นในร้าน ·
   ห้องของฉัน (สีที่ผู้ใช้เลือกเอง) · อิโมจิ · รูปถ่ายของคน
   ยกเลิกข้อยกเว้นเดิมสองข้อ เพราะรอบนี้สั่งขาวดำล้วน:
     • เหรียญโทเคน (12 ต.ค. เคยคืนเป็นทอง เพราะเหรียญเทากลืนกับชิปเทาจนหาไม่เจอ) → เงินขัดสว่าง + ขอบเข้มบาง ๆ กันกลืน
     • น้องฮูก/น้องไซ และโลโก้แอป → ขาวดำ
   ท่าประจำธีมมีแค่สาม (ไม่ให้รก): แตะปุ่ม = ประกายดาว · เข้าจอ = แสงวิ่งผ่านหัวข้อโครเมียม · เปลี่ยนแท็บ = เงาวาบบนแท็บที่เลือก
   ============================================================ */

/* ---------- สีที่ยังหลุด ---------- */
:root[data-theme="astral"] .phone .tok { filter: grayscale(1) brightness(1.2) contrast(1.15) drop-shadow(0 0 .7px rgba(0, 0, 0, .9)); }
:root[data-theme="astral"] .phone :is(img[src*="hook-"], img[src*="sai-"], img[src*="logo-splash"], img[src*="logo-mark"]) {
  filter: grayscale(1) contrast(1.06) !important;
}
/* ขอบวนของเหรียญตราพิเศษ (ฟ้า · เขียว · ชมพู) */
:root[data-theme="astral"] .bg-row.on::before { filter: grayscale(1); }
/* ช่องกรอกแบบ HaloField ในหน้าแก้โปรไฟล์ + ช่องค้นหาในกล่องข้อความ — ขอบวนชมพู/ฟ้า → เงิน/เทา (ทั้งตอนปกติและตอนโฟกัส) */
:root[data-theme="astral"] :is(.ep .ep-f > input[type="text"], .ep .ep-f > textarea, .ep .ep-at, #dmBody .dm-find input) {
  --hf-c2: rgba(175, 175, 175, .55) !important; --hf-c3: rgba(95, 95, 95, .6) !important;
}
/* การ์ดรูป/ชื่อในหน้าแก้โปรไฟล์ — ไม่ใช้ฟิลเตอร์ทั้งการ์ด เพราะข้างในคือรูปของคน (รูปถ่ายคงสี) เปลี่ยนแค่ขอบวน */
:root[data-theme="astral"] .ep .ep-face {
  background:
    linear-gradient(160deg, #2A2A2A, #1C1C1C) padding-box,
    conic-gradient(from var(--hf-a), #F2F2F2, #8C8C8C, #474747, #C4C4C4, #F2F2F2) border-box;
}
:root[data-theme="astral"] .ep .ep-face::after {
  background: conic-gradient(from var(--hf-a), rgba(255, 255, 255, .45), rgba(140, 140, 140, .3), rgba(255, 255, 255, .45));
}
/* ร้านค้า: ไอคอนเอฟเฟกต์ตอนงานเสร็จ (ลูกบาส ลูกบอล ฯลฯ) → ขาวดำ · ช่องสีธีมอื่นคงสีไว้ (ไม่งั้นแยกธีมไม่ออก) */
:root[data-theme="astral"] .tb-sw.fxi { filter: grayscale(1); }
/* หน้าสุ่มสกิน: พื้นเวทีฟ้า · ป้าย/แถบ Mythic ไล่สีรุ้ง → เงิน */
:root[data-theme="astral"] .gc-stage.idle { filter: grayscale(1); }
:root[data-theme="astral"] .r-mythic { filter: grayscale(1) brightness(1.3); }

/* ---------- ท่าประจำธีม ① แตะปุ่ม = ประกายดาว (JS ใน app.js · วางที่จุดแตะ) ----------
   วงแหวนบางขยายออกแล้วจาง + ประกายสี่แฉกหมุนครึ่งรอบ · ชิ้นเดียวทั้งแอป ย้ายไปตามจุดที่แตะ ไม่ยุ่งกับผังของปุ่ม */
.as-flare { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 9000; pointer-events: none; }
.as-flare i, .as-flare b { position: absolute; left: 0; top: 0; translate: -50% -50%; opacity: 0; }
.as-flare i {
  width: 52px; height: 52px; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .85);
  box-shadow: 0 0 10px rgba(255, 255, 255, .35), inset 0 0 8px rgba(255, 255, 255, .18);
}
.as-flare b {
  width: 34px; height: 34px;
  background:
    radial-gradient(circle, #FFFFFF 0 2.2px, rgba(255, 255, 255, .6) 3.4px, transparent 7px),
    linear-gradient(90deg, transparent 45.5%, #FFFFFF 50%, transparent 54.5%),
    linear-gradient(0deg, transparent 45.5%, #FFFFFF 50%, transparent 54.5%);
  -webkit-mask: radial-gradient(circle, #000 32%, transparent 72%); mask: radial-gradient(circle, #000 32%, transparent 72%);
  filter: drop-shadow(0 0 3px rgba(255, 255, 255, .8));
}

/* ---------- ② เข้าจอ = แสงวิ่งผ่านหัวข้อโครเมียมหนึ่งครั้ง ----------
   ชั้นแสงอยู่นอกจอทางซ้ายตอนนิ่ง (มองไม่เห็น) · .fx-in (เพิ่งเปิดจอ) = ลากผ่านไปทางขวา */
:root[data-theme="astral"] .phone :is(.page-title, .fd-title) {
  background-image: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, .95) 50%, transparent 60%), linear-gradient(180deg, #FFFFFF 30%, #A3A3A3 100%);
  background-size: 250% 100%, 100% 100%; background-repeat: no-repeat; background-position: 120% 0, 0 0;
}
:root[data-theme="astral"] .screen.fx-in :is(.page-title, .fd-title) { animation: as-title-shine 1.1s .25s cubic-bezier(.4, 0, .2, 1) both; }
@keyframes as-title-shine { from { background-position: 120% 0, 0 0; } to { background-position: -40% 0, 0 0; } }

/* ---------- ③ เปลี่ยนแท็บ = เงาวาบบนแท็บที่เพิ่งเลือก ----------
   เล่นตอนแท็บเพิ่งได้คลาส .active (สลับแท็บ) ครั้งเดียว · ทรง/สีเดิมของแท็บโลหะ (ข้างบน ③) ไม่เปลี่ยน */
:root[data-theme="astral"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) {
  background-image: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .95) 50%, transparent 62%), linear-gradient(180deg, #FFFFFF 0%, #DCDCDC 45%, #B9B9B9 100%) !important;
  background-size: 260% 100%, 100% 100% !important; background-repeat: no-repeat !important; background-position: 120% 0, 0 0;
  animation: as-tab-sheen .75s .05s cubic-bezier(.4, 0, .2, 1) both;
}
@keyframes as-tab-sheen { from { background-position: 120% 0, 0 0; } to { background-position: -40% 0, 0 0; } }

@media (prefers-reduced-motion: reduce) {
  :root[data-theme="astral"] .screen.fx-in :is(.page-title, .fd-title),
  :root[data-theme="astral"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { animation: none; }
}
:root[data-lite][data-theme="astral"] .screen.fx-in :is(.page-title, .fd-title),
:root[data-lite][data-theme="astral"]:not([data-nav="side"]) .phone .tabbar .tab.active:not(.scan) { animation: none; }

/* ============================================================
   แคปซูลหัวจองานอยู่บรรทัดเดียว (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "แก้ตรงนี้ให้มันอยู่ในบรรทัดเดียว" — "13–19 ต.ค. · ว่างรวม 15 ชม. 45 นาที · ค้าง 1" ตกเป็นสองบรรทัด
   วัดที่จอ 360: ตัวหนังสือ 13px ยาว 280px + ขอบใน 24px แต่แถวเหลือ 282px (เว้นขวา 34px ให้ปุ่มเพื่อน) → ล้น
   ห้ามตัดบรรทัด · ตัวหนังสือย่อตามความกว้างจอ (3.7% ของหัวจอ ≈ 12.5px ที่ 375 · 12px ที่ 360) สูงสุด 13px ต่ำสุด 11px
   ยาวกว่านั้นอีก (ค้างหลักสิบ + ชั่วโมงหลักสิบ บนจอแคบมาก) ตัดท้ายเป็น … แทนการขึ้นบรรทัดใหม่ */
.page-head .eyebrow { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ฟอนต์ — เจ้าของ: "ไม่เอาฟอนต์นี้ เอาฟอนต์ที่เข้ากับแอป"
   เดิมใช้ IBM Plex Sans (ฟอนต์หัวข้อ) แต่ Plex ไม่มีตัวไทย → ตัวเลข "13–19 · 15" เป็น Plex ส่วนคำไทยตกไป Sarabun = สองฟอนต์ในบรรทัดเดียว
   เปลี่ยนเป็น Sarabun ล้วน น้ำหนัก 600 ชุดเดียวกับแท็บ วันนี้/สัปดาห์/รายการ ที่อยู่ใต้มันพอดี · ตัวเลขกว้างเท่ากันไม่ให้กรอบยืดหดตามนาที */
.page-head .eyebrow { font-family: 'Sarabun', 'Leelawadee UI', sans-serif; font-weight: 600; font-variant-numeric: tabular-nums; }
:root[data-theme="astral"] .page-head .eyebrow { font-weight: 600; }
#scr-tasks .page-head { container-type: inline-size; }
#scr-tasks .tk-head-row .eyebrow { font-size: clamp(11px, 3.7cqi, 13px); letter-spacing: .01em; max-width: 100%; }

/* ============================================================
   ตัวหนังสือสวยและสบายตา — ฟอนต์เดียวทั้งแอป (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ตรวจฟอนต์ไหนที่ยังไม่เข้ากับเนื้อหาหรือหัวข้อ" → "ต้องให้ข้อความดูสวยและดูสบายตาด้วย"
   วัดทุกจอ (32 จอ · ธีมสว่างและมืด) ว่าตัวหนังสือแต่ละก้อนออกมาเป็นฟอนต์อะไรจริง ขนาดเท่าไร ระยะตัวอักษรเท่าไร สีตัดพื้นแค่ไหน
   ① หัวข้อ: IBM Plex Sans ไม่มีตัวไทย → คำไทยเป็น Sarabun แต่ "StudentOS" "Nah I'd" "Pro" ในบรรทัดเดียวกันเป็น Plex
      (กฎ 1A6M3 ตั้งใจแบบนั้น แต่พอวางคู่กันจริง ตาเห็นเป็นสองฟอนต์) → Sarabun ทั้งบรรทัด · คำไทยเหมือนเดิมทุกตัว
   ② ตัวเลข Outfit ถ้ามีคำไทยปน ให้ตกไป Sarabun (เดิมตกไป Space Mono → ฟอนต์ของเครื่อง)
      ยอดโทเคนในห้องของฉันเป็นฟอนต์พิมพ์ดีด + "โทเคน" เป็นฟอนต์ของเครื่อง → ตัวเลข Outfit แบบร้านค้า · คำไทย Sarabun
      ปุ่ม 2D / 3D ใช้ Orbitron ของธีม Metaverse ในทุกธีม → Outfit (ฟอนต์ตัวเลขของแอป)
   ③ หัวข้อไทยถูกบีบระยะตัวอักษร -0.015 ถึง -0.035em (ท่าของหัวข้อภาษาอังกฤษ) → สระบน วรรณยุกต์ ชิดจนเบียด
      ภาษาไทยไม่ควรบีบ → 0 · ธีมที่ตั้งระยะเองเพื่อเป็นลายของธีม (Metaverse · Glitch · Astral) กฎของธีมจำเพาะกว่า ยังชนะ
   ④ ตัวหนังสือไทยเล็กสุด 9.5–10.5px อยู่ 17 จุด (ป้าย · คำใต้ตัวเลข) → ขั้นต่ำ 11px
   ⑤ สีที่จางเกินเกณฑ์อ่าน (WCAG 4.5:1 สำหรับตัวเล็ก) เฉพาะจุดที่ต่ำชัด ๆ
   ============================================================ */

/* ① */
.page-title, .sh-title, .big-title, .fm-h, .ob-h, .obw-name, .empty-h,
.wg-title, .mt-lb, .pe-tx b, .fr-nm, .bg-nm,
.sec-label, .pe-wip {
  font-family: 'Sarabun', 'Leelawadee UI', sans-serif;
}

/* ② */
.mono, .tk-min, .wc i, .st b, .dr-t, .rk-d b, .tn-title .num,
.page-sub b, .fd-act b, .st-big, .wd b, .pf-stats.four .v, .pf-at, .ts b, .wg-time, .st-hero .v {
  font-family: 'Outfit', 'Sarabun', 'Leelawadee UI', sans-serif;
}
/* room.css โหลดหลังไฟล์นี้ → ต้องจำเพาะกว่า (.phone) */
.phone .rm-bal { font-family: 'Sarabun', 'Leelawadee UI', sans-serif; font-weight: 600; }
.phone .rm-bal [data-tok] { font-family: 'Outfit', 'Sarabun', sans-serif; font-weight: 700; font-variant-numeric: tabular-nums; }
/* hoop.css โหลดหลังไฟล์นี้ → .phone นำหน้า */
.phone .fx-seg button { font: 700 13.5px/1 'Outfit', 'Sarabun', sans-serif; letter-spacing: .04em; }

/* ③ */
.phone :is(.page-title, .sh-title, .fd-title, .lg-h, .ob-h, .cs-h, .wz-q, .es-t, .nt-empty-t, .ib2-hero-t,
  .ai-hello h2, .fs-h, .tc-tx b, .bg-nm, .pe-tx b, .set-lb, .set-lb i, .tg-lb2, .src-bd .t, .gc-title) {
  letter-spacing: 0;
}

/* ④ */
.phone :is(.td-stats .ts i, .wk-d i, .ds-d, .src-tag, .ig-stats > * > span, .ig-tick, .shw i, .at-k, .dn-mid i,
  .ab-ds, .tk-live, .ts-try, .pe-wip, .pro-tag, .rm-on, .so-egtag, .st-priv > div > span) {
  font-size: 11px;
}

/* ⑤ ธีมสว่าง */
:root[data-theme="light"] .pro-tag { color: #FFFFFF; }                      /* เขียวเข้มบนเขียว 2.8:1 → ขาว 6.5:1 */
:root[data-theme="light"] .tb-bd i { color: #15803D; }                      /* "มีแล้ว" 3.3:1 → 5.0:1 */
:root[data-theme="light"] .ts-try { color: #8B3FD9; }                       /* ม่วงตำนาน 3.6:1 → 5.6:1 (ยังเป็นม่วงเดิม แค่เข้มขึ้น) */
:root[data-theme="light"] .tk-skin.r-legendary .ts-nm { color: #B45309; }     /* ชื่อสกิน Legendary เหลืองอำพันบนขาว 2.2:1 → อำพันเข้ม 5.0:1 */
/* ⑤ ธีมมืด — ฟ้าบนกรมท่าในหน้าบริบท 3.7:1 · ส้ม "ยังไม่ล็อกอิน" 3.4:1 · ตัวย่อวัน 3.3:1 */
:root[data-theme="dark"] :is(#ctxBody, .phone) :is(.cx2-pick, .cx2-cap b, .cx2-opt span) { color: #8AB0FF; }
:root[data-theme="dark"] #ctxBody .cx2-chip.cx2-chip:not(.done) { color: #8AB0FF !important; }   /* กฎเดิมของชิปใส่ !important ไว้ */   /* #ctxBody นำหน้า — กฎเดิมของจอนี้ใช้ id ชนะ */
:root[data-theme="dark"] .ig-off { color: #F0956C; }
:root[data-theme="dark"] .pf-me .d { color: #A9B3CA; }
:root[data-theme="dark"] #ctxBody .cx2-day:not(.on) span { color: rgba(233, 237, 245, .74); }   /* ตัวย่อวันในแถบสัปดาห์ 55% → 74% */
:root[data-theme="dark"] #ctxBody .cx2-day.on span { color: #8AB0FF; }                /* วันที่เลือก ฟ้าเข้มบนกรมท่า 3.3:1 → ฟ้าสว่าง */

/* ============================================================
   เลิกท่าที่ดูเป็นแอป AI (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "แก้อันไหนที่ยังเป็น AI อยู่ พวกฟอนต์ UI อิโมจิที่ไม่จำเป็น หรือมองแล้ว AI จัดการให้หน่อย"
   ① ประกายสี่แฉก (sparkles) 27 จุด → ไอคอนที่บอกว่าปุ่มทำอะไร (เปลี่ยนใน index.html · app.js · feed.js ฯลฯ)
      ผู้ช่วย = หน้าน้องฮูก (lu-owl ใหม่) · Pro = มงกุฎ · อ่านรูป = สแกน · ถามคนอื่น = คนสองคน
   ② อิโมจิห้อยท้ายหัวข้อแจ้งเตือน 28 จุด (✓ 🔔 ✦ ⏳ ↩ 🔒 🦈 🌳 🌈 ⚠) ลบออก · 🔒 ในปุ่ม → ไอคอนกุญแจเส้นเดียวกับทั้งแอป
      คงไว้: อิโมจิที่เป็น "ของ" จริง (ปฏิกิริยาในแชท · เอฟเฟกต์ในร้าน 🏀 · อิโมจิที่ผู้ใช้พิมพ์เอง)
   ③ หัวข้อไล่สีทอง "แตะสำรับเพื่อเปิด" → สีหมึกเรียบ (หัวข้อไล่สีคือหน้าตาของหน้าเว็บที่ AI สร้าง
      และทองในแอปนี้สงวนไว้ให้ของที่ทำสำเร็จจริง)
   ④ ลายจุดตารางหลังจอว่าง ธีมสว่าง/มืด → ไม่มี (ลายจุดจาง ๆ + ไอคอนเรืองแสงตรงกลาง = แม่แบบหน้าว่างของเว็บ AI)
      ธีมอื่นที่ลายเป็นของธีมเอง (คลื่นทะเล · ตาราง Metaverse · ดาว · ฟองน้ำ ฯลฯ) คงไว้
   ============================================================ */

/* ① ② ขนาดไอคอนในจุดที่เดิมเป็นตัวอักษร/อิโมจิ */
.phone .fx-seg button svg { width: 13px; height: 13px; margin-right: 5px; vertical-align: -1.5px; flex: none; }
.phone .fx-seg button { display: inline-flex; align-items: center; justify-content: center; }
.ts-rar svg { width: 9px; height: 9px; margin-right: 3px; vertical-align: -1px; }
.ig-share svg { width: 18px; height: 18px; display: block; }
.statusbar .sb-ic { display: inline-flex; align-items: center; gap: 5px; }
.statusbar .sb-ic svg { width: 16px; height: 16px; }
.statusbar .sb-ic svg + svg { width: 22px; }
.phone .pe .pe-v svg { width: 13px; height: 13px; margin-right: 3px; vertical-align: -2px; }

/* ③ */
.gc-title { background: none; -webkit-background-clip: border-box; background-clip: border-box; color: var(--ink); }

/* ④ */
:root:is([data-theme="light"], [data-theme="dark"]) .es::before { display: none; }

/* ============================================================
   หัวตัวช่วยตั้งเวลา (13 ต.ค. 69)
   ------------------------------------------------------------
   ปุ่ม ✕ ยืมคลาส .set-back ของหัวจอตั้งค่า ซึ่งลอย (position: absolute; left: -8px) — ในแถวนี้ไม่มีที่ให้มันลอย
   เลยไปค้างที่มุมจอ บน -9 ซ้าย -8 · ล้นขอบจอและทับแถบความคืบหน้า (เห็นในภาพชุดธีมสว่าง ภาพ 23)
   → วางกลับในแถวปกติ ข้างแถบความคืบหน้า (แถว flex มีอยู่แล้ว gap 12px)
   ============================================================ */
.wz-top .set-back { position: static; left: auto; }
.wz-top { margin-top: 4px; }

/* ============================================================
   ผลตรวจ Impeccable รอบแรก — ส่วนที่เป็นข้อบกพร่องตรง ๆ (13 ต.ค. 69)
   ------------------------------------------------------------
   `impeccable detect` บน alt/ ได้ 152 จุด 15 หมวด · รอบนี้แก้เฉพาะหมวด "quality" ที่ไม่แตะลายของเจ้าของ
   หมวด "slop" ที่เป็นสไตล์ที่เจ้าของสั่งเอง (สปริงเด้ง · ปลาว่ายในธีม · ชื่อธีมไล่สี) ไม่แตะ — รอเจ้าของตัดสิน
   ============================================================ */

/* ตัวหนังสือจาง (--faint #617490) ผ่านบนการ์ดขาว 4.75:1 แต่บนพื้นฟ้าอ่อน/กระจก (--card2) เหลือ 4.0–4.2:1
   ไม่ลดโทเคนทั้งธีม (จะชนกับ --muted จนแยกสองระดับไม่ออก) → เฉพาะจุดที่วางบนพื้นสีใช้ --muted (5.0:1) */
/* (ไม่โดนป้ายที่มีสีของตัวเอง: เหรียญตราที่ได้แล้ว = วงเข้มตัวขาว · ป้ายรางวัล · ป้าย "รอโรงเรียนอนุมัติ") */
:root[data-theme="light"] .phone :is(.src-tag.noapi, .tk-mode:not(.on), .pe-v:not(.pe-reward), .bg-row:not(.on) .bg-mark span, .bg-ct) { color: var(--muted); }
/* ปุ่มลบสีแดงบนพื้นกระจก 4.3:1 → แดงเข้มขึ้น 5.5:1 (ยังเป็นแดงเตือนเดิม) */
:root[data-theme="light"] .phone :is(.warn, .ctx-wipe, .fm-del, .hdz-del) { color: #A8241A !important; }
/* หน้าโหลด: ข้อความรอง #8592AD บนขาว 3.1:1 → 5.1:1 */
.boot { --muted: #5F6E8C; }

/* ตัวหนังสือต่ำกว่า 11px ที่ต้องอ่าน */
.crop-hint { font-family: 'Sarabun', 'Leelawadee UI', sans-serif; font-size: 11px; }   /* เดิมฟอนต์พิมพ์ดีด + ไทยตกไปฟอนต์เครื่อง */
.th-grid :is(.th-meta, .th-astral) .nm { font-size: 11px; }

/* <img> ที่ยังไม่มีรูป (ครอบรูป · สแกนตาราง · พรีวิวพื้นหลัง — ใส่ src ทีหลังด้วย JS) อย่าโชว์กรอบรูปเสีย */
.phone img:not([src]) { visibility: hidden; }
/* ธีมมืด เกณฑ์ 4.5:1 — ฟ้าเข้ม (--blue) ที่ใช้เป็นตัวหนังสือบนพื้นกรมท่า 3.1–4.4:1 → ฟ้าสว่าง #8AB0FF (6–7:1) */
:root[data-theme="dark"] :is(.phone, #statFull) :is(.at-v i, .st-line b, .bg-pick span) { color: #8AB0FF; }
:root[data-theme="dark"] .phone :is(.src-how b, .src-how i, .qa-how i) { color: #BFD4FF; }                                   /* เลขขั้นในวงกลม 3.78 → 6.1 */
:root[data-theme="dark"] #scr-profile .pf-entry .pe-v:not(.pe-reward) { color: #A9B3CA; }               /* 4.42 → 5.9 */

/* วัดซ้ำด้วยเกณฑ์จริง 4.5:1 ทุกจอธีมสว่าง (รอบก่อนผมวัดหลวมไป จับแค่ที่ต่ำกว่า 3.5) — เหลือ 10 จุด
   ส่วนใหญ่เป็น "สีที่มีความหมาย" อ่อนเกินบนพื้นขาว → สีเดิม เฉดเข้มขึ้น */
:root[data-theme="light"] #scr-profile .pf-entry .pe-v:not(.pe-reward) { color: var(--muted); }          /* "ยังไม่เปิดขาย" 3.96 → 5.0 */
:root[data-theme="light"] .phone :is(.r-rare, .tk-skin.r-rare .ts-rar) { color: #2563EB; }                                              /* ฟ้าหายาก 3.68 → 5.2 */
:root[data-theme="light"] .phone :is(.r-legendary, .tk-skin.r-legendary .ts-rar) { color: #B45309; }     /* อำพันตำนาน 2.15 → 5.0 */
:root[data-theme="light"] .at-v i { color: #0B6E52; }                                                     /* "%" เขียวบนเขียวอ่อน 3.57 → 5.6 */
:root[data-theme="light"] .phone :is(.fx-seg button.lock, .tk-skin.r-mythic .ts-rar) { color: #8B3FD9; }                                  /* "3D" ม่วง 3.55 → 5.6 */
:root[data-theme="light"] .stp-v i { color: var(--muted); }                                               /* "ชม." 4.36 → 5.0 */
:root[data-theme="light"] #ctxBody :is(.cx2-big, .cx2-axis span, .cx2-day:not(.on) span) { color: var(--muted); }   /* บริบทของฉัน 3.3–3.9 → 5.6 */

/* ============================================================
   สัญลักษณ์ประจำธีม (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ตกแต่งแต่ละธีมให้มีความเฉพาะหน่อย" → เลือก: ตอนแตะปุ่ม · การ์ดใหญ่หน้าแรก · ตอนติ๊กงานเสร็จ · แท็บที่เลือก
   (แท็บที่เลือกเอาออกภายหลัง — เจ้าของ: "ตรงนี้ไม่ควรมี มันดูรก" · เหลือสามที่)
   ตรวจก่อนทำ: ทุกธีมมีของชุดเดียวกัน (ฉากหลัง · ลายจอว่าง · ท่าเปลี่ยนจอ · ทรงปุ่มกลับ) — ความเป็นตัวเองอยู่แค่ฉากหลัง
   ส่วนที่นักเรียนแตะทุกวันหน้าตาเหมือนกันทุกธีม มีแค่ Astral ที่ได้ท่าของตัวเอง
   ระบบเดียว: หนึ่งธีม = หนึ่งสัญลักษณ์ (--motif · รูป SVG ใช้เป็น mask) แล้วสัญลักษณ์เดียวกันไปโผล่สี่ที่
   ไม่ใช่ 60 ชิ้นที่ออกแบบแยก — จำได้เพราะมันซ้ำในที่ที่ถูก ("Brand lives in precise details" · Impeccable โหมด Operate)
   ธีมสว่าง / มืด = ธีมกลาง ไม่มีสัญลักษณ์ (ตั้งใจ)
   ============================================================ */
:root[data-theme="warm"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='6.6' r='4.3'/><circle cx='17.4' cy='10.5' r='4.3'/><circle cx='15.3' cy='16.8' r='4.3'/><circle cx='8.7' cy='16.8' r='4.3'/><circle cx='6.6' cy='10.5' r='4.3'/></svg>"); }   /* ดอกไม้ห้ากลีบ */
:root[data-theme="space"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.5l2.7 7.8 7.8 2.7-7.8 2.7L12 22.5l-2.7-7.8L1.5 12l7.8-2.7z'/></svg>"); }   /* ดาวสี่แฉก */
:root[data-theme="earth"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M1.5 20.5 9 7.5l4.2 7.2 2.6-4.2 6.7 10z'/></svg>"); }   /* ภูเขา */
:root[data-theme="ocean"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2.2C16.6 8 19.2 11.6 19.2 15a7.2 7.2 0 0 1-14.4 0C4.8 11.6 7.4 8 12 2.2z'/></svg>"); }   /* หยดน้ำ */
:root[data-theme="magic"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14.5 2.5A9.5 9.5 0 1 0 21.5 17 7.6 7.6 0 0 1 14.5 2.5z'/></svg>"); }   /* พระจันทร์เสี้ยว */
:root[data-theme="galaxy"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='4.6'/><ellipse cx='12' cy='12' rx='10.4' ry='3.8' fill='none' stroke='black' stroke-width='1.9' transform='rotate(-22 12 12)'/></svg>"); }   /* ดาวเคราะห์มีวงโคจร */
:root[data-theme="deepocean"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='8.6' fill='none' stroke='black' stroke-width='2.2'/><circle cx='8.8' cy='8.8' r='2.3'/></svg>"); }   /* ฟองอากาศ */
:root[data-theme="earth2"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20.5 3.5C11 3.5 4 8 4 15.5c0 1.6.4 3 1 4.2C7 14.5 11 11 15.5 9.5 11 12.5 8 16 6.5 20.8c1 .4 2.2.7 3.5.7 7.5 0 10.5-7 10.5-18z'/></svg>"); }   /* ใบไม้ */
:root[data-theme="sweet"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 21C5 16.2 2 12.6 2 8.9 2 6 4.3 3.8 7 3.8c2 0 3.6 1 5 2.8 1.4-1.8 3-2.8 5-2.8 2.7 0 5 2.2 5 5.1 0 3.7-3 7.3-10 12.1z'/></svg>"); }   /* หัวใจ */
:root[data-theme="genesis"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6.5 3h11l4.5 6.2L12 21.5 2 9.2z'/></svg>"); }   /* อัญมณี */
:root[data-theme="meta"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2.5l8.2 4.75v9.5L12 21.5l-8.2-4.75v-9.5z' fill='none' stroke='black' stroke-width='2.4'/><circle cx='12' cy='12' r='2.6'/></svg>"); }   /* หกเหลี่ยม */
:root[data-theme="glitch"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M3 3h6v6H3zM15 3h6v6h-6zM9 9h6v6H9zM3 15h6v6H3zM15 15h6v6h-6z'/></svg>"); }   /* พิกเซล */
:root[data-theme="astral"] { --motif: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.5l2.7 7.8 7.8 2.7-7.8 2.7L12 22.5l-2.7-7.8L1.5 12l7.8-2.7z'/></svg>"); }   /* ดาว (ชุดเดียวกับประกายตอนแตะ) */

/* ① การ์ดใหญ่หน้าแรก — สัญลักษณ์ตัวใหญ่จาง ๆ มุมขวาล่าง เอียงนิด ล้นขอบการ์ด (การ์ดตัดขอบอยู่แล้ว)
   isolation + z-index:-1 = อยู่เหนือพื้นการ์ด แต่ใต้ตัวหนังสือทุกตัว (ไม่กินความต่างสีของข้อความ) */
:root:is([data-theme="warm"], [data-theme="space"], [data-theme="earth"], [data-theme="ocean"], [data-theme="magic"], [data-theme="galaxy"], [data-theme="deepocean"], [data-theme="earth2"], [data-theme="sweet"], [data-theme="genesis"], [data-theme="meta"], [data-theme="glitch"], [data-theme="astral"]) #menuBody :is(.td-now, .td-clear) { isolation: isolate; }
:root:is([data-theme="warm"], [data-theme="space"], [data-theme="earth"], [data-theme="ocean"], [data-theme="magic"], [data-theme="galaxy"], [data-theme="deepocean"], [data-theme="earth2"], [data-theme="sweet"], [data-theme="genesis"], [data-theme="meta"], [data-theme="glitch"], [data-theme="astral"]) #menuBody :is(.td-now, .td-clear)::before {
  content: ''; position: absolute; right: -20px; bottom: -26px; width: 124px; height: 124px; z-index: -1; pointer-events: none;
  background: var(--fill); opacity: .12; rotate: -14deg;
  -webkit-mask: var(--motif) center / contain no-repeat; mask: var(--motif) center / contain no-repeat;
}
/* การ์ด "ตอนนี้" พื้นสีเข้ม ตัวขาว → สัญลักษณ์ขาว */
:root:is([data-theme="warm"], [data-theme="space"], [data-theme="earth"], [data-theme="ocean"], [data-theme="magic"], [data-theme="galaxy"], [data-theme="deepocean"], [data-theme="earth2"], [data-theme="sweet"], [data-theme="genesis"], [data-theme="meta"], [data-theme="glitch"], [data-theme="astral"]) #menuBody .td-now::before { background: #FFFFFF; opacity: .14; }

/* ② แท็บที่เลือก — เคยมีสัญลักษณ์เล็กมุมแคปซูล · เอาออกแล้ว (เจ้าของ: "ตรงนี้ไม่ควรมี มันดูรก") */

/* ③ ตอนแตะปุ่ม — วงแหวนบาง + สัญลักษณ์สามชิ้นกระเด็นออก (JS ใน app.js · Astral ใช้ประกายดาวเดิม .as-flare) */
.tm-tap { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 9000; pointer-events: none; }
.tm-tap i, .tm-tap b { position: absolute; left: 0; top: 0; translate: -50% -50%; opacity: 0; }
.tm-tap i { width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid var(--fill); }
.tm-tap b {
  width: 11px; height: 11px; background: var(--fill);
  -webkit-mask: var(--motif) center / contain no-repeat; mask: var(--motif) center / contain no-repeat;
}

/* ④ ติ๊กงานเสร็จ — เศษกระดาษในธีมที่มีสัญลักษณ์เป็นรูปสัญลักษณ์ (celebrate() ใน app.js ใส่คลาส .tm-glyph) */
.particle.tm-glyph {
  border-radius: 0 !important;
  -webkit-mask: var(--motif) center / contain no-repeat; mask: var(--motif) center / contain no-repeat;
}

/* โหมดลื่น / ลดการเคลื่อนไหว: สัญลักษณ์บนการ์ดยังอยู่ (ภาพนิ่ง) · ท่าแตะไม่เล่น (เช็กใน JS) */

/* ============================================================
   อนิเมชันตัวหนังสือ (13 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของดูตัวอย่างสี่แบบก่อน แล้วสั่ง "จัดการเลยทั้งสองอย่าง ฟอนต์และอนิเมชัน" → A + C + D (B ไม่ใส่ — ใส่ครบสี่แบบจะรก)
   A · หัวจอค่อย ๆ ชัดทีละคำ (BlurText · React Bits) — titleIn() ใน app.js ห่อคำเป็น .tw-t แล้วคืนเป็นข้อความเดิมเมื่อจบ
   C · ตัวเลขนับขึ้น (NumberTicker · Magic UI) — ต่อยอด rollNumbers() เดิม (JS ล้วน ไม่มี CSS)
   D · เผยจากซ้ายไปขวา (Text reveal · Aceternity) — เฉพาะ "งานที่แอปเลือกให้": การ์ด "ตอนนี้" หน้าแรก · จอ "ทำไมอันนี้ก่อน"
   ทั้งหมดเล่นครั้งเดียวตอนเพิ่งเปิดจอ (.fx-in) · โหมดลื่น / ลดการเคลื่อนไหว = ไม่เล่น
   ============================================================ */

/* A */
.tw-t {
  display: inline-block;
  animation: tw-t-in .6s cubic-bezier(.22, 1, .36, 1) backwards;
  animation-delay: calc(var(--k, 0) * 70ms + 60ms);
}
@keyframes tw-t-in { from { opacity: 0; filter: blur(6px); transform: translateY(8px); } }

/* D — ขอบบน/ล่างของกรอบตัดยื่นออก .6em: สระบนกับวรรณยุกต์ไทยสูงเกินกล่องบรรทัด ถ้าตัดพอดีกล่องจะโดนตัดหัว
   fill = backwards: ก่อนเริ่ม (ช่วงหน่วง) ซ่อนอยู่ · เล่นจบแล้วไม่เหลือ clip-path ค้างบนชื่องาน */
.screen.fx-in :is(#menuBody .td-now .tn-title, .wy2-hero h3) {
  animation: tx-wipe .75s .12s cubic-bezier(.65, 0, .35, 1) backwards;
}
@keyframes tx-wipe {
  from { clip-path: inset(-.6em 100% -.6em -.3em); }
  to   { clip-path: inset(-.6em -.3em -.6em -.3em); }
}

:root[data-lite] .tw-t, :root[data-lite] .screen.fx-in :is(#menuBody .td-now .tn-title, .wy2-hero h3) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .tw-t, .screen.fx-in :is(#menuBody .td-now .tn-title, .wy2-hero h3) { animation: none; }
}

/* ============================================================
   จอการแจ้งเตือนแบบหน้าแจ้งเตือนจริง (14 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ให้มันเป็นหน้าแจ้งเตือน ไม่เอาคำว่าเข้าแผนแล้ว จัดลำดับให้ถูก · เข้าไปแล้วเปลี่ยนเป็นอ่านแล้ว ·
            กระดิ่งขึ้นจำนวนเลข ไม่มีก็ไม่ต้องขึ้น · ปรับหน้าให้สวยกว่านี้" (JS อยู่ในบล็อก 1C40 ของ inbox.js)
   แถว: บรรทัดแรก = ของที่เข้ามาจริง (ตัวงาน · ชื่อคน) ตัวหนา · บรรทัดสอง = รายละเอียด · บรรทัดสาม = ที่มา · เวลา
        แบบแถวแจ้งเตือนของ IG / iOS · สถานะอยู่ที่ป้ายมุมไอคอน ไม่ใช่ประโยคขึ้นต้นแถว
   กลุ่ม: ใหม่ → วันนี้ → เมื่อวาน → 7 วันที่ผ่านมา → ก่อนหน้านี้ (แบบ IG)
   ปุ่มกรอง = GradientButtonGroup ของ Cult UI (มีอยู่แล้ว) · แถวไล่เข้าทีละแถว = AnimatedList ของ Magic UI (มีอยู่แล้ว)
   กระดิ่ง = Bell Toggle ของ React Bits · ป้ายเลขเด้ง = Pulse Heart ของ React Bits (ทั้งคู่ JS ใน inbox.js)
   ============================================================ */
#notifBody .ib2-sec { margin: 20px 6px 8px; }
#notifBody .ib2-sec span { font-size: 14px; font-weight: 700; color: var(--ink); letter-spacing: 0; }
#notifBody .nt-chips + .ib2-sec, #notifBody .nt-login + .ib2-sec { margin-top: 16px; }

#notifBody .nt-row { gap: 13px; padding: 14px 15px; align-items: flex-start; transition: background-color .2s ease; }
@media (hover: hover) and (pointer: fine) {
  #notifBody .nt-row:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
  #notifBody .nt-row.new:hover { background: color-mix(in srgb, var(--fill) 11%, transparent); }
}
#notifBody .nt-row:active { background: color-mix(in srgb, var(--ink) 7%, transparent); }
#notifBody .nt-row:focus-visible { outline: 2px solid var(--fill); outline-offset: -2px; }
#notifBody .nt-bd { gap: 2px; padding-top: 0; }
#notifBody .nt-t {
  font-size: 14.5px; line-height: 1.4; font-weight: 700; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
#notifBody .nt-p {
  font-size: 13px; line-height: 1.45; color: var(--muted);
  -webkit-line-clamp: 2;
}
#notifBody .nt-row.new .nt-p { color: color-mix(in srgb, var(--ink) 82%, var(--muted)); }
#notifBody .nt-meta {
  display: flex; align-items: center; gap: 5px; margin-top: 3px; min-width: 0;
  font-size: 12px; line-height: 1.3; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#notifBody .nt-meta i { font-style: normal; color: var(--muted); opacity: .9; }
/* จุด "ใหม่" ตรงแนวบรรทัดแรก (เดิมอยู่ต่ำกว่าหัวแถว) · ปุ่ม "ตรวจ / ดูคำขอ" กลางแถว */
#notifBody .nt-dot { width: 9px; height: 9px; margin: 7px 2px 0 0; }
#notifBody .nt-av { width: 46px; height: 46px; }

/* ---------- โลโก้แอปต้นทาง + ปุ่มติ๊กเข้าแผน (15 ต.ค. 69 · srcMark / notifAccept ใน inbox.js) ----------
   โลโก้ทึบเต็มกล่อง ไม่มีพื้นสีธีมรอง · มุมมนเท่ากล่องเดิม (14px) แบบไอคอนแอปบนมือถือ
   ธีม astral ล้างสีทุกอย่างเป็นขาวดำ — แต่โลโก้คือตัวที่คนจำแอปได้ :not(.src) ข้างบนกันไว้แล้ว */
.nt-av.src.brand { background: none; overflow: hidden; }
.nt-av.src.brand svg { width: 100%; height: 100%; display: block; }
#notifBody .nt-av.brand { box-shadow: 0 1px 2px rgba(0, 0, 0, .18); }

/* ปุ่มติ๊กอยู่นอกปุ่มแถว (ปุ่มซ้อนปุ่มไม่ได้) — วางทับขอบขวากลางแถว · แถวเว้นที่ทางขวาไว้ให้ */
.nt-wrap { position: relative; }
#notifBody .nt-row.has-tick { padding-right: 104px; }
.nt-tick {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 5px; height: 34px; padding: 0 13px 0 10px;
  border: 0; border-radius: 999px; cursor: pointer; font-family: inherit; font-size: 12.5px; font-weight: 700; line-height: 1;
  white-space: nowrap; color: var(--on-fill); background-color: var(--fill);
  background-image: radial-gradient(120% 100% at 18% -8%, rgba(255, 255, 255, .42), transparent 62%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 -1.5px 2px rgba(0, 0, 0, .12);
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1); -webkit-tap-highlight-color: transparent;
}
.nt-tick svg { width: 15px; height: 15px; stroke-width: 3; flex: none; }
.nt-tick:active { transform: translateY(-50%) scale(.94); }
.nt-tick:focus-visible { outline: 2px solid var(--fill); outline-offset: 2px; }

/* กระดิ่งหน้าแรก: ป้ายตัวเลขแทนจุด — ศูนย์ = ไม่มีป้าย (inbox.js ถอดทิ้ง) · เกิน 9 = "9+"
   ตัวเลขในป้ายเป็นข้อยกเว้นเดียวของขั้นต่ำ 11px (DESIGN.md ข้อ 3) · ตัวเลขกว้างเท่ากัน ป้ายไม่ยืดหดตามเลข */
.th-bell .th-dot.n {
  width: auto; height: 18px; min-width: 18px; padding: 0 5px; top: 1px; right: 0;
  display: grid; place-items: center; border-radius: 999px;
  font: 700 11px/1 'Outfit', 'Sarabun', sans-serif; font-variant-numeric: tabular-nums;
  color: #FFFFFF; background: var(--pri-red); border: 2px solid var(--scr); box-sizing: border-box;
}

/* ============================================================
   ชนวนนับถอยหลังของแจ้งเตือน — Swipe Toast ของ React Bits (14 ต.ค. 69)
   ------------------------------------------------------------
   เส้นบางขอบล่างของเกาะ หดเข้าหาขอบซ้ายจนหมด = แจ้งเตือนปิด (toastFuse ใน app.js)
   ชี้เมาส์ · โฟกัส · ลาก · สลับแอป = เส้นหยุด · ขาวจาง 40% บนพื้นดำของเกาะ ไม่แย่งสายตาจากข้อความ
   ลดการเคลื่อนไหว = ซ่อนเส้น (ตัวจับเวลายังเดิน เพราะเป็นตัวเดียวกัน)
   ============================================================ */
#appToast .tfuse {
  position: absolute; left: 26px; right: 26px; bottom: 5px; height: 2px; border-radius: 2px;
  background: rgba(255, 255, 255, .4); transform-origin: left center; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { #appToast .tfuse { visibility: hidden; } }

/* ---------- กดแจ้งเตือนงาน = พาไปที่งานชิ้นนั้นในกล่องเข้า (14 ต.ค. 69 · notifOpenItem ใน inbox.js) ----------
   Pointer Highlight ของ Aceternity: วงสีธีมวาดรอบการ์ดแล้วจาง · เส้นด้านใน (inset) เพราะรายการตัดขอบมนอยู่ เส้นด้านนอกจะโดนตัด
   เล่นครั้งเดียว 1.6 วิ (เงาเปลี่ยนสั้น ๆ ได้ ไม่ใช่ของวนไม่จบ) · ลดการเคลื่อนไหว = พื้นจางขึ้นแล้วหาย ไม่มีวงขยับ */
#scr-inbox .ib-spot { animation: ib-spot 1.6s cubic-bezier(.22, 1, .36, 1); }
/* สีพื้นใส่แค่จังหวะกลาง (ต้นกับปลายใช้สีเดิมของการ์ด) และผสมกับ --card ให้ทึบ — ไม่งั้นการ์ดขาวจะใสวูบ */
@keyframes ib-spot {
  0%   { box-shadow: inset 0 0 0 0 transparent; }
  18%  { box-shadow: inset 0 0 0 2px var(--fill); background-color: color-mix(in srgb, var(--fill) 10%, var(--card)); }
  100% { box-shadow: inset 0 0 0 2px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  #scr-inbox .ib-spot { animation: ib-spot-still 1.6s ease; }
  @keyframes ib-spot-still { 20% { background-color: color-mix(in srgb, var(--fill) 10%, var(--card)); } }
}

/* ============================================================
   จอตัวเชื่อมให้แน่นขึ้น (14 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "จัดตรงข้อความให้สวยกว่านี้ มันยังห่างไป"
   วัดแล้ว: ระหว่างการ์ด 33px (#srcBody gap 24 + margin การ์ด 9 ซ้อนกัน) · การ์ดสูง 150px เพราะป้ายล็อกกับปุ่มเรียงลงคนละบรรทัด ·
   ชื่อจอ "ตัวเชื่อม" ซ้ำสองที่ (หัวจอ + ในเนื้อหา) แล้วตัวในเนื้อหาเลื่อนไปซ้อนใต้ปุ่มกลับ
   แถวแบบ Item ของ shadcn (บน 21st): รูป · ชื่อ · สถานะกับปุ่มบรรทัดเดียวกัน — CSS ล้วน ไม่แตะ renderSources ใน inbox.js
   ============================================================ */
#srcBody { gap: 0; }
#srcBody > .page-head { display: none; }                    /* ชื่อจออยู่บนหัวจอแล้ว */
/* หัวกลุ่ม: เดิม 11px ยืดตัวอักษร .07em แบบหัวข้อภาษาอังกฤษตัวพิมพ์ใหญ่ — ภาษาไทยไม่ยืด (กติกาเดียวกับทั้งแอป) */
#srcBody > .sec-title { margin: 22px 4px 9px; font-size: 12.5px; letter-spacing: 0; text-transform: none; }
#srcBody > .sec-title:first-of-type { margin-top: 6px; }
#srcBody > .src { margin: 0 0 8px; padding: 13px 14px; gap: 12px; align-items: flex-start; }
#srcBody .src-ic { margin-top: 1px; }
#srcBody .src-bd { flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 5px; }
#srcBody .src-bd > * { flex-basis: 100%; }
#srcBody .src-bd > .t { line-height: 1.35; }
/* สถานะ ("ต้องล็อกอินก่อน") เป็นบรรทัดเล็กข้างปุ่ม ไม่ใช่กล่องเหลืองเต็มแถว */
#srcBody .src-bd > .src-need {
  flex: 1 1 0; min-width: 0; margin: 0; padding: 0; background: none; border-radius: 0;
  align-items: center; gap: 6px; font-size: 12.5px; line-height: 1.35; font-weight: 600; color: var(--warn);
}
#srcBody .src-bd > .ib-go {
  flex: 0 0 auto; margin-top: 0 !important; align-self: center !important;
  min-height: 36px; padding: 0 15px; font-size: 13px;
}
#srcBody .src-bd > .src-in + .ib-go { margin-top: 2px !important; }

/* ---------- จอตัวเชื่อม: อนิเมชัน (14 ต.ค. 69 · เจ้าของ: "ทำอนิเมชันด้วย") ----------
   ① เปิดจอ = หัวกลุ่มกับการ์ดไล่ขึ้นทีละชิ้น (AnimatedList ของ Magic UI · ท่า fx-up ชุดเดียวกับรายการอื่นในแอป) · 35ms ต่อชิ้น
   ② สวิตช์ = Squish Switch ของ React Bits (JS ท้าย app.js)
   ③ กดปุ่ม = ยุบ .96 แล้วคืน (press feedback ของ React Bits · 160ms ease-out) */
.screen.fx-in #srcBody > :is(.sec-title, .src) { animation: fx-up .45s cubic-bezier(.22, 1, .36, 1) backwards; }
.screen.fx-in #srcBody > :nth-child(2) { animation-delay: 0.04s; }
.screen.fx-in #srcBody > :nth-child(3) { animation-delay: 0.07s; }
.screen.fx-in #srcBody > :nth-child(4) { animation-delay: 0.11s; }
.screen.fx-in #srcBody > :nth-child(5) { animation-delay: 0.14s; }
.screen.fx-in #srcBody > :nth-child(6) { animation-delay: 0.18s; }
.screen.fx-in #srcBody > :nth-child(7) { animation-delay: 0.21s; }
.screen.fx-in #srcBody > :nth-child(8) { animation-delay: 0.25s; }
.screen.fx-in #srcBody > :nth-child(9) { animation-delay: 0.28s; }
.screen.fx-in #srcBody > :nth-child(10) { animation-delay: 0.32s; }
.screen.fx-in #srcBody > :nth-child(11) { animation-delay: 0.35s; }
.screen.fx-in #srcBody > :nth-child(12) { animation-delay: 0.39s; }
.screen.fx-in #srcBody > :nth-child(n+13) { animation-delay: .42s; }
#srcBody .ib-go { transition: transform .16s cubic-bezier(.23, 1, .32, 1); }
#srcBody .ib-go:active { transform: scale(.96); }
:root[data-lite] .screen.fx-in #srcBody > * { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .screen.fx-in #srcBody > * { animation: boot-fade .25s ease backwards; }
  #srcBody .ib-go:active { transform: none; }
}

/* ---------- แผงเพิ่มงานด่วน: ปุ่มเต็มแถว (14 ต.ค. 69 · เจ้าของ: "ให้มันเต็ม") ----------
   กล่อง "ต้องล็อกอินก่อน" กว้างเต็มแถว แต่ปุ่ม "ไปล็อกอิน" กับ "ลองเลย" เป็นเม็ดเล็กชิดซ้าย — สามชิ้นซ้อนกันคนละความกว้าง ดูไม่เป็นชุด
   → ปุ่มกว้างเต็มแถวเท่ากล่อง สูง 44px (ขั้นต่ำของเป้ากดใน DESIGN.md) · ปุ่ม "ไปล็อกอิน" ติดกล่องล็อก (ชุดเดียวกัน)
   ส่วน "ลองเลย" เว้นห่างกว่า (คนละเรื่อง) · ปุ่ม "ติดตั้งบน iPhone" เต็มแถวอยู่แล้ว · CSS ล้วน (quickadd.js ทีมอื่นเขียน) */
#srcBody .qa-panel :is(.ib-go, .qa-try) {
  align-self: stretch !important; width: 100%; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
}
/* รอบสอง (เจ้าของ: "ให้มันเต็มหน้า") — แผงยื่นไปใต้ไอคอน กว้างเต็มการ์ด (ไอคอน 38px + ช่อง 12px = 50px)
   เริ่มใต้ไอคอนพอดี ไม่ทับ (เดิมแผงเริ่มต่ำกว่าชื่อ 15px แต่ไอคอนสูงกว่าชื่อ ต้องเลื่อนลงอีกนิด) · ที่จอ 375: 255 → 305px */
#srcBody .src-bd > .qa-panel { margin: 24px 0 0 -50px; flex: 0 0 calc(100% + 50px); max-width: none; }   /* แถวนี้เป็น flex ห่อบรรทัด — ความกว้างคุมด้วย flex-basis ไม่ใช่ width */
#srcBody .qa-p > .src-need { margin: 0; }
/* ขั้นตอนสีเดียวทั้งบรรทัด (เจ้าของ: "ให้มันสีเหมือนกันสิ") — เดิมข้อความเทา (--muted) แต่คำตัวหนาเข้ม (--ink) บรรทัดเดียวมีสองสี
   ใช้สีเข้มทั้งหมด เพราะนี่คือขั้นตอนที่ต้องอ่านแล้วทำตาม ไม่ใช่ข้อความรอง · คำที่ต้องกดยังเป็นตัวหนา (น้ำหนักบอก ไม่ใช่สีบอก) */
#srcBody .qa-how li { color: var(--ink); }
#srcBody .qa-how b { color: inherit; }
/* ขั้นตอนของ "แชร์จากแอปอื่น" (.src-how) ในจอเดียวกัน ให้สีเดียวกับขั้นตอนข้างบน — วงตัวเลข (<b>) คงสีของมันเอง */
#srcBody .src-how > span { color: var(--ink); }
#srcBody .qa-p > .src-need + .ib-go { margin-top: 2px !important; }
#srcBody .qa-panel > .qa-try { margin-top: 2px; transition: transform .16s cubic-bezier(.23, 1, .32, 1); }
#srcBody .qa-panel > .qa-try:active { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) { #srcBody .qa-panel > .qa-try:active { transform: none; } }

/* ---------- ป้ายไฟในห้อง = สวิตช์ไฟ (14 ต.ค. 69 · roomLampToggle ใน app.js) ----------
   หน้าตาบอกว่ากดได้: เคอร์เซอร์มือ · กดแล้วยุบ (press feedback ของ React Bits) · วงโฟกัสเมื่อใช้คีย์บอร์ด
   ไฟที่เปิดเอง = จุดฟ้านิ่ง (ไม่กระพริบ — การกระพริบสงวนไว้ให้ "กำลังทำงานอยู่จริง") · ไม่ใช้สีเหลือง/ทอง (ทองสงวนให้ของที่สำเร็จ) */
#roomBody .rm-lamp[role="switch"] {
  cursor: pointer; -webkit-tap-highlight-color: transparent; user-select: none;
  transition: transform .16s cubic-bezier(.23, 1, .32, 1), background-color .25s ease, color .25s ease;
}
#roomBody .rm-lamp[role="switch"]:active { transform: scale(.95); }
#roomBody .rm-lamp[role="switch"]:focus-visible { outline: 2px solid var(--fill); outline-offset: 2px; }
#roomBody .rm-lamp.rm-manual { color: var(--ink); background: var(--blue-soft); border-color: transparent; }
#roomBody .rm-lamp.rm-manual .rm-dot { background: var(--blue); box-shadow: none; animation: none; }
@media (prefers-reduced-motion: reduce) { #roomBody .rm-lamp[role="switch"]:active { transform: none; } }

/* ---------- จอกว้าง: เนื้อหาเต็มความกว้าง (14 ต.ค. 69 · เจ้าของส่งภาพจอน้องฮูก: "ให้มันเต็มหน้าจอ") ----------
   จอกว้าง (แถบเมนูด้านข้าง) ตั้ง margin-inline:auto + max-width:720px ให้เนื้อหาอยู่กลาง — แต่จอที่เป็น flex (เช่น #aiBody ที่ flex:1)
   ขอบซ้ายขวา auto ทำให้ลูก flex หดเหลือแค่ความกว้างของเนื้อหา: จอน้องฮูกเลยกว้างแค่ 372px กลางจอ 764px
   → ให้กว้างเต็มก่อน (width:100%) แล้วเพดาน 720px ยังคุมอยู่ · มือถือไม่โดน (กฎเดิมมีเฉพาะจอกว้าง) */
:root[data-nav="side"] :is(.home-body, .scr-body) { width: 100%; box-sizing: border-box; }
/* ตัวอย่างหน้าแรกฉบับเรียบ: โฟกัสงานปัจจุบัน → งานถัดไป → ผู้ช่วย */
#menuBody.home-simple { display:flex; flex-direction:column; gap:20px; padding-bottom:20px; }
#menuBody.home-simple > * { margin:0; flex-shrink:0; }
#menuBody.home-simple .th-rank { display:none; }
#menuBody.home-simple .td-now { box-shadow:0 8px 28px -20px color-mix(in srgb,var(--ink) 25%,transparent); }
#menuBody.home-simple .td-now::before,
#menuBody.home-simple .td-now::after { display:none; }
#menuBody.home-simple .tn-title { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden; }
.home-next { padding:0 4px; }
.hn-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.hn-head > b { font-size:15px; color:var(--ink); }
.hn-head > button { display:flex; align-items:center; gap:4px; min-height:36px; background:none; border:0; color:var(--muted,var(--ink)); font:inherit; font-size:12px; cursor:pointer; }
.hn-head svg, .hn-task > svg { width:16px; height:16px; flex-shrink:0; }
.hn-task { display:flex; align-items:center; gap:12px; width:100%; text-align:left; padding:12px; border:1px solid color-mix(in srgb,var(--ink) 10%,transparent); border-radius:16px; color:var(--ink); background:color-mix(in srgb,var(--card) 80%,transparent); cursor:pointer; font:inherit; }
.hn-icon { display:grid; place-items:center; width:38px; height:38px; border-radius:12px; background:color-mix(in srgb,var(--fill) 8%,transparent); color:var(--fill); flex-shrink:0; }
.hn-icon svg { width:20px; height:20px; }
.hn-copy { display:flex; flex:1; min-width:0; flex-direction:column; gap:3px; }
.hn-copy b { font-size:14px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hn-copy > span, .hn-empty { font-size:12px; line-height:1.6; color:var(--muted,var(--ink)); }
.hn-empty { margin:0; padding:8px 0; }
.hn-pending { display:flex; flex-wrap:wrap; gap:4px 12px; margin-top:6px; }
.hn-pending button { display:flex; align-items:center; gap:5px; min-height:36px; background:none; border:0; color:var(--fill); font:inherit; font-size:12px; cursor:pointer; }
.hn-pending svg { width:15px; height:15px; }
.home-assistant { padding:16px; border-radius:20px; border:1px solid color-mix(in srgb,var(--ink) 10%,transparent); background:color-mix(in srgb,var(--card) 70%,transparent); }
.ha-heading { display:flex; align-items:center; gap:10px; margin-bottom:12px; }
.ha-heading img { object-fit:contain; flex-shrink:0; }
.ha-heading > div { display:flex; flex-direction:column; gap:2px; }
.ha-heading b { font-size:14px; font-weight:600; color:var(--ink); }
.ha-heading span { font-size:12px; color:var(--muted,var(--ink)); }
#menuBody.home-simple .td-ask { margin:0; min-height:48px; background:var(--card); border:1px solid color-mix(in srgb,var(--ink) 12%,transparent); box-shadow:none; }
#menuBody.home-simple .td-ask::before,
#menuBody.home-simple .td-ask::after { display:none; }
#menuBody.home-simple .td-ask:focus-within { outline:2px solid color-mix(in srgb,var(--fill) 35%,transparent); outline-offset:2px; }
:root[data-nav="side"] #menuBody.home-simple { gap:12px; }
:root[data-nav="side"] #menuBody.home-simple .tn-head { padding:12px 16px; }
:root[data-nav="side"] #menuBody.home-simple .tn-body { padding:10px 14px; }
:root[data-nav="side"] #menuBody.home-simple .home-assistant { padding:12px; }
:root[data-nav="side"] #menuBody.home-simple .ha-heading { margin-bottom:8px; }
@media(max-width:619px) and (max-height:860px) {
  .phone #menuBody.home-simple { gap:16px; padding-bottom:14px; }
  #menuBody.home-simple .home-assistant { padding:12px; }
  #menuBody.home-simple .ha-heading { margin-bottom:8px; }
}

/* สำรวจฟีเจอร์: เห็นภาพรวมก่อน แล้วค่อยเปิดทีละหมวด */
.feature-categories { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.feature-category { display:flex; flex-direction:column; align-items:flex-start; gap:5px; min-height:104px; text-align:left; padding:12px; border:1px solid color-mix(in srgb,var(--ink) 10%,transparent); border-radius:16px; background:var(--card); color:var(--ink); font:inherit; cursor:pointer; }
.feature-category > svg { width:22px; height:22px; color:var(--fill); margin-bottom:3px; }
.feature-category > b { font-size:14px; line-height:1.4; font-weight:600; }
.feature-category > span { font-size:11px; line-height:1.6; color:var(--muted,var(--ink)); }
.pf-feature-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:-12px; }
.pf-feature-head > b { font-size:14px; }
.pf-feature-head > button { display:flex; align-items:center; gap:3px; min-height:36px; border:0; background:none; color:var(--fill); font:inherit; font-size:12px; cursor:pointer; }
.pf-feature-head svg { width:14px; height:14px; }
.explore-body { display:flex; flex-direction:column; gap:18px; }
.explore-header { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.explore-header h2 { margin:0; font-size:24px; }
.explore-header p { margin:4px 0 0; font-size:13px; color:var(--muted,var(--ink)); }
.explore-back { display:grid; place-items:center; width:40px; height:40px; flex-shrink:0; border:1px solid color-mix(in srgb,var(--ink) 12%,transparent); border-radius:50%; background:var(--card); color:var(--ink); cursor:pointer; }
.explore-back svg { width:20px; height:20px; transform:rotate(180deg); }
.explore-search { display:flex; align-items:center; gap:10px; padding:0 12px; min-height:48px; border:1px solid color-mix(in srgb,var(--ink) 15%,transparent); border-radius:14px; background:var(--card); color:var(--muted,var(--ink)); }
.explore-search svg { width:19px; height:19px; flex-shrink:0; }
.explore-search input { min-width:0; width:100%; padding:12px 0; border:0; outline:none; background:transparent; color:var(--ink); font:inherit; font-size:13px; }
.explore-search:focus-within { outline:2px solid color-mix(in srgb,var(--fill) 35%,transparent); }
.explore-intro { display:flex; flex-direction:column; gap:6px; padding:14px; border-radius:16px; background:color-mix(in srgb,var(--fill) 8%,var(--card)); color:var(--ink); }
.explore-intro b { font-size:14px; }
.explore-intro span { font-size:12px; }
.explore-intro button { display:flex; align-items:center; justify-content:center; gap:8px; min-height:40px; margin-top:5px; border:0; border-radius:10px; background:var(--fill); color:var(--on-fill); font:inherit; font-size:13px; cursor:pointer; }
.explore-intro svg { width:17px; height:17px; }
.explore-selected { display:flex; justify-content:space-between; align-items:center; gap:12px; }
.explore-selected > button { display:flex; align-items:center; gap:4px; background:none; border:0; color:var(--fill); min-height:36px; font:inherit; font-size:13px; cursor:pointer; }
.explore-selected svg { width:16px; height:16px; transform:rotate(180deg); }
.explore-selected > b { font-size:14px; }
.explore-section h3 { margin:0 0 10px; font-size:13px; color:var(--muted,var(--ink)); }
.explore-section .pf-entry { overflow:hidden; border:1px solid color-mix(in srgb,var(--ink) 10%,transparent); border-radius:16px; background:var(--card); }
.explore-section .pe { width:100%; color:var(--ink); text-align:left; }
.explore-section .pe-ic { background:color-mix(in srgb,var(--fill) 10%,transparent); color:var(--fill); }
.explore-section .pe > svg:last-child { width:16px; height:16px; flex-shrink:0; }
.explore-no-results { font-size:14px; line-height:1.8; color:var(--muted,var(--ink)); text-align:center; padding:20px 10px; }
#menuBody.home-simple .home-discover { display:flex; align-items:center; gap:10px; width:100%; min-height:44px; padding:4px 8px; border:0; border-radius:12px; background:none; color:var(--ink); text-align:left; font:inherit; cursor:pointer; }
.home-discover > svg { width:19px; height:19px; color:var(--fill); flex-shrink:0; }
.home-discover > svg:last-child { width:15px; height:15px; margin-left:auto; color:var(--muted,var(--ink)); }
.home-discover > span { display:flex; flex-direction:column; gap:2px; }
.home-discover b { font-size:13px; font-weight:600; }
.home-discover span span { font-size:11px; color:var(--muted,var(--ink)); }
#scr-explore [hidden] { display:none !important; }
#scr-profile .pf-body > .feature-categories { margin-top:0; }
#scr-profile .pf-body { gap:14px; }
#scr-profile .feature-category { display:grid; grid-template-columns:22px minmax(0,1fr); column-gap:8px; row-gap:4px; min-height:72px; padding:10px; align-content:center; }
#scr-profile .feature-category > svg { grid-row:1; margin:0; width:20px; height:20px; }
#scr-profile .feature-category > b { align-self:center; font-size:12px; }
#scr-profile .feature-category > span { grid-column:1/-1; font-size:10px; }
#scr-profile .pf-feature-head { margin-bottom:-10px; }
.pf-personal { border:1px solid color-mix(in srgb,var(--ink) 10%,transparent); border-radius:16px; background:var(--card); overflow:hidden; }
.pf-personal > summary { display:flex; align-items:center; gap:8px; min-height:60px; padding:10px 12px; cursor:pointer; list-style:none; }
.pf-personal > summary::-webkit-details-marker { display:none; }
.pf-personal > summary > span { display:flex; flex:1; flex-direction:column; gap:3px; }
.pf-personal summary b { font-size:13px; font-weight:600; }
.pf-personal summary span span { font-size:11px; color:var(--muted,var(--ink)); }
.pf-personal summary em { font-size:11px; font-style:normal; color:var(--fill); }
.pf-personal > summary > svg { width:15px; height:15px; transform:rotate(90deg); flex-shrink:0; }
.pf-personal[open] > summary > svg { transform:rotate(-90deg); }
.pf-personal-body { display:flex; flex-direction:column; gap:12px; padding:4px 12px 12px; }
.pf-personal #showBox .show-strip { margin:0; }
@media(max-width:619px) and (max-height:860px) {
  .phone #menuBody.home-simple { gap:8px; }
  #menuBody.home-simple:has(.hn-task) .tn-title { -webkit-line-clamp:2; }
  #scr-profile .feature-category { min-height:72px; }
}

/* ---------- จอกว้าง: จอเพื่อนของฉันเต็มความกว้าง (14 ต.ค. 69 · เจ้าของ: "ให้มันเต็มจอ") ----------
   ① #feedBody (feed.css · ทีมอื่น) ตั้ง margin: 0 auto อยู่ในกล่อง flex ของ .scr-body — ลูก flex ที่ขอบซ้ายขวา auto หดเหลือความกว้างเนื้อหา
     จอเพื่อนเลยกว้างแค่ 367px ทั้งที่คอลัมน์กว้าง 720 (โรคเดียวกับจอน้องฮูก) → width:100% แก้ทั้งฟีดและจอเพื่อน
   ② เพดาน 560px ของ feed.css ตั้งใจไว้ให้ "ฟีด" อ่านเป็นโพสต์ (บรรทัดไม่ยาวเกิน) — ยังคงไว้สำหรับฟีด
     แต่ตอนเปิดมุมมองเพื่อน (#friendsBody) ไม่ใช่ฟีด ปลดเพดานให้เต็มคอลัมน์เหมือนจออื่นในแอป
     เบราว์เซอร์ที่ไม่รู้จัก :has() = ได้แค่ข้อ ① (กว้าง 560) ไม่พัง */
:root[data-nav="side"] #feedBody { width: 100%; box-sizing: border-box; }
:root[data-nav="side"] #feedBody:has(#friendsBody) { max-width: none; }

/* ---------- ป้ายตัวเลขบนแถบเมนู: ฟอนต์เดียวกับป้ายกระดิ่ง (14 ต.ค. 69 · เจ้าของ: "ปรับฟอนหน่อย") ----------
   เดิม Space Mono 9px — ฟอนต์พิมพ์ดีด เลข 1 มีขีดฐานแบบเครื่องพิมพ์ ตัวเล็กจนอ่านเป็นจุด และไม่เข้ากับฟอนต์ที่เหลือของแอป
   → Outfit 700 ชุดเดียวกับป้ายตัวเลขบนกระดิ่งหน้าแรก (.th-bell .th-dot.n) · 10.5px ในป้าย 16px
   ตัวเลขกว้างเท่ากัน ป้ายไม่ยืดหดเมื่อเลขเปลี่ยน · ตัวเลขในป้ายเป็นข้อยกเว้นของขั้นต่ำ 11px (เหตุผลเดียวกับป้ายกระดิ่ง) */
.tab-badge {
  min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
  font: 700 10.5px/16px 'Outfit', 'Sarabun', sans-serif; font-variant-numeric: tabular-nums; letter-spacing: 0;
}

/* ---------- แผ่นเพิ่มงานที่กำลังปิด ต้องไม่บังการแตะ (17 ต.ค. 69 · คู่กับ openAddSheet/closeAddSheet ใน app.js) ----------
   ตอนปิด แผ่นถอด .on แล้วรอตัวจับเวลา 200ms ถึงจะซ่อน — ระหว่างนั้นทั้งแผ่น (เต็มจอ · z-index 95) ยังรับการแตะ
   ฉากหลังจางเป็น 0 แล้วจึงมองไม่เห็นว่ามีอะไรบังอยู่ · มือถือช้า ตัวจับเวลามาช้ากว่า 200ms มาก = แตะอะไรก็ไม่ติด
   ไม่มี .on = ทะลุทั้งแผ่น · เทสต์: devtools/sheetcheck.js */
.add-sheet:not(.on) { pointer-events: none; }

/* ---------- เมนูซ้าย: แผ่นที่เลื่อนขึ้นจากล่างไม่ยืดเต็มหน้าต่าง ไม่ทับเมนู (17 ต.ค. 69) ----------
   เจ้าของ: "ตอนที่ปุ่มอยู่ฝั่งซ้าย … อะไรต่าง ๆ ที่ยังเป็นปัญหาค้าง"
   แผ่นทุกใบออกแบบมาสำหรับมือถือ (left:0 · right:0 / width:100%) — พอแอปเต็มหน้าต่างจอคอม แผ่นยืดตาม
   วัดที่ 1920×1080: แผ่นเพิ่มงาน · กำลังจะเปิด · น้องฮูก · รายงาน · ติดตั้งแอป กว้าง 1920px · กล่องยืนยัน 1896px — ทุกใบทับเมนูซ้าย (x 14–106)
   ปุ่มบนแผ่นยืดตามจนยาวเกือบเต็มจอ · ตอนนี้แผ่นอยู่ในพื้นที่ทางขวาของเมนู กว้างสุดเท่าคอลัมน์เนื้อหา (720px) อยู่กลาง
   กล่องยืนยันแคบกว่า (480px) — คำถามสั้น ปุ่มสองปุ่ม กว้างกว่านี้ปุ่มห่างกันเกินสายตา */
:root[data-nav="side"] :is(.as-card, .ah-card) { left: 106px; right: 0; max-width: 720px; margin-inline: auto; }
:root[data-nav="side"] .ac-sheet { left: 106px; right: 0; max-width: 480px; margin-inline: auto; }
:root[data-nav="side"] :is(.rp-sheet, #installGuide) { padding-left: 106px; justify-content: center; }
:root[data-nav="side"] :is(.rp-card, .ig-sheet) { max-width: 720px; }

/* ============================================================
   ตัวหนังสืออ่านออกทุกธีม (17 ต.ค. 69)
   ------------------------------------------------------------
   เจ้าของ: "ตรวจสอบพวกฟอนต์หรือข้อความที่ยังไม่ชัดในแต่ละธีมและแก้ด้วย"
   วัดด้วย devtools/textcheck.mjs — อ่านพิกเซลใต้ตัวอักษรจริง 15 ธีม × 16 จอ (~540 ชิ้นต่อธีม) เกณฑ์ DESIGN.md ข้อ 2–3
   ก่อนแก้: สีจางเกินเกณฑ์ 77–129 ชิ้นต่อธีม · ตัวเล็กกว่า 11px 16 ชิ้น
   รอบก่อน ๆ แก้เฉพาะธีมสว่าง/มืดทีละจุด — อีก 13 ธีมไม่เคยถูกวัด · รอบนี้แก้ที่ต้นเหตุ 5 แบบ ใช้โทเคนของธีม ไม่ไล่ใส่สีทีละธีม
   ============================================================ */

/* ① หรี่ทั้งแถวด้วย opacity เพื่อบอก "ยังไม่ได้ / ผ่านไปแล้ว / ซื้อไม่ได้" — ตัวหนังสือที่ต้องอ่านจางตามไปด้วย (1.4–2.6:1 ทุกธีม)
     → แถวเต็มสี ตัวหนังสือใช้ --muted (≥4.5 บนการ์ดทุกธีม) · บอกสถานะด้วยเส้นประ/ไอคอนขาวดำแทน */
.phone .tk-skin:not(.got) { opacity: 1; border-style: dashed; box-shadow: none; }
.phone .tk-skin:not(.got) :is(.ts-nm, .ts-ct) { color: var(--muted); }
.phone .bg-row:not(.on) { opacity: 1; }
.phone .bg-row:not(.on) .bg-mark { filter: grayscale(1); }
.phone .dayrow.past { opacity: 1; }
.phone .dayrow.past :is(.dayrow-t, .dayrow-l) { color: var(--muted); font-weight: 400; }
.phone .dayrow.past .dayrow-dot { opacity: .4; }
.phone .tb-go.poor { opacity: 1; background: var(--card2); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); }
/* เส้นประกลางตั๋วจาง .55 ทั้งก้อน — ตัวเลขนาทีที่นั่งคร่อมเส้นจางตามไปด้วย → จางเฉพาะเส้น */
.td-now .tk-line { opacity: 1; background: none; }
.td-now .tk-line::before { content: ''; position: absolute; inset: 0; opacity: .55;
  background: repeating-linear-gradient(to right, currentColor 0 4px, transparent 4px 8px); }
.td-now .tk-line i { z-index: 1; }
/* ป้ายเล็กบนพื้นสีเน้น (การ์ด "ทำก่อน" · การ์ดงานที่ควรทำก่อน) — เดิมจาง .72–.85 */
.phone .wy2-k { opacity: .94; }
.phone .wy2-stats span { opacity: .92; }
.phone .tb-focus :is(.tb-fc-lb, .tb-fc-s) { opacity: 1; }

/* ② ประกายกระจกของปุ่มหลัก/ชิปที่เลือก (1C40) ไหลลงมาถึงกลางปุ่ม = ตัวหนังสือนั่งบนพื้นที่ถูกทำให้สว่างขึ้น
     ปุ่มหลักวัดได้ 3.8–4.2 ทั้งที่คู่สี --fill/--on-fill ของทุกธีมผ่าน 4.55+ → เก็บประกายไว้ที่ขอบบน · เงาเข้มบาง ๆ ใต้ตัวหนังสือ
     (หน้าตากระจกเดิม: แสงมุมซ้ายบน + ไล่สว่างจากขอบบน — แค่ไม่ลงมาถึงบรรทัดตัวหนังสือ) */
:root :is(.btn.primary, .fm-save, .sai-cta, .daysheet-go:not(.ghost), .ib-go, .fr-go, .ai-read, .cx2-scan,
          .ep-save, .ep-face-go, .pro-cta:not(.done), .ig-btns button.pri, .ig-av-cam,
          .cp-chip.on, .sp.active, .tk-mode.on, .rm-tab.on, .ds.on, .tg.on, .ctx-sw.on) {
  background-image:
    radial-gradient(110% 70% at 18% -18%, rgba(255,255,255,.42) 0%, rgba(255,255,255,.08) 45%, transparent 70%),
    linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0) 32%, rgba(0,0,0,.06) 62%, rgba(0,0,0,.12)) !important;
}
.phone .ds.on .ds-d { color: color-mix(in srgb, var(--on-fill) 92%, transparent); }   /* "วันนี้" บนวันที่เลือก เดิม 72% */

/* ③ สีตายตัวที่ไม่ตามธีม */
.phone .td-now .tn-eyebrow { color: var(--on-fill); }   /* ชื่อวิชาบนหัวการ์ด "ตอนนี้" ขาว 80% ตายตัว — ธีมที่พื้นหัวการ์ดสว่าง (อวกาศ · Astral) มองแทบไม่เห็น 1.2:1 */
.phone .tk-goal b { color: var(--gold-text); }   /* "10 โทเคน" อำพัน #E9A93C ตายตัว 2.0:1 → อำพันเข้มของธีม (สีเดิม เฉดอ่านออก) */
:root:not([data-theme="astral"]) .tab-badge { background: color-mix(in srgb, var(--pri-red) 86%, #000); }   /* เลขบนจุดแดง 4.36 → แดงเข้มขึ้นนิดเดียว */

/* ④ ตัวแดง/ส้มบนพื้นแดง/ส้มอ่อนของตัวเอง — คู่โทเคน --alert/--alert-soft ไม่ถึง 4.5 ใน 9 ธีม (sweet 3.6 · glitch 4.0)
     ดึงสีตัวหนังสือเข้าหา --ink 28% — ธีมสว่างได้แดงเข้มขึ้น ธีมมืดได้แดงอ่อนลง ยังเป็นแดงเตือนเดิมทุกธีม */
.phone :is(.tk-chip.hot, .nbadge.lv5, .tn-plan-note.warn, .wk-late-h i, .wy-sac, .bin-act .del) { color: color-mix(in srgb, var(--alert) 72%, var(--ink)); }
.phone :is(.nbadge.lv4, .povf-head) { color: color-mix(in srgb, var(--warn) 68%, var(--ink)); }
.phone .povf.danger .povf-head { color: color-mix(in srgb, var(--alert) 68%, var(--ink)); }

/* ⑤ ตัวหนังสือที่วางบนฉากของธีมตรง ๆ (ไม่มีการ์ดรอง) — ดาวเคราะห์ · แมงกะพรุน · ปลา ลอยผ่านหลังตัวหนังสือ
     (Astral: คำบรรยายหัวจอบนดาวเคราะห์สีเทา 1.7:1 · ทะเลลึก: "ดูแผนทั้งหมด" บนแมงกะพรุน 2.4:1)
     → ขอบนุ่มสีพื้นจอรอบตัวอักษร (แบบชื่อสถานที่บนแผนที่) — พื้นเรียบไม่เห็นอะไรเปลี่ยน · มีของลอยผ่านตัวหนังสือยังอ่านออก */
.phone :is(.page-head .page-sub, .hn-head > b, .hn-head > button, .home-discover b, .home-discover span span,
           .povf-head, .tl-hint, .hn-empty) {
  text-shadow: 0 0 1px var(--scr), 0 0 6px var(--scr), 0 0 12px var(--scr);
}
.phone .tl-hint b { color: var(--blue); }   /* "บอกตาราง" ใช้ --fill เป็นสีตัวหนังสือ (สีพื้นปุ่ม ไม่ใช่สีตัวหนังสือ) 3.5:1 ใน 3 ธีม */

/* ตัวหนังสือจาง (--faint) บนพื้นรอง/กระจก — --faint ผ่านบนการ์ดทุกธีม แต่บน --card2 ไม่ถึง 4.5 ใน 6 ธีม → --muted */
.phone :is(.ctx-empty, .dn-mid i, .shw i, .ab-ds, .bg-ct, .pslot .ptime .e) { color: var(--muted); }
.phone .an-bd.got .ab-ds { opacity: 1; }   /* "ได้แล้ว" อำพันบนทองอ่อน จาง .8 */
.phone .ai-priv-go { color: color-mix(in srgb, var(--blue) 62%, var(--ink)); }   /* ลิงก์ฟ้าบนแถบพื้นฟ้า 2.4:1 → ฟ้าที่ดึงเข้าหาสีตัวหนังสือ */
.phone .pctx-nudge .pn-tx span { color: color-mix(in srgb, var(--ink) 74%, var(--blue)); }   /* บนพื้นฟ้าอ่อน 2.6:1 ในธีมมืด */

/* ตัวหนังสือต่ำกว่า 11px ที่เป็นคำ (DESIGN.md ข้อ 3 · ต่ำกว่านี้ได้เฉพาะตัวเลขในแบดจ์) */
.phone :is(.ts-rar, .bg-ct, .nbadge, .sh-badge, .ab-nm) { font-size: 11px; }
#scr-profile .feature-category > span { font-size: 11px; }

/* ---------- รอบ 2 (วัดซ้ำหลังรอบแรก: light 95→35 · warm 105→40 · ocean 127→74 · deepocean 90→29 · astral 77→27) ---------- */
/* ป้ายบนแถบล่างกระจก — แถบเบลอเนื้อหาข้างหลัง: ฉากทะเลของ ocean (ป้ายเทาบนเขียวน้ำเงิน 2.0:1 ทุกจอ)
   หรือปุ่มสีฟ้าที่เลื่อนไปอยู่หลังแถบ ("เพิ่ม" บนแสงฟ้า) → ขอบนุ่มสีการ์ดรอบตัวอักษร อ่านออกไม่ว่าอะไรอยู่ข้างหลัง */
.tabbar .tab:not(.active) > span:last-child { text-shadow: 0 0 1px var(--card), 0 0 6px var(--card), 0 0 10px var(--card); }
/* ชิ้นเล็กที่เลือกอยู่ (วันที่ · ปุ่มสลับมุมมอง · ชิป) — ตัวหนังสือชิดขอบบนที่มีประกาย · ธีมที่ใช้ตัวขาวเผื่อแค่ 4.55 (warm)
   → ประกายเหลือแค่แถบบางที่ขอบบน · ป้ายบนวันที่เลือกเต็มสี (แยกลำดับด้วยขนาด ไม่ใช่ความจาง) */
/* ต้องมี .phone — กฎกระจกของปุ่มใหญ่มี ".ig-btns button.pri" ในรายการ ความเฉพาะเลยเป็น (0,3,1)
   ชนะกฎของชิ้นเล็ก (0,3,0) ที่เขียนทีหลัง → ชิ้นเล็กโดนประกาย/แสงในแบบปุ่มใหญ่มาตลอด (กฎ "ของชิ้นเล็ก" เดิมก็ไม่เคยทำงาน)
   .tk-thumb = เม็ดเลื่อนของแถบสลับมุมมอง (ตัวปุ่มที่เลือกโปร่งใส สีพื้นมาจากเม็ดนี้) */
:root .phone :is(.cp-chip.on, .sp.active, .tk-mode.on, .rm-tab.on, .ds.on, .tg.on, .ctx-sw.on, .tk-thumb) {
  background-image: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0) 16%, rgba(0,0,0,.06) 55%, rgba(0,0,0,.12)) !important;
}
.phone .ds.on .ds-d { color: var(--on-fill); }
/* ตัวหนังสือเล็กที่มุมสว่างของหัวการ์ดไล่สี (การ์ด "ตอนนี้" · การ์ด "ทำก่อน") — มุมซ้ายบนผสมขาว 22% ตามดีไซน์
   ธีมตัวขาวทุกธีมได้ 3.3–3.7 ตรงนั้น (ชื่องานตัวใหญ่ผ่านเกณฑ์ตัวใหญ่อยู่แล้ว) · ลดมุมสว่างจนผ่านทุกธีม = ต้องเอามุมสว่างออกหมด
   → คงไล่สีไว้ ใส่เงานุ่มสีเข้มของพื้นการ์ดเองใต้ตัวหนังสือเล็ก (แบบตัวขาวบนรูปถ่ายของ iOS)
   เฉพาะ 8 ธีมที่ใช้ตัวขาวบนพื้นการ์ด — ธีมตัวเข้ม (อวกาศ · เวทมนตร์ · กาแล็กซี · ทะเลลึก · meta · glitch · Astral) มุมสว่าง = ยิ่งชัด
   ใส่เงาเข้มใต้ตัวเข้มแล้วกลายเป็นรอยเปื้อน (ดูภาพแล้ว) · เพิ่มธีมตัวขาวใหม่ = เติมชื่อในรายการนี้ด้วย */
:root:is(:not([data-theme]), [data-theme="light"], [data-theme="dark"], [data-theme="warm"], [data-theme="earth"],
         [data-theme="ocean"], [data-theme="earth2"], [data-theme="sweet"], [data-theme="genesis"])
  :is(.phone .td-now .tn-head .tn-eyebrow, .phone .wy2-hero .wy2-k) {
  text-shadow: 0 0 1px color-mix(in srgb, var(--fill) 40%, #000), 0 0 3px color-mix(in srgb, var(--fill) 55%, #000), 0 0 8px color-mix(in srgb, var(--fill) 65%, #000);
}
/* วงสถิติ "รวม · ชม." — กฎของ #statFull ใช้ตัวหลักจาง 55% (3.9:1) ชนะกฎรวมข้างบนด้วย id */
#statFull .dn-mid i { color: var(--muted); }
/* เวลาในไทม์ไลน์ที่ยังไม่ใส่ตาราง ("06:00 ตื่นนอน") วางบนฉากตรง ๆ — ปลาในธีมทะเลว่ายผ่าน */
.phone .dayrow :is(.dayrow-t, .dayrow-l, .dayrow-due) { text-shadow: 0 0 1px var(--scr), 0 0 6px var(--scr), 0 0 12px var(--scr); }
/* 23 ต.ค. 69 · .dayrow-due ("ถึงกำหนด · …") ถูกลืมไว้นอกกฎนี้ — บนฉากเรือผี/สุสานมันทับใบเรือสว่างได้ 2.05:1 */
/* ตัวรองบนพื้นอมสี/กระจกที่ได้ 4.2–4.45 (เฉียดเกณฑ์) — --muted เข้มขึ้นอีกนิด ยังเป็นระดับรองเหมือนเดิม */
.phone :is(.ctx-empty, .pslot .ptime .e, .tk-chip:not(.hot), .sd-tx span, .st-tx span, .tb-grp > b, .tb-grp > button, .tn-plan-note:not(.warn), .sd-all, .sh-badge) {
  color: color-mix(in srgb, var(--muted) 70%, var(--ink));
}
/* รอบ 3 · ชิ้นเล็กที่เลือก: เงาขาวด้านใน 12px ท่วมทั้งเม็ด (ปุ่มสูง ~32px) → ตัวหนังสือนั่งบนพื้นที่สว่างขึ้นทั้งเม็ด 3.5:1
   → แสงในเหลือแค่ขอบ (6px · จางลง) ยังเห็นเป็นเม็ดกระจกเหมือนเดิม */
:root .phone :is(.cp-chip.on, .sp.active, .tk-mode.on, .rm-tab.on, .ds.on, .tg.on, .ctx-sw.on, .ig-av-cam) {
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.55), inset 0 -1.5px 3px rgba(0,0,0,.14),
    inset 0 0 6px rgba(255,255,255,.06), 0 0 0 .5px var(--lgb-edge, transparent) !important;
}
/* เม็ดเลื่อน: แสงในเหลือแค่ขอบเหมือนกัน — ยกเว้น meta/glitch ที่ตั้งเรืองแสงนีออนของเม็ดไว้เป็นเอกลักษณ์ธีม */
:root:not([data-theme="meta"]):not([data-theme="glitch"]) .phone .tk-thumb {
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.55), inset 0 -1.5px 3px rgba(0,0,0,.14),
    inset 0 0 6px rgba(255,255,255,.06), 0 0 0 .5px var(--lgb-edge, transparent) !important;
}
/* เม็ดเลื่อนที่ตั้งใจให้ปุ่มที่เลือกโปร่งใส — อย่าให้กฎบนไปใส่พื้นซ้อนให้ตัวปุ่ม (ปุ่มยังโปร่ง สีมาจากเม็ด) */
:root .phone .tk-modes.has-thumb .tk-mode.on { background-image: none !important; box-shadow: none !important; }
/* รอบ 3 · ข้อความรองที่วางบนฉากของธีมตรง ๆ — ฉากจริง (แสงลอดน้ำ · ไล่สีก้นจอ · ผลึกของ genesis) เข้มกว่าโทเคน --scr มาก
   --muted ที่ผ่านบน --scr จึงไม่ผ่านบนฉากจริง (ocean "สำรวจแอป" 2.7 · earth "เข้านอน" 2.4 · genesis "บอกตาราง" 3.0)
   → ดึงเข้าหาตัวหลัก (--ink) ครึ่งทาง ยังเบากว่าหัวข้อ · ขอบนุ่มสีพื้นจอจากรอบแรกยังอยู่ */
.phone :is(.page-head .page-sub, .home-discover span span, .hn-head > button, .hn-empty, .dayrow-t, .dayrow-l, .th-sub, .sh-sub) {
  color: color-mix(in srgb, var(--muted) 50%, var(--ink));
}
.phone .dayrow.past :is(.dayrow-t, .dayrow-l) { color: color-mix(in srgb, var(--muted) 62%, var(--ink)); }
.phone .tl-hint b { color: color-mix(in srgb, var(--blue) 55%, var(--ink)); }
/* หัวจอไล่สีของ genesis — คราม → ฟ้าอมเขียวอ่อน บนฉากลาเวนเดอร์ 1.1:1 (วัดหลังให้ตัววัดอ่านตัวหนังสือไล่สีได้)
   → โทนเดิม (คราม · น้ำเงิน · ฟ้าอมเขียว) เฉดเข้มขึ้น ทุกจุดของไล่สีผ่านเกณฑ์ตัวใหญ่ 3:1 */
:root[data-theme="genesis"] { --id-title-ink: linear-gradient(100deg, #1E2A8C, #2F3FB5 50%, #0B4A5E); }
/* รอบ 4 · ป้ายเล็กบนหัวการ์ดไล่สี ("ทำก่อน" · "ที่ต้องใช้" · ชื่อวิชา) ยัง 3.5–4.0 ในธีมตัวขาว แม้มีเงารอง
   → เต็มสี + มุมสว่างผสมขาวน้อยลง (22% → 12%) ทั้งสองการ์ดพร้อมกัน (เจ้าของสั่งให้สองใบนี้หน้าตาเดียวกัน) · มุมเข้มขวาล่างคงเดิม */
.phone .wy2-k, .phone .wy2-stats span { opacity: 1; }
.phone .td-now .tn-head, .phone .wy2-hero {
  background: linear-gradient(140deg,
    color-mix(in srgb, var(--fill) 88%, #fff) 0%,
    var(--fill) 55%,
    color-mix(in srgb, var(--fill) 78%, #000) 100%);
}
:root:is(:not([data-theme]), [data-theme="light"], [data-theme="dark"], [data-theme="warm"], [data-theme="earth"],
         [data-theme="ocean"], [data-theme="earth2"], [data-theme="sweet"], [data-theme="genesis"]) .phone .wy2-hero .wy2-stats span { text-shadow: 0 0 1px color-mix(in srgb, var(--fill) 40%, #000), 0 0 6px color-mix(in srgb, var(--fill) 60%, #000); }
/* แถวกิจวัตรในไทม์ไลน์ (ฉาก glitch/ทะเล/ผลึก) ยัง 3.7–4.2 → เข้าใกล้ตัวหลักอีก */
.phone .dayrow :is(.dayrow-t, .dayrow-l), .phone .dayrow.past :is(.dayrow-t, .dayrow-l) { color: color-mix(in srgb, var(--muted) 30%, var(--ink)); }

/* รอบ 5 (วัดครบ 15 ธีมไม่มีงานอื่นซ้อน: 1,494 → 330) */
/* เงาใต้ "พรุ่งนี้ · กำหนดส่ง" เดิมใส่ทุกธีม — ธีมตัวเข้มได้เงาเข้มใต้ตัวเข้ม 2.8:1 → จำกัดเฉพาะธีมตัวขาว (แก้ที่กฎข้างบนแล้ว) */
/* "เพิ่ม" บนแถบล่าง — เนื้อหาสีเข้มที่เลื่อนไปอยู่หลังกระจก (ปุ่มฟ้า "ถ่ายรูปตารางเรียน") ยังกลบได้ 2.5 → ขอบนุ่มหนาขึ้น */
.tabbar .tab:not(.active) > span:last-child { text-shadow: 0 0 1px var(--card), 0 0 2px var(--card), 0 0 4px var(--card), 0 0 8px var(--card), 0 0 12px var(--card); }
/* หัวจอไล่สีของ earth2 — ปลายเขียวอ่อน 2.7:1 (เกณฑ์ตัวใหญ่ 3) → เขียวเดิม เฉดเข้มขึ้น */
:root[data-theme="earth2"] { --id-title-ink: linear-gradient(100deg, #1E5B2E, #3B7F2B); }
/* ตัวรอง/ลิงก์ที่เหลือ 2.9–4.4 ในบางธีม — ดึงเข้าหาตัวหลัก */
.phone :is(.ai-hello p, .pctx-note, .ai-priv-tx, .wy2-n, .tb-more, .sh-badge) { color: color-mix(in srgb, var(--muted) 45%, var(--ink)); }
.phone :is(.ai-priv-go, .tl-hint b) { color: color-mix(in srgb, var(--blue) 45%, var(--ink)); }
.phone .povf-head { color: color-mix(in srgb, var(--warn) 50%, var(--ink)); }
.phone .tk-chip.warm { color: color-mix(in srgb, var(--warn) 60%, var(--ink)); }
/* รอบ 6 · ป้าย "ไม่ทัน/แน่น" ในหัววันของไทม์ไลน์วางลอยบนฉากตรง ๆ พื้นป้ายโปร่ง 26% — ธีมมืดของในฉากลอยผ่านหลังป้าย 2.4:1
   → พื้นป้ายทึบ (สีเตือนผสมพื้นการ์ด) ไม่ขึ้นกับฉาก */
.phone .dayvd-h .tk-chip.hot { background: color-mix(in srgb, var(--alert) 22%, var(--card)); }
.phone .dayvd-h .tk-chip.warm { background: color-mix(in srgb, var(--warn) 22%, var(--card)); }
/* ป้ายแถบล่าง — แถบไม่มีสีพื้นของตัวเอง (โปร่ง + เบลอ + เร่งสี 2 เท่า) ปุ่มสีที่เลื่อนไปหลังแถบกลายเป็นพื้นสีสด
   ขอบนุ่มอย่างเดียวได้ 2.7 → ตัวป้ายเข้มขึ้นหนึ่งระดับ (--faint → --muted) */
:root:not([data-nav="side"]) .tabbar .tab:not(.active) { color: var(--muted); }

/* ---------- ปุ่ม "เปิดแอปหลัก" (ตั้งค่า › แจ้งเตือน) · 18 ต.ค. 69 ----------
   เจ้าของ: "แก้ให้ตรงและสวยหน่อย" — ปุ่มนี้เป็น <a> ตัวเดียวในแอปที่ใช้หน้าตา .btn
   <button> จัดตัวหนังสือกึ่งกลางแนวตั้งให้เอง แต่ <a> เป็น display:block บรรทัดสูง 23px ในปุ่มสูง 34px
   → ตัวหนังสือกองอยู่ข้างบน + มีขีดเส้นใต้ของลิงก์ติดมา
   → จัดกึ่งกลางด้วย inline-flex เหมือนปุ่มข้าง ๆ · ลูกศรเฉียงขึ้น (↗) บอกว่าพาออกไปแอปอื่น */
.phone a.btn.open-main {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  width: auto; min-height: 34px; padding: 0 12px 0 14px; flex-shrink: 0;
  line-height: 1; white-space: nowrap; text-decoration: none;
}
.phone a.btn.open-main svg {
  width: 13px; height: 13px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  transform: rotate(45deg); opacity: .75;
}

/* ============================================================
   ระดับกราฟิก น้อย · กลาง · มาก (ตั้งค่า › กราฟิก) · 19 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ทำให้มีปุ่มสามารถปรับกราฟิกหรือความสวยได้หน่อย และก็ปรับตามนั้น มี น้อย กลาง มาก"
   กลาง = กฎ :root[data-lite] เดิมทั้งหมด · น้อย = กลาง + ข้างล่างนี้ (:root[data-quality="low"] — ห้ามใช้ data-gfx: ธีม glitch ใช้สั่นจอแล้วลบทิ้ง) · ตัวควบคุมอยู่ที่ setGfx (app.js)
   ปุ่มแบ่งช่องหน้าตาเดียวกับปุ่ม 2D/3D ของเอฟเฟกต์ (.fx-seg) และแถบสลับมุมมองงาน — แบบที่แอปใช้อยู่แล้ว ไม่ใช่ปุ่มแบบใหม่
   ============================================================ */
.gfx-row { flex-wrap: wrap; row-gap: 10px; }
.gfx-row .set-lb { flex: 1; min-width: 0; }
.gfx-seg { flex: 0 0 calc(100% - 48px); box-sizing: border-box; display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 3px; margin-left: 48px;
  border-radius: 999px; background: var(--card2); box-shadow: inset 0 0 0 1px var(--line); }
.gfx-seg button { min-height: 36px; border: 0; border-radius: 999px; background: none; color: var(--muted);
  font: 700 13.5px/1 'Sarabun', 'Leelawadee UI', sans-serif; cursor: pointer; transition: background-color .18s ease, color .18s ease; }
.gfx-seg button.active { background: var(--fill); color: var(--on-fill); box-shadow: 0 2px 8px -4px color-mix(in srgb, var(--fill) 70%, transparent); }
.gfx-seg button:active { transform: scale(.97); }
:root[data-nav="side"] .gfx-seg { margin-left: 0; flex-basis: 100%; }

/* น้อย: ไม่วาดฉากของธีมเลย (กลางแค่หยุดนิ่ง) — สีพื้นของธีมยังอยู่ */
:root[data-quality="low"] :is(.fx, .starfield) { display: none !important; }
/* น้อย: ไม่มีอนิเมชันเข้าจอ — จอใหม่โผล่ทันที
   ชิ้นที่ไล่เข้าทีละชิ้น "เล่นจบทันที" (ไม่ใช่ animation:none) — บางชิ้นเริ่มจากโปร่งใสแล้วให้อนิเมชันพาให้เห็น
   ปิดทิ้งเฉย ๆ จะค้างโปร่งใส · จบทันที = ไปอยู่ท่าสุดท้ายเสมอ */
:root[data-quality="low"] .screen.on { animation: none !important; }
:root[data-quality="low"] :is(.screen.just-in, .screen.fx-in) :is(*, *::before, *::after) {
  animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
}

/* ============================================================
   18 ต.ค. 69 · วันนี้ — บรรทัดเดาบนหน้าแรก (.dc-line · แบบ ก "เดาให้ แล้วแตะแก้") + แผ่น #daySheet
   ============================================================
   แผ่นยืมโครง .add-sheet/.as-scrim/.as-card จาก today.css ทั้งก้อน (เหมือน #soonSheet)
   ทุกแถวที่มีไอคอนข้างข้อความใช้ grid ไม่ใช่ flex — <span> ที่เป็น flex item ใน alt/ กว้างศูนย์
   หัวข้อไทยไม่มี letter-spacing — ตัวสระแยกออกจากพยัญชนะ */
.dc-line svg { width: 16px; height: 16px; color: var(--blue); }
.dc-chips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.dc-chips button {
  min-height: 40px; padding: 4px 4px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--card2); color: var(--ink); font-family: inherit; font-size: 12.5px; font-weight: 600;
  line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
.dc-chips button:active { transform: scale(.97); }
.dc-chips button.on { border-color: var(--blue); background: var(--blue-soft); color: var(--ink); font-weight: 700; }
.dc-line {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px;
  width: 100%; box-sizing: border-box; margin: 0 0 10px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card); color: var(--ink);
  font-family: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer;
}
.dc-line span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-line i { font-style: normal; font-weight: 700; color: var(--blue); }
.dc-line small { font-size: 12.5px; font-weight: 600; color: var(--muted); }

.dc-card { padding-bottom: calc(20px + env(safe-area-inset-bottom)); }
.dc-h { margin: 4px 0 12px; font-size: 18px; font-weight: 800; color: var(--ink); }
.dc-card .dc-chips { margin-bottom: 12px; }
.dc-ai, .dc-conf, .dc-man { display: grid; gap: 10px; }
.dc-ai textarea {
  width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card2); color: var(--ink); font-family: inherit; font-size: 15px; line-height: 1.5; resize: none;
}
.dc-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.dc-yes, .dc-no, .dc-add button {
  min-height: 44px; padding: 8px 14px; border-radius: 14px;
  font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
}
.dc-yes {
  display: grid; grid-template-columns: auto auto; justify-content: center; align-items: center; gap: 6px;
  border: 0; background: var(--blue); color: var(--on-accent);
}
.dc-yes svg, .dc-add button svg { width: 16px; height: 16px; }
.dc-no, .dc-add button { border: 1px solid var(--line); background: var(--card); color: var(--ink); }
.dc-link {
  justify-self: start; min-height: 40px; padding: 6px 0; border: 0; background: none;
  font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--muted); cursor: pointer;
}
.dc-conf > b { font-size: 15px; color: var(--ink); }
.dc-conf ul, .dc-man ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.dc-conf li, .dc-man li { font-size: 14px; color: var(--ink); }
.dc-conf li { padding: 8px 10px; border-radius: 12px; background: var(--card2); }
.dc-man li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  padding: 4px 4px 4px 10px; border-radius: 12px; background: var(--card2);
}
.dc-man li button { width: 36px; height: 36px; border: 0; background: none; color: var(--muted); cursor: pointer; }
.dc-man li svg { width: 16px; height: 16px; }
.dc-adv {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; margin: 0; padding: 10px 12px;
  border-radius: 12px; background: var(--blue-soft); font-size: 13.5px; line-height: 1.55; color: var(--ink);
}
.dc-adv svg { width: 16px; height: 16px; margin-top: 2px; color: var(--blue); }
.dc-sub { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
.dc-sub b { color: var(--ink); }
.dc-err { margin: 0; font-size: 13px; color: var(--alert); }
.dc-chk { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; align-items: center; font-size: 14px; color: var(--ink); }
.dc-chk input { width: 20px; height: 20px; accent-color: var(--blue); }
.dc-add { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.dc-add input {
  min-height: 42px; box-sizing: border-box; padding: 6px 10px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--card2); color: var(--ink); font-family: inherit; font-size: 15px;
}
.dc-add input[type="text"], .dc-add button { grid-column: 1 / -1; }
.dc-add button { display: grid; grid-template-columns: auto auto; justify-content: center; align-items: center; gap: 6px; }
.dc-brk-d {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px;
  font-size: 14px; font-weight: 600; color: var(--ink);
}
.dc-brk-d input {
  min-height: 42px; box-sizing: border-box; padding: 6px 10px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--card2); color: var(--ink); font-family: inherit; font-size: 15px;
}
.dc-brk-body { display: grid; gap: 10px; }
.dc-brkq i { color: var(--blue); }

/* ============================================================
   แผนวันนี้ อ่านง่าย ใช้ง่าย (scr-sai · renderSaiPlan) · 19 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ปรับหน้าแผนวันนี้ให้มันดูเข้าใจง่าย ใช้งานง่าย"
   • การ์ดบน = มาสคอต + งานถัดไป + ปุ่มเริ่ม (เดิมปุ่มอยู่ท้ายจอ ใต้ทั้งวัน)
   • ผลลัพธ์ = แถบบรรทัดเดียว ประโยคเดิม (เดิมการ์ดทึบสูงเกือบครึ่งจอ)
   • เส้นเวลาเริ่มที่ตอนนี้ · ช่วงที่ผ่านไปแล้วพับไว้ใต้ปุ่ม .sd-pastbtn
   ============================================================ */
#saiBody .sai-next { grid-template-columns: 74px minmax(0, 1fr); align-items: center; padding: 14px 16px 16px 8px; }
#saiBody .sai-next .saip-stage, #saiBody .sai-next .saip-chibi { width: 74px; height: 128px; }
.sn-body { display: grid; gap: 2px; min-width: 0; }
.sn-k {
  justify-self: start; margin-bottom: 4px; padding: 3px 10px; border-radius: 99px;
  font-size: 12.5px; font-weight: 800; line-height: 1.4;
  color: color-mix(in srgb, var(--fill) 55%, var(--ink)); background: color-mix(in srgb, var(--fill) 13%, transparent);
}
.sn-t {
  font-size: 18px; font-weight: 800; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sn-m { font-style: normal; font-size: 13px; font-weight: 600; color: var(--muted); }
#saiBody .sai-next .sai-cta { margin-top: 10px; padding: 12px; }

/* ผลลัพธ์: แถบบรรทัดเดียวบนพื้นการ์ด — ไม่ใช่พื้นทึบ --fill อีกแล้ว ตัวหนังสือจึงกลับมาใช้ --ink */
#saiBody .sp-hero {
  display: flex; align-items: center; gap: 10px; margin: 10px 0 2px; padding: 12px 16px; border-radius: 16px;
  background: color-mix(in srgb, var(--alert) 12%, var(--card)); color: var(--ink);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--alert) 22%, transparent);
}
#saiBody .sp-hero.ok {
  background: color-mix(in srgb, var(--fill) 10%, var(--card));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fill) 20%, transparent);
}
#saiBody .sp-hero::before, #saiBody .sp-hero::after { display: none; }
#saiBody .sp-hero > svg {
  width: 20px; height: 20px; flex: none; fill: none; stroke: var(--alert);
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
#saiBody .sp-hero.ok > svg { stroke: var(--fill); }
#saiBody .sp-hero b { font-size: 15px; font-weight: 700; line-height: 1.4; letter-spacing: 0; color: var(--ink); }
#saiBody .sp-hero b em { font-size: 16px; font-weight: 800; letter-spacing: 0; }

/* ปุ่มดูช่วงที่ผ่านไปแล้ว */
.sd-pastbtn {
  display: inline-flex; align-items: center; min-height: 34px; margin: 0 0 8px; padding: 6px 14px;
  border: 0; border-radius: 99px; cursor: pointer;
  background: color-mix(in srgb, var(--ink) 7%, transparent); color: var(--muted);
  font: inherit; font-size: 13px; font-weight: 700;
}
.sd-pastbtn:active { transform: scale(.97); }
.sd-pastbtn { width: fit-content; }
/* ธีม astral เป็นขาวดำทั้งแอป — แดงของ --alert กลายเป็นเทาอ่อน ตัวขาวบนป้าย "ตอนนี้" จมหาย → ตัวเข้มแทน */
:root[data-theme="astral"] #saiBody .sd-now span { color: #111; }
:root[data-theme="astral"] #saiBody .sd-now span em { background: #111; }
#saiBody .sd-t-now { color: var(--alert); font-size: 14px; }
:root[data-theme="astral"] #saiBody .sd-t-now { color: var(--ink); }
#saiBody .sd-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; margin-bottom: 0; }
#saiBody .sd-head .sd-pastbtn { margin: 0; min-height: 32px; padding: 5px 12px; font-size: 12.5px; }

/* ============================================================
   แผนวันนี้: ช่อง "ว่าง" ใช้สีของธีม · 19 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "ปรับสีให้ตรงแต่ละธีมด้วย" — เดิมฟ้าตายตัว (#3B82F6 → --sig-blue → #1748A8) ทุกธีม
   ธีมเขียว (earth) ชมพู (warm/sweet) ม่วง (galaxy) ก็ยังได้ก้อนน้ำเงินกลางจอ
   ตอนนี้ไล่จาก --fill ของธีม (สีเดียวกับปุ่ม "เริ่มทำเลย") · ไล่แค่นิดเดียว (+8% ขาว → +12% ดำ)
   ให้ตัวหนังสือ --on-fill ได้คอนทราสต์เท่ากับบนปุ่ม — บางธีม on-fill เป็นตัวเข้ม (galaxy) ไล่เข้มมากจะจม
   ⚠️ ตัวหนังสือบนก้อนนี้ต้องสืบจาก --on-fill ทุกตัว ห้ามขาวตายตัว
   การ์ดงานสีขาวที่ซ้อนอยู่ข้างในคงเดิม — ตัวเข้มบนขาว อ่านได้บนพื้นทุกสี
   ============================================================ */
#saiBody .sd-free .sd-x {
  background: linear-gradient(150deg, color-mix(in srgb, var(--fill) 92%, #fff), var(--fill) 50%, color-mix(in srgb, var(--fill) 88%, #000));
  box-shadow: 0 14px 28px -16px color-mix(in srgb, var(--fill) 80%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
}
#saiBody .sd-free .sd-x::after { background: radial-gradient(closest-side, color-mix(in srgb, var(--on-fill) 16%, transparent), transparent 70%); }
#saiBody .sd-free .sd-x > b { color: var(--on-fill); }
#saiBody .sd-free .sd-x > i { color: color-mix(in srgb, var(--on-fill) 84%, transparent); }
#saiBody .sd-free .sd-tag {
  color: var(--on-fill); background: color-mix(in srgb, var(--on-fill) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--on-fill) 26%, transparent);
}
#saiBody .sd-free .sd-job.brk { border-color: color-mix(in srgb, var(--on-fill) 40%, transparent); background: color-mix(in srgb, var(--on-fill) 6%, transparent); }
#saiBody .sd-free .sd-job.brk .sd-jx b { color: var(--on-fill); }
#saiBody .sd-free .sd-job.brk :is(.sd-jt, .sd-jx i) { color: color-mix(in srgb, var(--on-fill) 78%, transparent); }

/* ============================================================
   แท็บฉัน › "ห้อง · เหรียญ · สถิติ": การ์ดสถิติไม่ซ้อนกล่อง · 19 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ (ภาพการ์ดสถิติ + กราฟ 7 วัน): "มันไม่ตรงขอบ"
   .pf-me เป็นการ์ดเต็มใบ (พื้น · ขอบ · เงา · มุม 24px) แล้วถูกห่อด้วยแผงพับ .pf-personal
   ซึ่งเป็นการ์ดอีกใบ (มุม 16px · ห่าง 12px) — ได้ขอบสองชั้นที่โค้งไม่เท่ากัน ช่องไฟเลยไม่สม่ำเสมอ
   กล่องในกล่องแบบที่ 1C08 เคยถอดไปแล้วด้วยเหตุผลเดียวกัน (ดูคอมเมนต์เหนือ .pf-me)
   ในแผงพับ: การ์ดในเหลือแค่เส้นคั่นบาง ๆ · ขยายเต็มความกว้างแผง ให้ตัวเลขตรงแนวกับหัวแผง
   ============================================================ */
.pf-personal .pf-me {
  margin-inline: -12px; background: none; border: 0; border-radius: 0; box-shadow: none;
  border-top: 1px solid color-mix(in srgb, var(--ink) 9%, transparent);
}
.pf-personal .pf-me .st-card { padding-bottom: 2px; }

/* ============================================================
   หน้าแรก › บรรทัด "วันนี้" (.dc-line) อ่านออกว่าคืออะไร กดตรงไหน · 19 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ (ภาพบรรทัด "ไปเรียน · เปลี่ยน"): "แก้หน้านี้หน่อย"
   เดิม: กล่องเปล่าเต็มความกว้าง ไอคอนลอย · "ไปเรียน" ไม่มีบริบท · "เปลี่ยน" ตัวหนังสือฟ้าตายตัวสุดขอบขวา
   ตอนนี้: พื้นเจือสีธีม · ไอคอนในวงกลม · "วันนี้" + คำเดาตัวหนา · "เปลี่ยน" เป็นแคปซูลที่ดูออกว่ากดได้
   สีทั้งหมดจาก --fill ของธีม (เดิม --blue ทุกธีม) · สูง 36px เท่าเดิม — หน้าแรกห้ามต้องเลื่อน
   ============================================================ */
.dc-line {
  gap: 9px; padding: 5px 5px 5px 6px; border-radius: 999px;
  border-color: color-mix(in srgb, var(--fill) 20%, transparent);
  background: color-mix(in srgb, var(--fill) 7%, var(--card));
}
.dc-line .dc-ic {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  background: color-mix(in srgb, var(--fill) 24%, transparent);
}
.dc-line .dc-ic svg { width: 14px; height: 14px; color: color-mix(in srgb, var(--fill) 70%, var(--ink)); }
.dc-line .dc-tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-line .dc-tx em { font-style: normal; font-weight: 600; color: var(--muted); }
.dc-line .dc-tx b { font-weight: 800; color: var(--ink); }
.dc-line > i, .dc-brkq > i {
  padding: 4px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 700; line-height: 1.3;
  color: color-mix(in srgb, var(--fill) 60%, var(--ink)); background: color-mix(in srgb, var(--fill) 15%, transparent);
}
.dc-line:active { transform: scale(.985); }

/* ---------- บรรทัด "วันนี้" ตอนแอปยังไม่รู้ (.dc-line.ask) · 19 ต.ค. 69 ----------
   เจ้าของ: "ทำให้มันดูเห็นเป็นที่สะดุดตาว่าเราควรทำอะไร" → เลือก "แถบวันนี้ ตอนแอปยังไม่รู้"
   พื้น --fill เต็ม ตัวหนังสือ --on-fill (ทุกตัว — บางธีม on-fill เป็นตัวเข้ม) · หมุดมีวงกระเพื่อม · ปุ่ม "บอกเลย" ขาว
   ไม่ใช่สีทอง — ทองใช้เฉพาะของที่ทำสำเร็จแล้ว · สูง 36px เท่าเดิม (หน้าแรกห้ามต้องเลื่อน)
   กราฟิกน้อย/ลดการเคลื่อนไหว = วงไม่กระเพื่อม สียังเด่นเหมือนเดิม */
.dc-line.ask {
  border-color: transparent; color: var(--on-fill);
  background: linear-gradient(135deg, color-mix(in srgb, var(--fill) 88%, #fff), var(--fill) 55%, color-mix(in srgb, var(--fill) 88%, #000));
  box-shadow: 0 10px 22px -12px color-mix(in srgb, var(--fill) 85%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
}
.dc-line.ask .dc-ic { position: relative; background: color-mix(in srgb, var(--on-fill) 20%, transparent); }
.dc-line.ask .dc-ic svg { color: var(--on-fill); }
.dc-line.ask .dc-ic::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--on-fill) 55%, transparent);
  animation: dc-ask-ping 1.8s cubic-bezier(.22, 1, .36, 1) infinite;
}
@keyframes dc-ask-ping { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--on-fill) 55%, transparent); } 80%, 100% { box-shadow: 0 0 0 9px transparent; } }
.dc-line.ask .dc-tx b { color: var(--on-fill); }
.dc-line.ask .dc-tx small { color: color-mix(in srgb, var(--on-fill) 82%, transparent); }
.dc-line.ask > i { color: var(--fill); background: var(--on-fill); box-shadow: 0 2px 8px -3px rgba(0,0,0,.3); }
@media (prefers-reduced-motion: reduce) { .dc-line.ask .dc-ic::after { animation: none; } }
:root[data-lite] .dc-line.ask .dc-ic::after { animation: none; }
/* คอนทราสต์ (textcheck 19 ต.ค. 69): ไล่สีขึ้นสว่างที่หัวแถบทำให้ตัวขาว 12.5–13px ได้แค่ 3.4–4.0:1 ใน 7 ธีม
   ธีมที่ on-fill เป็นตัวขาว (light dark warm earth earth2 ocean sweet genesis) → ไล่จาก --fill ลงเข้ม
   ธีมที่ on-fill เป็นตัวเข้ม (astral deepocean galaxy glitch magic meta space) → ไล่จากสว่างขึ้นมาที่ --fill
   ทิศไล่สีต้องหนีจากสีตัวหนังสือเสมอ — ไล่ผิดทางแปลว่าตัวหนังสือจมลงในพื้นตัวเอง */
.dc-line.ask { background: linear-gradient(135deg, var(--fill), color-mix(in srgb, var(--fill) 74%, #000)); }
:root:is([data-theme="astral"], [data-theme="deepocean"], [data-theme="galaxy"], [data-theme="glitch"], [data-theme="magic"], [data-theme="meta"], [data-theme="space"]) .dc-line.ask {
  background: linear-gradient(135deg, color-mix(in srgb, var(--fill) 78%, #fff), var(--fill));
}
.dc-line.ask .dc-tx small { color: var(--on-fill); font-weight: 500; }

/* จอแผน: โน้ตที่เอนจินติด ⚠ (ทำไม่ครบก่อนกำหนด) — เดิม ⚠ หลุดมาเป็นตัวอักษร · ตอนนี้ถอดตัวอักษรออก แล้วบอกด้วยสีแทน (19 ต.ค. 69) */
.pslot .work .nt.hot { color: var(--alert); font-weight: 600; }

/* หน้าเข้าสู่ระบบ: ปุ่มกลับมุมซ้ายบน (เปิดจากในแอปเท่านั้น · 20 ต.ค. 69)
   กฎปุ่มกลับกลางตั้ง display:inline-grid !important — ทับ [hidden] ของเบราว์เซอร์ ต้องซ่อนเองด้วย !important */
/* อยู่ในแถวของตัวเองเหนือใบพระเอก (ไม่ลอยทับโลโก้มุมซ้ายบนของใบ) · ซ่อน = ไม่กินที่ · ลูกศรพลิกชี้ซ้ายแบบ .sh-btn */
#scr-login .lg-back { align-self: flex-start; margin: 0 0 10px; }
#scr-login .lg-back svg { transform: scaleX(-1); }
.phone #scr-login .lg-back[hidden] { display: none !important; }

/* ============================================================
   แผนวันนี้ รอบสอง: การ์ดบนเป็นพระเอกสีเต็ม · 20 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ (ภาพจอแผนตอนดึก): "แก้ใหม่หน่อยให้มันดูง่ายและสนใจ ดูน่าใช้กว่านี้"
   ที่รกในภาพ: งานเดียวกันขึ้นสองที่ (การ์ดบน + ก้อนเส้นเวลา) · ป้ายสี่ชิ้นตะโกนเท่ากัน · การ์ดบนเป็นกล่องเทา
   • การ์ดบน = พื้น --fill ตัว --on-fill (สูตรการ์ดงานหน้าแรก) · ทิศไล่สีแยกตามธีมตัวขาว/ตัวเข้ม (เหมือน .dc-line.ask)
   • ปุ่มเริ่ม = สีกลับด้าน (พื้น on-fill ตัว fill) เต็มความกว้าง — ของที่กดได้ชิ้นเดียวที่เด่นที่สุดในจอ
   • แถบผลลัพธ์อยู่ท้ายการ์ด (ข้อความเดิมของเจ้าของ) · เส้นเวลาไม่ขึ้นงานที่การ์ดบนบอกแล้ว (sai.js)
   • ปุ่ม "เล่าทีละข้อ" เบาลงเป็นลิงก์ — ไม่ใช่สิ่งที่ต้องทำ
   ============================================================ */
#saiBody .sn-hero {
  grid-template-columns: 70px minmax(0, 1fr); row-gap: 12px; padding: 16px 16px 14px 8px; border: 0;
  color: var(--on-fill);
  background: linear-gradient(150deg, var(--fill), color-mix(in srgb, var(--fill) 76%, #000));
  box-shadow: 0 18px 36px -20px color-mix(in srgb, var(--fill) 90%, transparent), inset 0 1px 0 rgba(255,255,255,.2);
}
:root:is([data-theme="astral"], [data-theme="deepocean"], [data-theme="galaxy"], [data-theme="glitch"], [data-theme="magic"], [data-theme="meta"], [data-theme="space"]) #saiBody .sn-hero {
  background: linear-gradient(150deg, color-mix(in srgb, var(--fill) 80%, #fff), var(--fill));
}
#saiBody .sn-hero .saip-stage, #saiBody .sn-hero .saip-chibi { width: 70px; height: 121px; }
#saiBody .sn-hero .sn-k { color: var(--on-fill); background: color-mix(in srgb, var(--on-fill) 16%, transparent); }
#saiBody .sn-hero .sn-t { color: var(--on-fill); font-size: 21px; line-height: 1.3; }
#saiBody .sn-hero .sn-m { color: var(--on-fill); opacity: .88; font-size: 13.5px; }
#saiBody .sn-hero .sn-go {
  grid-column: 1 / -1; margin: 0; padding: 14px; border-radius: 16px; font-size: 16px; font-weight: 800;
  background: var(--on-fill) !important; color: var(--fill) !important;
  box-shadow: 0 8px 18px -10px rgba(0,0,0,.45) !important;
}
#saiBody .sn-hero .sn-go svg { color: var(--fill); }
/* แถบผลลัพธ์ในการ์ด — ไม่มีกรอบ ไม่มีพื้นแดง (บนพื้นสีเต็มแดงจะจม) · ไอคอนบอกดี/ไม่ดี */
#saiBody .sn-hero .sp-hero {
  grid-column: 1 / -1; margin: 0; padding: 10px 12px; border-radius: 14px; box-shadow: none;
  background: color-mix(in srgb, var(--on-fill) 12%, transparent); color: var(--on-fill);
}
#saiBody .sn-hero .sp-hero b { color: var(--on-fill); font-size: 14px; }
#saiBody .sn-hero .sp-hero b em { font-size: 15px; }
#saiBody .sn-hero .sp-hero > svg { stroke: var(--on-fill); }
/* ปุ่มเล่าทีละข้อ → ลิงก์เบา ๆ */
#saiBody .sai-tour {
  border: 0 !important; background: none !important; box-shadow: none !important; margin-top: 2px; padding: 12px;
  color: var(--muted) !important; font-size: 14px; font-weight: 700; text-decoration: underline; text-underline-offset: 4px;
}
/* ช่องว่างในเส้นเวลา → เจือสีอ่อนของธีม (ไม่ใช่สีเต็ม) — การ์ดบนเป็นสีเต็มแล้ว สองก้อนสีเดียวกันแย่งกันเป็นพระเอก
   ตัวหนังสือกลับมาเป็น --ink · การ์ดงานข้างในเป็น --card (ธีมมืดได้การ์ดมืด ไม่ใช่การ์ดขาวลอย) */
#saiBody .sd-free .sd-x {
  background: color-mix(in srgb, var(--fill) 13%, var(--card)) !important;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 22%, transparent) !important;
}
#saiBody .sd-free .sd-x::after { display: none; }
#saiBody .sd-free .sd-x > b { color: var(--ink); }
#saiBody .sd-free .sd-x > i { color: var(--muted); }
#saiBody .sd-free .sd-tag { color: color-mix(in srgb, var(--fill) 65%, var(--ink)); background: color-mix(in srgb, var(--fill) 16%, transparent); box-shadow: none; }
#saiBody .sd-free .sd-job:not(.brk) { background: var(--card); box-shadow: 0 1px 0 color-mix(in srgb, var(--ink) 6%, transparent), 0 6px 14px -10px rgba(0,0,0,.35); }
#saiBody .sd-free .sd-job:not(.brk) .sd-jx b { color: var(--ink); }
#saiBody .sd-free .sd-job:not(.brk) :is(.sd-jt, .sd-jx i) { color: var(--muted); }
#saiBody .sd-free .sd-job.brk { border-color: color-mix(in srgb, var(--ink) 18%, transparent); background: none; }
#saiBody .sd-free .sd-job.brk .sd-jx b { color: var(--ink); }
#saiBody .sd-free .sd-job.brk :is(.sd-jt, .sd-jx i) { color: var(--muted); }

/* ============================================================
   แผนวันนี้ · ตารางทั้งวันแบบ ก "รายการเรียงเวลา" (sai.js · .tl) · 20 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของเลือกแบบ ก จากสามแบบ (รายการ · แถบทั้งวัน+รายการ · ตารางชั่วโมงจริง)
   แถวเดียวเรียงเวลา ไม่มีกล่องซ้อน: เวลาตัวหนาคอลัมน์ซ้าย (คงไว้ตามที่เจ้าของเคาะ "เวลาต้องเด่นสุด" · ไม่มีรางเส้นตั้ง)
   งาน = การ์ด --card · ทำก่อน = เจือ --fill + ขอบ · เรียน/กิจวัตร = จาง · พัก/นอน = บรรทัดเล็ก · ว่าง = เส้นประ
   ============================================================ */
#saiBody .dt { display: grid; gap: 8px; margin: 2px 0 6px; }
#saiBody .dt-r { display: grid; grid-template-columns: 52px minmax(0, 1fr); align-items: start; gap: 10px;
  animation: sd-in .45s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--n, 0) * 35ms); }
#saiBody .dt-t { padding-top: 11px; text-align: right; font-size: 15px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
#saiBody .dt-c {
  display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; min-height: 48px; padding: 9px 12px;
  border: 0; border-radius: 16px; text-align: left; font: inherit; color: var(--ink);
  background: var(--card); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent), 0 6px 14px -12px rgba(0,0,0,.35);
}
#saiBody button.dt-c { cursor: pointer; }
#saiBody button.dt-c:active { transform: scale(.985); }
#saiBody .dt-x { flex: 1; min-width: 0; }
#saiBody .dt-x b { display: block; font-size: 14.5px; font-weight: 700; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
#saiBody .dt-x i { display: block; margin-top: 1px; font-style: normal; font-size: 12.5px; color: var(--muted); }
#saiBody .dt-c > svg { width: 16px; height: 16px; flex: none; color: var(--muted); }
/* งานที่การ์ดบนบอกให้ทำ */
#saiBody .dt-job.hot .dt-c {
  background: color-mix(in srgb, var(--fill) 14%, var(--card));
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--fill) 55%, transparent), 0 8px 18px -12px color-mix(in srgb, var(--fill) 70%, transparent);
}
#saiBody .dt-job.hot .dt-t { color: color-mix(in srgb, var(--fill) 60%, var(--ink)); }
#saiBody .dt-tag { flex: none; padding: 3px 9px; border-radius: 999px; font-style: normal; font-size: 12px; font-weight: 800;
  color: var(--on-fill); background: var(--fill); }
/* เรียน · กิจวัตร — ของที่ถูกกำหนดมาแล้ว ไม่ใช่สิ่งที่ต้องตัดสินใจ */
#saiBody .dt-busy .dt-c { min-height: 42px; background: color-mix(in srgb, var(--ink) 5%, transparent); box-shadow: none; }
#saiBody .dt-busy .dt-x b { font-weight: 600; color: color-mix(in srgb, var(--ink) 75%, transparent); }
#saiBody .dt-busy .dt-t { font-weight: 600; color: var(--muted); }
/* กิจกรรมที่ต้องไปให้ทัน */
#saiBody .dt-ev .dt-c { box-shadow: inset 3px 0 0 var(--pri-yellow-text), 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent); border-radius: 4px 16px 16px 4px; }
/* พัก · ตื่น · นอน — บรรทัดเล็ก */
#saiBody .dt-line .dt-t { padding-top: 0; font-size: 13px; font-weight: 600; color: var(--muted); }
#saiBody .dt-l { font-size: 13px; font-weight: 600; color: var(--muted); }
/* ว่าง — เส้นประบาง ๆ ระหว่างแถว */
#saiBody .dt-gap { display: flex; align-items: center; gap: 8px; margin: -1px 0 -1px 62px; font-size: 12px; font-weight: 600; color: var(--muted); }
#saiBody .dt-gap::after { content: ''; flex: 1; border-top: 1.5px dashed color-mix(in srgb, var(--ink) 16%, transparent); }
/* ตอนนี้ */
#saiBody .dt-now { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 10px; align-items: center; margin: 2px 0; }
#saiBody .dt-now span { justify-self: end; display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px 3px 7px; border-radius: 99px;
  font-size: 12px; font-weight: 800; color: #fff; background: var(--alert); }
#saiBody .dt-now span em { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: sd-blink 1.6s ease-in-out infinite; }
#saiBody .dt-now i { height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--alert), color-mix(in srgb, var(--alert) 10%, transparent)); }
:root[data-theme="astral"] #saiBody .dt-now span { color: #111; }
:root[data-theme="astral"] #saiBody .dt-now span em { background: #111; }
#saiBody .dt .past { opacity: .5; }
@media (prefers-reduced-motion: reduce) { #saiBody .dt-r { animation: none; } }
:root[data-quality="low"] #saiBody .dt-r { animation: none; }

/* ============================================================
   แคปซูลนาฬิกา .run-timer (แบบ Timer ของ Cult UI · MIT · nolly-studio/cult-ui) · 20 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของแปะตัวอย่าง Timer ของ Cult UI มา: "หน้าไหนที่ควรใช้ ลองเอาไปปรับใช้ดู"
   ใช้สามที่ที่โชว์ "เวลาที่เดินอยู่": แถบจับเวลาเหนือเมนู · การ์ดบนของจอแผน · แถวงานในตารางทั้งวัน
   ต้นฉบับ: แคปซูล rounded-full · ไอคอนนาฬิกา · ตัวเลข font-mono tabular-nums · variant ตามพื้นที่วาง
   ปรับ: หมุนแค่เข็ม (transform ล้วน · 4 วิ/รอบ) · หยุดหมุนใน data-lite / ลดการเคลื่อนไหว
   ============================================================ */
.run-timer {
  display: inline-flex; align-items: center; gap: 6px; flex: none; height: 30px; padding: 0 11px 0 8px;
  border-radius: 999px; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.run-timer svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.run-timer .rt-hand { transform-box: view-box; transform-origin: 12px 12px; animation: rt-sweep 4s linear infinite; }
@keyframes rt-sweep { to { transform: rotate(360deg); } }
.run-timer .rt-n { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 15px; font-weight: 700; letter-spacing: -.02em; min-width: 4ch; }
:root[data-lite] .run-timer .rt-hand { animation: none; }
@media (prefers-reduced-motion: reduce) { .run-timer .rt-hand { animation: none; } }

/* แถบจับเวลา (พื้นเขียว --good ตัวขาว) — variant "outline" บนพื้นสี */
.runbar .rb-timer { color: #fff; background: rgba(255,255,255,.2); box-shadow: inset 0 0 0 1px rgba(255,255,255,.28); }
.runbar .rb-k { display: block; font-style: normal; font-size: 11.5px; font-weight: 600; opacity: .9; }
.runbar .rb-tt { font-size: 14px; }

/* การ์ดบนของจอแผน (พื้น --fill ตัว --on-fill) */
#saiBody .sn-timer { justify-self: start; margin-bottom: 4px; height: 28px; color: var(--on-fill); background: color-mix(in srgb, var(--on-fill) 16%, transparent); }
#saiBody .sn-timer .rt-n { font-size: 14px; }

/* แถวงานในตารางทั้งวัน (พื้น --card) */
#saiBody .dt-timer { height: 28px; color: color-mix(in srgb, var(--fill) 60%, var(--ink)); background: color-mix(in srgb, var(--fill) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 30%, transparent); }
#saiBody .dt-timer .rt-n { font-size: 13.5px; }
/* แถบจับเวลา: ตัวขาวบน --good อ่านไม่ออกใน 9 ธีม (วัด 20 ต.ค. 69 · ของเดิมก่อนรอบนี้)
   astral 2.4 · dark 1.7 · deepocean 1.8 · galaxy 1.5 · glitch 1.4 · magic 1.7 · meta 1.7 · space 1.8 · sweet 3.8 — ต้อง ≥ 4.5
   ธีมเหล่านี้ --good เป็นเขียวสว่าง → ตัวเขียวเข้มเกือบดำแทน (ได้ ≥ 4.9 ทุกธีม) · ธีมที่ --good เข้มอยู่แล้ว (light earth ocean …) คงตัวขาว */
:root:is([data-theme="astral"], [data-theme="dark"], [data-theme="deepocean"], [data-theme="galaxy"], [data-theme="glitch"], [data-theme="magic"], [data-theme="meta"], [data-theme="space"], [data-theme="sweet"]) .runbar { color: #04130E; }
:root:is([data-theme="astral"], [data-theme="dark"], [data-theme="deepocean"], [data-theme="galaxy"], [data-theme="glitch"], [data-theme="magic"], [data-theme="meta"], [data-theme="space"], [data-theme="sweet"]) .runbar :is(.rb-stop, .rb-timer) {
  color: #04130E; background: rgba(0,0,0,.12); box-shadow: inset 0 0 0 1px rgba(0,0,0,.14);
}
:root:is([data-theme="astral"], [data-theme="dark"], [data-theme="deepocean"], [data-theme="galaxy"], [data-theme="glitch"], [data-theme="magic"], [data-theme="meta"], [data-theme="space"], [data-theme="sweet"]) .runbar .rb-k { opacity: 1; }

/* ============================================================
   หน้าแรก › แถบ "เลยเวลาทำงานแล้ว" (.dc-line.td-night) · 20 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: การ์ดหมดเวลาของคืนนี้ยาวเกินและอ่านเหมือนเครื่องเขียน — ให้เหลือบรรทัดเดียว
   เดิมเป็นการ์ด .td-note สูง 139px ดันหน้าแรกเป็น 909 จาก 803 (หน้าแรกห้ามต้องเลื่อน)
   ตอนนี้ยืมหน้าตาบรรทัด "วันนี้" (.dc-line) ทั้งก้อน แล้วบีบให้เตี้ยลงอีกนิด:
   ข้อความ "ว่างอีกที 06:00 พรุ่งนี้" ยาวกว่า "ไปเรียน" มาก — ที่ 375px ต้องลดช่องไฟ/ตัวอักษร
   ไม่งั้นโดนตัดท้าย · ไม่ใช่สีทอง (ทองใช้เฉพาะของที่ทำเสร็จแล้ว) */
.dc-line.td-night { gap: 7px; padding: 3px 4px 3px 5px; font-size: 12.5px; }
.dc-line.td-night .dc-ic { width: 22px; height: 22px; }
.dc-line.td-night .dc-tx small { font-size: 12px; }
.dc-line.td-night > i { padding: 3px 10px; font-size: 12px; }

/* ============================================================
   แผ่นแตะแถวงานในเส้นเวลาจอแผน (#planRowSheet) · 20 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ (ขอปรับหน้าแผนวันนี้ให้ใช้ง่ายขึ้น): แตะงานในเส้นเวลาแล้วอยากเริ่ม/ติ๊กเสร็จ/เลื่อนได้เลย
   ไม่ใช่เด้งไปฟอร์มแก้ไข
   ยืมโครง .add-sheet/.as-scrim/.as-card จาก today.css ทั้งก้อน (เหมือน #soonSheet) — ของใหม่มีแค่เนื้อใน
   แถวไอคอน+ข้อความใช้ grid ไม่ใช่ flex (<span> ที่เป็น flex item ใน alt/ กว้างศูนย์)
   ปุ่มหลักพื้น --fill ตัว --on-fill · ปุ่มอื่นพื้น --card2 ตัว --ink · "เสร็จแล้ว" ไม่ใช่สีทอง (ทองใช้เฉพาะของที่เสร็จจริงแล้ว) */
.prs-card { padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
.prs-h { display: grid; gap: 2px; margin: 2px 4px 12px; text-align: left; }
.prs-h b {
  font-size: 17px; font-weight: 800; line-height: 1.35; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.prs-h i { font-style: normal; font-size: 13px; font-weight: 600; color: var(--muted); }
.prs-list { display: grid; gap: 8px; }
.prs-b {
  display: grid; grid-template-columns: 22px minmax(0, 1fr); align-items: center; gap: 12px;
  width: 100%; min-height: 50px; box-sizing: border-box; padding: 8px 16px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card2); color: var(--ink);
  font-family: inherit; font-size: 15px; font-weight: 700; text-align: left; cursor: pointer;
}
.prs-b svg { width: 20px; height: 20px; }
.prs-b:active { transform: scale(.98); }
.prs-b.primary { border-color: transparent; background: var(--fill); color: var(--on-fill); }
.prs-b.quiet { border-color: transparent; background: none; color: var(--muted); font-weight: 600; }
/* ============================================================
   ความชัดของตัวหนังสือ/ไอคอนทั้งแอป · รอบ 1 · 24 ต.ค. 69
   ------------------------------------------------------------
   เจ้าของ: "แก้ความชัดฟอนต์ทั้งแอปและทุกธีม" · วัดด้วย textcheck ครบ 22 ธีม (เพิ่มการวัดไอคอนแล้ว)
   ต้นเหตุใหญ่: โทเคนตัวหนังสือของธีมพื้นสว่างจางเกินบนพื้นรอง --card2 (ชิป · กล่อง) — แก้ที่โทเคน
   ลดแค่ความสว่าง (OKLCH) จนได้ ≥ 4.8:1 บน --card2 และ --scr · สีเดิม เข้มขึ้นนิดเดียว
   ============================================================ */
:root[data-theme="light"]{--faint:#586B86}
:root[data-theme="warm"]{--faint:#855B6D;--blue:#BC2C6A;--alert:#C3293E;--warn:#865F00}
:root[data-theme="earth"]{--muted:#556B60;--faint:#576B60;--blue:#167456;--warn:#865F00}
:root[data-theme="earth2"]{--muted:#516D58;--faint:#546C59;--blue:#247339;--warn:#865F00}
:root[data-theme="ocean"]{--muted:#45687C;--faint:#486879;--blue:#056A8E;--alert:#B83023;--good:#007068;--warn:#845C00}
:root[data-theme="sweet"]{--muted:#79598E;--faint:#79598B;--blue:#A22DBD;--alert:#BA2A69;--good:#007365;--warn:#8C5B00}
:root[data-theme="genesis"]{--alert:#AF254D;--good:#00695F;--warn:#7D5500}
/* ส่วนประกอบที่พังทุกธีม (ต้นเหตุยืนยันแล้ว) */
#ctxBody .cx2-axis { color: var(--muted); }                       /* เดิม --ink 50% โปร่ง = 3.0–4.2 ใน 14 ธีม */
.stp-v i { color: var(--muted); }                                 /* เดิม --ink 60% โปร่ง · light เคยแก้แยกไว้ธีมเดียว */
.td-now .tn-why-go svg:last-child { opacity: 1; }                 /* ลูกศรจาง .55 = 1.8:1 ใน 15 ธีม */
.tk-skin .ts-try, .tk-skin.r-mythic .ts-rar { color: color-mix(in srgb, #B45CFF 62%, var(--ink)); } /* ม่วงฝังตายบนขาว 2.9 */
.ig-tick { color: color-mix(in srgb, var(--blue) 60%, var(--ink)); } /* ฟ้าบนพื้นฟ้าจาง 3.3 */
/* "+100" ชิปรางวัล: ไล่สี --grad-brand + ตัวขาวฝังตาย = 2.0–2.2 ใน 13 ธีม → คู่ --fill/--on-fill ที่ DESIGN.md รับประกัน */
#scr-profile .pf-entry .pe-v.pe-reward:not(:empty), .phone .pe .pe-v.pe-reward:not(:empty) { background: var(--fill); color: var(--on-fill); }
/* ไฟ "ต่อเนื่อง": เปลวขาวบนส้มอ่อน #FB923C (2.2) + หรี่ .84 → ส้มเข้มขึ้น ขาวได้ ≥ 3 แม้ตอนหรี่ */
.shw-streak .shw-ic { background: linear-gradient(160deg, #C2410C, #9A3412); }
/* "เพิ่ม" ใต้ปุ่ม + นั่งบนวงแสงของปุ่ม (2.9 ใน 14 ธีม) — ป้ายอื่นในแถบผ่าน · เข้มขึ้นเฉพาะป้ายนี้ */
.tabbar .tab.scan > span:not(.scan-dot) { color: color-mix(in srgb, var(--muted) 45%, var(--ink)); }

/* 26 ต.ค. 69 · เรือนลับแล "จันทร์หยก" — รางวัลชวนเพื่อน (แยกสิทธิ์จากธีมบอสฮาโลวีน)
   เจ้าของปฏิเสธสามแนวก่อนหน้า (เขียวหมึกเดิม · ผีไทยหลอนจัด · เวกเตอร์วาดเอง) แล้วส่งภาพวาดฉากเรือนไทยกลางสระใต้จันทร์เสี้ยวมาเอง
   ฉากจึงเป็นภาพนั้นทั้งภาพ (jade-moon.webp) ไม่มีผี ไม่มีลายบัว/เครื่องราง/กรอบทอง — ลายเซ็นคือจันทร์หยกกับโคมลอย
   การ์ดเป็นกระจกเขียวเข้ม (--tg-glass) ให้ภาพไม่ถูกตัดเป็นท่อน · หัวการ์ดหลักเขียวป่าลึกทึบ เป็นก้อนทึบก้อนเดียวของหน้าแรก (1B28)
   สีระดับความสำคัญไม่แตะ · ทองไม่ใช้ตกแต่ง (สงวนให้ของที่ทำสำเร็จ) */
:root[data-theme="thai-ghost"]{
 color-scheme:dark;
 --scr:#0A1F18;--card:#0E271E;--card2:#163428;--surface:#163428;
 --ink:#EEF6EC;--muted:#B9D3C0;--faint:#A9C8B3;--line:#D8E8C933;
 --fill:#D8E8C9;--on-fill:#123A2B;--fill-on:#123A2B;--on-accent:#123A2B;
 --blue:#BFE3C9;--blue-deep:#D8E8C9;--blue-soft:#1F4A37;--neon:#BFE3C9;
 --alert:#FFADB8;--alert-soft:#FFADB81A;--warn:#F4CF85;--warn-soft:#F4CF851A;
 --good:#ACD5B6;--good-soft:#ACD5B61A;--fire:#FFADB8;
 --gold-text:#E1C38A;--gold-soft:#E1C38A22;
 --tint:#1F4A37;--tint2:#24503D;--glass:#0A1F18D9;--glass-line:#D8E8C933;
 --pg:#0A1F18;--pg-ink:#EEF6EC;--pg-muted:#B9D3C0;--frame:#0A1F18;
 --soft-card:#0E271EF2;--soft-shadow:0 8px 24px #00080455;--soft-shadow-lg:0 16px 40px #00080477;
 --shadow:0 8px 24px #00080455;--shadow-lg:0 20px 50px #00080477;--shadow-brand:0 8px 24px #5FB08A22;
 --grad-brand:linear-gradient(140deg,#247454,#174E39);--grad-hero:linear-gradient(140deg,#1C5A42,#0E271E);
 --tile-plan:#1C4635;--tile-tasks:#1A3F31;--tile-route:#24503D;--tile-me:#213F33;--tile-on:#EEF6EC;
 --tg-glass:#0B2219D1;--tg-forest:#174E39;--tg-moon:#D8E8C9;--tg-edge:#D8E8C92B;
}
.sw-thai-ghost{background:radial-gradient(circle at 72% 26%,#D8E8C9 0 13%,transparent 14%),linear-gradient(170deg,#163A2E,#0A1F18 55%,#1E5A44);box-shadow:inset 0 0 0 1px #D8E8C955}
:root[data-theme="thai-ghost"] .phone{isolation:isolate;background:var(--scr)}
:root[data-theme="thai-ghost"] :is(.fx,.starfield){display:none!important}
:root[data-theme="thai-ghost"] .screens{position:relative;z-index:1;background:transparent}
:root[data-theme="thai-ghost"] .screen{background:transparent}
:root[data-theme="thai-ghost"] .brand-light{display:none}
:root[data-theme="thai-ghost"] .brand-dark{display:block}

/* ---------- ฉาก: ภาพวาด + ม่านอ่านง่าย + โคมลอย/หมอก/แสงหน้าต่างที่ขยับ ---------- */
.tg-scene{position:absolute;inset:0;z-index:0;isolation:isolate;overflow:hidden;pointer-events:none;background:#0A1F18}
.tg-scene[hidden]{display:none!important}
/* ภาพสูง 852×1847 (สัดส่วนเท่าจอมือถือ) — ยึดขอบล่างไว้ เรือนกับสระจึงอยู่ตำแหน่งเดิมทุกความสูงจอ */
.tg-art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 100%}
.tg-veil{position:absolute;inset:0;background:linear-gradient(#04110C66,#04110C14 28%,#04110C2E 62%,#04110C70)}
.tg-mist{position:absolute;left:-12%;right:-12%;bottom:24%;height:16%;background:radial-gradient(ellipse at 40% 60%,#CFE6D633,transparent 62%),radial-gradient(ellipse at 78% 40%,#CFE6D626,transparent 55%);animation:tg-mist 22s ease-in-out infinite alternate}
.tg-mist.far{bottom:36%;height:12%;opacity:.7;animation-duration:19s;animation-direction:alternate-reverse}
.tg-glow{position:absolute;left:44%;top:63%;width:46%;height:10%;background:radial-gradient(ellipse,#FFC46A2E,transparent 68%);animation:tg-glow 6.5s ease-in-out infinite alternate}
.tg-lanterns i{position:absolute;left:var(--x);top:var(--y);width:var(--w);height:calc(var(--w)*1.3);border-radius:35% 35% 28% 28%/40% 40% 22% 22%;
 background:radial-gradient(ellipse at 50% 72%,#FFF0C4,#F6B45A 55%,#C2662A);box-shadow:0 0 calc(var(--w)*1.3) calc(var(--w)*.35) #F6B25A55;opacity:.85;
 animation:tg-lantern var(--d) ease-in-out var(--o) infinite alternate}
@keyframes tg-mist{from{transform:translate3d(-8px,0,0)}to{transform:translate3d(8px,0,0)}}
@keyframes tg-glow{from{opacity:.55}to{opacity:1}}
@keyframes tg-lantern{from{transform:translate3d(0,8px,0);opacity:.65}to{transform:translate3d(3px,-8px,0);opacity:.95}}
.tg-scene.tg-still *{animation:none!important}
@media (prefers-reduced-motion: reduce){:root[data-theme="thai-ghost"]:not([data-tg-motion="full"]) .tg-scene *{animation:none!important}
 :root[data-theme="thai-ghost"] body .screen.on{animation:none!important}
 :root[data-theme="thai-ghost"] :is(.tn-cta,.tg-t .tg-ic){transition:none!important}}

/* ---------- การ์ด: กระจกเขียวเข้ม · ทึบพอให้ตัวรอง ≥ 4.5 แม้ทับจุดสว่างที่สุดของภาพ ---------- */
:root[data-theme="thai-ghost"] :is(.card,.td-now,.td-clear,.set-card,.pf-me,.shw,.saih,.t-card,.ts-card,.tp-card,.tb-row,.fd-post,.ai-panel,.r-card,.qn-card,.cls-card){
 background:var(--tg-glass);border:1px solid var(--tg-edge);border-radius:18px;box-shadow:0 8px 24px #00080455;color:var(--ink);
 -webkit-backdrop-filter:blur(10px) saturate(1.1);backdrop-filter:blur(10px) saturate(1.1)}
:root[data-theme="thai-ghost"] .set-card .set-row{background:transparent;border:0;border-radius:0;box-shadow:none}
:root[data-theme="thai-ghost"] .set-card .set-row+.set-row{border-top:1px solid #D8E8C922}
:root[data-theme="thai-ghost"] :is(.tabbar,.topbar,.as-card){background:var(--glass)!important;border-color:var(--tg-edge)!important;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
:root[data-theme="thai-ghost"] .tabbar .tab.active:not(.scan){background:var(--tg-moon)!important;color:var(--on-fill)!important;box-shadow:none!important}
/* เครื่องอ่อน/โหมดประหยัด: เบลอหลังกระจกแพง → ทึบแทน */
:root[data-theme="thai-ghost"]:is([data-lite="1"],[data-quality="low"]) :is(.card,.td-now,.td-clear,.set-card,.pf-me,.shw,.saih,.t-card,.ts-card,.tp-card,.tb-row,.fd-post,.ai-panel,.r-card,.qn-card,.cls-card,.tabbar,.topbar,.as-card,#menuBody .tg-ic,#menuBody .td-ask){backdrop-filter:none!important;-webkit-backdrop-filter:none!important;background:#0E271EF5!important}
/* ตัวหนังสือที่วางบนภาพตรง ๆ (หัวข้อหมวด · ชื่อจอ · ป้ายใต้ไอคอน) ได้เงาเข้มรองไว้ */
:root[data-theme="thai-ghost"] :is(.page-title,.big-title,.sh-title,.th-greet,.set-hd,.td-sec,.sec-h,.tg-l){color:var(--ink);text-shadow:0 1px 10px #04110CE6,0 0 2px #04110C}
:root[data-theme="thai-ghost"] :is(input,textarea,select){background:#0A1F18A6;color:var(--ink);border-color:#D8E8C933}
:root[data-theme="thai-ghost"] #scr-tasks :is(.wk-card,.wk-d,.tb-focus){background:var(--tg-glass)!important;color:var(--ink)!important;border-color:var(--tg-edge)!important}
/* 31 ต.ค. 69 · เจ้าของ (ภาพการ์ด "ควรทำก่อน" จองาน): "ตรงปุ่มเริ่มทำปรับให้ชัดหน่อย" — ธีมอื่นการ์ดเป็นสีเน้น ปุ่มเป็น --card สีตรงข้าม เด่นออกมา
   แต่กฎบนเปลี่ยนการ์ดเป็นกระจกเขียวเข้ม ปุ่ม --card (#0E271E) เลยสีเดียวกับการ์ด เหลือแค่ตัวหนังสือลอย ๆ
   → ปุ่มสูตรเดียวกับ "เริ่มทำ" หน้าแรกของธีมนี้ (.tn-cta): พื้นจันทร์ ตัวหนังสือเขียวป่าเข้ม */
:root[data-theme="thai-ghost"] #scr-tasks .tb-focus .tb-fc-go{background:var(--tg-moon);color:var(--on-fill);font-weight:700;box-shadow:0 4px 16px #00000040,inset 0 1px 0 #FFFFFF80}
/* 26 ต.ค. 69 · เจ้าของ (ภาพช่อง "26 ต.ค." จอสัปดาห์): "ทำให้เป็นสีที่มองเห็นได้" — ช่องวันนี้ใช้ตัวหนังสือ --on-fill (เขียวเข้ม ทำไว้วางบนพื้นจันทร์)
   แต่กฎบนเปลี่ยนพื้นทุกช่องเป็นกระจกเขียวเข้ม (และ --grad-brand ของธีมนี้ก็เขียวเข้ม) = เข้มบนเข้ม มองไม่เห็น
   → ช่องวันนี้เป็นพื้นจันทร์หยก สัญญาณ "ตอนนี้/ที่เลือก" ชุดเดียวกับแท็บที่เลือกและปุ่มเริ่ม · ตัวหนังสือเข้มบนจันทร์ ≈ 9:1 */
:root[data-theme="thai-ghost"] #scr-tasks .wk-row.now .wk-d{background:var(--tg-moon)!important;border-color:transparent!important;box-shadow:0 0 0 3px #D8E8C924,0 6px 16px -8px #D8E8C9AA!important}
:root[data-theme="thai-ghost"] #scr-tasks .wk-row.now .wk-d :is(b,i){color:var(--on-fill)!important}
/* 26 ต.ค. 69 · เจ้าของ (ภาพแถบ "เลยเวลาทำงานแล้ว · ว่างอีกที 06:00 พรุ่งนี้ [ขยายเวลา]"): "ปรับให้เห็นได้ชัดกว่านี้"
   แถบ .dc-line ผสมทุกสีจาก --fill ซึ่งธีมนี้เป็นจันทร์ซีด → พื้นเขียวเข้มทึบบนภาพเข้ม · ขอบ 20% · ปุ่ม "ขยายเวลา" จันทร์ 15% = ก้อนเทา
   → ขอบจันทร์ชัด + เส้นสะท้อนบน ให้แยกจากฉาก · นาฬิกาเป็นสีเตือน (--warn อำพัน — สีสถานะ "เลยเวลา" ไม่ใช่ทองตกแต่ง)
   · ข้อความรองสว่างขึ้น · "ขยายเวลา" เป็นแคปซูลจันทร์ทึบ ตัวเข้ม (ดูออกว่ากดได้) · ความสูงเท่าเดิม (หน้าแรกห้ามต้องเลื่อน) */
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night{background:#0B2219F2!important;border-color:#D8E8C966!important;box-shadow:inset 0 1px 0 #FFFFFF1F,0 0 0 1px #00000040,0 8px 20px -10px #000000AA}
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night .dc-ic{background:color-mix(in srgb,var(--warn) 22%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--warn) 45%,transparent)}
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night .dc-ic svg{color:var(--warn)}
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night .dc-tx b{color:#FFFFFF}
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night .dc-tx small{color:#DCEBDD;font-weight:600}
:root[data-theme="thai-ghost"] #menuBody .dc-line.td-night > i{background:var(--tg-moon);color:var(--on-fill);font-weight:800;box-shadow:inset 0 1px 0 #FFFFFFB3,0 2px 8px -2px #00000066}
:root[data-theme="thai-ghost"] #themePick button:not(.active){background:var(--card)!important;color:var(--muted);border-color:var(--line)!important}
:root[data-theme="thai-ghost"] #themePick button.active{background:var(--blue-soft)!important;color:var(--ink);border-color:var(--tg-moon)!important}
:root[data-theme="thai-ghost"] .runbar,:root[data-theme="thai-ghost"] .runbar :is(.rb-timer,.rb-stop){color:var(--on-fill)}

/* ---------- หัวการ์ด "ควรทำอะไร": เขียวป่าลึกทึบ + แสงหยกมุมขวาบนแบบนิ่ง ---------- */
:root[data-theme="thai-ghost"] #menuBody .td-now{border-radius:24px;overflow:hidden}
:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head{background:radial-gradient(circle at 96% 0%,#5FB08A45,transparent 48%),#174E39!important;border-bottom:1px solid #D8E8C926}
:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head::before,:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head::after{display:none}
:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head :is(.tn-title,.tk-t){color:#FFFFFF}
:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head :is(.tn-eyebrow,.tn-why2){color:#D8E8C9!important}
:root[data-theme="thai-ghost"] #menuBody .td-now .tk-line{color:#D8E8C9;opacity:.6}
:root[data-theme="thai-ghost"] #menuBody .td-now .tk-line i{background:#174E39;color:#FFFFFF}
:root[data-theme="thai-ghost"] #menuBody .tn-body{background:transparent;border-color:var(--line)}
:root[data-theme="thai-ghost"] #menuBody .tn-cta{background:var(--tg-moon)!important;color:var(--on-fill)!important;border:0!important;box-shadow:0 4px 16px #00000040!important;transition:transform .12s ease}
:root[data-theme="thai-ghost"] #menuBody .tn-cta .tc-main{background:none;box-shadow:none;border:0;color:inherit}
:root[data-theme="thai-ghost"] #menuBody .tn-ib{background:var(--tg-glass);border:1px solid #D8E8C933;color:var(--tg-moon)}
:root[data-theme="thai-ghost"] #menuBody :is(.tn-route .tk-t){color:#FFFFFF}
/* 26 ต.ค. 69 · เจ้าของ (ภาพหัวการ์ด "ยังไม่มีคิว · ใช้เวลา 40 นาที" แทบมองไม่เห็น): "ปรับตรงนี้หน่อย"
   บรรทัดเส้นทางมีสองแบบ: มีเวลา (.tk-t — ตั้งขาวไว้แล้ว) กับยังไม่มีคิว (.tk-solo — ตกหล่น ได้ --on-fill เขียวเข้มบนหัวเขียวป่า)
   → จันทร์หยกแบบเดียวกับชื่อวิชา/คะแนนบนหัวเดียวกัน (≥ 4.5 บน #174E39 ตามเทสต์ธีม) · ทึบเต็ม ไม่ใช้ opacity .9 เดิม */
:root[data-theme="thai-ghost"] #menuBody .td-now .tn-head .tn-route .tk-solo{color:#D8E8C9!important;opacity:1;font-weight:700}
:root[data-theme="thai-ghost"] #menuBody .td-ask{background:var(--tg-glass)!important;border-color:var(--tg-edge)!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
:root[data-theme="thai-ghost"] .td-ask::before,:root[data-theme="thai-ghost"] .td-ask::after{display:none}
:root[data-theme="thai-ghost"] .td-ask .tk-in{background:transparent}

/* ---------- ไอคอนหน้าแรก: กระจกเดียวกับการ์ด · วงในเขียวป่า ไอคอนสีจันทร์ ---------- */
:root[data-theme="thai-ghost"] #menuBody .tg-ic{background:var(--tg-glass)!important;border:1px solid var(--tg-edge)!important;border-radius:18px!important;box-shadow:none!important;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:transform .12s ease}
:root[data-theme="thai-ghost"] #menuBody .tg-ic svg{background:#174E39!important;color:var(--tg-moon)!important;box-shadow:none!important}

/* ---------- ท่า: เปลี่ยนจอ 8px + จาง 250ms · กดย่อ .98 ---------- */
:root[data-theme="thai-ghost"] body:not([data-godir="lat"]) .screen.on{animation:tg-page .25s cubic-bezier(.22,1,.36,1) both}
@keyframes tg-page{from{opacity:0;transform:translate3d(0,8px,0)}to{opacity:1;transform:none}}
:root[data-theme="thai-ghost"] #menuBody :is(.tn-cta:active,.tg-t:active .tg-ic){transform:scale(.98)}

/* ---------- ปุ่มเสียงบนหัวหน้าแรก ---------- */
:root[data-theme="thai-ghost"] .tg-sound-quick{flex:none;width:32px;min-width:32px;padding:5px;color:var(--tg-moon);border:1px solid var(--line);border-radius:50%;background:#0A1F1899}
:root[data-theme="thai-ghost"] .tg-sound-quick[aria-pressed="true"]{background:var(--tg-moon);color:var(--on-fill);box-shadow:0 0 12px #D8E8C933}
@media(max-width:599px){:root[data-theme="thai-ghost"] .td-top .tt-rank b{display:none}}
@media(max-width:359px){:root[data-theme="thai-ghost"] .td-top{gap:2px}:root[data-theme="thai-ghost"] .td-top .tt-chip:not(.tg-sound-quick){padding-inline:5px;gap:3px}}
.tg-sound-quick[hidden],.tg-preferences[hidden]{display:none!important}

.iv-theme-preview{width:calc(100% - 20px);max-width:440px;height:calc(100dvh - 20px);max-height:900px;margin:auto;padding:0;overflow:hidden;border:1px solid #BDA47166;border-radius:20px;background:#0B1817;color:#F0EAD5}
.iv-theme-preview::backdrop{background:#020A07CC}
.iv-theme-preview header{display:flex;gap:10px;align-items:center;justify-content:space-between;min-height:58px;padding:10px 14px;background:#11251F}
.iv-theme-preview header small{display:block;color:#C2CFBA;font-size:11px;margin-top:3px}
.iv-theme-preview header button{flex-shrink:0;background:#223B33;color:#F0EAD5;border:1px solid #BDA47166;border-radius:10px;min-width:40px;min-height:40px}
.iv-theme-preview[open]{display:flex;flex-direction:column}
.iv-theme-preview header{flex-shrink:0}
.iv-preview-body{position:relative;flex:1;min-height:0;overflow:hidden}
.iv-theme-preview iframe{display:block;position:absolute;left:50%;top:50%;width:375px;height:812px;max-width:none;border:0;background:#0B1817;transform:translate(-50%,-50%) scale(var(--iv-preview-scale,1))}
.hq-thai-note{font-size:12px;color:var(--muted);line-height:1.8}

/* หมวดสะสมใช้ปุ่มเดิมทั้งหมด ไม่เผยชื่อ/จำนวนธีมลับที่ยังซ่อนอยู่ */
#themePick.th-catalog{display:flex;flex-direction:column;gap:19px;width:100%;min-width:0}
.th-rarity{display:block;width:100%;min-width:0;padding-top:2px}
.th-rarity[hidden]{display:none!important}
.th-rarity h3{display:flex;align-items:center;justify-content:space-between;gap:8px;border-left:3px solid var(--rarity-color);padding:3px 0 3px 9px;margin:0 0 9px;color:var(--ink);font-size:13px;font-weight:800;line-height:1.5}
.th-rarity h3 small{font-size:11px;color:var(--muted);font-weight:600}
.th-rarity h3 em{font-size:10px;font-weight:500;font-style:normal;color:var(--muted);white-space:nowrap}
.th-rarity>.th-grid{width:100%;margin:0;min-width:0}
.th-rarity>.th-grid>button{min-width:0}
.th-rarity[data-rarity="limited"]{padding:12px;border:1px solid color-mix(in srgb,var(--rarity-color) 48%,transparent);border-radius:18px 5px 18px 5px;background:color-mix(in srgb,var(--rarity-color) 7%,var(--card))}
.th-rarity[data-rarity="limited"] h3{border-left:0;padding-left:0}

/* แผงเสียง/ภาพในหน้าธีม */
.tg-preferences{display:grid;gap:13px;margin-top:22px;padding:17px 15px;border:1px solid #D8E8C944;border-radius:18px;background:linear-gradient(150deg,#174E39,#0E271E);color:#EEF6EC}
.tg-pref-title{display:flex;gap:12px;align-items:center}
.tg-pref-title>svg{width:42px;height:34px;color:#D8E8C9;flex:none}
.tg-pref-title b{font-size:14px}
.tg-pref-title small,.tg-motion small{display:block;font-size:11px;color:#C9DECF;margin-top:4px}
.tg-preferences button{padding:11px 15px;border:1px solid #D8E8C966;border-radius:12px;background:#D8E8C9;color:#123A2B;font:inherit;font-size:13px;font-weight:700;min-height:42px}
.tg-volume{display:grid;gap:7px;font-size:12px;color:#C9DECF}
.tg-volume input{width:100%;accent-color:#D8E8C9;min-height:28px}
.tg-motion{display:flex;justify-content:space-between;align-items:center;gap:15px;font-size:13px}
.tg-motion input{width:22px;height:22px;accent-color:#D8E8C9;flex:none}
.tg-audio-hint{margin:0;color:#C9DECF;font-size:11px;line-height:1.6}
.tg-audio-hint:empty{display:none}
@keyframes tg-haunt{0%{transform:translate3d(4px,10px,0);opacity:.22}55%{transform:translate3d(-24px,-10px,0);opacity:.55}100%{transform:translate3d(-44px,2px,0);opacity:.32}}
@keyframes tg-haunt-far{from{transform:translate3d(-20px,6px,0);opacity:.12}to{transform:translate3d(22px,-11px,0);opacity:.37}}
@keyframes tg-talisman{from{transform:rotate(-5deg)}to{transform:rotate(6deg)}}
@keyframes tg-breath{from{transform:scale(.9);opacity:.3}to{transform:scale(1.12);opacity:.8}}
@keyframes tg-window{0%{opacity:.35}40%{opacity:.7}100%{opacity:.45}}
@media(prefers-reduced-motion:reduce){:root:not([data-tg-motion="full"]) .tg-scene *{animation:none!important}}

/* ============================================================
   ปฏิทินเดือน · การ์ด + ช่องวันตรงคอลัมน์ — 26 ต.ค. 69
   เจ้าของ (ภาพจอปฏิทินบนจอกว้าง ธีม Halloween): "แก้ให้หน่อยให้มันดูสวยกว่านี้"
   ที่เห็นในภาพ: ① ปฏิทินลอยบนฉากตรง ๆ ไม่มีพื้น ตัวเลขแย่งที่กับภาพฉาก
     ② ชื่อวัน (อา จ อ…) ไม่ตรงเลขวัน — ช่องวัน aspect-ratio: 1 + max-height 58px ทำให้กว้างแค่ 58px ด้วย
        แล้วชิดซ้ายในคอลัมน์ที่กว้าง 200px+ ส่วนชื่อวันอยู่กลางคอลัมน์ (บนมือถือไม่เห็นเพราะคอลัมน์กว้าง ~48px พอดี)
     ③ วันที่เลือกเป็นกล่องเปล่าห้อยใต้วงกลมวันนี้ · ④ ยืดเต็มจอกว้าง วันห่างกันเกินไป
   แก้: ห่อเดือนด้วยการ์ดกระจก (calHtml ใน app.js เพิ่ม .cal-card) · ช่องวันเต็มคอลัมน์ สูงคงที่ ไม่ใช่จัตุรัส
     · วันที่เลือกย้อมสีธีม · กว้างสุด 760px อยู่กลางจอ · แผ่นรายละเอียดของวันเป็นการ์ดคู่กัน
   ============================================================ */
.cal-card {
  max-width: 760px; margin: 4px auto 0; padding: 12px 12px 10px; border-radius: 22px;
  background: color-mix(in srgb, var(--soft-card, var(--card)) 88%, transparent);
  border: 1px solid var(--glass-line, var(--line));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 10%, transparent), 0 12px 30px -18px rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%);
}
.cal-card .calbar { margin: 0 0 8px; }
.cal-card .calbar b { font-size: 16px; font-weight: 700; }
.cal-card .calbar button {
  background: color-mix(in srgb, var(--fill) 12%, transparent); color: color-mix(in srgb, var(--fill) 65%, var(--ink));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 30%, transparent);
}
.cal-card .calwd { margin-bottom: 6px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.cal-card .calwd span { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.cal-card .calwd span:is(:first-child, :last-child) { color: color-mix(in srgb, var(--fill) 55%, var(--muted)); }
.cal-card .calgrid { gap: 3px; }
.cal-card .cal-c { width: 100%; aspect-ratio: auto; height: 52px; max-height: none; border-radius: 12px; }
@media (hover: hover) { .cal-card .cal-c:not(.off):hover { background: color-mix(in srgb, var(--ink) 6%, transparent); } }
.cal-card .cal-c.on {
  background: color-mix(in srgb, var(--fill) 14%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fill) 55%, transparent);
}
.cal-card .cal-c.big.on { box-shadow: inset 0 0 0 1.5px var(--sj); }
.cal-card .cal-c.today b { box-shadow: 0 0 12px -2px color-mix(in srgb, var(--fill) 80%, transparent); }
/* แผ่นของวันที่เลือก = การ์ดคู่กับปฏิทิน (เดิมเป็นเส้นคั่นบนพื้นฉาก) */
.cal-card + .cal-day {
  max-width: 760px; margin: 12px auto 0; padding: 12px 14px; border-top: none; border-radius: 20px;
  background: color-mix(in srgb, var(--soft-card, var(--card)) 88%, transparent);
  border: 1px solid var(--glass-line, var(--line));
  -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%);
}
:root[data-lite] :is(.cal-card, .cal-card + .cal-day) { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--card); }

/* ============================================================
   ไม่ให้ของขาดหรือล้นจอ — 26 ต.ค. 69 · เจ้าของ: "ทำให้ปุ่มหรืออะไรก็ตามอยู่เต็มหน้าจอเสมอ และไม่ขาด ทั้งแอปเลย"
   ตรวจด้วย devtools/fitcheck.mjs (16 จอ × 8 ขนาด 320–1600px) · ที่เจอแล้วแก้ที่นี่:
   ============================================================ */
/* ไทม์ไลน์รายวัน · แถว "ถึงกำหนด · ชื่องาน" เป็น inline-flex ไม่มีขอบเขต ชื่องานยาวพุ่งพ้นจอ 62px ทุกขนาด
   → กว้างไม่เกินคอลัมน์ ตัดบรรทัดได้ (เห็นชื่อครบ ไม่ใช่ตัด "…" เพราะเป็นชื่องานที่ต้องรู้ว่าอะไรถึงกำหนด) */
.dayrow-due { display: flex; align-items: flex-start; max-width: 100%; overflow-wrap: anywhere; line-height: 1.4; }
.dayrow-due svg { flex: none; margin-top: 2px; }
/* ชื่อเหรียญตรา (ตัดสองบรรทัดพร้อม "…" อยู่แล้ว) — "คุณจะเลิกทำการบ้านไหม?" ทั้งก้อนกว้างกว่าช่อง 4px ที่ 600px
   จัดกลางจึงโดนตัดข้างละ 2px · overflow-wrap: anywhere ไม่ช่วย (เบราว์เซอร์ไม่นับว่าก้อนนี้ล้น) · ช่องเหลือ padding 6px แล้ว
   ตัวอักษร 11px คือขั้นต่ำที่อ่านได้ → ยอมให้ตัดบรรทัดกลางคำเฉพาะชื่อเหรียญ (ไม่ตัดกลางสระ/วรรณยุกต์ · ยังตัด 2 บรรทัดเหมือนเดิม) */
.ab-nm { word-break: break-all; }

/* ============================================================
   จองาน · อ่านง่ายขึ้น + แถบค้นหาใต้สวิตช์โหมด + ปุ่มเสร็จมีขอบ — 26 ต.ค. 69
   เจ้าของ (ภาพรายการงาน ธีม Halloween): "ปรับให้ฟอนต์สีชัดกว่านี้ · ปุ่มค้นหาไปอยู่ข้างงานทั้งหมด · ปุ่มเสร็จงานให้มีขอบ"
   ① ชื่อวิชา (.tk-sub) กับเวลาที่ใช้ (.tk-min) เป็น --muted 11px น้ำหนักปกติ — บนการ์ดมืดจางจนต้องเพ่ง
      → หมึกหลัก 78% หนาขึ้น ใหญ่ขึ้นนิด · ดาวความสำคัญโตตาม (ยังเล็กกว่าชื่อวิชา)
   ② ช่องค้นหาเคยอยู่ท้ายรายการ → แถบค้นหาใต้สวิตช์ วันนี้/สัปดาห์/รายการ เหนือการ์ดใบแรก (เจ้าของชี้ตำแหน่งในภาพ)
      เคยลองเป็นปุ่มแว่นข้างชื่อจอ แต่บนจอกว้างปุ่มทับชื่อจอ และต้องกดก่อนถึงจะเห็นช่อง
   ③ วงติ๊กเสร็จ: ขอบ 1.5px สี --line (โปร่ง 26% ในธีมมืด) แทบหายไปบนการ์ด → ขอบ 2px สีธีมผสมหมึก
      ยังเป็นวงกลวง (ยังไม่เสร็จ) · ติ๊กแล้วใช้สีเขียวเดิม (.on) ไม่แตะ
   ============================================================ */
.phone #scr-tasks .tk-sub { font-size: 12px; font-weight: 600; color: color-mix(in srgb, var(--ink) 78%, transparent); }
.phone #scr-tasks .tk-sub .tk-pri { font-size: 11px; }
.phone #scr-tasks .tk-min { font-size: 12px; font-weight: 600; color: color-mix(in srgb, var(--ink) 78%, transparent); }

#scr-tasks .page-head + .tk-search { margin: 0 0 12px; }
/* ช่องค้นหา: เดิมพื้น --card2 ไม่มีขอบ บนฉากมืด = กล่องมืดบนพื้นมืด · คำว่า "ค้นหางาน" กับแว่นเป็น --faint
   → ขอบสีธีม (เงาใน ไม่ดันผัง) · แว่นสีธีม · คำแนะนำในช่องเป็นหมึก 70% · กดแล้วยังได้วงโฟกัสเดิม */
.phone #scr-tasks .tk-search {
  background: var(--card);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fill) 55%, transparent), 0 8px 20px -14px rgba(0,0,0,.6);
}
.phone #scr-tasks .tk-search > svg { width: 19px; height: 19px; color: color-mix(in srgb, var(--fill) 80%, var(--ink)); stroke-width: 2.4; }
.phone #scr-tasks .tk-search input { font-weight: 600; }
.phone #scr-tasks .tk-search input::placeholder { color: color-mix(in srgb, var(--ink) 70%, transparent); font-weight: 500; }
.phone #scr-tasks .tk-search:focus-within { outline: 2px solid var(--fill); outline-offset: -2px; }
/* ช่องพิมพ์ข้างในมีวงโฟกัสของตัวเอง (สีรองของธีม) ซ้อนในวงสีธีมของกรอบ — เห็นเป็นกล่องสองชั้น · กรอบบอกโฟกัสแล้ว */
.phone #scr-tasks .tk-search input:focus { outline: none; }
/* สวิตช์โหมดอยู่ต่อตอนค้นหา (ไม่มีช่องไหนถูกเลือก) — ปุ่มที่ถูกเลือกสูงกว่าปุ่มปกติ 2px แล้วดึงทั้งแถวให้สูงตาม
   พิมพ์ตัวแรกแถวเลยเตี้ยลง แถบค้นหาข้างล่างขยับขึ้นใต้นิ้ว → ล็อกความสูงปุ่มเท่ากันทุกสถานะ */
#scr-tasks .tk-modes .tk-mode { min-height: 32px; }

.phone #scr-tasks .tk-tick:not(.on) {
  border: 2px solid color-mix(in srgb, var(--fill) 65%, var(--ink));
  background: color-mix(in srgb, var(--fill) 8%, transparent);
}
@media (hover: hover) { .phone #scr-tasks .tk-tick:not(.on):hover { background: color-mix(in srgb, var(--fill) 18%, transparent); } }

/* ============================================================
   การ์ดงาน · ตกแต่ง + ตัวหนังสือเด่นขึ้น — 26 ต.ค. 69
   เจ้าของ (ภาพรายการงาน ธีม Halloween): "ตกแต่งสักหน่อยให้มันสวยกว่านี้ ฟอนต์สีเด่นขึ้นมาหน่อย"
   ① เปลือกการ์ดแบบ Halo (cult-ui · MIT — ชุดเดียวกับช่องถามน้องฮูก/แถบโหลดที่แอปพอร์ตไว้แล้ว):
      ขอบสะท้อนบน 1px + เส้นขอบบาง + เงาสัมผัส + เงาฟุ้ง · พื้นยังเป็นกระจกเดิม (backdrop-filter ไม่แตะ)
   ② แสงมุมซ้ายบนสีวิชา — ไอเดีย Spotlight Card (React Bits · MIT + Commons Clause) แต่ตายตัว ไม่ตามนิ้ว
      (ไม่มีงานต่อเฟรม เครื่องช้าไม่สะดุด) · สีวิชาเป็น "ป้ายชื่อ" ตามกติกาหัวไฟล์ (.sj-*) ไม่ใช่สีความด่วน
      จึงแค่ฟุ้งจาง ๆ ที่มุม ไม่ย้อมทั้งใบ — แดงของวิชาคณิตต้องไม่ถูกอ่านว่า "ด่วน"
   ③ ตัวหนังสือ: ชื่องาน 16px หนา หมึกเต็ม · ชื่อวิชามีจุดสีวิชานำหน้า ตัวหนังสือผสมสีวิชากับหมึก (อ่านได้ทั้งธีมมืด/สว่าง)
      · เวลาที่ใช้เป็นแคปซูลมีไอคอนนาฬิกา · ชิปสถานะหนาขึ้นและมีวงขอบสีของตัวเอง
   ④ ปุ่ม "เสร็จแล้ว · N งาน" ท้ายรายการ = เปลือกเดียวกับการ์ด ไอคอนเขียว (เขียว = เสร็จ ตามกติกาสีสถานะ)
   ============================================================ */
.phone #scr-tasks .tk.sw-card {
  background:
    radial-gradient(130% 110% at 0% 0%, color-mix(in srgb, var(--sj) 17%, transparent), transparent 52%),
    linear-gradient(180deg, color-mix(in srgb, #fff 5%, transparent), transparent 42%),
    color-mix(in srgb, var(--card) 93%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 10%, transparent),
    inset 0 0 0 1px color-mix(in srgb, var(--sj) 20%, var(--glass-line, var(--line))),
    0 1px 2px rgba(0, 0, 0, .22),
    0 16px 32px -18px rgba(0, 0, 0, .65);
}
.phone #scr-tasks .tk.sw-card .tk-ttl { font-size: 16px; font-weight: 700; color: var(--ink); letter-spacing: -.01em; margin-top: 2px; }
.phone #scr-tasks .tk.sw-card .tk-sub {
  display: flex; align-items: center; gap: 6px;
  color: color-mix(in srgb, var(--sj) 45%, var(--ink)); font-weight: 700;
}
.phone #scr-tasks .tk.sw-card .tk-sub .sjdot { width: 8px; height: 8px; box-shadow: 0 0 8px -1px var(--sj); }
.phone #scr-tasks .tk.sw-card .tk-sub .tk-pri { margin-left: 2px; }
.tk-min svg { width: 13px; height: 13px; flex: none; }
.phone #scr-tasks .tk.sw-card .tk-min {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 999px;
  color: color-mix(in srgb, var(--ink) 88%, transparent);
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 12%, transparent);
}
.phone #scr-tasks .tk.sw-card .tk-chip { font-weight: 700; font-size: 11.5px; }
.phone #scr-tasks .tk.sw-card .tk-chip.hot  { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--alert) 45%, transparent); border-color: transparent; }
.phone #scr-tasks .tk.sw-card .tk-chip.warm { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 45%, transparent); border-color: transparent; }
.phone #scr-tasks .tk.sw-card .tk-chip.warn { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--pri-yellow-text, var(--warn)) 40%, transparent); border-color: transparent; }
.phone #scr-tasks .tk.sw-card .tk-chip.good,
.phone #scr-tasks .tk.sw-card .tk-chip.ok   { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--good) 45%, transparent); border-color: transparent; }

.phone #scr-tasks .bin-btn {
  font-weight: 700; color: color-mix(in srgb, var(--ink) 88%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, #fff 5%, transparent), transparent 50%),
    color-mix(in srgb, var(--card) 90%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 9%, transparent), inset 0 0 0 1px var(--glass-line, var(--line)), 0 10px 24px -16px rgba(0, 0, 0, .6);
}
.phone #scr-tasks .bin-btn svg { width: 17px; height: 17px; }
.phone #scr-tasks .bin-btn.bin-done svg { color: var(--good); }

/* ============================================================
   ปุ่ม "ลองเล่นดู" ของเอฟเฟกต์งานเสร็จ — 26 ต.ค. 69
   เจ้าของ (ภาพจอเลือกเอฟเฟกต์ ธีม Halloween): "ปรับให้ปุ่มลองเล่นดูน่าสนใจกว่านี้ ใช้สีที่มองเห็นชัดเจน"
   เดิม (hoop.css): พื้นโปร่ง ขอบเส้นประ ตัวหนังสือสีรองบาง ๆ — หน้าตาเหมือนช่องว่างให้วางของ ไม่ใช่ปุ่ม
   ตอนนี้: ปุ่มทึบสีธีม (--fill + --on-fill ชุดเดียวกับปุ่มหลักทั้งแอป จึงอ่านชัดทุกธีม) · ไอคอนเล่น ▶ วาดด้วย clip-path
   · เปลือกแบบ Halo (cult-ui · MIT: ขอบสะท้อนบน + เงาฟุ้งสีธีม) · แถบแสงวาบพาดผ่านเป็นจังหวะ แบบปุ่ม shine ของ Uiverse (MIT)
   แสงวาบขยับด้วย transform อย่างเดียว · วิ่ง 0.9 วิ แล้วพัก ~3 วิ (ชวนกด ไม่กระพริบรบกวน)
   โหมดลื่นหยุด · ลดการเคลื่อนไหวไม่มีแสงวาบ
   ============================================================ */
.phone .fx-try {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 46px; margin-top: 12px; border: 0; border-radius: 14px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 55%),
    var(--fill);
  color: var(--on-fill, #fff);
  font-size: 15px; font-weight: 800; letter-spacing: .01em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 10px 22px -10px color-mix(in srgb, var(--fill) 80%, transparent);
  transition: transform .16s cubic-bezier(.23, 1, .32, 1), box-shadow .2s ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.phone .fx-try::before {
  content: ""; flex: none; width: 13px; height: 14px; margin-left: 2px;
  background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); border-radius: 2px;
}
.phone .fx-try::after {
  content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: 0; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: translateX(-120%) skewX(-18deg);
  animation: fx-try-shine 4s cubic-bezier(.45, 0, .2, 1) 1s infinite;
}
@keyframes fx-try-shine {
  0% { transform: translateX(-120%) skewX(-18deg); }
  22%, 100% { transform: translateX(330%) skewX(-18deg); }
}
.phone .fx-try:active { transform: scale(.97); }
@media (hover: hover) { .phone .fx-try:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 14px 28px -10px color-mix(in srgb, var(--fill) 90%, transparent); } }
.phone .fx-try:focus-visible { outline: 2px solid var(--fill); outline-offset: 3px; }
:root[data-lite] .phone .fx-try::after { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) { .phone .fx-try::after { animation: none; opacity: 0; } .phone .fx-try { transition: none; } }

/* ============================================================
   เส้นเวลา "ที่เหลือของวันนี้" (จอน้องฮูก · sai.js .dt) · ตกแต่ง — 26 ต.ค. 69
   เจ้าของ (ภาพ ธีมสว่าง): "ปรับตรงนี้หน่อย มันยังไม่ค่อยสวย"
   คงของที่เจ้าของเคาะไว้: เวลาตัวหนาคอลัมน์ซ้ายเด่นสุด · ไม่มีรางเส้นตั้ง · ปุ่มเล่าไม่มีดาว (9 ต.ค.)
   ① การ์ดงาน = เปลือกแบบ Halo (cult-ui · MIT — ชุดเดียวกับการ์ดจองาน): ขอบสะท้อนบน + เส้นขอบบาง + เงาฟุ้ง
      + จุดสีวิชาหน้าบรรทัดรอง (sai.js ใส่ .sj-* · ดูก็รู้ว่าวิชาไหน เหมือนการ์ดจองาน)
   ② ตื่น · นอน · พัก: เดิมตัวหนังสือเทาลอย ๆ ขนาดไม่เข้ากับเวลาตัวหนาข้างบน → แคปซูลจางมีไอคอน ☀ ☾ ☕
      เวลาของแถวพวกนี้กลับมาขนาดเดียวกับแถวงาน (จางกว่า) แถวเวลาจึงเรียงเป็นคอลัมน์เดียวกันทั้งราง
   ③ "ตอนนี้": แคปซูลแดงมีวงเรืองจาง ๆ · เส้นจางลงเร็วขึ้น (เดิมเส้นแดงยาวเต็มจอแย่งสายตากับงานถัดไป)
   ④ "ให้น้องฮูกเล่าให้ฟังทีละข้อ": เดิมตัวหนังสือขีดเส้นใต้แบบลิงก์เว็บ → แคปซูลโปร่งสีธีม (ยังเบากว่าปุ่มหลัก)
   ============================================================ */
#saiBody .dt-c {
  background:
    linear-gradient(180deg, color-mix(in srgb, #fff 9%, transparent), transparent 46%),
    color-mix(in srgb, var(--card) 94%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 18%, transparent),
    0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent),
    0 1px 2px rgba(0, 0, 0, .08),
    0 12px 26px -16px rgba(0, 0, 0, .45);
}
#saiBody .dt-job .dt-x i { font-weight: 600; color: color-mix(in srgb, var(--ink) 70%, transparent); }
/* จุดเป็น inline ไม่ใช่ flex — บรรทัดรองยาวตัดลงบรรทัดสอง จุดต้องอยู่หน้าบรรทัดแรก ไม่ลอยกลางสองบรรทัด */
#saiBody .dt-job .dt-x i .sjdot { display: inline-block; width: 7px; height: 7px; margin-right: 6px; vertical-align: 1px; box-shadow: 0 0 6px -1px var(--sj); }
#saiBody .dt-job.hot .dt-c {
  background:
    linear-gradient(180deg, color-mix(in srgb, #fff 12%, transparent), transparent 46%),
    color-mix(in srgb, var(--fill) 15%, var(--card));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 22%, transparent),
    0 0 0 1.5px color-mix(in srgb, var(--fill) 60%, transparent),
    0 12px 26px -12px color-mix(in srgb, var(--fill) 65%, transparent);
}
#saiBody .dt-tag { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 4px 10px -4px color-mix(in srgb, var(--fill) 80%, transparent); padding: 4px 11px; }

#saiBody .dt-line { align-items: center; }
#saiBody .dt-line .dt-t { padding-top: 0; font-size: 15px; font-weight: 700; color: color-mix(in srgb, var(--ink) 55%, transparent); }
#saiBody .dt-l {
  justify-self: start; display: inline-flex; align-items: center; gap: 7px; padding: 6px 13px 6px 10px; border-radius: 999px;
  font-size: 13.5px; font-weight: 700; color: color-mix(in srgb, var(--ink) 78%, transparent);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent);
}
#saiBody .dt-l svg { width: 15px; height: 15px; flex: none; color: color-mix(in srgb, var(--fill) 70%, var(--ink)); }
#saiBody .dt-sleep .dt-l svg { color: color-mix(in srgb, #8B7CF6 75%, var(--ink)); }
#saiBody .dt-wake .dt-l svg { color: color-mix(in srgb, #F2A93B 80%, var(--ink)); }

/* แคปซูล "ตอนนี้" กว้างกว่าคอลัมน์เวลา 52px เลยยื่นออกซ้ายเลยแนวเวลา → คอลัมน์ 58px ทั้งราง + แคปซูลกระชับลง */
#saiBody :is(.dt-r, .dt-now) { grid-template-columns: 58px minmax(0, 1fr); }
#saiBody .dt-gap { margin-left: 68px; }
#saiBody .dt-now span { padding: 3px 8px 3px 6px; gap: 4px; }
#saiBody .dt-now span { box-shadow: 0 0 0 3px color-mix(in srgb, var(--alert) 18%, transparent), 0 4px 12px -4px color-mix(in srgb, var(--alert) 70%, transparent); }
#saiBody .dt-now i { height: 2px; background: linear-gradient(90deg, var(--alert), color-mix(in srgb, var(--alert) 35%, transparent) 35%, transparent 85%); }

#saiBody .sai-tour {
  display: flex !important; align-items: center; justify-content: center; gap: 6px;
  width: fit-content; margin: 8px auto 4px; padding: 10px 18px; border-radius: 999px;
  text-decoration: none !important;
  color: color-mix(in srgb, var(--fill) 60%, var(--ink)) !important;
  background: color-mix(in srgb, var(--fill) 9%, transparent) !important;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 38%, transparent) !important;
}
#saiBody .sai-tour::after {
  content: ""; width: 7px; height: 7px; margin-left: 2px; border: solid currentColor; border-width: 2px 2px 0 0;
  transform: rotate(45deg); border-radius: 1px;
}
#saiBody .sai-tour:active { transform: scale(.97); background: color-mix(in srgb, var(--fill) 16%, transparent) !important; }

/* 30 ต.ค. 69 · หน้าตรวจตารางที่สแกน — ตารางที่มีแค่รหัสวิชา บอกใต้ช่องว่าแอปจะเรียกว่าอะไร
   สีเดียวกับป้ายสัปดาห์ (ข้อมูลที่แอปเติมให้ ไม่ใช่ของที่อ่านจากรูป) */
.tt-subhint:empty { display: none; }
.tt-subhint { font-size: 11.5px; font-weight: 600; color: var(--blue); margin-top: -2px; }
/* จอบริบท · รหัสวิชาเป็นบรรทัดเล็กใต้ชื่อ — เป็นป้ายข้างชื่อแล้วชนชื่อยาว ๆ ที่ 375px */
.ctx-per b small { display: block; font-size: 10.5px; font-weight: 400; color: var(--faint); line-height: 1.3; }

/* ---------- ร้านค้าแบบแท็บ + เติมโทเคน (30 ต.ค. 69) ----------
   แท็บยืม .tk-modes/.tk-mode ของจองานทั้งชุด — ตัวที่เลือกเป็นน้ำเงินทึบเหมือนกันทั้งแอป
   ปุ่ม "เติม" อยู่บนการ์ดยอด เป็นจุดน้ำเงินจุดเดียวในการ์ด (เหรียญทองยังเป็นพระเอก)
   แผ่นเติมยืม .soon-card (แผ่นเร็ว ๆ นี้) · ข้างในปุ่มแพ็กใช้ grid ไม่ใช่ flex
   (span ที่เป็น flex item ใน alt/ กว้าง 0 — ดูความจำ flex-span-zero-width) */
.sh-tabs { margin: 4px 0 12px; }
.tk-topup {
  margin-left: auto; align-self: center;
  display: inline-grid; grid-auto-flow: column; align-items: center; gap: 4px;
  padding: 8px 13px 8px 10px; border: 0; border-radius: 12px; cursor: pointer;
  background: var(--fill); color: var(--on-fill);
  font-family: inherit; font-size: 13.5px; font-weight: 700;
}
.tk-topup svg { width: 16px; height: 16px; }
.tk-topup:active { transform: scale(.96); }
.tu-card { text-align: left; }
.tu-card .soon-t { text-align: center; }
.tu-has { margin: 0 0 14px; text-align: center; font-size: 13px; color: var(--muted); }
.tu-has b { color: var(--ink); font-weight: 700; }
.tu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-bottom: 14px; }
.tu-pack {
  position: relative; display: grid; justify-items: center; gap: 3px;
  padding: 13px 8px 11px; border: 1.5px solid var(--line); border-radius: 14px; cursor: pointer;
  background: var(--card); color: var(--ink); font-family: inherit;
}
.tu-pack.on { border-color: var(--fill); background: var(--blue-soft); }
.tu-pack:active { transform: scale(.97); }
.tu-n { display: inline-grid; grid-auto-flow: column; align-items: center; gap: 5px; }
.tu-n b { font-size: 19px; font-weight: 700; }
.tu-p { font-size: 13px; font-weight: 600; color: var(--muted); }
.tu-pack.on .tu-p { color: var(--ink); }
.tu-b {
  position: absolute; top: -8px; right: 8px;
  padding: 2px 7px; border-radius: 999px;
  background: var(--fill); color: var(--on-fill); font-size: 10.5px; font-weight: 700;
}
.tu-note { margin: 10px 2px 0; font-size: 11.5px; line-height: 1.5; color: var(--faint); text-align: center; }
.tu-test { margin: 6px 0 0; font-size: 11.5px; font-weight: 700; color: var(--alert); text-align: center; }
