/* ============================================================
   StudentOS AI — จอ "วันนี้" + โหมดโฟกัส + แผ่นเพิ่มงาน
   ============================================================
   แยกไฟล์จาก alt.css เพราะเป็นของใหม่ทั้งก้อน ไม่ใช่การแก้ของเดิม
   ถอยกลับหน้าแรกแบบเก่า = เอา <link> บรรทัดเดียวออก ไม่ต้องคุ้ยไฟล์ 300 KB
   ห้ามใส่สี hex ตรง ๆ ใช้ token เท่านั้น ไม่งั้นธีมเขียว/ม่วงจะได้ปุ่มสีน้ำเงินติดมาด้วย

   กฎเดียวที่คุมทั้งไฟล์: **ห้ามมีของสองชิ้นบนจอนี้ที่ขนาดเท่ากัน**
   ขนาดคือวิธีที่จอบอกว่าอะไรสำคัญกว่า — การ์ดเท่ากันเรียงลงมาคือ dashboard
   และ dashboard แปลว่า "อ่านเองนะว่าอันไหนสำคัญ" ซึ่งเป็นงานที่แอปนี้รับปากว่าจะทำแทน

     NOW    ชื่องาน 26px     การ์ดใบเดียวในจอ + ปุ่มทึบสีเน้นปุ่มเดียวในจอ
     NEXT   ชื่องาน 13px     แถวเปล่า มีแค่เส้นสีวิชา
     LATER  ชื่องาน 13px     แถวเดียวกัน ต่างที่หัวข้อกำกับ
     แผน    12.5px           รางเวลาเส้นบาง ไม่มีกรอบการ์ด
     แจ้งเตือน 12.5px        พื้นเรียบ ไม่มีสี — เป็นการรายงาน ไม่ใช่คำตอบ
   ============================================================ */

/* ---------- หัวจอ ---------- */
/* สามส่วนบรรทัดเดียว: รูปฉัน · คำทักทาย+เวลาที่มีจริง · กระดิ่ง
   เดิมรูปฉันอยู่ขวาคู่กับคำทักทายที่ชิดซ้าย ทำให้หัวจอมีสองจุดที่สายตาต้องแวะ
   ซ้ายสุดคือที่ที่สายตาเริ่มอ่านอยู่แล้ว วางรูปไว้ตรงนั้นจึงได้จุดแวะเดียว
   และเหลือมุมขวาว่างให้กระดิ่งซึ่งเป็นของที่ "มีก็ต่อเมื่อมีอะไรเข้ามา" */
.td-head {
  display: flex; align-items: center; gap: 11px; padding-top: 2px;
}
.th-me {
  flex: none; width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--blue-soft); color: var(--blue);
  font: inherit; font-size: 17px; font-weight: 700; cursor: pointer;
}
.th-me svg { width: 17px; height: 17px; }
/* วงกลมนี้ใส่รูปแล้ว — ต้องตัดขอบเป็นวงกลมจริงและไม่มีระยะขอบใน ไม่งั้นรูปจะโผล่เป็นสี่เหลี่ยม */
.th-me { padding: 0; overflow: hidden; }
.th-face { width: 100%; height: 100%; display: block; object-fit: cover; }
/* ตราแอปวาดมาสำหรับพื้นขาว วางบนพื้นน้ำเงินจางแล้วจมหายไปครึ่งอัน — เหตุผลเดียวกับ
   .login-plate ที่หน้าล็อกอิน · และต้อง contain ไม่ใช่ cover เพราะตราไม่ได้เต็มกรอบ
   ถ้า cover มันจะถูกซูมจนขอบตราหายออกนอกวงกลม */
.th-brand { background: #fff; object-fit: contain; padding: 3px; }
.th-tx { flex: 1; min-width: 0; }
/* คำทักทายต้องเล็กกว่าชื่องานอย่างเห็นได้ชัด
   24px ข้าง 26px คืออ่านเป็นสองหัวข้อที่สำคัญเท่ากัน — แต่คำทักทายไม่ใช่ข้อมูล
   มันคือมารยาท · ของที่ใหญ่ที่สุดในจอต้องเป็นคำตอบเสมอ */
.th-greet {
  margin: 0; font-size: 16.5px; line-height: 1.3; font-weight: 700; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* บรรทัดรองคือตัวเลข ไม่ใช่คำพูด — "เหลือเวลาว่าง 2 ชม. 30 นาที · 5 งานค้าง"
   เคยลองทำเป็นการ์ดสถิติสามช่องแล้ว ได้สองปัญหาพร้อมกัน: มันแย่งสายตากับการ์ดโฟกัสทันที
   และตัวเลขเวลาต้องย่อจนเหลือ "3ช" ซึ่งไม่มีใครอ่านออก */
/* 1C40 · เจ้าของ: "คำนี้ทำให้ดูชัดขึ้นหน่อย" — เดิม 12.5px น้ำหนักปกติ สีรอง (--muted)
   บนธีมมืดที่มีฉากหลังเคลื่อนไหวมันจางจนกลืน · ตอนนี้เข้มเกือบเท่าตัวหลัก หนาขึ้น ใหญ่ขึ้นครึ่ง px
   แต่ยังเล็กกว่าคำทักทาย (16.5px หนา 700) ลำดับความสำคัญเลยไม่เปลี่ยน
   ไม่ใหญ่กว่า 13px: ประโยคยาวสุด ("12 รายการรออยู่ — ไม่มีงานที่ต้องเจียดเวลา") พอดีกล่องเป๊ะที่ 375px
   13.5px ล้น 3px แล้วโดนตัดเป็น "…" */
.th-sub {
  margin: 3px 0 0; font-size: 13px; line-height: 1.45; font-weight: 600;
  color: color-mix(in srgb, var(--ink) 80%, transparent);
}
.th-bell {
  position: relative; flex: none; width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; background: none;
  color: var(--muted); cursor: pointer;
}
.th-bell:active { background: var(--card2); }
.th-bell svg { width: 20px; height: 20px; }
/* จุดแดงบอกว่ามีของรอตรวจในกล่องเข้า — ไม่ใส่ตัวเลข เพราะตัวเลขบนหัวจอเรียกร้องให้เคลียร์
   ส่วนหน้านี้มีหน้าที่เดียวคือพาไปลงมือทำงานที่สำคัญที่สุด ไม่ใช่พาไปเคลียร์กล่อง */
.th-dot {
  position: absolute; top: 7px; right: 8px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pri-red); border: 2px solid var(--scr);
}

/* ---------- NOW ---------- */
/* การ์ดใบเดียวในจอที่มี "พื้นของตัวเอง" — ที่เหลือทั้งหมดเป็นแถวบนพื้นจอ
   ขนาดตัวอักษรอย่างเดียวยังแพ้การกวาดตาเร็ว ๆ · สิ่งที่ตาจับได้ก่อนคือ "ก้อนสีที่ต่างจากพื้น"
   จึงเก็บสิทธิ์นั้นไว้ให้คำตอบใบเดียว ถ้ามีก้อนที่สองเมื่อไหร่ แปลว่ายังไม่ได้ตัดสินใจแทนผู้ใช้

   ไล่สีทำจาก token ล้วน (--blue-soft จางลงหาย ทับบน --card) ไม่ได้ฝัง hex น้ำเงินไว้
   ธีมส้ม/เขียว/ม่วงจึงได้ไล่สีของตัวเองอัตโนมัติ ไม่ใช่การ์ดสีน้ำเงินติดมาทุกธีม

   ลำดับสายตาในการ์ดมี 5 จุด และห้ามเกินนี้:
     1  แถวบน      ไอคอนเป้า + ป้ายคำตัดสิน   "ใบนี้คือใบที่เลือกมา และมันด่วนแค่ไหน"
     2  ชื่องาน     23px หนา                  คำตอบ
     3  สองช่อง     เริ่มกี่โมง · ใช้เวลาเท่าไหร่  ตัวเลขล้วน ไม่มีประโยค
     4  ปุ่ม        พื้นทึบสีเน้นปุ่มเดียวในจอ
     5  ท้ายการ์ด   ความคืบหน้า + ทางเลือกรอง
   ============================================================ */
.td-now {
  position: relative; margin-top: 14px; padding: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: calc(var(--r-card) + 6px);
  background: var(--card); box-shadow: var(--shadow-lg);
}
.td-now.running { border-color: var(--blue); }

/* ---- 1B28: หัวตั๋วสีทึบ — ก้อนสีเดียวของทั้งจอ ---- */
.tn-head { background: var(--fill); color: var(--on-fill); padding: 13px 15px 15px; }
.tn-body { padding: 12px 14px 13px; }
/* ทุกอย่างในหัวสืบสีจาก --on-fill ไม่ใช่ --ink · ถ้าลืมตัวใดตัวหนึ่งจะได้ตัวหนังสือ
   สีเข้มบนพื้นน้ำเงินเข้ม ซึ่งอ่านไม่ออกเฉพาะบางธีมและมองข้ามได้ง่ายมากตอนเทส */
/* ความจาง .78 ย้ายจาก opacity มาอยู่ในค่าสีแทน — opacity ตกทอดถึงลูกทุกตัวและลูกลบทิ้งไม่ได้
   ตราวงกลมขาวที่อยู่ข้างในจึงกลายเป็นขาวขุ่น 78% ทั้งที่มันต้องทึบถึงจะเรียกว่า "จุดเด่น"
   หัวตั๋วเป็นสีทึบพร้อมตัวหนังสือขาวเสมอทุกโทน ใช้ค่าขาวโปร่งตรง ๆ ได้ปลอดภัย */
.td-now .tn-eyebrow { color: rgba(255,255,255,.8); opacity: 1; font-weight: 700;
  letter-spacing: .04em; margin-top: 0; flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 8px; }
/* ตราวงกลมขาวบนหัวตั๋ว — ของที่การ์ดใบเก่ามีแล้วหายไปตอนเปลี่ยนเป็นตั๋ว
   หัวตั๋วเปลี่ยนสีตามความด่วน (แดง/เหลือง/เขียว) ไอคอนจึงเป็นกรมท่าคงที่ ไม่ใช่สีน้ำเงิน
   ไม่งั้นบนหัวสีแดงจะได้ไอคอนน้ำเงินบนขาว ซึ่งเป็นสีที่ไม่เกี่ยวกับอะไรบนจอเลย */
.td-now .tn-mark { flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: #fff; color: #16306B; display: grid; place-items: center; opacity: 1; }
.td-now .tn-mark svg { width: 14px; height: 14px; stroke-width: 2.2; }
/* 1B39 · 22 → 25px · จอนี้มีคำสั่งเดียว มันจึงเป็นตัวหนังสือที่ใหญ่ที่สุดบนจอได้
   ไม่มีหัวข้ออื่นแข่งแล้วตั้งแต่ก้อน "เสี่ยงพัง" ถูกถอดออก */
.td-now .tn-title { color: var(--on-fill); font-size: 25px; line-height: 1.2;
  letter-spacing: -.028em; margin: 6px 0 0; }
/* ============================================================
   โทเคนสัญญาณ (signal) — สีทึบที่ไม่พลิกตามธีม
   ============================================================
   ระบบสีของแอปมีสองตระกูลที่ห้ามเอามาปนกัน:

     --pri-*-soft / --pri-*-text   พลิกตามธีม · ใช้คู่กันเสมอ (พื้นอ่อน + ตัวอักษรเข้ม)
                                   สำหรับป้ายที่วางอยู่บน "พื้นการ์ด" ซึ่งพลิกตามธีมเหมือนกัน
     --sig-*                       ไม่พลิกตามธีม · เป็นพื้นทึบที่มีตัวอักษรขาวทับเสมอ
                                   สำหรับของที่วางบนพื้นซึ่งไม่พลิกตามธีม (หัวตั๋วน้ำเงิน)
                                   หรือของที่ต้องดังเท่ากันทุกธีม (แบดจ์เตือน)

   ปนกันเมื่อไหร่ = พังธีมใดธีมหนึ่งเสมอ และพังแบบไม่มี error ให้เห็น:
   --pri-red-text ในธีมมืดคือ #FF9AA6 (ชมพูอ่อนสำหรับพื้นเข้ม) เอาไปเป็นพื้นของแบดจ์
   ที่มีตัวอักษรขาว จะได้ชมพูซีดที่อ่านแทบไม่ออก — เคยเกิดสองที่ ทั้งป้ายด่วนบนหัวตั๋ว
   (วัดได้ 2.01:1) และแบดจ์บนไทล์ · ทั้งคู่ต้องใช้ --sig-* เท่านั้น
   ค่าที่เลือกไว้ให้ตัวอักษรขาวผ่าน AA ทั้งชุด: แดง 4.8 · ส้ม 5.9 · เขียว 6.3 */
:root {
  --sig-red:   #D92D20;
  --sig-amber: #B54708;
  --sig-green: #0B6E3F;
}

/* ---- ป้ายความด่วนบนหัวตั๋ว: พื้นทึบสีเต็ม ตัวอักษรขาว ----
   เคยเป็นพื้นขาว + ตัวอักษรสีจาก --pri-*-text ซึ่งพังเงียบ ๆ:
   ตัวแปรพวกนั้น "พลิกตามธีม" เพราะถูกออกแบบมาให้วางบนพื้นการ์ด — ธีมมืดมันคือ
   #FF9AA6 (ชมพูอ่อนสำหรับพื้นเข้ม) เอามาวางบนพื้นขาวได้คอนทราสต์ 2.01:1
   ซึ่งต่ำกว่าทุกเกณฑ์ · ป้ายเลยดูซีดจนแทบหายไปทั้งที่มันคือสัญญาณด่วนที่สุดบนจอ

   กฎที่ได้จากบั๊กนี้: พื้นที่ "ไม่พลิกตามธีม" (หัวตั๋วเป็นน้ำเงินเดียวกันทุกธีม)
   ต้องจับคู่กับสีตัวอักษรที่ไม่พลิกตามธีมด้วย — ผสมกันเมื่อไหร่คือพังธีมใดธีมหนึ่งเสมอ
   สามสีนี้จึงเป็นค่าคงที่โดยตั้งใจ และเลือกให้ตัวอักษรขาวผ่าน AA ทั้งชุด
   (ขาวบน #D92D20 = 4.6 · #B54708 = 5.9 · #0B6E3F = 6.0) */
.td-now .tn-head .tn-pill { color: #fff; font-weight: 700; }
.td-now .tn-head .tn-pill.red    { background: var(--sig-red); }
.td-now .tn-head .tn-pill.yellow { background: var(--sig-amber); }
.td-now .tn-head .tn-pill.green  { background: var(--sig-green); }

/* ---- เส้นทางของช่วงนี้: เริ่ม ···N นาที··· จบ ---- */
.tn-route { display: flex; align-items: center; gap: 10px; margin-top: 11px; }
.tk-t { font-size: 21px; font-weight: 700; letter-spacing: -.03em; line-height: 1.1; }
.tk-line { position: relative; flex: 1; min-width: 0; height: 1px; align-self: center;
  background: repeating-linear-gradient(to right,
    currentColor 0 4px, transparent 4px 8px); opacity: .55; }
/* ตัวเลขนาทีนั่งคร่อมเส้นประตรงกลาง มีพื้นสีหัวตั๋วคั่นเส้นให้ขาดพอดี
   วิธีเดียวกับที่ตั๋วจริงวางไอคอนเครื่องบิน — และมันตอบ "ช่วงนี้ยาวเท่าไหร่"
   โดยไม่ต้องมีบรรทัดของตัวเอง */
.tk-line i { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  background: var(--fill); padding: 0 7px; font-style: normal;
  font-size: 11px; font-weight: 700; opacity: 1; white-space: nowrap; }
.tk-solo { font-size: 14px; font-weight: 700; opacity: .9; }

.tn-why2 { margin-top: 9px; font-size: 12px; line-height: 1.4; font-weight: 600;
  color: var(--on-fill); opacity: .85; }

/* ---- 1 · แถวบน ---- */
.tn-top { display: flex; align-items: center; gap: 10px; }
/* ชิปไอคอนเป้า — บอกว่าก้อนนี้คือ "สิ่งที่เลือกมาให้แล้ว" ไม่ใช่งานใบแรกของลิสต์
   เล็กลงจาก 40 เหลือ 34 เพราะตอนนี้มันไม่ได้ยืนเดี่ยวแล้ว มีป้ายอีกฝั่งช่วยถือน้ำหนักแถว */
.tn-mark {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 10px; background: var(--card); color: var(--blue);
  box-shadow: var(--shadow);
}
.tn-mark svg { width: 16px; height: 16px; }
/* ป้ายคำตัดสินของเอนจิน — สองคำ อยู่มุมที่เคยว่างเปล่า
   สีมาจาก priorityTone() ชุดเดียวกับทั้งแอป ไม่ได้ตั้งเกณฑ์สีใหม่ของตัวเอง */
.tn-pill {
  margin-left: auto; display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; white-space: nowrap;
  background: var(--card2); color: var(--muted);
}
.tn-pill svg { width: 13px; height: 13px; }
.tn-pill.red    { background: var(--pri-red-soft);    color: var(--pri-red-text); }
.tn-pill.yellow { background: var(--pri-yellow-soft); color: var(--pri-yellow-text); }
.tn-pill.green  { background: var(--pri-green-soft);  color: var(--pri-green-text); }

/* ---- 2 · ชื่องาน ---- */
.tn-eyebrow {
  margin-top: 11px; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; color: var(--blue);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ตัวหนังสือที่ใหญ่ที่สุดในแอป — ต้องอ่านออกตอนวางมือถือไว้ข้างสมุด ไม่ใช่ตอนถือใกล้ตา
   ไม่มีวงแหวนมาเบียดข้าง ๆ อีกแล้ว (ย้ายลงท้ายการ์ด) ชื่องานจึงได้ความกว้างเต็มใบ */
.tn-title {
  margin: 4px 0 0; font-size: 20px; line-height: 1.26; font-weight: 700;
  color: var(--ink); letter-spacing: -.01em; word-break: break-word;
}
/* ทำไมใบนี้ + คะแนนเก็บ — บรรทัดเดียว ห้ามพูดเรื่องเส้นตายซ้ำกับที่อื่นในการ์ด */
.tn-why {
  margin-top: 7px; font-size: 12px; line-height: 1.4;
  font-weight: 600; color: var(--pri-yellow-text);
}
.tn-why.red { color: var(--pri-red-text); }
.tn-why.green { color: var(--muted); font-weight: 400; }

/* ---- 3 · สองช่องข้อมูล ---- */
/* เส้นคั่นบนกับเส้นตั้งตรงกลางทำให้มันอ่านเป็น "ตาราง 2 ช่อง" ไม่ใช่ประโยคที่มีจุดคั่น
   ตัวเลขจึงถูกอ่านทีละตัว ไม่ใช่กวาดผ่านเป็นแถบข้อความยาว ๆ เหมือนบรรทัดข้อเท็จจริงแบบเดิม */
.tn-stats {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
}
.tn-stat { display: flex; align-items: center; gap: 9px; min-width: 0; }
.tn-stat + .tn-stat { padding-left: 12px; border-left: 1px solid var(--line); }
.ts-ic {
  flex: none; display: grid; place-items: center; width: 28px; height: 28px;
  border: 1px solid var(--line); border-radius: 50%; color: var(--muted);
}
.ts-ic svg { width: 14px; height: 14px; }
.ts-tx { min-width: 0; }
.ts-tx i {
  display: block; font-style: normal; font-size: 10.5px; color: var(--faint);
}
.ts-tx b {
  display: block; margin-top: 1px; font-size: 14px; font-weight: 700; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- 4 · ปุ่ม ---- */
/* ปุ่มเดียวบนจอที่เป็นพื้นทึบสีเน้น — กฎ 60/30/10 ข้อ 10% ทั้งหมดถูกใช้ตรงนี้ที่เดียว */
/* 1B28: ปุ่มหลักเลิกเป็นพื้นทึบ — หัวตั๋วเหนือมันเป็นน้ำเงินทึบไปแล้ว
   สองก้อนทึบสีเดียวกันในการ์ดใบเดียวหักล้างกันเอง ปุ่มจึงเป็นขอบหนา + พื้นฟ้าจาง
   ซึ่งยังเป็นตัวเดียวในครึ่งล่างของการ์ดที่มีสี = ยังอ่านเป็นปุ่มหลักอยู่ */
/* ใช้ --blue ไม่ใช่ --fill สำหรับตัวหนังสือกับขอบ
   --fill (#2563EB) ถูกออกแบบมาให้เป็น "พื้น" ที่มีตัวหนังสือขาวทับ ไม่ใช่ให้เป็นตัวหนังสือเอง
   วัดจริงบนการ์ดธีมมืดได้คอนทราสต์ 3.28:1 ซึ่งต่ำกว่าเกณฑ์ AA (4.5) — อ่านยากจริง ๆ ไม่ใช่แค่ทฤษฎี
   --blue คือน้ำเงินที่แต่ละธีมกำหนดไว้ว่า "อ่านออกบนพื้นของธีมนี้" (มืด #6FA8FF · สว่าง #1566CE) */
/* 1B39 · ปุ่มโครงเส้น → ปุ่มทึบ
   ปุ่มโครงเส้นบนพื้นการ์ดอ่านว่า "ทางเลือกรอง" ซึ่งเป็นข้อความที่ผิดสำหรับปุ่มเดียว
   ที่จอนี้มี · ทึบแล้วมันคือ "กดอันนี้" ไม่ใช่ "ถ้าจะกดก็ได้"
   พื้นเป็น --fill ตัวเดียวกับหัวตั๋วด้านบน การ์ดจึงยังเป็นก้อนสีเดียวไม่ใช่สองสี */
.tn-cta {
  display: block; width: 100%; margin: 0; padding: 13px 16px;
  border: 1.5px solid var(--fill); border-radius: 16px;
  background: var(--fill); color: var(--on-fill);
  font: inherit; text-align: center; cursor: pointer;
}
.tn-cta:active { filter: brightness(.9); }
.tn-cta:active { transform: scale(.985); }
.tc-main {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 16px; font-weight: 700;
}
.tc-main svg { width: 17px; height: 17px; }
.tc-sub {
  display: block; margin-top: 3px; font-size: 12px; font-weight: 400;
  color: var(--on-fill); opacity: .78;
}

/* ---- 5 · ท้ายการ์ด: ความคืบหน้า + ทางเลือกรอง ---- */
.tn-foot {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
}
/* ยังไม่เริ่มทำ = ไม่มีวงแหวน · ทางเลือกรองเลื่อนมาอยู่กลางแทน ไม่ทิ้งช่องว่างค้างไว้ */
.tn-foot.noprog { justify-content: center; }
.tn-prog { display: flex; align-items: center; gap: 9px; min-width: 0; }
.tp-ring { position: relative; flex: none; width: 44px; height: 44px; }
.tp-ring svg { width: 44px; height: 44px; transform: rotate(-90deg); }
.tp-ring circle { fill: none; stroke-width: 4; }
.tr-bg { stroke: var(--line); }
.tr-fg { stroke: var(--pri-green); stroke-linecap: round; }
.tp-ring b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: var(--ink);
}
.tp-tx { min-width: 0; }
.tp-tx i { display: block; font-style: normal; font-size: 10.5px; color: var(--faint); }
.tp-tx b {
  display: block; margin-top: 1px; font-size: 12.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ทางเลือกรองเป็นตัวหนังสือล้วน ไม่มีกรอบ — กรอบทำให้มันดูเท่ากับปุ่มหลัก
   ซึ่งเป็นการถามซ้ำว่า "จะทำหรือไม่ทำ" ทั้งที่จอนี้ตอบไปแล้วว่าควรทำ */
.tn-acts { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.tn-foot.noprog .tn-acts { margin-left: 0; gap: 24px; }
.tn-acts button {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 36px; padding: 0 2px; border: 0; background: none;
  color: var(--muted); font: inherit; font-size: 12.5px; white-space: nowrap; cursor: pointer;
}
.tn-acts svg { width: 15px; height: 15px; }
.tn-acts button:active { color: var(--ink); }
.tn-acts .ta-done { color: var(--pri-green-text); }

/* ขอข้อมูลที่ขาด แทนที่จะเดาแทน — งานที่ไม่มีกำหนดส่งได้ปุ่มนี้แทนป้ายสีแดง */
.tn-ask {
  display: flex; align-items: center; gap: 8px; width: 100%;
  margin-top: 10px; padding: 10px 0 0; border: 0; border-top: 1px solid var(--line);
  background: none; color: var(--blue); font: inherit; font-size: 12.5px;
  text-align: left; cursor: pointer;
}
.tn-ask svg { width: 15px; height: 15px; flex: none; }
.tn-ask svg:last-child { margin-left: auto; color: var(--faint); }

/* ---------- หัวข้อกำกับกลุ่ม ---------- */
.tu-lb {
  margin-bottom: 7px; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; color: var(--faint);
}

/* ---------- NEXT ---------- */
/* ใบเดียว มีกรอบบาง ๆ แต่ไม่มีพื้นสี — "มีอยู่จริงและกดได้" โดยไม่แข่งกับการ์ดโฟกัส
   ช่วงเวลาขึ้นก่อนชื่องาน เพราะคำถามของบล็อกนี้คือ "แล้วอะไรต่อ" ซึ่งคำตอบเริ่มที่เวลา */
.td-up { margin-top: 18px; }
.tu-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 10px; border: 1px solid var(--line); border-radius: 15px;
  background: var(--card); font: inherit; text-align: left; cursor: pointer;
}
.tu-row:active { background: var(--card2); }
.tu-ic {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 11px; background: var(--blue-soft); color: var(--sj, var(--blue));
}
.tu-ic svg { width: 18px; height: 18px; }
.tu-tx { flex: 1; min-width: 0; }
.tu-when { display: block; font-size: 11.5px; font-weight: 600; color: var(--blue); }
.tu-tx b {
  display: block; margin-top: 1px; font-size: 13.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tu-meta { display: block; margin-top: 1px; font-size: 11.5px; color: var(--muted); }
.tu-go { flex: none; display: flex; color: var(--faint); }
.tu-go svg { width: 17px; height: 17px; }
/* ทางไปรายการเต็ม — บรรทัดเดียว ไม่ใช่การ์ด เพราะมันไม่ใช่งาน มันคือประตู */
.tu-more {
  display: flex; align-items: center; gap: 4px; width: 100%;
  margin-top: 6px; padding: 8px 0; border: 0; background: none;
  color: var(--muted); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
}
.tu-more.solo { margin-top: 16px; }
.tu-more svg { width: 14px; height: 14px; }

/* ---------- เตือนความจำ ---------- */
/* แถวเตี้ยกว่าแถว "ถัดไป" ชัดเจน — ของพวกนี้ไม่มีอะไรให้ตัดสินใจ มีแค่ให้จำ
   ถ้าทำให้สูงเท่ากัน จอจะอ่านเป็น "นี่คือทางเลือกอีกสองสามอัน" ซึ่งไม่จริง */
.td-rem { margin-top: 18px; }
.tm-row {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: 12px;
  background: none; font: inherit; text-align: left; cursor: pointer;
}
.tm-row + .tm-row { margin-top: 2px; }
.tm-row:active { background: var(--card2); }
.tm-ic {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 10px; background: var(--card2); color: var(--muted);
}
.tm-ic.soon { background: var(--pri-yellow-soft); color: var(--pri-yellow-text); }
.tm-ic.late { background: var(--pri-red-soft); color: var(--pri-red-text); }
.tm-ic svg { width: 16px; height: 16px; }
.tm-tx { flex: 1; min-width: 0; }
.tm-tx b {
  display: block; font-size: 13px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tm-tx span { display: block; margin-top: 1px; font-size: 11.5px; color: var(--muted); }
.tm-tx span.soon { color: var(--pri-yellow-text); }
.tm-tx span.late { color: var(--pri-red-text); font-weight: 600; }
.tm-go { flex: none; display: flex; color: var(--faint); }
.tm-go svg { width: 16px; height: 16px; }

/* ---------- แผนวันนี้ — ของประกอบ จึงพับไว้ ---------- */
.td-plan { margin-top: 16px; }
/* หัวข้อที่กดกาง = บรรทัดเดียวที่บอกรูปร่างของทั้งเย็นไว้ก่อน (3 ช่วง · 2 ชม.)
   คนที่พอใจกับตัวเลขนั้นไม่ต้องกาง คนที่อยากเห็นรายละเอียดกดครั้งเดียวได้ทั้งหมด */
.tp-fold {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 13px;
  background: var(--card2); font: inherit; text-align: left; cursor: pointer;
}
.tp-fold:active { background: var(--surface); }
.tp-fic { flex: none; display: flex; color: var(--muted); }
.tp-fic svg { width: 17px; height: 17px; }
.tp-ftx { flex: 1; min-width: 0; }
.tp-ftx b { display: block; font-size: 13px; font-weight: 600; color: var(--ink); }
.tp-ftx span { display: block; margin-top: 1px; font-size: 11.5px; color: var(--muted); }
.tp-fgo { flex: none; display: flex; color: var(--faint); transition: transform .2s ease; }
.tp-fgo svg { width: 16px; height: 16px; }
.td-plan.open .tp-fgo { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .tp-fgo { transition: none; } }

/* รางเวลาใช้เส้นตั้งเส้นเดียวแทนกรอบการ์ดทีละใบ — ทำให้ทั้งบล็อกอ่านเป็นของชิ้นเดียว
   ที่เป็น "ตารางเวลา" ไม่ใช่รายการงานอีกชุดที่มาแข่งกับ NOW */
.tp-rail { position: relative; margin-top: 12px; padding-left: 14px; }
.tp-rail::before {
  content: ''; position: absolute; left: 3px; top: 8px; bottom: 8px;
  width: 1px; background: var(--line);
}
.tp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; position: relative; cursor: pointer;
}
.tp-row::before {
  content: ''; position: absolute; left: -14px; top: 15px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--sj, var(--muted)); opacity: .85;
}
.tp-row.brk { cursor: default; color: var(--faint); }
.tp-row.brk::before { width: 5px; height: 5px; left: -13px; opacity: .5; background: var(--faint); }
.tp-row > .mono { flex: none; min-width: 40px; font-size: 12px; color: var(--muted); }
.tp-tx { flex: 1; min-width: 0; }
.tp-tx b {
  display: block; font-size: 12.5px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tp-tx span { display: block; font-size: 11px; color: var(--faint); }
.tp-row.brk .tp-tx { font-size: 12px; color: var(--faint); }
/* ป้ายที่เย็บการ์ดใหญ่เข้ากับรางเวลา — บอกว่างานบนการ์ดคือช่องไหนในแผน
   ไม่มีป้าย ผู้ใช้จะอ่านว่ามีงานสองใบชื่อเหมือนกัน */
.tp-pill {
  flex: none; padding: 2px 8px; border-radius: 999px;
  font-size: 10px; font-weight: 700; white-space: nowrap;
}
.tp-pill.now  { background: var(--fill); color: var(--on-fill); }
.tp-pill.next { border: 1px solid var(--line); color: var(--muted); }
/* ช่องที่กำลังเป็น "ตอนนี้" — พื้นจาง ๆ ให้ตาจับได้ว่าเรากำลังอยู่ตรงไหนของวัน */
.tp-row.cur { background: var(--card2); border-radius: 10px; padding-left: 8px; margin-left: -8px; }
.tp-row.cur::before { left: -6px; }
/* ลูกศรจาง ๆ ท้ายแถว — รางที่ไม่มีกรอบดูไม่ออกว่าแตะได้ ต้องมีสัญญาณอย่างน้อยหนึ่งอย่าง */
.tp-go { flex: none; display: flex; color: var(--faint); }
.tp-go svg { width: 14px; height: 14px; }
.tp-all {
  display: flex; align-items: center; gap: 4px;
  margin-top: 4px; padding: 10px 0 0; border: 0; background: none;
  color: var(--blue); font: inherit; font-size: 12.5px; cursor: pointer;
}
.tp-all svg { width: 14px; height: 14px; }

/* ---------- ช่องถามน้องไซ ---------- */
/* ทรงแคปซูลเหมือนปุ่มหลัก แต่พื้นโปร่ง — อ่านเป็น "ของตระกูลเดียวกันที่เบากว่า"
   ไม่ใช่ปุ่มที่สองที่มาแข่งกับปุ่มเริ่มทำงาน */
/* 1B38 · ย้ายขึ้นไปอยู่ใต้คำทักทาย เหนือการ์ด "ตอนนี้"
   ตำแหน่งใหม่อยู่เหนือของที่สำคัญกว่ามัน มันจึงต้องเบาลงเท่าที่ยังกดติด:
   ทิ้งเงา · พื้นเป็นสีชั้นเดียวกับการ์ดรอง · ปุ่มส่งเป็นสีเทาจนกว่าจะโฟกัส
   ของสีน้ำเงินทึบวางไว้เหนือการ์ดสีน้ำเงินทึบคือของสองชิ้นที่แย่งกันเอง */
.td-ask {
  display: flex; align-items: center; gap: 9px;
  margin: 14px 0 4px; padding: 4px 4px 4px 13px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card2);
}
.td-ask:focus-within { border-color: var(--blue); background: var(--card); }
.td-ask:focus-within .tk-go { background: var(--fill); color: var(--on-fill); }
.tk-ic { flex: none; display: flex; color: var(--muted); }
.td-ask:focus-within .tk-ic { color: var(--blue); }
.tk-ic svg { width: 17px; height: 17px; }
.tk-in {
  flex: 1; min-width: 0; height: 36px; padding: 0;
  border: 0; background: none; color: var(--ink);
  font: inherit; font-size: 13.5px; outline: none;
}
.tk-in::placeholder { color: var(--faint); }
.tk-go {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border: 0; border-radius: 50%; background: var(--card); color: var(--muted);
  cursor: pointer; transition: background .16s ease, color .16s ease;
}
/* ลูกศรของชุดไอคอนชี้ขวา — ที่นี่ต้องการ "ส่งขึ้นไป" จึงหมุนเอา ไม่ต้องเพิ่มไอคอนใหม่ */
.tk-go svg { width: 17px; height: 17px; transform: rotate(-90deg); }
.tk-go:active { transform: scale(.94); }

/* ---------- บรรทัดเตือนเรื่องตารางเรียน ---------- */
.td-nudge {
  display: flex; align-items: center; gap: 8px; width: 100%;
  margin-top: 16px; padding: 11px 0 0; border: 0; border-top: 1px solid var(--line);
  background: none; color: var(--faint); font: inherit; font-size: 11.5px;
  line-height: 1.5; text-align: left; cursor: pointer;
}
.td-nudge svg { width: 14px; height: 14px; flex: none; }
.td-nudge svg:last-child { margin-left: auto; }

/* วันนี้หมดเวลาแล้ว — พื้นเรียบ ไม่ใช่สีเตือน เพราะมันไม่ใช่ความผิดของใคร
   เป็นแค่ข้อเท็จจริงเรื่องเวลาที่ต้องบอกให้รู้ว่าทำไมข้างล่างถึงว่าง */
.td-note {
  margin-top: 26px; padding: 14px; border-radius: 14px; background: var(--card2);
}
.td-note b { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink); }
.td-note b svg { width: 16px; height: 16px; color: var(--muted); }
.td-note p { margin: 6px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.td-note .tn-ask { margin-top: 10px; }

/* ---------- ยังไม่มีงาน ----------
   1C40 · การ์ดกระจกใบเดียว: น้องไซในวงแสง (ซ้าย) + หัวข้อ/คำอธิบาย (ขวา) ·
   สามขั้นเฉพาะครั้งแรก · ปุ่มเต็มความกว้าง · สูงไม่เกินของเดิม (~213px) */
.td-clear {
  position: relative; overflow: hidden;
  margin-top: 10px; padding: 14px;
  border-radius: 24px; border: 1px solid var(--line);
  background:
    radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--fill) 16%, transparent), transparent 60%),
    var(--soft-card, var(--card));
  box-shadow: var(--soft-shadow, var(--shadow));
  -webkit-backdrop-filter: blur(14px) saturate(150%); backdrop-filter: blur(14px) saturate(150%);
}
.tc-top { display: flex; align-items: center; gap: 14px; }
/* วงแสงหลังน้องไซ — สีเน้นของธีมจาง ๆ ลอยขึ้นลงช้า ๆ ให้จอว่างไม่นิ่งตาย */
.tc-art {
  position: relative; flex: none; width: 64px; height: 64px; border-radius: 50%;
  display: grid; place-items: center;
  background: radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--fill) 34%, transparent), color-mix(in srgb, var(--fill) 8%, transparent) 70%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fill) 26%, transparent);
  animation: tc-float 4.5s ease-in-out infinite;
}
.tc-art img { width: 56px; height: 56px; object-fit: cover; border-radius: 50%; }
.tc-fb { display: none; color: var(--fill); }
.tc-fb svg { width: 28px; height: 28px; }
.tc-art.no-img .tc-fb { display: grid; }
@keyframes tc-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.tc-tx { flex: 1; min-width: 0; text-align: left; }
.td-clear b { display: block; font-size: 18px; font-weight: 800; letter-spacing: -.02em; line-height: 1.3; color: var(--ink); }
.td-clear p { margin: 5px 0 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* วันนี้ทำเสร็จไปกี่งาน — ตัวเลขคือของที่น่าภูมิใจที่สุดบนการ์ดนี้ */
.tc-badge {
  flex: none; align-self: flex-start; display: inline-flex; align-items: center; gap: 3px;
  padding: 4px 9px 4px 7px; border-radius: 999px;
  background: var(--good-soft); color: var(--good);
  font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.tc-badge svg { width: 13px; height: 13px; stroke-width: 3; }
/* สามขั้นของแอป — บอกว่ากดปุ่มข้างล่างแล้วจะเกิดอะไร ไม่ต้องเดา */
.tc-steps {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  margin-top: 11px; padding: 7px 8px; border-radius: 14px;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
}
.tc-steps span { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.tc-steps span svg { width: 14px; height: 14px; color: var(--fill); }
.tc-steps > svg { width: 13px; height: 13px; color: var(--faint); flex: none; }
.tc-cta {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 10px; padding: 11px 22px; border: 0; border-radius: 13px;
  background: var(--fill); color: var(--on-fill);
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
}
.tc-cta svg { width: 17px; height: 17px; }
@media (prefers-reduced-motion: reduce) { .tc-art { animation: none; } }

/* ---------- แผ่นเลือกวิธีเพิ่มงาน (ปุ่ม +) ---------- */
.add-sheet { position: absolute; inset: 0; z-index: 95; }
.add-sheet[hidden] { display: none; }
.as-scrim {
  position: absolute; inset: 0; background: rgba(0, 0, 0, .5);
  opacity: 0; transition: opacity .2s ease;
}
.add-sheet.on .as-scrim { opacity: 1; }
.as-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);
}
.add-sheet.on .as-card { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .as-scrim, .as-card { transition: none; }
}
.as-grip {
  width: 38px; height: 4px; margin: 4px auto 12px;
  border-radius: 999px; background: var(--line);
}
.as-h { margin-bottom: 8px; font-size: 15px; font-weight: 700; color: var(--ink); }
.as-row {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 11px 4px; border: 0; background: none;
  font: inherit; text-align: left; cursor: pointer;
}
.as-row + .as-row { border-top: 1px solid var(--line); }
.as-row:active { background: var(--surface); border-radius: 12px; }
.as-ic {
  flex: none; width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 12px; background: var(--blue-soft); color: var(--blue);
}
.as-ic svg { width: 18px; height: 18px; }
.as-tx { flex: 1; min-width: 0; }
.as-tx b { display: block; font-size: 14.5px; font-weight: 600; color: var(--ink); }
.as-tx span { display: block; margin-top: 1px; font-size: 12px; color: var(--muted); }
.as-go { flex: none; display: flex; color: var(--faint); }
.as-go svg { width: 16px; height: 16px; }

/* ---------- จอกว้าง ---------- */
/* ไม่ยืดเนื้อหาเต็มความกว้าง — บรรทัดยาวเกิน ~70 ตัวอักษรอ่านยากขึ้นไม่ใช่ง่ายขึ้น
   ที่ว่างที่เหลือปล่อยว่างไว้ ดีกว่าเอา widget มาถมให้เต็ม */
@media (min-width: 720px) {
  .th-greet { font-size: 21px; }
  .tn-title { font-size: 29px; }
  .td-now, .td-up, .td-rem, .td-plan, .td-head, .td-ask, .td-note { max-width: 620px; }
}

/* ============================================================
   โหมดโฟกัส
   ============================================================
   ทับทุกอย่างรวมถึงแถบล่าง — ระหว่างทำงานอยู่ "ไปหน้าอื่น" ไม่ใช่สิ่งที่ควรทำได้ง่าย
   บนจอนี้มีทางออกสามทางเท่านั้น: เสร็จ · พัก · กากบาท */
.focus-wrap {
  /* 1C14 · 90 → 92 · ปุ่มลอยมุมขวาบนสองตัว (.top-friends · .top-set) อยู่ที่ 91
     มันจึงลอยอยู่เหนือจอโฟกัสทั้งใบ ทั้งจอจับเวลาและจอฉลอง — บั๊คตัวเดียวกับ
     ปุ่มประกายที่ทับปุ่มบันทึกในจอกรอกงาน (FAB_HIDE ใน feed.js) — ของที่ลอย
     อยู่นอกกองจอ จะทับอะไรสักอย่างเสมอ · 94/95 (.fab-hub · .add-sheet) ยังอยู่เหนือตามเดิม */
  position: absolute; inset: 0; z-index: 92;
  background: var(--scr); display: flex; flex-direction: column;
  animation: fcIn .22s ease-out;
}
/* ต้องมาหลัง .focus-wrap และห้ามลบเด็ดขาด
   —————————————————————————————————————————————————————————
   `hidden` เป็น attribute ที่ซ่อนของด้วย `display:none` จาก stylesheet ของเบราว์เซอร์เอง
   ซึ่งมีน้ำหนักต่ำกว่า `display:flex` ที่เราเขียนในไฟล์นี้ — พอเขียนทับ มันก็ไม่ซ่อนอีกต่อไป
   ผลคือกล่องเปล่าพื้นทึบกางเต็มจอทับทั้งแอปตั้งแต่วินาทีแรกที่เปิด และกินทุกการกด
   เปิดมาเจอจอดำสนิท ไม่มี error ใน console สักบรรทัด เพราะ DOM ถูกต้องทุกอย่าง
   (หลุดขึ้นเว็บจริงมาแล้วหนึ่งรอบ — 20 ส.ค. 2569)
   ใครก็ตามที่จะตั้ง display ให้ของที่ซ่อนด้วย `hidden` ต้องเขียนบรรทัดคู่แบบนี้เสมอ */
.focus-wrap[hidden] { display: none; }
@keyframes fcIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .focus-wrap { animation: none; } }

.fc-sheet {
  flex: 1; display: flex; flex-direction: column;
  padding: 16px 18px calc(18px + env(safe-area-inset-bottom));
  overflow-y: auto;
}
.fc-top { display: flex; align-items: center; gap: 10px; }
.fc-x {
  width: 38px; height: 38px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--surface); color: var(--muted); cursor: pointer;
}
.fc-x svg { width: 17px; height: 17px; }
.fc-sub { margin-left: auto; font-size: 12.5px; color: var(--muted); }

.fc-head { margin-top: 22px; }
.fc-subj { font-size: 13px; font-weight: 700; color: var(--blue); }
.fc-title { margin: 4px 0 0; font-size: 24px; line-height: 1.3; font-weight: 700; color: var(--ink); }

/* นาฬิกาเป็นของชิ้นเดียวที่เคลื่อนไหวบนจอนี้ — ทุกอย่างอื่นนิ่ง */
.fc-clock { margin-top: 30px; text-align: center; }
.fc-el { font-size: 52px; font-weight: 700; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.fc-target { margin-top: 8px; font-size: 13px; color: var(--muted); }
.fc-over {
  margin-top: 12px; padding: 9px 12px; border-radius: 10px;
  background: var(--warn-soft); color: var(--ink);
  font-size: 12.5px; line-height: 1.5; text-align: center;
}

.fc-now {
  margin-top: 24px; padding: 13px 14px;
  background: var(--blue-soft); border-radius: 13px;
}
.fn-lb {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--blue); margin-bottom: 3px;
}
.fc-now b { font-size: 15.5px; color: var(--ink); font-weight: 600; }

.fc-steps { display: grid; gap: 3px; margin-top: 14px; }
.fs-row {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 11px 12px; border: 0; border-radius: 11px;
  background: var(--card2); font: inherit; text-align: left; cursor: pointer;
}
.fs-tick {
  flex: none; width: 21px; height: 21px; display: grid; place-items: center;
  border: 1.6px solid var(--line); border-radius: 50%; color: transparent;
}
.fs-tick svg { width: 13px; height: 13px; }
.fs-row.done .fs-tick { background: var(--pri-green); border-color: var(--pri-green); color: var(--on-fill); }
.fs-row.done .fs-tx { color: var(--faint); text-decoration: line-through; }
.fs-row.cur { background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--blue); }
.fs-tx { flex: 1; min-width: 0; font-size: 14px; color: var(--ink); }
.fs-min { flex: none; font-size: 12px; color: var(--muted); }

.fc-act { margin-top: auto; padding-top: 22px; display: grid; gap: 8px; }
.fc-done, .fc-pause, .fc-go, .fc-later {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 50px; border: 0; border-radius: 14px;
  font: inherit; font-size: 15.5px; font-weight: 700; cursor: pointer;
}
.fc-done, .fc-go { background: var(--fill); color: var(--on-fill); box-shadow: var(--shadow-brand); }
.fc-pause, .fc-later {
  background: transparent; color: var(--muted);
  border: 1px solid var(--line); font-weight: 500; min-height: 44px; font-size: 14px;
}
.fc-done svg, .fc-go svg, .fc-pause svg { width: 18px; height: 18px; }

/* ============================================================
   จอฉลอง (1C14) — ใบพระเอกเต็มจอ ภาษาเดียวกับจอล็อกอิน
   ============================================================
   ของเดิมเป็นวงกลมถูกเขียว + ตัวหนังสือ + การ์ดขาวใบหนึ่ง ทั้งหมดกองกลางจอ
   เหลือที่ว่างบน 35% ล่าง 35% · และปุ่มสองใบในการ์ดไม่เต็มแถว ชิดซ้าย
   กว้างไม่เท่ากัน เพราะ .fc-next ไม่ได้บังคับความกว้างให้ลูกของมัน

   ตอนนี้ปุ่มอยู่นอกการ์ด ใน .fw-act ซึ่งเป็น grid — ความกว้างมาจากผัง
   ไม่ใช่จากความยาวของคำในปุ่ม ซึ่งเป็นสาเหตุเดิมของ "ของที่ดูพัง" */
.fc-sheet.done { align-items: stretch; justify-content: flex-start; text-align: left; }

/* ใบกินสลักทั้งหมดด้วย flex:1 — ไม่ใช่ margin-top:auto ที่ของข้างล่าง
   รอบก่อนย้ายที่ว่างไปไว้กลางจอ วัดได้ 350px ที่ไม่มีอะไรอยู่เลย — อาการเดียวกับจอเก่า
   ตอนนี้ใบเป็นคนกินที่ว่างเอง จอสูงเท่าไหร่ก็ได้สัดส่วนเดิม และจอฉลองควรเป็นจอที่มีสีเต็มตาอยู่แล้ว */
.fw-hero {
  position: relative;
  display: flex; flex-direction: column;
  margin-top: 8px;
  padding: 30px 20px 34px;
  border-radius: 26px;
  /* ม่านทึบปลายสว่างของไล่สี — ชุดเดียวกับ .lg-hero ของจอล็อกอิน
     เหตุผลเต็มอยู่ที่นั่น — วัดมาได้ 2.22 : 1 บนธีม warm ก่อนแก้ */
  /* พื้นชุดเดียวกับ .lg-hero ของจอล็อกอิน — เหตุผลเต็มอยู่ที่นั่น (style.css) */
  background-image: linear-gradient(150deg,
    color-mix(in srgb, var(--fill) 84%, #000) 0%,
    var(--fill) 58%,
    color-mix(in srgb, var(--fill) 88%, #000) 100%);
  color: var(--on-fill);
  box-shadow: var(--shadow-lg);
}
/* วงกลมจาง ๆ หลังใบ ชุดเดียวกับ .lg-hero และ .td-now .tn-head */
.fw-hero::after {
  content: ''; position: absolute; right: -50px; top: -58px;
  width: 180px; height: 180px; border-radius: 50%;
  background: color-mix(in srgb, var(--on-fill) 12%, transparent); pointer-events: none;
  clip-path: inset(58px 50px 0 0 round 0 26px 0 0);
}
.fw-hero > * { position: relative; z-index: 2; }

/* เครื่องหมายถูกเป็นวงขาวโปร่งบนพื้นสี ไม่ใช่วงเขียวบนพื้นขาว
   เขียวตัวเดิม (--pri-green) เป็นสีเดียวบนจอและไม่ได้อยู่ในชุดของแบรนด์
   — 1C13 เคาะไว้ว่าสีของแอปคือฟ้า คุมให้แน่น */
.fw-ring {
  width: 62px; height: 62px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--on-fill) 22%, transparent);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--on-fill) 48%, transparent);
  color: var(--on-fill);
}
.fw-ring svg { width: 30px; height: 30px; stroke-width: 3; }

/* 40 → 15 → 11.5 — ต้องกระโดด ไม่ใช่ไล่เลี่ยกัน (กฎ 1C13)
   ของเดิม 26 → 14 บนพื้นขาว ซึ่งอ่านเป็นหัวข้อของกล่องข้อความ ไม่ใช่คำฉลอง */
.fw-mid { margin: 20px 0 26px; }
.fw-t { margin: 0; font-size: 40px; font-weight: 800;
  letter-spacing: -.04em; line-height: 1.05; color: var(--on-fill); }
.fw-p { margin: 7px 0 0; font-size: 15px; font-weight: 500; line-height: 1.5;
  color: var(--on-fill); max-width: 15em; }

/* ตัวเลขที่เพิ่งได้มาจริง ๆ — ไม่มีอันไหนเป็นค่าที่เขียนไว้ล่วงหน้า
   เส้นคั่นเป็นขอบซ้ายของใบที่สองเป็นต้นไป จึงไม่ต้องนับจำนวนช่องใน CSS */
/* กันที่ให้น้องไซ 84px — วัดจริงรอบแรกแล้วตัวเลขช่องที่สามไปอยู่ใต้รูปพอดี
   รูปกว้าง 72 + ชิดขวา 18 − พาดดิ้งของใบ 20 ≈ 70 · เผื่ออีกนิดกันช่องหายใจ */
.fw-stats { display: flex; gap: 0; margin-top: 0; padding-right: 84px; }
.fw-stats > div { flex: 1; min-width: 0; padding: 0 12px; }
.fw-stats > div:first-child { padding-left: 0; }
.fw-stats > div + div { border-left: 1px solid color-mix(in srgb, var(--on-fill) 24%, transparent); }
.fw-stats b { display: block; font-size: 26px; font-weight: 800;
  line-height: 1.1; color: var(--on-fill); font-variant-numeric: tabular-nums; }
.fw-stats span { display: block; margin-top: 2px; font-size: 11.5px;
  font-weight: 600; color: var(--on-fill); opacity: .88; }

/* น้องไซคร่อมขอบล่าง ครึ่งในครึ่งนอก — ท่าเดียวกับจอล็อกอินเป๊ะ
   จอสองจอที่วางตัวละครคนละท่า อ่านเป็นสองแอป */
.fw-sai {
  position: absolute; right: 18px; bottom: -26px;
  width: 72px; height: 72px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--scr); box-shadow: var(--shadow);
  pointer-events: none; z-index: 3;
}

/* งานถัดไปเป็นแถวเปล่าบนพื้นจอ ไม่ใช่การ์ดขาว — การ์ดขาวใต้ใบสี
   ทำให้จอมีของสองชิ้นที่แข่งกัน ทั้งที่ใบบนคือคำตอบ ใบล่างคือคำถามถัดไป */
/* margin-top:auto อยู่ที่ .fw-next ไม่ใช่ .fw-act — ที่ว่างที่เหลือจึงไปกอง
   อยู่ใต้ใบพระเอก แทนที่จะแทรกคั่นกลางระหว่าง "งานถัดไป" กับปุ่มที่เป็นของคู่กัน
   รอบแรกวัดได้ 300px คาอยู่ตรงกลางนั้นพอดี — อาการเดียวกันกับจอเก่า */
.fw-next { margin-top: 28px; padding: 0 2px; }
/* --blue-deep ไม่ใช่ --blue — ทุกธีมนิยามมันไว้เป็นตัวที่ตัดกับพื้นมากกว่าเสมอ
   ทั้งธีมสว่างและธีมมืด · --blue บน --scr ของธีมชมพูวัดได้แค่ 4.30 : 1 */
.fw-lb { display: block; font-size: 11.5px; font-weight: 700;
  letter-spacing: .01em; color: var(--muted); }
.fw-next b { display: block; margin-top: 5px; font-size: 19px; font-weight: 700;
  line-height: 1.35; color: var(--ink); }
.fw-min { display: block; margin-top: 5px; font-size: 12.5px;
  line-height: 1.5; color: var(--muted); }

/* ปุ่มถูกดันไปติดก้นจอ และเต็มแถวทั้งคู่ — ทรงเดียวกับกองปุ่มจอล็อกอิน */
/* คิวที่เหลือของวันนี้ — แถวบาง ไม่มีพื้น เส้นคั่นทีละเส้น
   การ์ดขาวสามใบใต้ใบสีจะกลายเป็นกองของสี่ก้อนที่แข่งกันเอง ตามกฎ 1C13 */
.fw-rest { margin-top: 26px; padding: 0 2px; }
/* ข้อควรระวัง: ตัวหนังสือที่นั่งบนพื้นจอ (--scr) ตรง ๆ ใช้ --faint ไม่ได้
   ธีม genesis มี --scr เป็นสีกลาง (142,155,232) — --faint บนนั้นวัดได้ 2.16 : 1
   (--blue 2.83 · --blue-deep 4.49 · --muted 4.52 · --ink 5.75) — มีแค่ --muted กับ --ink ที่ผ่าน
   --faint ถูกออกแบบมาสำหรับของที่นั่งบนการ์ด (--card ซึ่งเกือบขาวทุกธีม) ไม่ใช่พื้นจอ */
.fw-rest .fw-lb { margin-bottom: 4px; color: var(--muted); }
.fw-row {
  display: grid; grid-template-columns: 46px 1fr auto; align-items: center;
  gap: 10px; padding: 10px 0;
  border-top: 1px solid var(--line);
  font-size: 13.5px;
}
.fw-rt { color: var(--muted); font-size: 12.5px; }
.fw-rx { min-width: 0; color: var(--ink); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.fw-rm { color: var(--muted); font-size: 12px; }

.fw-act { margin-top: auto; padding-top: 24px; display: grid; gap: 9px; }
.fw-act .fc-go, .fw-act .fc-later { width: 100%; min-height: 54px; border-radius: 16px; }

/* จอกว้าง: การ์ด NOW ยังต้องเป็นของชิ้นเดียวที่ใหญ่ที่สุด ไม่ใช่ยืดจนอ่านยาก */
@media (min-width: 720px) {
  .tn-title { font-size: 23px; }
  .fc-sheet { max-width: 560px; margin: 0 auto; width: 100%; }
}

/* ---------- สรุปประจำสัปดาห์ (ในหน้า "ฉัน") ---------- */
/* ตัวเลขสามตัวคือของจริงที่วัดได้ · รายการข้างล่างคือสิ่งที่ระบบสรุปได้จากตัวเลขนั้น
   ห้ามมีบรรทัดไหนที่เขียนไว้ล่วงหน้าโดยไม่ขึ้นกับข้อมูล */
.st-card.wk .st-h { display: flex; align-items: center; gap: 7px; }
.st-card.wk .st-h svg { width: 16px; height: 16px; color: var(--blue); }
.wk-nums {
  display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px;
  font-size: 13px; color: var(--muted);
}
.wk-nums b { font-size: 17px; color: var(--ink); margin-right: 3px; }
.wk-lb { margin-top: 14px; font-size: 12.5px; font-weight: 700; color: var(--ink); }
.wk-list { margin: 6px 0 0; padding-left: 18px; display: grid; gap: 4px; }
.wk-list li { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.wk-note { margin: 10px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--faint); }

/* ปุ่มเพื่อนลอยมุมขวาบน (.top-friends) หลบหน้า "วันนี้"
   สองเหตุผล: มันนั่งทับกระดิ่งกล่องเข้าพอดีจนกดผิดตัวได้ · และ "เพื่อนออนไลน์กี่คน"
   ไม่ใช่คำตอบของคำถามที่พาคนมาเปิดแอป · ทางเข้ายังอยู่ครบสองที่ในแท็บ "ฉัน" */
.home-scr .top-friends { display: none; }

/* จอ "น้องไซ" ก็เหมือนกัน — หัวจอมีวงกลมของตัวเองอยู่ขวาสุดแล้ว (.sh-me + .sh-wipe)
   ปุ่มเพื่อนลอยลงมาทับพอดีตั้งแต่ 1A9r ที่ขยับมันพ้นแบต · หลบให้หัวจอไปเลย */
.ai-scr .top-friends { display: none; }

/* ============================================================
   จอ "น้องไซ" — ผู้ช่วย ไม่ใช่ช่องแชทเปล่า
   ============================================================
   ช่องแชทเปล่ากับเคอร์เซอร์กะพริบ คือจอที่โยนคำถามกลับให้ผู้ใช้ว่า "จะถามอะไรล่ะ"
   ซึ่งเป็นงานเดียวกับที่หน้าแรกรับปากว่าจะทำแทน · จอนี้จึงพูดก่อนเสมอ และพูดจากข้อมูลจริง

   ลำดับจากบนลงล่าง:
     หัวจอ → ภาพรวมวันนี้ + งานที่ควรทำก่อน → ความโปร่งใส → บทสนทนา → ทางลัด → ช่องพิมพ์

   ห้ามใส่ hex ตรง ๆ — จอนี้ใช้ token ชุดเดียวกับทั้งแอป ธีมม่วง/ส้มต้องได้สีของตัวเอง
   ============================================================ */

/* ---------- 1 · หัวจอ ---------- */
.sai-head { display: flex; align-items: center; gap: 12px; padding-top: 6px; }
.sh-id { flex: 1; min-width: 0; }
.sh-name {
  margin: 0; display: flex; align-items: center; gap: 8px;
  font-size: 21px; line-height: 1.2; font-weight: 700; color: var(--ink);
}
/* ป้าย AI — บอกตรง ๆ ว่าอีกฝั่งไม่ใช่คน · เป็นเรื่องที่ต้องบอก ไม่ใช่เรื่องที่ต้องเดา */
.sh-badge {
  padding: 2px 7px; border-radius: 6px;
  background: var(--blue-soft); color: var(--blue);
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
}
.sh-role { margin: 3px 0 0; font-size: 12.5px; color: var(--muted); }
.sh-me {
  flex: none; width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--blue-soft); color: var(--blue);
  font: inherit; font-size: 16px; font-weight: 700; cursor: pointer;
}
.sh-me svg { width: 18px; height: 18px; }

/* ---------- 2 + 3 · ภาพรวมวันนี้ + งานที่ควรทำก่อน ---------- */
/* การ์ดใบเดียว สองชั้น — ชั้นนอกคือ "วันนี้มีเท่าไหร่" ชั้นในคือ "แล้วเริ่มใบไหน"
   สองคำถามนี้ถูกถามต่อกันเสมอ แยกเป็นสองการ์ดคือบังคับให้สายตาเชื่อมเอง */
.sai-day {
  margin-top: 16px; padding: 13px;
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: linear-gradient(158deg, var(--blue-soft) 0%, transparent 70%), var(--card);
  box-shadow: var(--shadow);
}
.sd-head { display: flex; align-items: center; gap: 10px; }
.sd-tx { flex: 1; min-width: 0; }
.sd-tx b { display: block; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.sd-tx > span { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); }
.sd-all {
  flex: none; display: inline-flex; align-items: center; gap: 2px;
  padding: 6px 2px 6px 8px; border: 0; background: none;
  color: var(--blue); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.sd-all svg { width: 14px; height: 14px; }

/* ชั้นใน — พื้นทึบกว่าชั้นนอกหนึ่งขั้น ให้อ่านเป็น "ของที่อยู่ในนั้น" ไม่ใช่การ์ดที่วางซ้อน */
.sd-task {
  margin-top: 11px; padding: 12px;
  border: 1px solid var(--line); border-radius: 15px; background: var(--card2);
}
.sd-task.empty {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; color: var(--muted);
}
.sd-task.empty svg { width: 17px; height: 17px; color: var(--pri-green); flex: none; }
.sd-task.empty b { font-size: 13px; font-weight: 600; color: var(--ink); }
.st-lb {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; color: var(--muted);
}
.st-lb svg { width: 13px; height: 13px; }
.st-lb.red { color: var(--pri-red-text); }
.st-lb.yellow { color: var(--pri-yellow-text); }
.st-lb.green { color: var(--pri-green-text); }
.st-mid { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.st-tx { flex: 1; min-width: 0; }
.st-tx b {
  display: block; font-size: 16px; font-weight: 700; line-height: 1.3; color: var(--ink);
  word-break: break-word;
}
.st-tx > span { display: block; margin-top: 3px; font-size: 12px; color: var(--muted); }
/* ปุ่มเดียวในจอนี้ที่เป็นพื้นทึบสีเน้น — ช่องพิมพ์กับปุ่มส่งเป็นของประจำจอ ไม่ใช่การตัดสินใจ
   สิ่งเดียวที่จอนี้อยากให้กดคือ "ไปลงมือทำ" ซึ่งแปลว่าออกจากจอนี้ไป */
.st-go {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; margin-top: 12px; padding: 11px;
  border: 0; border-radius: 13px; background: var(--fill); color: var(--on-fill);
  font: inherit; font-size: 14.5px; font-weight: 700; cursor: pointer;
  box-shadow: var(--shadow-brand);
}
.st-go svg { width: 16px; height: 16px; }
.st-go:active { transform: scale(.985); }

/* ---------- 5 · ปุ่มทางลัด ---------- */
/* อยู่เหนือช่องพิมพ์เสมอ ไม่ใช่เฉพาะตอนจอว่าง — "ไม่รู้ว่าถามอะไรได้"
   ไม่ได้หายไปหลังถามคำถามแรก · เลื่อนแนวนอนได้เพราะสี่ปุ่มไทยไม่มีทางลงสองแถวสวย */
.sai-qa {
  display: flex; gap: 7px; margin-top: 9px;
  overflow-x: auto; scrollbar-width: none;
  padding-bottom: 2px; scroll-padding: 0 20px;
}
.sai-qa::-webkit-scrollbar { display: none; }
.sai-qa button {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer;
}
.sai-qa button svg { width: 13px; height: 13px; color: var(--blue); }
/* ปุ่มความโปร่งใส — อยู่ในแถวเดียวกับปุ่มทางลัดแต่ไม่ใช่คำถาม จึงต้องอ่านออกว่าคนละชนิด
   พื้นจางกว่าและตัวหนังสือเบากว่า: หยิบได้ตลอดโดยไม่แย่งสายตาไปจากคำถามที่ถามได้จริง */
.sai-qa .qa-priv { background: transparent; color: var(--muted); border-style: dashed; }
.sai-qa .qa-priv svg { color: var(--muted); }
.sai-qa button:active { background: var(--card2); transform: scale(.97); }
.sai-qa button:disabled { opacity: .5; }

/* ---------- 6 · ช่องพิมพ์ ---------- */
.sai-bar {
  display: flex; align-items: flex-end; gap: 6px; margin-top: 10px;
  padding: 5px 5px 5px 14px;
  border: 1px solid var(--line); border-radius: 24px;
  background: var(--card); box-shadow: var(--shadow);
}
.sai-bar:focus-within { border-color: var(--blue); }
.sai-bar .ai-in {
  flex: 1; min-width: 0; max-height: 120px; padding: 9px 0;
  border: 0; background: none; color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1.45; resize: none; outline: none;
}
.sai-bar .ai-in::placeholder { color: var(--faint); }
.sai-bar .ai-in:disabled { opacity: .55; }
.sb-mic, .sb-send {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px;
  border: 0; border-radius: 50%; cursor: pointer;
}
.sb-mic { background: none; color: var(--muted); }
.sb-mic svg { width: 18px; height: 18px; }
.sb-mic:active { background: var(--card2); }
/* กำลังฟังอยู่ — ต้องเห็นจากหางตาว่าไมค์เปิดค้าง ไม่งั้นมันคือไมค์ที่แอบฟัง */
.sb-mic.rec { background: var(--pri-red-soft); color: var(--pri-red-text); }
.sb-mic.rec svg { animation: sb-pulse 1.1s ease-in-out infinite; }
@keyframes sb-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .sb-mic.rec svg { animation: none; } }
.sb-send { background: var(--fill); color: var(--on-fill); }
.sb-send svg { width: 17px; height: 17px; transform: rotate(-90deg); }
.sb-send:disabled { opacity: .45; }
.sb-send:active { transform: scale(.94); }

/* บทสนทนาต้องมีที่หายใจระหว่างการ์ดข้างบนกับปุ่มทางลัดข้างล่าง */
#aiBody .ai-thread { margin-top: 14px; }
#aiBody .ai-priv { margin-top: 12px; }
.sd-task.empty.tap { width: 100%; text-align: left; font: inherit; cursor: pointer; }
.sd-task.empty.tap svg:last-child { margin-left: auto; color: var(--faint); }
.sd-task.empty.tap svg:first-child { color: var(--blue); }

/* ---------- จอน้องไซเต็มจอ ---------- */
/* จอนี้เป็นห้องสนทนา ไม่ใช่หน้าเอกสารที่เลื่อนอ่านยาว ๆ
   ห้องสนทนามีรูปทรงตายตัว: หัวจออยู่บน ช่องพิมพ์อยู่ล่าง และบทสนทนากินที่ที่เหลือทั้งหมด
   ถ้าปล่อยให้ทั้งจอเลื่อนตามปกติ ช่องพิมพ์จะไหลตามเนื้อหาลงไปเรื่อย ๆ จนต้องเลื่อนหา
   ซึ่งเป็นสิ่งเดียวที่ห้ามเกิดในจอที่มีไว้พิมพ์ */
#scr-ai.screen { padding: 0; overflow: hidden; }
#scr-ai.screen.on { display: flex; flex-direction: column; }
#aiBody.scr-body {
  flex: 1; min-height: 0; gap: 0;
  /* บนสุดกัน notch เอง — จอนี้ตั้ง padding แบบย่อ ซึ่งทับกฎ safe-area ใน alt.css ทิ้ง
     ล่างสุดต้องพ้นแถบล่างที่ติดขอบจอแล้ว: 44 (ปุ่ม) + 6 (padding) + safe-area + ช่องว่าง */
  padding: calc(8px + env(safe-area-inset-top)) 20px 66px;
}
/* บทสนทนาคือส่วนเดียวที่ยืดได้ · min-height:0 จำเป็นจริง ไม่ใช่ของประดับ —
   ไม่มีมันแล้ว flex item จะไม่ยอมหดต่ำกว่าเนื้อหาตัวเอง กล่องเลยดันช่องพิมพ์ตกจอ */
#aiBody .ai-thread {
  flex: 1; min-height: 0; overflow-y: auto;
  margin-top: 14px; display: flex; flex-direction: column;
  scrollbar-width: none;
}
#aiBody .ai-thread::-webkit-scrollbar { display: none; }
/* ดันฟองแชทลงชิดล่างด้วย margin-top:auto ไม่ใช่ justify-content:flex-end
   เพราะ flex-end บนกล่องที่ scroll ได้ ทำให้เนื้อหาส่วนบนเลื่อนขึ้นไปหาไม่เจอเมื่อล้น */
.at-in { margin-top: auto; display: flex; flex-direction: column; gap: 9px; }

/* ปุ่มล้างประวัติ — ย้ายจากบรรทัดใต้ช่องพิมพ์ (ที่ถูกถอดออก) มาเป็นไอคอนบนหัวจอ
   ขึ้นเฉพาะตอนมีอะไรให้ล้าง · ปุ่มลบที่อยู่ตลอดเวลาคือปุ่มที่รอวันโดนกดพลาด */
.sh-wipe {
  flex: none; width: 36px; height: 36px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: none; color: var(--faint); cursor: pointer;
}
.sh-wipe svg { width: 17px; height: 17px; }
.sh-wipe:active { background: var(--card2); color: var(--pri-red-text); }

/* จอเตี้ย = คีย์บอร์ดเปิดอยู่ (Android ย่อ viewport จริงตอนคีย์บอร์ดขึ้น)
   ตอนกำลังพิมพ์ ไม่มีใครอ่านการ์ดสรุปวัน — สิ่งที่ต้องเห็นคือสิ่งที่เพิ่งพิมพ์กับคำตอบล่าสุด
   ถ้าไม่ยุบ บทสนทนาจะเหลือ ~30px แล้วห้องแชทกลายเป็นช่องมองแคบ ๆ
   iOS ไม่ย่อ viewport จึงไม่โดนกฎนี้ และไม่ต้องโดน เพราะมันเลื่อนช่องพิมพ์ให้เอง */
@media (max-height: 620px) {
  #aiBody .sai-day, #aiBody .ai-priv { display: none; }
  .sai-head { padding-top: 2px; }
  .sh-role { display: none; }
}

/* ---------- ตัวเชื่อมในเมนู + ---------- */
/* หน้าเต็มอยู่ลึกสองชั้นซึ่งแปลว่าไม่มีใครหาเจอ · ปุ่ม + อยู่บนแถบล่างของทุกหน้า
   ตัวเชื่อมเป็นของที่ตั้งครั้งเดียวก็จริง แต่ "ครั้งเดียว" นั้นจะไม่เกิดถ้าหาไม่เจอ */
.as-conn .as-ic { background: var(--good-soft); color: var(--good); }

/* หัวข้อที่กดกลับได้ — ลูกศรหันซ้าย ต่างจาก .as-go ที่หันขวา */
.as-back { display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 2px 0 0; }
.as-bk { display: flex; color: var(--muted); transform: rotate(180deg); }
.as-bk svg { width: 17px; height: 17px; }
.as-back:active .as-bk { color: var(--blue); }
.as-sub { margin: 2px 0 6px; font-size: 12px; line-height: 1.55; color: var(--muted); }

.as-cnt {
  margin-left: auto; padding: 3px 9px 4px; border-radius: 999px;
  background: var(--blue-soft); color: var(--blue);
  font-size: 11px; font-weight: 700; white-space: nowrap;
}
.as-cnt.sm { margin-left: 0; }
/* ป้ายสถานะของตัวเชื่อมที่ต่อผ่าน API — สามสถานะที่ต้องแยกออกจากกันด้วยหางตา:
   ฟ้า = กดได้เลย · เขียว = ทำงานอยู่ ไม่ต้องทำอะไร · เหลือง = ต้องมากด ไม่งั้นงานหยุดไหล */
.as-cnt.ok { background: var(--good-soft); color: var(--good); }
.as-cnt.bad { background: var(--warn-soft); color: var(--warn); }
.as-cnt svg { width: 12px; height: 12px; vertical-align: -2px; margin-right: 3px; }

/* แถวสวิตช์ — ทั้งแถวกดสลับได้ ไม่ใช่เฉพาะตัวสวิตช์
   บนมือถือเป้ากดกว้าง 42px กลางแถวยาว ๆ คือเป้าที่พลาดง่ายที่สุดเป้าหนึ่ง */
.as-tgl { cursor: pointer; }
.as-tgl.off .as-ic { background: var(--card2); color: var(--faint); }
.as-tgl.off .as-tx b { color: var(--muted); }
.as-tgl .tg { margin-top: 0; }

.as-more .as-ic.dim { background: var(--card2); color: var(--muted); }

/* ============================================================
   1B21 — เส้นเวลาของวัน (.td-rail)
   ============================================================
   แทน .td-up + .td-rem + .td-plan ที่เคยเป็นสามก้อนแยกกัน
   เส้นแกนตั้งเป็น ::before ของราง ไม่ใช่ border ของแต่ละแถว — แถวจึงเว้นระยะกันได้
   โดยที่เส้นยังต่อเนื่อง และจุดของแต่ละแถวทับเส้นพอดีเพราะอ้างพิกัดเดียวกัน */
/* ============================================================
   1B29 — เส้นเวลา: รายการจุดแวะ ไม่ใช่ตั๋วใบที่สอง
   ============================================================
   โครงตั๋ว (สองหมุด · เส้นประ · รอยปรุ) ย้ายไปอยู่ที่การ์ดบนใบเดียวใน 1B28 แล้ว
   การให้รางมีโครงเดียวกันอีกใบทำให้จอมีของซ้ำกันทั้งชุด แล้วสายตาต้องอ่านสองรอบ
   เพื่อแยกว่าตั๋วใบไหนพูดถึงอะไร · รางจึงเหลือหัวข้อบรรทัดเดียว แล้วให้แถบสีวิชา
   ทำงานของมันไป ซึ่งเป็นสิ่งเดียวที่รางมีและการ์ดไม่มี */
/* 1B38 · หัวข้อออกมายืนบนพื้นจอ การ์ดเหลือแต่แถว */
.td-railwrap { margin-top: 22px; }
.td-rail { position: relative;
  background: var(--card); border-radius: 20px; box-shadow: var(--shadow);
  padding: 6px 14px 8px; }

/* หัวข้อกับตัวเลขสรุปอยู่บรรทัดเดียวกัน คนละฝั่ง — ซ้ายบอกว่านี่คืออะไร
   ขวาบอกว่ามีเท่าไหร่
   1B38: หัวข้อเคยเป็นตัวเล็กสีจาง 13px ด้วยเหตุผลว่า "ของจริงคือแถวข้างล่าง"
   ซึ่งจริงแต่ไม่พอ — จอนี้มีของอยู่สามก้อนแล้ว (ตอนนี้ · เสี่ยงพัง · ที่เหลือ)
   ก้อนที่ไม่มีหัวข้อให้เกาะจะถูกกวาดตาข้ามไปทั้งก้อน ไม่ใช่แค่ตัวหัวข้อ
   17px/700 สีหมึกเต็ม = หัวข้อของส่วนหนึ่งในหน้า ยังเล็กกว่าชื่องานบนการ์ดฟ้า
   ซึ่งเป็นลำดับที่ถูก: การ์ดฟ้าคือคำตอบ ก้อนนี้คือของที่เหลือหลังจากนั้น */
.rl-lb { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 0 3px 10px; }
.rl-lb b { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -.015em; }
.rl-lb span { font-size: 11.5px; font-weight: 600; color: var(--muted);
  white-space: nowrap; }

/* 1B39 · กฎชุด .td-risk / .rk-* ถูกลบทิ้งพร้อมกับ riskBlock() ใน app.js
   ก้อน "เสี่ยงพัง" มีอายุรุ่นเดียว — งานเลยกำหนดอยู่ในแท็บ "งาน" ที่เดียว */

/* ---------- บรรทัดปิดท้าย: ทางไปเครื่องมือทั้งหมด ----------
   ของที่มาแทนกริดแปดก้อน · เป็นตัวหนังสือสีจางบรรทัดเดียว ไม่ใช่ปุ่ม
   เพราะมันไม่ใช่สิ่งที่จอนี้อยากให้กด มันแค่ต้องมีอยู่ให้คนที่ตามหาของหาเจอ */
.td-more { display: flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; margin-top: 20px; padding: 10px 0; background: none; border: none;
  cursor: pointer; font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--muted); }
.td-more svg { width: 14px; height: 14px; }
.td-more:active { color: var(--ink); }

/* ---- จุดแวะ ---- */
/* แถบสีเต็มความสูงของแถว ให้พื้นที่สีมากกว่าจุดเล็ก ๆ หลายเท่า สีจึงอ่านออก
   ตั้งแต่ยังไม่เพ่ง และมันคือสิ่งเดียวบนจอที่บอกว่า "เย็นนี้เป็นวิชาอะไรบ้าง" */
.dr-row { position: relative; display: flex; align-items: center; gap: 11px;
  width: 100%; text-align: left; background: none; border: none;
  padding: 8px 2px 8px 14px; color: var(--ink); }
.dr-row::before {
  content: ''; position: absolute; left: 0; top: 5px; bottom: 5px; width: 4px;
  border-radius: 2px; background: var(--sj, var(--line));
}
.dr-t { flex: none; width: 44px; font-size: 12.5px; color: var(--muted); font-weight: 700; }
.dr-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dr-b b { font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-m { font-size: 12px; color: var(--muted); }
/* คำเดียวในแถวที่ถือสีของวิชา — ตัวเชื่อมระหว่างแถบสีกับความหมายของมัน */
.dr-sj { font-style: normal; font-weight: 700; color: var(--sj, var(--muted)); }
.dr-go { flex: none; color: var(--muted); opacity: .5; display: flex; }
.dr-go svg { width: 15px; height: 15px; }
.dr-row:active { background: var(--press, rgba(127,127,127,.09)); border-radius: 10px; }

/* ช่วงพักไม่มีแถบสี — ช่องว่างระหว่างสองวิชาคือสิ่งที่ทำให้ "พัก" อ่านออกโดยไม่ต้องอ่านคำ */
.dr-row.brk { color: var(--muted); font-size: 12.5px; padding-top: 4px; padding-bottom: 4px; }
.dr-row.brk::before { background: none; }
/* ปลายทางเป็นแถวสุดท้ายของแกน ไม่ใช่หัวข้อ — นี่คือที่ที่ "หมดเวลา 21:30" ควรอยู่
   ตอนมันไปอยู่บนหัวตั๋วของราง มันซ้ำกับแถวนี้พอดีทั้งเลขและความหมาย */
.dr-row.end { color: var(--muted); font-size: 12.5px; padding-top: 9px; }
.dr-row.end::before { background: var(--line); opacity: .7; }
.dr-row.brk, .dr-row.end { pointer-events: none; }

/* ของที่ "ถึงเวลาแล้วต้องไป" ไม่มีวิชาเป็นเจ้าของ — ยืม --sj มาเป็นสีเตือนแทน
   แล้วแถบกับชื่อก็ได้สีนั้นเองโดยไม่ต้องเขียนกฎซ้ำ */
.dr-row.rem { --sj: var(--pri-yellow-text, #D97706); }
.dr-row.rem.late { --sj: var(--pri-red-text, #DC2626); }
.dr-row.rem.late .dr-m { color: var(--pri-red-text, #DC2626); }


/* ---- การ์ดโฟกัสรุ่นบีบ (1B21) ---- */
/* .tn-band (แถบเหตุผล) ถูกถอดออกตั้งแต่ 1B28 — เหตุผลย้ายไปอยู่บนหัวตั๋วแล้ว */
/* ---- 1B26: แถวตัวเลขสามช่อง ---- */
/* ของที่กวาดตาหา ไม่ใช่ของที่อ่านเป็นประโยค · เส้นคั่นตั้งทำให้มันอ่านเป็นตาราง
   ป้ายกำกับตัวเล็กข้างบนคือสิ่งที่ทำให้ "19:00" มีความหมาย โดยไม่ต้องเปลืองคำในค่า
   (เคยเขียนว่า "เริ่ม 19:00" ในบรรทัดยาว ซึ่งกินที่กว่าและยังอ่านเป็นประโยคอยู่ดี) */
.tn-cells { display: flex; margin-top: 12px;
  border-top: 1px solid var(--line); padding-top: 10px; }
.tn-cell { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 0 10px; border-left: 1px solid var(--line); }
.tn-cell:first-child { padding-left: 0; border-left: 0; }
.tn-cell:last-child { padding-right: 0; }
.tn-cell i { font-style: normal; font-size: 10.5px; font-weight: 700;
  letter-spacing: .03em; color: var(--muted); }
.tn-cell b { font-size: 15px; font-weight: 700; color: var(--ink);
  letter-spacing: -.015em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* คำว่า "ตอนนี้ · ฟิสิกส์" เคยเป็นน้ำเงิน ซึ่งแย่งความเป็นสีเน้นกับปุ่มข้างล่าง
   น้ำเงินทึบต้องมีที่เดียวบนจอ คือปุ่มที่ต้องกด */
/* 1B28: กฎสีของ .tn-eyebrow / .tn-title ย้ายไปอยู่กับบล็อกหัวตั๋วข้างบนแล้ว (ราวบรรทัด 90)
   เหลือไว้ตรงนี้จะชนะเพราะอยู่ท้ายไฟล์ แล้วคำว่า "ตอนนี้ · ฟิสิกส์" จะกลายเป็นเทา
   บนพื้นน้ำเงิน — พออ่านได้ในธีมมืด แต่แทบมองไม่เห็นในธีมสว่าง
   (กับดักเดิม: ทับกฎเดียวกันสองที่ในไฟล์เดียว แล้วเทสต์แค่ธีมเดียว) */
/* ชื่องานคือจุดโฟกัสจุดเดียวของการ์ด — ต้องใหญ่พอที่ตาลงตรงนี้ก่อนอย่างอื่นเสมอ */

.tn-bar { height: 4px; border-radius: 2px; background: var(--line);
  margin: 0 0 11px; overflow: hidden; }
.tn-bar i { display: block; height: 100%; border-radius: 2px; background: var(--blue); }
.tn-row { display: flex; align-items: stretch; gap: 8px; }
.tn-row .tn-cta { flex: 1; min-width: 0; margin: 0; }
/* .tn-eyebrow เดิมอยู่บรรทัดของตัวเอง จึงมี margin-top ติดมา — ในแถวบนมันต้องไม่ดันแถว
   และต้องกินที่ที่เหลือทั้งหมดเพื่อผลักป้ายไปชิดขวา */
.tn-top .tn-eyebrow { margin-top: 0; flex: 1; min-width: 0; }
.tn-ib { flex: none; width: 48px; border-radius: 15px; display: flex;
  align-items: center; justify-content: center;
  background: var(--card-2, rgba(127,127,127,.10)); border: 1px solid var(--line); color: var(--muted); }
.tn-ib svg { width: 19px; height: 19px; }
.tn-ib.done { color: var(--green, #16A34A); }
.tn-ib:active { transform: scale(.96); }

/* ============================================================
   1B22 — กริดฟีเจอร์ท้ายจอ "วันนี้"
   ============================================================
   สี่ช่องต่อแถวคือความหนาแน่นที่พอดีบนจอ 375px: ไทล์กว้าง ~74px ซึ่งยังแตะไม่พลาด
   และป้ายภาษาไทยยาวสุดที่ใช้ ("สแกนใบงาน") ยังลงได้ในบรรทัดเดียว
   ห้าช่องขึ้นไปป้ายจะขึ้นบรรทัดที่สองไม่เท่ากันแต่ละใบ แล้วแถวจะเดี้ยงทั้งแถว */
/* 1C12 · กฎชุดนี้กลับมาทำงานบนจอ "วันนี้" อีกครั้ง — toolsGrid() เป็นบล็อกสุดท้าย
   ของ HOME_ORDER แล้ว (ระหว่าง 1B38–1C11 มันไปวาดอยู่จอ scr-tools ซึ่งถูกถอดทิ้ง)
   ห้ามลบทั้งบล็อกเหมือนที่โน้ตเดิมเคยแนะนำ */
/* 1C12 · ปุ่มลอยมุมล่างขวา (.fd-fab สูง 52 · ลอยอยู่ทุกจอ) ทับป้ายของไทล์แถวล่างพอดี
   ตอนกริดกลับมาอยู่ท้ายจอ — เว้นที่ว่างใต้กริดให้เลื่อนพ้นปุ่มได้
   แก้ที่กริด ไม่ใช่ขยับปุ่ม เพราะปุ่มเป็นของทุกจอ ส่วนที่ว่างนี้เป็นของจอเดียว */
.td-tiles { margin-top: 22px; padding-bottom: 58px; }
/* ปุ่มลอยถูกพักไว้ (FAB_PARKED ใน feed.js · 1C30) = ที่ว่างหลบปุ่มไม่มีอะไรให้หลบแล้ว
   คืน 58px ให้หน้าแรก · เอาปุ่มกลับเมื่อไหร่ กฎนี้ปิดตัวเองเพราะปุ่มไม่ได้ [hidden] อีก */
.phone:has(.fd-fab[hidden]) .td-tiles { padding-bottom: 0; }
.tg-lb { font-size: 12.5px; font-weight: 700; color: var(--muted); margin: 0 0 10px 1px; }
.tg-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 6px; }

.tg-t { display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: none; border: none; padding: 0; color: var(--ink); }
/* กรอบไอคอนเป็นสี่เหลี่ยมมนไม่ใช่วงกลม — ทั้งแอปใช้สี่เหลี่ยมมนเป็นภาษาเดียว
   (การ์ด · ปุ่ม · ชิป) วงกลมจะอ่านเป็นรูปโปรไฟล์ซึ่งมีความหมายอื่นอยู่แล้ว */
.tg-ic { position: relative; width: 100%; aspect-ratio: 1; border-radius: 18px;
  display: grid; place-items: center; color: var(--tg-fg); }
/* ไอคอนนั่งบนแผ่นกลมขาวทึบ ไม่ใช่ลอยอยู่บนพื้นน้ำเงินเฉย ๆ
   ของเดิมเป็นเส้นสีจางบนพื้นน้ำเงิน คอนทราสต์ต่ำจนทั้งกริดอ่านเป็นก้อนสีเดียวกันแปดก้อน
   วงกลมขาวคือทรีตเมนต์เดียวกับตราบนปุ่ม Google ที่จอล็อกอิน — ทั้งแอปจึงพูดภาษาเดียวกัน
   ระบายสีที่ตัว svg เลย ไม่ต้องเพิ่ม element ซ้อนใน markup ที่วนลูปวาดแปดใบ */
.tg-ic svg { width: 23px; height: 23px; stroke-width: 2.05;
  background: #fff; color: #16306B; border-radius: 50%; padding: 8px;
  box-sizing: content-box; }
/* ป้ายยาวไม่เท่ากัน (2 พยางค์ ถึง "สแกนตารางเรียน") — กันความสูงไว้สองบรรทัดเท่ากันทุกใบ
   ไม่งั้นใบที่ป้ายสั้นจะลอยขึ้น แล้วแถวอ่านเป็นฟันปลาแทนที่จะเป็นตาราง */
.tg-lb2 { font-size: 11px; font-weight: 600; line-height: 1.25; text-align: center;
  color: var(--ink); opacity: .78; letter-spacing: -.02em; min-height: 2.5em;
  display: flex; align-items: flex-start; justify-content: center; }
.tg-t:active .tg-ic { transform: scale(.94); }
.tg-t:active .tg-lb2 { color: var(--ink); }

/* ตัวเลขมุมขวาบน — ขึ้นเฉพาะตอนมีอะไรรออยู่จริง ไทล์ที่ว่างต้องเงียบสนิท */
.tg-ct { position: absolute; top: -5px; right: -5px; min-width: 19px; height: 19px;
  padding: 0 5px; border-radius: 10px; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; font-style: normal; line-height: 1;
  background: var(--card); color: var(--ink);
  box-shadow: 0 0 0 2.5px var(--scr), var(--shadow); }
/* บั๊กตัวเดียวกับป้ายบนหัวตั๋ว: --pri-red-text เป็นสีตัวอักษรที่พลิกตามธีม
   ธีมมืดได้ #FF9AA6 มาเป็นพื้นของแบดจ์ที่มีตัวอักษรขาว = ชมพูซีดที่แทบไม่มีน้ำหนัก
   ทั้งที่แบดจ์มีหน้าที่เดียวคือ "ดึงสายตา" · แบดจ์ต้องดังเท่ากันทุกธีม จึงใช้ --sig-red */
.tg-ct.hot { background: var(--sig-red); color: #fff; }
/* จุดเปล่า ๆ (ของรางวัลรายวันที่ยังไม่ได้กดรับ) — มีชิ้นเดียวต่อวัน เลข "1" จึงไม่บอกอะไรเพิ่ม
   ต้องเป็นวงกลมทึบ ไม่ใช่แคปซูลว่าง ซึ่งอ่านเป็นแบดจ์ที่โหลดตัวเลขไม่สำเร็จ */
.tg-ct.dot { min-width: 0; width: 11px; height: 11px; padding: 0; border-radius: 50%;
  top: -3px; right: -3px; }

/* โทนสีของไทล์: จับกลุ่มตามหน้าที่ ไม่ได้ไล่สีรุ้งทีละใบ
     tone-in   = เอางานเข้าระบบ (สแกน · กล่องเข้า · ตัวเชื่อม)
     tone-time = เวลาและแผน (แผนวันนี้ · ปฏิทิน · ตารางเรียน)
     tone-me   = ของตัวเอง (สถิติ · ร้านค้า)
   สามกลุ่มตรงกับสามคำถามที่คนเปิดแอปมาถาม จึงกวาดตาหาได้โดยไม่ต้องอ่านป้ายทุกใบ

   ห้ามใส่สีดิบลงไปเอง — ต้องใช้ตัวแปร --tile-* ของธีม เพราะแอปมีธีมให้ซื้อ/คราฟต์
   อีกหกชุด (warm · space · deepocean · sweet · earth2 …) สีที่ฮาร์ดโค้ดจะสวยธีมเดียว
   แล้วหลุดกรอบทุกธีมที่เหลือ · ธีมพื้นฐานตั้งใจให้อยู่ในตระกูลฟ้าทั้งหมด ไทล์จึงต่างกัน
   ด้วยน้ำหนักสีไม่ใช่คนละวงล้อสี ซึ่งเป็นสิ่งที่ตั้งใจ ไม่ใช่ข้อจำกัด
   พื้นชิปใช้ตัวเดียวกันหมดเพื่อให้แถวอ่านเป็นชุดเดียว สีจึงอยู่ที่ไอคอนอย่างเดียว */
/* 1B24: กรอบสัญลักษณ์เป็นน้ำเงินทุกใบ
   เคยแบ่งเป็นสามโทน (น้ำเงิน/ม่วง/เขียวน้ำทะเล) เพื่อจับกลุ่มตามหน้าที่ ซึ่งล้มเพราะ
   สองโทนหลังในธีมมืดจางจนเกือบเป็นสีพื้น — กลายเป็นไทล์ที่มองไม่เห็นครึ่งกริด
   การจับกลุ่มด้วยสีจึงไม่คุ้มกับการที่ของหายไปจากสายตา ลำดับซ้าย-ขวาทำหน้าที่นั้นแทนได้

   พื้นกรอบ = ทับฟ้าจาง ๆ สองชั้นบนสีการ์ด (≈28%) ไม่ใช่ฟ้าทึบ:
   ทึบแปดใบจะกลายเป็นสีเน้น 8 ก้อนแข่งกับปุ่ม "เริ่มทำเลย" ซึ่งผิดกฎ 60/30/10 อีกทางหนึ่ง
   สองชั้นนี้อ่านออกชัดว่าเป็นน้ำเงิน แต่ยังเบากว่าปุ่มอยู่หนึ่งระดับเสมอทุกธีม
   (ใช้ linear-gradient ซ้อนแทน color-mix เพราะ color-mix ต้องการ Safari 16.4 ขึ้นไป) */
/* 1B25: กรอบทึบน้ำเงิน + สัญลักษณ์ขาว — ชุดสีเดียวกับปุ่มแท็บที่ถูกเลือกอยู่บนแถบล่าง
   ฟ้าจางซ้อนสองชั้นของรอบก่อนยังอ่านเป็น "การ์ดสีเทาที่บังเอิญอมฟ้า" ไม่ใช่สีน้ำเงิน
   เพราะบนพื้นมืด สีที่จางกว่าพื้นแค่ขั้นเดียวจะถูกตาอ่านเป็นพื้นผิว ไม่ใช่เป็นสี
   ตัวเทียบที่ถูกต้องคือแท็บ "วันนี้" ที่กำลังทำงานอยู่: ทึบ --fill กับสัญลักษณ์ขาว */
.tg-t { --tg-bg: var(--fill, #2563EB); --tg-fg: var(--on-fill, #fff); }
.tg-ic { background: var(--tg-bg); box-shadow: var(--shadow); }
/* เส้นหนาขึ้นนิดเดียว เพราะสัญลักษณ์ขาวบนพื้นทึบต้องการน้ำหนักมากกว่าบนพื้นจาง
   จึงจะดูหนักเท่ากันด้วยตา (เส้นบางบนพื้นเข้มถูกอ่านว่าจางกว่าที่เป็นจริง) */
.tg-ic svg { stroke-width: 2.15; }
/* ป้ายบนกรอบทึบไม่ต้องมีวงแหวนสีพื้นจอ — ขอบของกรอบตัดมันออกจากพื้นให้อยู่แล้ว
   วงแหวนสีพื้นจอบนกรอบทึบจะกลายเป็นรูเจาะที่มองทะลุเห็นพื้นหลังแทน */
/* ไทล์วางอยู่บนพื้นจอตรง ๆ ไม่ได้อยู่ในการ์ด วงแหวนจึงต้องเป็นสีพื้นจอ (--scr)
   ไม่ใช่ --card · และไม่ใช่ --bg ซึ่งไม่มีอยู่จริงในระบบธีมนี้ */
.tg-ct { box-shadow: 0 0 0 2.5px var(--scr), var(--shadow); }
.tg-t:active .tg-ic { filter: brightness(.88); }

/* จอกว้างขึ้นแล้วห้ามคลี่เป็นแถวเดียวแปดช่อง
   เคยตั้งไว้ repeat(8,1fr) ที่ 620px ซึ่งพังสองชั้นพร้อมกัน: ป้ายไทยยาว ๆ อย่าง
   "สแกนตารางเรียน" ถูกบีบจนขึ้นสามบรรทัดคนละความสูงกับเพื่อนบ้าน แถวเลยเป็นฟันปลา
   และแถวเดียวยาว ๆ ทำลายลำดับสายตาที่ตั้งใจไว้ — กริดสองแถวสื่อว่า "แถวบนสำคัญกว่า"
   ส่วนแถวเดียวสื่อว่าทุกใบเท่ากัน ซึ่งคือการไม่จัดลำดับให้เลย
   สี่ช่องต่อแถวจึงคงที่ทุกความกว้าง · จอกว้างได้กรอบที่ใหญ่ขึ้นแทน ไม่ใช่ช่องที่มากขึ้น */
@media (min-width: 620px) {
  .td-tiles { max-width: 620px; }
  .tg-grid { gap: 16px 12px; }
  .tg-ic { border-radius: 22px; }
}

/* .th-guess (นาฬิกา "เวลามาจากการเดา" บนหัวจอ) ถูกถอดออกใน 1B25 —
   ย้ายลงไปอยู่ในกริดในรูปไทล์ "สแกนตารางเรียน" ที่ติดป้าย ! ซึ่งมีอยู่แล้ว
   บรรทัดตัวเลขบนหัวจอยังต้องกันตกสองแถว จึงเก็บกฎ nowrap ไว้ */
.td-head .th-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 1B41 · ปุ่มย้อนกลับบนหัวจอน้องไซ
   จอนี้เสียแท็บของตัวเองไปตอนคืนช่องกลางให้ปุ่ม + (แถบต้องมีช่องคี่ถึงจะมีกึ่งกลาง)
   ทางเข้าหลักคือช่องถามน้องไซบนหน้าแรก ซึ่งเป็นการ "เข้าไป" ไม่ใช่การ "สลับแท็บ"
   ของที่เข้าไปแล้วต้องมีทางออกที่เห็นได้ ไม่ใช่ให้เดาว่ากดแท็บไหนถึงจะกลับ */
.sh-back {
  flex: none; width: 34px; height: 34px; margin-left: -4px;
  display: grid; place-items: center;
  border: none; border-radius: 12px; cursor: pointer;
  background: none; color: var(--muted);
  transition: background .14s ease;
}
.sh-back svg { width: 20px; height: 20px; transform: rotate(180deg); }
.sh-back:active { background: var(--card2); }

/* ============================================================
   1B42 · F1 — การ์ด "อันนี้เป็นงานใหม่ใช่ไหม" ในบทสนทนา
   ============================================================
   ทรงเป็นฟองของน้องไซที่กดได้ ไม่ใช่การ์ดชนิดใหม่ — มันอยู่ในสายสนทนา
   จึงต้องอ่านเป็นสิ่งที่น้องไซพูด ไม่ใช่กล่องระบบที่โผล่ขึ้นมาขวาง */
.ai-offer {
  flex: 1; min-width: 0;
  background: var(--card); border: 1px solid var(--blue);
  border-radius: 4px 16px 16px 16px; padding: 12px 13px 11px;
}
.ao-h { display: block; font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.ao-t {
  margin-top: 4px; font-size: 13.5px; line-height: 1.45; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ao-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.ao-chips span {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--card2); border-radius: 999px; padding: 3px 9px; white-space: nowrap;
}
.ao-row { display: flex; gap: 8px; margin-top: 11px; }
.ao-yes {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: none; border-radius: 12px; padding: 10px 0; cursor: pointer;
  background: var(--fill); color: var(--on-fill);
  font-family: inherit; font-size: 13px; font-weight: 700;
}
.ao-yes svg { width: 15px; height: 15px; }
.ao-no {
  flex: none; border: 1px solid var(--line); border-radius: 12px; padding: 10px 13px;
  cursor: pointer; background: none; color: var(--muted);
  font-family: inherit; font-size: 13px; font-weight: 600;
}
.ao-yes:active, .ao-no:active { transform: scale(.97); }
/* ตอบไปแล้ว = เหลือไว้เป็นบันทึกว่าเคยถาม ไม่ใช่ปุ่มที่กดซ้ำได้ */
.ai-offer.spent { border-color: var(--line); opacity: .72; }

/* ============================================================
   1B54 · แผ่นเพิ่มงาน — สองท่าที่ไม่ต้องพิมพ์อยู่บนสุดเป็นไทล์
   ============================================================
   คำสัญญาทั้งหมดของหน้าเพิ่มงานคือ "ไม่ต้องพิมพ์" แต่แผ่นเดิมวางท่าที่ไม่ต้องพิมพ์
   ปนกับท่าที่ต้องพิมพ์ทีละช่อง โดยให้หน้าตาเท่ากันเป๊ะทั้งหกแถว
   คนจึงกดแถวแรกที่ตาไปโดน ไม่ใช่แถวที่เร็วที่สุดสำหรับเขา */
.as-heroes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 4px 0 2px; }
.as-hero {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 15px 14px 14px; border: none; border-radius: 20px; cursor: pointer;
  background: linear-gradient(145deg, var(--blue), var(--fill));
  color: var(--on-fill); font-family: inherit; text-align: left;
  box-shadow: 0 12px 26px -12px rgba(37, 99, 235, .6);
  transition: transform .14s ease;
}
.as-hero:active { transform: scale(.97); }
.as-hero-ic {
  display: grid; place-items: center; width: 38px; height: 38px; margin-bottom: 8px;
  border-radius: 14px; background: rgba(255, 255, 255, .22);
}
.as-hero-ic svg { width: 20px; height: 20px; }
.as-hero b { font-size: 14.5px; font-weight: 700; letter-spacing: -.015em; line-height: 1.3; }
.as-hero span { font-size: 11.5px; opacity: .85; line-height: 1.4; }

/* 1B93 · ท่าที่สาม "ถามน้องไซ" — เจ้าของขอปุ่ม AI ในแผ่นนี้ (13 ก.ย. 2569)

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

   และทำให้จางกว่าสองอันบนหนึ่งขั้น (พื้นโปร่ง ขอบสีแทนพื้นทึบ) เพราะคำสัญญา
   ของแผ่นนี้คือ "ไม่ต้องพิมพ์" — ท่าที่เร็วที่สุดต้องยังเด่นที่สุดอยู่ */
.as-hero.wide {
  grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 12px;
  padding: 12px 14px; margin-top: 10px; border-radius: 18px;
  background: var(--blue-soft);
  border: 1.5px solid var(--blue); color: var(--blue); box-shadow: none;
}
.as-hero.wide .as-hero-ic {
  width: 34px; height: 34px; margin-bottom: 0; flex: none;
  background: var(--card);
}
.as-hero.wide .as-tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.as-hero.wide span { opacity: .78; }

/* คั่นก่อนรายการทางสำรอง — เส้นกับคำสั้น ๆ บอกว่าข้างล่างเป็นของอีกชนิด
   ไม่ใช่ตัวเลือกที่ห้าหกเจ็ดของชุดเดียวกัน */
.as-or {
  display: flex; align-items: center; gap: 10px;
  margin: 16px 2px 4px; font-size: 12px; font-weight: 600; color: var(--faint);
}
.as-or::after { content: ''; flex: 1; height: 1px; background: var(--line); }

/* ทางสำรองเตี้ยลง — มันคือรายการ ไม่ใช่ปุ่มหลัก */
.as-row.slim { padding: 11px 2px; }
.as-row.slim + .as-row.slim { border-top: 1px solid var(--line); }
.as-row.slim .as-ic { width: 34px; height: 34px; }
.as-row.slim .as-ic svg { width: 17px; height: 17px; }
.as-row.slim .as-tx b { font-size: 14px; }

/* ============================================================
   1B57 · แถวสถิติสามช่องบนจอวันนี้
   ============================================================
   สามช่องเท่ากันเป๊ะ · ไอคอนอยู่ในชิปสีจางด้านบน ตัวเลขใหญ่ ป้ายเล็ก
   โครงนี้มาจากภาพอ้างอิงตรง ๆ (2h 45m Study Time / 5 Task / 12 Days Streak)
   ต่างกันที่ตัวเลขของเราไม่มีหน่วยแทรกกลาง — หน่วยอยู่ในป้ายข้างล่าง
   เพราะช่องที่มีเลขสองตัวจะดูไม่เป็นชุดเดียวกับช่องที่มีเลขตัวเดียว */
/* auto-flow แทน repeat(3,1fr) — ผลเหมือนเดิมเป๊ะตอนมีสามช่อง แต่ปรับตามจำนวนที่เหลือ
   เมื่อเจ้าของระบบปิดช่องไหนจาก Control Center · ตรึงไว้ 3 แล้วปิดช่องเดียว
   จะเหลือช่องว่างค้างอยู่ ซึ่งดูเหมือนของหาย ไม่ใช่ของที่ถูกเอาออก */
.td-stats { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 9px; margin-top: 14px; }
.ts {
  background: var(--soft-card, var(--card)); border-radius: 19px; padding: 12px 11px;
  box-shadow: var(--soft-shadow, var(--shadow));
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
}
/* กระเบื้องไล่สีแบบไอคอนแอป + ภาพทึบสีขาว (ภาพอยู่ใน STAT_ART ของ app.js)
   สามสีแยกกันชัด และตรงกับเรื่องของช่อง: ฟ้า = เวลาว่าง (สบาย) · ม่วง = งานค้าง · ส้มแดง = ไฟต่อเนื่อง
   ประกายขอบบน + เงาสีเดียวกับกระเบื้อง ให้ดูเป็นก้อนนูน ไม่ใช่สติกเกอร์แปะ
   ขนาด 30 + ระยะล่าง 7 = 37px เท่าของเดิม (29 + 8) — หน้าแรกเลื่อนอยู่แล้ว ห้ามสูงขึ้น
   --ts-ink = สีเข้มของกระเบื้อง ใช้ระบายเข็ม/บรรทัด/ช่วงเวลาบนภาพสีขาว (currentColor) */
.ts-ic {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 10px; margin-bottom: 7px;
  color: var(--ts-ink);
  background: linear-gradient(150deg, var(--ts-a), var(--ts-b));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(0,0,0,.08),
    0 5px 12px -5px var(--ts-glow);
}
.ts-ic svg { width: 19px; height: 19px; filter: drop-shadow(0 1px 1px rgba(0,0,0,.14)); }
.ts.v { --ts-a: #7DD3FC; --ts-b: #2563EB; --ts-ink: #1D4ED8; --ts-glow: rgba(37,99,235,.55); }
.ts.w { --ts-a: #C4B5FD; --ts-b: #7C3AED; --ts-ink: #6D28D9; --ts-glow: rgba(124,58,237,.55); }
.ts.g { --ts-a: #FDBA74; --ts-b: #EF4444; --ts-ink: #DC2626; --ts-glow: rgba(239,68,68,.5); }
/* เปลวไฟไหวช้า ๆ จากโคนเปลว — ของชิ้นเดียวในแถวที่ขยับ เพราะมันคือ "ไฟที่ยังไม่ดับ" */
.ts-flame { transform-box: fill-box; transform-origin: 50% 100%; animation: ts-flame 2.4s ease-in-out infinite; }
@keyframes ts-flame {
  0%, 100% { transform: scale(1, 1) skewX(0); }
  35% { transform: scale(.96, 1.05) skewX(-2deg); }
  70% { transform: scale(1.03, .96) skewX(1.5deg); }
}
@media (prefers-reduced-motion: reduce) { .ts-flame { animation: none; } }
/* Astral Black: ขาว–ดำ–เทาล้วน → กระเบื้องเงินไล่เทา ภาพขาว ระบายเทาเข้ม */
:root[data-theme="astral"] .ts-ic { filter: grayscale(1); }
.ts b {
  display: block; font-family: 'Outfit', ui-monospace, monospace;
  font-size: 21px; font-weight: 700; letter-spacing: -.03em; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.ts i {
  font-style: normal; display: block; margin-top: 3px;
  font-size: 10px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- 1B57 · หัวการ์ดคำสั่งเป็นไล่สีพร้อมวงกลมซ้อนหลัง ----
   ภาพร่างวาดไว้แบบนี้ · สีทึบสีเดียวอ่านเป็น "แถบสี" ส่วนไล่สีที่มีวงกลมจาง ๆ
   ซ้อนอยู่หลังอ่านเป็น "วัตถุ" ซึ่งเป็นสิ่งที่ทำให้การ์ดใบนี้ดูเป็นของชิ้นเอก
   ไม่ใช่บล็อกสีที่ใหญ่กว่าเพื่อน */
.td-now .tn-head {
  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%);
}
.td-now .tn-head::after {
  content: ''; position: absolute; right: -44px; top: -54px;
  width: 168px; height: 168px; border-radius: 50%;
  background: rgba(255, 255, 255, .11); pointer-events: none;
}
.td-now .tn-head::before {
  content: ''; position: absolute; right: 18px; bottom: -66px;
  width: 124px; height: 124px; border-radius: 50%;
  background: rgba(255, 255, 255, .07); pointer-events: none;
}
/* เนื้อหาต้องอยู่เหนือวงกลม ไม่งั้นวงกลมทับตัวหนังสือ */
.td-now .tn-head > * { position: relative; z-index: 2; }

/* ============================================================
   แถวสถิติหน้าแรก — สีตามธีมแบบรุ่นก่อน 1C41b (เจ้าของส่งรูปเทียบ: "ยังดูแปลก ๆ ปรับสีให้คล้ายรูปสอง")
   ------------------------------------------------------------
   กระเบื้องไล่สีฟ้า/ม่วง/ส้มแดงตายตัว + ภาพขาวทึบ หลุดจากทุกธีม (บน Deep Ocean ดูเป็นปุ่มแอปอื่นแปะมา)
   กลับไปใช้สีของธีมชุดเดิม: เวลาว่าง = --blue · งานค้าง = เหลืองของระดับความสำคัญ · ต่อเนื่อง = --good
   กระเบื้อง = พื้นจาง 18% + เส้นขอบบางสีเดียวกัน · ภาพสองโทนสีเดียว (STAT_ART ใน app.js)
   การ์ดทั้งใบได้ขอบสว่างบาง ๆ เหมือนในรูปสอง
   ============================================================ */
.ts.v { --ts-c: var(--blue); }
.ts.w { --ts-c: var(--pri-yellow-text, var(--warn)); }
.ts.g { --ts-c: var(--good); }
.ts-ic {
  color: var(--ts-c);
  background: color-mix(in srgb, var(--ts-c) 18%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ts-c) 38%, transparent);
}
.ts-ic svg { width: 18px; height: 18px; filter: none; }
.ts { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent), var(--soft-shadow, var(--shadow)); }

/* ช่อง "วันต่อเนื่อง" ใช้สีไฟ (เจ้าของ: "ใช้โทนสีเกี่ยวกับไฟ") — เดิมเป็น --good (เขียวอมฟ้าบน Deep Ocean) ไม่เข้ากับเปลวไฟ
   ส้มทุกธีม (ไฟสีเดียวไม่ว่าพื้นจะเป็นอะไร) · เปลวในเป็นเหลืองอำพัน (--ts-c2) ให้ดูมีแกนร้อนตรงกลาง
   Astral Black ยังเป็นขาวดำตามกฎ grayscale ข้างบน */
.ts.g { --ts-c: #F97316; --ts-c2: #FBBF24; }

/* ---------- 24 ต.ค. 69 · แถบบนสุดแบบ Duolingo (todayTop ใน app.js) ----------
   ตัวเลขของเราล้วน ๆ: วันต่อเนื่อง · โทเคน · Candy (ช่วงอีเวนต์) · อันดับ ชิดซ้าย กระดิ่งชิดขวา · สูง 44px บรรทัดเดียว
   ชิปไม่มีกรอบ (ตัวเลขกับไอคอนพอแล้ว แบบ Duolingo) · ปุ่มอีเวนต์ย้ายไปเป็นช่องของตัวเองข้างล่าง (.td-event) */
.td-top { display: flex; align-items: center; gap: 4px; min-height: 44px; }
.tt-chip {
  display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 9px;
  border: 0; border-radius: 999px; background: transparent; color: var(--ink);
  font: inherit; font-size: 17px; font-weight: 800; text-decoration: none; cursor: pointer;
  font-variant-numeric: tabular-nums; -webkit-tap-highlight-color: transparent;
}
.tt-chip:first-child { padding-left: 2px; }
span.tt-chip { cursor: default; }
.tt-chip:active { background: var(--card2); }
.tt-chip:focus-visible, .td-event:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.tt-chip svg { width: 24px; height: 24px; flex: none; }
.tt-streak { color: #F97316; --ts-c2: #FBBF24; }
.tt-tok b { color: var(--ink); }
.tt-candy { color: #f0569a; }
.tt-rank { color: #D9A21F; }
.tt-rank b { color: var(--gold-text, #D9A21F); font-size: 15px; }
/* กระดิ่งของหัวจอมาต่อท้ายแถบ (headBell) ชิดขวา */
.tt-acts { display: flex; align-items: center; flex: none; margin-left: auto; }

/* 24 ต.ค. 69 · แถบมีกรอบของมันเอง (เจ้าของ: "ยังดูลอยไป อยากให้มันมีกรอบ") — ตัวเลขลอยบนฉากธีมไม่มีขอบเขต
   ตาเลยไม่รู้ว่าเป็นชุดเดียวกัน · กรอบกระจกบาง ๆ ใบเดียวรวมทั้งแถบรวมกระดิ่ง สูงเท่าเดิม (ไม่ดันหน้าแรกลง)
   ใช้ --glass/--glass-line ของธีม จึงเข้ากับทุกธีมเอง · กระดิ่งเลิกวงกลมแยก กลายเป็นปุ่มในกรอบ */
#menuBody .td-top {
  min-height: 48px; padding: 2px 4px 2px 8px; gap: 2px; border-radius: 999px;
  background: var(--glass, var(--card));
  border: 1px solid var(--glass-line, var(--line));
  box-shadow: 0 8px 22px -16px rgba(0, 0, 0, .55), inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2);
}
#menuBody .td-top .tt-chip { height: 40px; }
#menuBody .td-top .th-bell {
  width: 40px; height: 40px; border: 0; box-shadow: none;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
}
:root[data-lite] #menuBody .td-top { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--card); }

/* ---------- ช่องอีเวนต์ (eventSlot ใน app.js) ----------
   การ์ดเต็มความกว้าง สูง 60px — สูงพอให้รูปฟักทอง ชื่อ ตัวนับ และปุ่มอ่านได้ในแวบเดียว
   แต่เตี้ยกว่าการ์ด "ตอนนี้" มาก จึงไม่แย่งว่าอะไรสำคัญที่สุด · สีม่วงกลางคืนคงที่ทุกธีม เพราะเป็นสีของอีเวนต์ ไม่ใช่ของแอป */
.td-event {
  position: relative; display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 8px 10px 8px 8px;
  border-radius: 18px; text-decoration: none; color: #f4eeff; overflow: hidden;
  background: radial-gradient(120% 140% at 0% 0%, #7a4fe0 0%, #3b2580 45%, #1d1640 100%);
  border: 1px solid #9d7cf0; box-shadow: 0 8px 22px -14px rgba(122, 79, 224, .9);
  -webkit-tap-highlight-color: transparent;
}
/* ดาวจาง ๆ มุมขวา — บอกว่าเป็นของพิเศษช่วงนี้ โดยไม่ต้องมีข้อความ */
.td-event::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: radial-gradient(1.5px 1.5px at 72% 22%, #fff, transparent), radial-gradient(1px 1px at 84% 70%, #fff, transparent),
    radial-gradient(1.2px 1.2px at 60% 78%, #fff, transparent), radial-gradient(1px 1px at 93% 30%, #fff, transparent);
}
.td-event:active { transform: scale(.985); }
.te-art { flex: none; width: 46px; height: 46px; display: grid; place-items: center; border-radius: 14px;
  background: radial-gradient(circle at 50% 60%, rgba(255, 154, 46, .35), transparent 70%); }
.te-art svg { width: 42px; height: 40px; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .35)); animation: te-bob 3.2s ease-in-out infinite; }
@keyframes te-bob { 0%, 100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-2px) rotate(3deg); } }
.te-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.te-tx b { font-size: 15px; font-weight: 800; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.te-tag { font-weight: 600; color: #d9c8ff; }
.te-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; line-height: 1.2; }
.te-meta i { font-style: normal; display: inline-flex; align-items: center; gap: 3px; font-weight: 700; }
.te-left { color: #ffd166; font-variant-numeric: tabular-nums; }
.te-candy { color: #ff8cc0; font-variant-numeric: tabular-nums; }
.te-candy svg { width: 15px; height: 15px; }
.te-try { color: #cbbcf5; font-weight: 600 !important; padding: 1px 7px; border-radius: 999px; background: rgba(255, 255, 255, .12); }
.te-go { position: relative; z-index: 1; flex: none; padding: 8px 14px; border-radius: 999px; font-size: 13px; font-weight: 800;
  background: #fff; color: #4b2aa8; box-shadow: 0 3px 0 rgba(0, 0, 0, .25); }
:root[data-lite] .te-art svg { animation: none; }
@media (prefers-reduced-motion: reduce) { .te-art svg { animation: none; } .td-event:active { transform: none; } }

/* ---------- การ์ดอีเวนต์แบบมีภาพ (.td-event.art) ----------
   เจ้าของ: "ปรับให้การ์ด halloween สวย ๆ ด้วยได้ไหม มันตัวละครอะไรพวกนั้น" — ได้ที่ของบรรทัด "วันนี้ไปไหน" มา
   พื้น = โถงประตูสี่บานของอีเวนต์ · ฝั่งซ้ายไล่มืดให้ตัวหนังสืออ่านได้ · NPC สี่ไบโอมยืนเรียงฝั่งขวา ขยับหายใจเหลื่อมกัน
   สูง ~120px (ที่ของบรรทัด "วันนี้ไปไหน" + การ์ดอีเวนต์เดิม) · ยังเตี้ยกว่าการ์ด "ตอนนี้" มาก ลำดับความสำคัญของจอไม่เปลี่ยน */
.td-event.art {
  display: block; min-height: 118px; padding: 10px 14px 11px; gap: 0; line-height: 1.2;
  background: #140f2e; border: 1px solid #8f6fe8; box-shadow: 0 10px 26px -16px rgba(122, 79, 224, 1);
  isolation: isolate;
}
.td-event.art::after { display: none; }
.te-bg { position: absolute; inset: 0; z-index: -1; background: var(--te-art) 50% 35% / cover no-repeat; }
.te-bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(16, 10, 38, .94) 0%, rgba(16, 10, 38, .8) 38%, rgba(16, 10, 38, .25) 68%, rgba(16, 10, 38, .05) 100%),
    linear-gradient(0deg, rgba(16, 10, 38, .7) 0%, transparent 45%); }
.te-cast { position: absolute; right: 2px; bottom: -3px; display: flex; align-items: flex-end; z-index: 0; pointer-events: none; }
.te-cast img { display: block; height: 76px; width: auto; margin-left: -13px; transform-origin: 50% 100%;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, .55)); animation: te-idle 3.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.85s); }
.te-cast img:nth-child(2) { height: 82px; }
.te-cast img:nth-child(3) { height: 74px; }
.te-cast img:nth-child(4) { height: 84px; }
@keyframes te-idle { 0%, 100% { transform: translateY(0) scaleY(1); } 50% { transform: translateY(-1.5px) scaleY(1.015); } }
.td-event.art .te-tx { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; max-width: 58%; }
.td-event.art .te-left { font-style: normal; font-size: 11px; font-weight: 800; color: #2a1600; background: #ffc94d;
  padding: 2px 8px; border-radius: 999px; font-variant-numeric: tabular-nums; box-shadow: 0 2px 0 rgba(0, 0, 0, .3); }
.te-name { font-size: 22px !important; font-weight: 900 !important; letter-spacing: .01em; line-height: 1.1 !important; margin-top: 4px;
  color: #fff3dc; text-shadow: 0 0 14px rgba(255, 150, 40, .55), 0 2px 0 #3b1d00; }
.td-event.art .te-tag { font-size: 12px; font-weight: 700; line-height: 1.3; color: #d9c8ff; text-shadow: 0 1px 2px #000; }
.te-foot { display: flex; align-items: center; gap: 7px; margin-top: 4px; }
.td-event.art .te-go { padding: 6px 16px; font-size: 13px; line-height: 1.2; background: linear-gradient(180deg, #ffb347, #f07f16); color: #2a1100;
  box-shadow: 0 3px 0 #8a3b00; }
.td-event.art .te-try { font-style: normal; font-size: 11px; }
:root[data-lite] .te-cast img { animation: none; }
@media (prefers-reduced-motion: reduce) { .te-cast img { animation: none; } }

/* ---------- ป้าย "วันนี้ไปไหน" บนหัวข้อราง (railDayChip) ----------
   แทนบรรทัดเต็มที่ออกจากหน้าแรก · เงียบเมื่อรู้แล้ว สีเน้นเมื่อยังไม่รู้ (ask) */
.rl-lb .rl-day {
  margin-left: auto; display: inline-flex; align-items: center; gap: 4px; max-width: 46%; height: 24px; padding: 0 9px 0 7px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--muted);
  font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer; align-self: center;
}
.rl-lb .rl-day svg { width: 13px; height: 13px; flex: none; }
.rl-lb .rl-day em { font-style: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rl-lb .rl-day.ask { background: var(--fill, #2563EB); border-color: transparent; color: var(--on-fill, #fff); }
.rl-lb:has(.rl-day) > span { margin-left: 0; }

/* จอแคบมาก (≤340px): ชิปชิดกันขึ้น ตัวอักษรเล็กลงหนึ่งขั้น · การ์ดอีเวนต์เหลือ NPC สองตัว */
@media (max-width: 340px) {
  .tt-chip { padding: 0 5px; font-size: 15px; } .tt-chip svg { width: 21px; height: 21px; }
  .td-event { gap: 9px; } .td-event:not(.art) .te-tag { display: none; } .te-go { padding: 7px 11px; }
  .te-cast img:nth-child(1), .te-cast img:nth-child(3) { display: none; }
}

/* ---------- 24 ต.ค. 69 · การ์ดหลักเป็นสไลด์ (heroDeck ใน app.js) ----------
   รางแนวนอน scroll-snap ของเบราว์เซอร์เอง — ปัดด้วยนิ้วลื่นเท่าแอปจริงโดยไม่ต้องเขียนตัวลากเอง
   สองสไลด์สูงเท่ากันเสมอ (ยืดตามการ์ดงาน) · จุดใต้การ์ดบอกว่าอยู่สไลด์ไหน ในจุดมีแถบเวลานับถอยหลังก่อนเลื่อนเอง */
.td-deck { position: relative; }
#menuBody > .td-deck { margin-top: 12px; }
.dk-track {
  display: flex; align-items: stretch; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; border-radius: 28px;
  /* เงาของการ์ดงานล้นออกนอกกรอบได้ — เผื่อขอบให้เงาไม่โดนตัด */
  margin: -14px -14px 0; padding: 14px 14px 18px; scroll-padding-inline: 14px;
}
.dk-track::-webkit-scrollbar { display: none; }
.dk-slide { flex: 0 0 100%; min-width: 0; scroll-snap-align: center; scroll-snap-stop: always; display: flex; flex-direction: column; }
.dk-slide + .dk-slide { margin-left: 28px; }
.dk-slide > * { margin-top: 0 !important; }
/* รางสไลด์ตัดทุกอย่างที่ล้นขอบ รวมถึงเงา — เงาใหญ่ของการ์ดงานจึงโดนตัดเป็นกรอบจาง ๆ ให้เห็นบนธีมสว่าง
   ในสไลด์ใช้เงาที่สั้นพอจะจบในระยะเผื่อของราง */
.dk-slide > :is(.td-now, .td-clear, .td-empty, .td-hero) { box-shadow: 0 10px 18px -14px rgba(0, 0, 0, .45) !important; }
.dk-slide > .td-now, .dk-slide > .td-clear, .dk-slide > .td-empty, .dk-slide > .td-hero { flex: 1; }
/* 25 ต.ค. 69 · เจ้าของ: "ปรับให้มันกดง่ายกว่านี้ ปุ่มใหญ่กว่านี้" — เดิมปุ่มคือจุด 8×8 เอง
   (::before ที่ตั้งใจขยายที่กดโดน overflow:hidden ของจุดตัดทิ้ง จึงกดได้แค่ 8px จริง ๆ)
   ตอนนี้ตัวปุ่มเป็นช่องกดโปร่ง 36×28 (ตัวที่เลือกอยู่ 48) · จุดที่เห็นย้ายไปอยู่ใน <i> ใหญ่ขึ้นเป็น 10px (ตัวที่เลือก 34px)
   ขอบติดลบบน/ล่างรวมกันเท่าความสูงปุ่ม แถวจึงกินที่เท่าเดิม (หน้าแรกห้ามเลื่อน) · หลอดเวลายังวิ่งด้วย transform ตามกติกา */
.dk-dots { display: flex; justify-content: center; gap: 2px; margin: -18px 0 -10px; }
.dk-dot { position: relative; display: grid; place-items: center; width: 36px; height: 28px; padding: 0; border: 0;
  background: none; cursor: pointer; transition: width .25s ease; -webkit-tap-highlight-color: transparent; }
.dk-dot.on { width: 48px; }
.dk-dot i { position: relative; display: block; width: 10px; height: 10px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--ink) 30%, transparent); transition: width .25s ease; }
.dk-dot.on i { width: 34px; }
.dk-dot i::after { content: ""; position: absolute; inset: 0; background: var(--blue); transform-origin: 0 50%; transform: scaleX(0); }
.dk-dot.ev i::after { background: #ff9a2e; }
.dk-dot.on i::after { transform: scaleX(1); }
.dk-dot:active i { transform: scale(.88); }
.td-deck.auto.tick .dk-dot.on i::after { animation: dk-fill var(--dk-stay, 6000ms) linear both; }
/* tock = สำเนาของ tick ด้วย keyframes คนละชื่อ — deckPaint สลับสองตัวนี้เพื่อเริ่มแถบใหม่โดยไม่ต้องบังคับคิดผัง (app.js) */
.td-deck.auto.tock .dk-dot.on i::after { animation: dk-fill2 var(--dk-stay, 6000ms) linear both; }
@keyframes dk-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes dk-fill2 { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- การ์ดอีเวนต์ใหญ่ในสไลด์ (eventHero) ----------
   ขนาดเท่าการ์ดงาน · โถงประตูสี่บานเต็มการ์ด · ชื่ออีเวนต์ตัวใหญ่เรืองส้ม · NPC สี่ไบโอมยืนเรียงหน้าประตูพร้อมชื่อ
   ปุ่ม "เข้าเล่น" ใหญ่เท่าปุ่ม "เริ่มทำเลย" ของการ์ดงาน — สองสไลด์ต้องมีปุ่มหลักที่ตำแหน่งใกล้กัน */
.td-hero {
  position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; gap: 4px;
  min-height: 250px; padding: 16px 18px 16px; border-radius: 28px; text-decoration: none; color: #f6efff;
  background: #120c2a; border: 1px solid #9d7cf0; box-shadow: 0 18px 40px -22px rgba(122, 79, 224, 1);
  line-height: 1.25; -webkit-tap-highlight-color: transparent;
  /* สูงตามการ์ดงานในสไลด์แรก (บางวันเป็นการ์ดจอว่าง 250px) — วัดความสูงตัวเองเพื่อหลบคำโปรยเมื่อเตี้ย */
  container: th / size;
}
@container th (max-height: 268px) { .th-blurb { display: none; } }
.th-bg { position: absolute; inset: 0; z-index: -2; background: var(--te-art) 50% 22% / cover no-repeat;
  animation: th-drift 18s ease-in-out infinite alternate; }
.th-bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(14, 9, 34, .82) 0%, rgba(14, 9, 34, .35) 38%, rgba(14, 9, 34, .15) 58%, rgba(14, 9, 34, .9) 100%); }
@keyframes th-drift { from { transform: scale(1.04) translateX(-1.5%); } to { transform: scale(1.1) translateX(1.5%); } }
/* แสงจันทร์จาง ๆ มุมขวาบน + หมอกพื้น — ให้ฉากมีชั้นลึก ไม่ใช่รูปแปะ */
.th-moon { position: absolute; z-index: -1; right: -40px; top: -60px; width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 236, 190, .28), transparent 65%); pointer-events: none; }
.th-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.th-top i { font-style: normal; font-size: 11px; font-weight: 800; padding: 3px 9px; border-radius: 999px; line-height: 1.2; }
.th-kind { background: rgba(255, 255, 255, .14); color: #e9dcff; letter-spacing: .04em; }
.th-left { background: #ffc94d; color: #2a1600; font-variant-numeric: tabular-nums; box-shadow: 0 2px 0 rgba(0, 0, 0, .3); }
.th-try { background: rgba(0, 0, 0, .35); color: #cbbcf5; }
.th-title { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.th-title b { font-size: 32px; font-weight: 900; line-height: 1.05; letter-spacing: .01em; color: #fff3dc;
  text-shadow: 0 0 18px rgba(255, 150, 40, .6), 0 3px 0 #3b1d00; }
.th-title span { font-size: 14px; font-weight: 800; color: #d9c8ff; text-shadow: 0 1px 3px #000; }
.th-blurb { font-size: 12.5px; font-weight: 600; color: #e6dcff; opacity: .9; text-shadow: 0 1px 3px #000; max-width: 92%; }
.th-cast { position: absolute; z-index: -1; left: 0; right: 0; bottom: 70px; display: flex; justify-content: center; align-items: flex-end; gap: 2px; pointer-events: none; }
.th-cast figure { margin: 0 -6px; display: flex; flex-direction: column; align-items: center; }
.th-cast img { display: block; height: 90px; width: auto; transform-origin: 50% 100%;
  filter: drop-shadow(0 4px 3px rgba(0, 0, 0, .6)); animation: te-idle 3.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.85s); }
.th-cast figure:nth-child(2) img, .th-cast figure:nth-child(4) img { height: 97px; }
.th-cast figcaption { margin-top: -2px; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 800; color: #fff;
  background: rgba(10, 6, 26, .75); border: 1px solid rgba(255, 255, 255, .18); }
.th-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.th-go { display: inline-flex; align-items: center; justify-content: center; gap: 4px; flex: 1; max-width: 62%; height: 46px; border-radius: 16px;
  font-size: 16px; font-weight: 900; color: #2a1100; background: linear-gradient(180deg, #ffbe5c, #f07f16); box-shadow: 0 4px 0 #8a3b00; }
.th-go svg { width: 18px; height: 18px; }
.th-candy { display: inline-flex; align-items: center; gap: 5px; height: 36px; padding: 0 12px; border-radius: 999px;
  background: rgba(10, 6, 26, .7); color: #ffd0e4; font-size: 13px; font-weight: 700; }
.th-candy svg { width: 18px; height: 18px; color: #ff6fae; }
.th-candy b { font-size: 15px; color: #fff; font-variant-numeric: tabular-nums; }
.td-hero:active .th-go { transform: translateY(2px); box-shadow: 0 2px 0 #8a3b00; }
:root[data-lite] :is(.th-bg, .th-cast img) { animation: none; }
@media (prefers-reduced-motion: reduce) { :is(.th-bg, .th-cast img) { animation: none; } .dk-dot, .dk-dot i { transition: none; } }
@media (max-width: 340px) { .th-cast img { height: 78px !important; } .th-title b { font-size: 27px; } .th-blurb { display: none; } }

/* ---------- 24 ต.ค. 69 · หน้าแรกแบบใหม่ (#menuBody.home-v2 = แถบบนสุดเปิด) ----------
   เก็บสี่จุดที่ตรวจเจอหลังจัดโครงใหม่ (ภาพเทียบส่งเจ้าของแล้ว):
   1 รางตัดแถวกลางบรรทัด → แถวเต็ม 2–3 แถว + ลิงก์ "ดูแผนทั้งวัน" (dayRail)
   2 ช่องถามสูงและมีวงแสงหมุนตลอด ทั้งที่แถบล่างมีแท็บน้องฮูกอยู่แล้ว → บางลง แสงขึ้นเฉพาะตอนพิมพ์
   3 ไทล์ที่ทำครั้งเดียว/ซ้ำของบนจอ → ถอดออก ไทล์เหลือแถวเดียว · สแกนตารางเป็นการ์ดตั้งค่าครั้งเดียว
   4 กล่องเข้าซ้ำกับกระดิ่ง → เหลือกระดิ่ง */
.phone #menuBody.home-v2 .td-railwrap.capped .td-rail { max-height: none; overflow: visible; }
.dr-row.dr-more { width: 100%; min-height: 36px; padding-block: 6px; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; color: var(--blue); }
.dr-row.dr-more::before { display: none; }
.dr-more .dr-t { color: var(--blue); font-weight: 800; }
.dr-more .dr-b { font-size: 12.5px; font-weight: 700; color: var(--blue); }
.dr-more .dr-go { margin-left: auto; display: grid; place-items: center; color: var(--blue); }
.dr-more .dr-go svg { width: 16px; height: 16px; }

#menuBody.home-v2 .td-ask { min-height: 42px; padding-block: 2px; }
:root #menuBody.home-v2 .td-ask .tk-go.tk-go { width: 34px; height: 34px; }
#menuBody.home-v2 .td-ask:not(:focus-within)::before { opacity: 0; animation: none; }

/* --tg-cols: หกปุ่มแบ่ง 3+3 (24 ต.ค. 69 เจ้าของ) · จำนวนอื่นยังแถวเดียว · จอคอม (desktop.css) ใช้ --tg-n แถวเดียวเหมือนเดิม */
#menuBody.home-v2 .tg-grid { grid-template-columns: repeat(var(--tg-cols, var(--tg-n, 4)), minmax(0, 1fr)); }
#menuBody.home-v2 .td-tiles { margin-top: 12px; }

.td-setup {
  display: flex; align-items: center; gap: 11px; width: 100%; margin-top: 10px; padding: 9px 12px 9px 10px;
  border: 1px dashed color-mix(in srgb, var(--blue) 55%, transparent); border-radius: 16px;
  background: color-mix(in srgb, var(--blue) 9%, var(--card)); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.td-setup .ts-ic2 { flex: none; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 11px; background: var(--fill, #2563EB); color: var(--on-fill, #fff); }
.td-setup .ts-ic2 svg { width: 19px; height: 19px; }
.td-setup .ts-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; line-height: 1.3; }
.td-setup .ts-tx b { font-size: 13.5px; font-weight: 800; }
.td-setup .ts-tx small { font-size: 11.5px; color: var(--muted); }
.td-setup .ts-go { color: var(--muted); display: grid; place-items: center; }
.td-setup .ts-go svg { width: 16px; height: 16px; }
.td-setup:active { transform: scale(.99); }

/* ---------- 24 ต.ค. 69 · โลโก้ใหม่ทั้ง ALT (เจ้าของ: "เอาโลโก้ใหม่นี้ไปแทน alt ทั้งหมด") ----------
   ตราเก่าเป็นหนังสือกรมท่าบนพื้นใส วาดมาสำหรับพื้นขาว จึงมีแผ่นรองขาว + ช่องว่างในทุกที่ที่ตราขึ้น
   ตราใหม่เป็นไอคอนเต็มใบ มีพื้นม่วงกลางคืนและมุมมนในภาพเอง (logo-mark / logo-splash-light / logo-splash)
   แผ่นขาวรอบไอคอนจะกลายเป็นกรอบขาวหนา ๆ — เลิกแผ่นรองและช่องว่าง ให้ภาพเต็มกรอบ */
.lg-mark, .ob-mark, .ig-icon img, .toast .tav, #appToast .tav, .th-face.th-brand {
  background: none; padding: 0; object-fit: cover;
}

/* Keep the complete mobile home above the tab bar, including first-time setup.
   31 ต.ค. 69 · เจ้าของ (ภาพไทล์หน้าแรกเป็นแถวไอคอนเล็ก ป้ายอยู่ข้าง): "ปรับให้มันเหมือนกับปุ่มที่ใช้ในโทรศัพท์" → เลือก "แบบมือถือ 3×2"
   เดิมโหมดหน้าแรกใหม่ (home-v2) ย่อไทล์เป็นแถวสูง 44 ไอคอน 30 ป้ายข้าง ๆ เพื่อเผื่อที่ให้การ์ดตั้งค่าเริ่มต้น · ถอดข้อย่อนั้น
   ไทล์กลับเป็นทรงเดียวกับโหมดปกติและทุกธีมบนมือถือ (กรอบ 60 ชิปขาว ป้ายอยู่ใต้)
   วัดที่ 375×812: หน้าแรกปกติไม่ต้องเลื่อน · คนใหม่ที่การ์ด "ตั้งค่าเริ่มต้น" ยังค้างเลื่อนราว 59px จนตั้งค่าเสร็จ — เจ้าของเลือกข้อแลกนี้เอง */
@media (max-width: 600px) and (min-height: 760px) {
  #menuBody.home-v2 .td-tiles { padding-bottom: 0; margin-top: 8px; }
  #menuBody.home-v2 .td-setup { margin-top: 6px; padding-block: 6px; }
  #menuBody.home-v2 > .td-deck { margin-top: 8px; }
  #menuBody.home-v2 .td-railwrap { margin-top: 8px; }
  .phone #menuBody.home-v2 .tg-grid { gap: 8px 6px; }
}
