/* WC Portal — token สี/ระยะ/เงา/ฟอนต์ของทั้งระบบ ย้ายไปอยู่ design_system/tokens.css แล้ว
   (sync เข้ามาที่ /static/design/tokens.css) — ห้ามประกาศ :root/--primary/[data-theme] ที่นี่อีก
   แก้ที่ design_system/tokens.css แล้วรัน design_system/sync_design.py เท่านั้น (ดู DESIGN_GUIDE.md) */
@font-face{
  font-family:"Noto Sans Thai"; font-style:normal; font-weight:400 800; font-display:swap;
  src:url("/static/fonts/NotoSansThai-thai.woff2?v=1") format("woff2");
  unicode-range:U+0E01-0E5B,U+200C-200D,U+25CC;
}
@font-face{
  font-family:"Noto Sans Thai"; font-style:normal; font-weight:400 800; font-display:swap;
  src:url("/static/fonts/NotoSansThai-latin-ext.woff2?v=1") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:"Noto Sans Thai"; font-style:normal; font-weight:400 800; font-display:swap;
  src:url("/static/fonts/NotoSansThai-latin.woff2?v=1") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

* { box-sizing: border-box; }
html, body { margin:0; padding:0; }
html{ scroll-behavior:smooth; }
body{
  background:var(--ground); color:var(--ink); font-family:var(--font-body);
  min-height:100vh;
}
h1,h2,h3{ font-family:var(--font-display); margin:0 0 .5em; }
a{ color:var(--steel); }

/* Global form controls (input/select/textarea baseline) ย้ายไปอยู่ design_system/base-controls.css
   แล้ว (sync เข้ามาที่ /static/design/base-controls.css) — ห้ามเขียน rule ซ้ำที่นี่ แก้ที่
   design_system/base-controls.css แล้วรัน design_system/sync_design.py เท่านั้น */

/* ---------- shell DashStack: topbar + sidebar เดียว (redesign 3 ส.ค. 2569 — แทนที่ shell v5 mega-menu +
   pinned-sidebar ซ้อนกันเดิมทั้งคู่ เหลือ nav เดียว) — คงชื่อ class เดิม .app-shell/.topheader/.body-shell/
   .main-col/.pinned-sidebar ไว้บนโครงใหม่ เพราะ print CSS ของโมดูล outgoing_letters/letter_templates
   (app/modules/outgoing_letters/templates/index.html, app/modules/letter_templates/templates/index.html)
   อ้างชื่อเหล่านี้ตรงๆ เพื่อซ่อน/คลี่เปลือกตอนพิมพ์ — ไม่ต้องแก้ไฟล์โมดูลทั้งสอง ส่วน .mega-menu/.contact-fab/
   .contact-panel ที่ print CSS อ้างถึงด้วยนั้น ตอนนี้ไม่มี element ในหน้าแล้ว (เอาออกทั้งคู่ตามสั่ง) เป็นแค่
   selector ที่ไม่ match อะไรอีกต่อไป ไม่กระทบการพิมพ์ */
.app-shell{ display:flex; flex-direction:column; min-height:100vh; width:100%; }

.topheader{
  display:flex; align-items:center; gap:14px; background:var(--ground-raised); border-bottom:1px solid var(--line);
  padding:0 20px; height:64px; position:sticky; top:0; z-index:30;
}
.sidebar-trigger{
  display:flex; align-items:center; justify-content:center; width:40px; height:40px; border-radius:10px;
  border:none; background:transparent; color:var(--ink-soft); font-size:1.15rem; cursor:pointer; flex:0 0 auto;
}
.sidebar-trigger:hover{ background:var(--accent-soft); color:var(--accent); }
@media (min-width:1024px){ .sidebar-trigger{ display:none; } }

.topheader-logo{ display:flex; align-items:center; gap:10px; text-decoration:none; color:var(--ink); flex:0 0 auto; }
.topheader-logo img{ height:30px; width:auto; }
.topheader-logo .t1{ font-family:var(--font-display); font-weight:800; font-size:1rem; line-height:1.15; }
.topheader-logo .t2{ font-size:.7rem; color:var(--ink-soft); }
@media (max-width:480px){ .topheader-logo .t2{ display:none; } }

.topheader-search{ flex:1; max-width:420px; position:relative; }
.topheader-search input{
  width:100%; height:42px; border-radius:999px; border:1px solid var(--line); background:var(--ground);
  color:var(--ink); font-family:var(--font-body); font-size:.92rem; padding:0 18px 0 42px;
}
.topheader-search input:focus{
  outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); background:var(--ground-raised);
}
.topheader-search .sic{ position:absolute; left:16px; top:50%; transform:translateY(-50%); color:var(--ink-soft); font-size:1rem; }
@media (max-width:640px){ .topheader-search{ max-width:none; } }
@media (max-width:420px){ .topheader-search{ display:none; } }

.topheader-right{ display:flex; align-items:center; gap:6px; flex:0 0 auto; margin-left:auto; }
.icon-btn{
  width:40px; height:40px; border-radius:10px; border:none; background:transparent; color:var(--ink-soft);
  font-size:1.05rem; cursor:pointer; display:flex; align-items:center; justify-content:center; position:relative;
}
.icon-btn:hover{ background:var(--accent-soft); color:var(--accent); }
.notif-btn .dot{
  position:absolute; top:6px; right:7px; width:8px; height:8px; border-radius:50%; background:var(--pill-red);
  border:2px solid var(--ground-raised);
}
.profile-chip{ display:flex; align-items:center; gap:9px; padding:4px 6px 4px 4px; border-radius:999px; min-width:40px; min-height:40px; }
.profile-chip .who{ display:none; min-width:0; }
@media (min-width:640px){ .profile-chip .who{ display:block; max-width:140px; } }
.profile-chip .name{ font-size:.83rem; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.profile-chip .role{ font-size:.72rem; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.avatar{
  width:38px; height:38px; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:flex;
  align-items:center; justify-content:center; font-size:.9rem; font-weight:800; font-family:var(--font-display);
  flex:0 0 auto;
}
.logout-btn{
  background:none; border:none; color:var(--ink-soft); font-size:1.05rem; cursor:pointer; width:40px; height:40px;
  border-radius:10px; display:flex; align-items:center; justify-content:center; flex:0 0 auto;
}
.logout-btn:hover{ background:var(--signal-red-soft); color:var(--signal-red); }

/* ---------- body: sidebar ซ้าย + คอลัมน์เนื้อหาหลัก ---------- */
.body-shell{ display:flex; align-items:flex-start; width:100%; flex:1; min-height:0; }
.main-col{ flex:1; min-width:0; }

/* ---------- sidebar เดียว: ตรึงซ้ายถาวร ≥1024px, drawer ทับซ้าย <1024px (ปุ่ม ☰ เปิด, overlay/Esc ปิด) ---------- */
.pinned-sidebar{
  position:fixed; top:64px; left:0; bottom:0; width:240px; background:var(--ground-raised);
  border-right:1px solid var(--line); padding:14px 0 24px; overflow-y:auto; z-index:35;
  transform:translateX(-100%); transition:transform .2s ease;
}
.pinned-sidebar.open{ transform:translateX(0); box-shadow:var(--shadow); }
.sidebar-overlay{
  position:fixed; inset:64px 0 0 0; background:rgba(20,22,26,.35); z-index:34; opacity:0; pointer-events:none;
  transition:opacity .2s ease;
}
.sidebar-overlay.show{ opacity:1; pointer-events:auto; }
@media (min-width:1024px){
  .pinned-sidebar{ position:sticky; top:64px; transform:none; height:calc(100vh - 64px); box-shadow:none; }
  .sidebar-overlay{ display:none !important; }
  .body-shell{ padding-left:0; }
}
.sb-sec{
  font-size:.7rem; font-weight:800; letter-spacing:.08em; color:var(--ink-soft); text-transform:uppercase;
  padding:16px 22px 6px;
}
.sb-sec:first-child{ padding-top:6px; }
.sb-item{
  position:relative; display:flex; align-items:center; gap:11px; margin:2px 12px; padding:10px 12px;
  border-radius:var(--r-sm); font-size:.87rem; font-weight:600; color:var(--ink-soft); text-decoration:none;
  min-height:40px; cursor:pointer; border:none; background:none; width:calc(100% - 24px); text-align:left;
  font-family:inherit;
}
.sb-item:hover{ background:var(--ground); color:var(--ink); }
.sb-item.active{ background:var(--accent); color:var(--accent-ink); }
.sb-item .ext{ margin-left:auto; font-size:.7rem; opacity:.7; }
.sb-foot{ margin-top:14px; border-top:1px solid var(--line); padding-top:10px; }

/* ---------- ชุด SVG icon กลาง (แทน emoji — รอบ UX polish 15 ส.ค. 2569) ----------
   .ic ใช้ทั้งใน .sb-item (sidebar), .icon-btn (theme toggle), ลิงก์แท็บ subnav, ปุ่ม/badge/ข้อความทั่วโมดูล
   — ค่า default ต้องอิงขนาดตัวอักษรรอบข้าง (1em) ไม่ใช่ 20px ตายตัว มิฉะนั้นไอคอนใน .badge (.78rem) /
   ตารางหน้าพิมพ์ (11.5px) จะบวมดันความสูงบรรทัด (เก็บงาน finding Opus #4) แล้วค่อย override เป็น 20px
   เฉพาะบริบท nav/ปุ่มไอคอนที่ออกแบบไว้ที่ 20px */
.ic{ width:1.05em; height:1.05em; flex:0 0 auto; vertical-align:-0.18em; }
.sb-item .ic, .icon-btn .ic, .sidebar-trigger .ic, .logout-btn .ic{
  width:20px; height:20px; vertical-align:-5px;
}

/* ---------- badge จำนวนข้างเมนู sidebar (เฉพาะเมนูที่ต้องการ attention — PR รออนุมัติ/Kanban ค้างรับของ) ---------- */
.sb-badge{
  margin-left:auto; display:inline-flex; align-items:center; justify-content:center; min-width:20px; height:20px;
  padding:0 6px; border-radius:999px; background:var(--signal-amber-soft); color:var(--signal-amber);
  font-size:.72rem; font-weight:800; line-height:1; flex:0 0 auto;
}
.sb-item.active .sb-badge{ background:rgba(255,255,255,.28); color:var(--accent-ink); }

main{ max-width:1080px; margin:0 auto; padding:24px 28px 60px; }
/* หน้าเดียวที่ override เป็นเต็มความกว้าง (Dashboard ชุด KPI เต็ม, 15 ส.ค. 2569) — ผ่าน
   {% block main_class %}wide{% endblock %} ใน dashboard.html เท่านั้น หน้าอื่นไม่ override = class="" ว่าง
   ไม่โดนผลอะไร */
main.wide{ max-width:none; }

/* ---------- จอใหญ่ (FHD ขึ้นไป) — ตัวอักษรที่ตั้งเป็น rem ทั้งเว็บใหญ่ขึ้นตามจริง ไม่ใช่แค่ขยายพื้นที่ว่าง
   (พนักงานที่จอ 1920px+ รายงานว่าตัวหนังสือเล็กกว่าที่เจ้าของเห็นบนจอตัวเอง — ฐาน design เดิมจูนไว้แค่ ~1200px) ---------- */
@media (min-width:1440px){
  html{ font-size:17px; }
  main{ max-width:1200px; }
}
@media (min-width:1920px){
  html{ font-size:18.5px; }
  main{ max-width:1320px; }
}

/* ---------- module launcher: การ์ดโมดูลหลัก 4 ใบบนหน้าแรก (โครง ERP 3 ชั้น 22 ก.ค. 2569) ---------- */
.section-title{ font-size:1.05rem; margin:26px 0 12px; }

/* ---------- รอดำเนินการ (actionable items) — เฉพาะ MR/DCC เจ้าของระบบ ---------- */
.action-card{ background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r); overflow:hidden; margin-bottom:10px; box-shadow:var(--shadow); }
.action-row{
  display:flex; align-items:center; gap:14px; padding:14px 18px; text-decoration:none; color:var(--ink);
  border-top:1px solid var(--line);
}
.action-row:first-child{ border-top:none; }
a.action-row:hover{ background:var(--ground); }
.action-row.disabled{ opacity:.6; cursor:default; }
.ar-icon{ font-size:1.2rem; flex:0 0 auto; }
.ar-text{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.ar-label{ font-size:.9rem; font-weight:600; }
.ar-sub{ font-size:.78rem; color:var(--ink-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ar-count{
  flex:0 0 auto; min-width:28px; height:28px; border-radius:999px; background:var(--line); color:var(--ink-soft);
  display:flex; align-items:center; justify-content:center; font-size:.85rem; font-weight:700; padding:0 8px;
}
.action-row.has-count .ar-count{ background:var(--signal-red-soft); color:var(--signal-red); }
.ar-count.zero{ background:var(--line); color:var(--ink-soft); }
.ar-count.na{ background:transparent; color:var(--ink-soft); font-weight:400; }

/* ---------- widget แถวคู่: เอกสารล่าสุด + ทางลัดของฉัน ---------- */
.widget-grid{ display:grid; grid-template-columns:1fr; gap:20px; margin:20px 0 30px; }
.recent-list, .fav-list{ list-style:none; margin:0; padding:0; }
.recent-list li, .fav-list li{
  display:flex; align-items:center; gap:10px; padding:9px 0; border-top:1px solid var(--line); font-size:.85rem;
}
.recent-list li:first-child, .fav-list li:first-child{ border-top:none; }
.recent-list a, .fav-list a{ flex:1; min-width:0; display:flex; align-items:center; gap:8px; text-decoration:none; color:var(--ink); }
.rl-code{ font-family:var(--font-display); font-weight:600; color:var(--steel); flex:0 0 auto; }
.rl-title{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rl-date{ flex:0 0 auto; font-size:.76rem; color:var(--ink-soft); }
.fav-remove{ background:none; border:none; color:var(--ink-soft); cursor:pointer; font-size:.8rem; flex:0 0 auto; padding:4px; }
.fav-remove:hover{ color:var(--signal-red); }

/* ---------- ปุ่มปักหมุด (favorite) บน module tile ---------- */
.fav-toggle{
  position:absolute; top:10px; right:10px; background:none; border:none; font-size:1rem; cursor:pointer;
  opacity:.35; padding:4px; line-height:1;
}
.fav-toggle:hover{ opacity:.8; }
.fav-toggle.active{ opacity:1; }
.module-launcher{ display:grid; grid-template-columns:repeat(auto-fit, minmax(240px,1fr)); gap:16px; margin-bottom:32px; }
.launcher-card{
  display:flex; flex-direction:column; align-items:flex-start; gap:8px; text-decoration:none; color:var(--ink);
  background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r); padding:22px 20px;
  border-top:3px solid var(--line); box-shadow:var(--shadow);
}
.launcher-card:hover{ border-color:var(--accent); transform:translateY(-2px); }
.launcher-card .lc-icon{
  width:52px; height:52px; border-radius:14px; display:flex; align-items:center; justify-content:center;
  font-size:1.7rem; background:var(--ground); margin-bottom:2px;
}
.launcher-card .lc-name{ font-family:var(--font-display); font-weight:600; font-size:1.05rem; line-height:1.25; }
.launcher-card .lc-en{ font-size:.74rem; color:var(--ink-soft); letter-spacing:.02em; margin-top:-6px; }
.launcher-card .lc-desc{ font-size:.83rem; color:var(--ink-soft); line-height:1.45; flex:1; }
.launcher-card .lc-count{ font-size:.76rem; color:var(--ink-soft); border-top:1px solid var(--line); padding-top:8px; width:100%; }
/* แถบสีบนหัวการ์ด + พื้นไอคอน แยกโมดูลด้วยสายตา */
.launcher-card.c-green{ border-top-color:var(--signal-green); }
.launcher-card.c-green .lc-icon{ background:var(--signal-green-soft); }
.launcher-card.c-steel{ border-top-color:var(--steel); }
.launcher-card.c-steel .lc-icon{ background:var(--steel-soft); }
.launcher-card.c-accent{ border-top-color:var(--accent); }
.launcher-card.c-accent .lc-icon{ background:var(--accent-soft); }
.launcher-card.c-amber{ border-top-color:var(--signal-amber); }
.launcher-card.c-amber .lc-icon{ background:var(--signal-amber-soft); }
.launcher-card.c-red{ border-top-color:var(--signal-red); }
.launcher-card.c-red .lc-icon{ background:var(--signal-red-soft); }

/* ---------- หน้า workspace ของโมดูล: หัวโมดูล + section (sub-module) ---------- */
.mod-header{
  display:flex; align-items:center; gap:18px; background:var(--ground-raised); border:1px solid var(--line);
  border-left:4px solid var(--line); border-radius:var(--r); padding:22px 24px; margin-bottom:26px; box-shadow:var(--shadow);
}
.mod-header .mh-icon{
  width:58px; height:58px; border-radius:15px; display:flex; align-items:center; justify-content:center;
  font-size:1.9rem; background:var(--ground); flex:0 0 auto;
}
.mod-header h1{ font-size:1.35rem; margin:0 0 2px; }
.mod-header .mh-en{ font-size:.78rem; color:var(--ink-soft); margin-bottom:6px; }
.mod-header p{ margin:0; color:var(--ink-soft); font-size:.88rem; line-height:1.45; }
.mod-header.c-green{ border-left-color:var(--signal-green); }
.mod-header.c-green .mh-icon{ background:var(--signal-green-soft); }
.mod-header.c-steel{ border-left-color:var(--steel); }
.mod-header.c-steel .mh-icon{ background:var(--steel-soft); }
.mod-header.c-accent{ border-left-color:var(--accent); }
.mod-header.c-accent .mh-icon{ background:var(--accent-soft); }
.mod-header.c-amber{ border-left-color:var(--signal-amber); }
.mod-header.c-amber .mh-icon{ background:var(--signal-amber-soft); }

/* ---------- policy banner: ทางลัดไปนโยบายคุณภาพ/สิ่งแวดล้อม/ความปลอดภัย (เฉพาะโมดูลที่กำหนดไว้จริง) ---------- */
.policy-banner{
  display:flex; align-items:center; gap:14px; text-decoration:none; color:var(--ink);
  background:var(--accent-soft); border:1px solid var(--accent); border-radius:14px; padding:14px 18px; margin-bottom:26px;
}
.policy-banner:hover{ opacity:.92; }
.policy-banner .pb-icon{ font-size:1.5rem; flex:0 0 auto; }
.policy-banner .pb-text{ flex:1; min-width:0; }
.policy-banner .pb-label{ display:block; font-family:var(--font-display); font-weight:600; font-size:.92rem; color:var(--accent); }
.policy-banner .pb-desc{ display:block; font-size:.8rem; color:var(--ink-soft); margin-top:2px; }
.policy-banner .pb-chevron{ font-size:1.3rem; color:var(--accent); flex:0 0 auto; }

.mod-section{ margin-bottom:30px; scroll-margin-top:90px; }
.section-desc{ color:var(--ink-soft); font-size:.83rem; margin:-6px 0 12px; line-height:1.45; }

.group{ margin-bottom:30px; scroll-margin-top:90px; }
.group-head{ display:flex; align-items:baseline; gap:10px; margin-bottom:12px; }
.group-head h2{ font-size:1.05rem; }
.group-head .count{ font-size:.8rem; color:var(--ink-soft); }

/* ---------- การ์ดบริการแบบแถว: ไอคอนสี่เหลี่ยมสี + ข้อความ + ลูกศร ---------- */
.svc-icon{
  width:46px; height:46px; border-radius:12px; display:flex; align-items:center; justify-content:center;
  font-size:1.35rem; flex:0 0 auto;
}
.svc-icon.c-accent{ background:var(--accent-soft); }
.svc-icon.c-green{ background:var(--signal-green-soft); }
.svc-icon.c-amber{ background:var(--signal-amber-soft); }
.svc-icon.c-red{ background:var(--signal-red-soft); }
.svc-icon.c-steel{ background:var(--steel-soft); }
.svc-text{ flex:1; min-width:0; }
.svc-text .row1{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.svc-text .name{ font-family:var(--font-display); font-weight:600; font-size:.96rem; }
.svc-text .desc{ color:var(--ink-soft); font-size:.82rem; margin-top:3px; line-height:1.4; }
.svc-text .caveat{ margin-top:6px; font-size:.75rem; color:var(--signal-amber); }
.svc-chevron{ flex:0 0 auto; color:var(--ink-soft); font-size:1.3rem; line-height:1; }

.chip{ display:inline-block; padding:2px 9px; border-radius:999px; font-size:.7rem; font-weight:600; white-space:nowrap; }
.chip.live{ background:var(--signal-green-soft); color:var(--signal-green); }
.chip.soon{ background:var(--line); color:var(--ink-soft); }
.chip.ext{ background:var(--steel-soft); color:var(--steel); }

.search-empty{ display:none; color:var(--ink-soft); font-size:.86rem; padding:18px 4px; }
.search-empty.show{ display:block; }

/* ---------- toast แทน modal ---------- */
.toast-lane{ max-width:1080px; margin:0 auto; padding:0 28px; position:sticky; top:70px; z-index:20; height:0; }
.toast{
  transform:translateY(-10px); opacity:0; pointer-events:none; transition:transform .18s ease,opacity .18s ease;
  background:var(--ink); color:var(--ground); font-size:.86rem; padding:10px 16px; border-radius:10px;
  box-shadow:var(--shadow); display:inline-flex; align-items:center; gap:8px; max-width:360px;
}
.toast-lane.show .toast{ transform:translateY(0); opacity:1; }

/* ---------- press feedback (ไม่มี stagger/count-up อีกต่อไป — ตัดออกตาม redesign 3 ส.ค. 2569) ---------- */
.rail-link,.icon-btn,.category-card,.module-tile.live,.module-tile.soon,.sb-item,.launcher-card,.tool{ transition:transform .12s ease,border-color .15s ease,background-color .15s ease; }
.rail-link:active,.icon-btn:active,.category-card:active,.module-tile.live:active,.module-tile.soon:active{ transform:scale(.97); }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
}

.card{
  background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r);
  padding:20px; box-shadow: var(--shadow);
}
.card-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(220px,1fr)); gap:16px; margin:20px 0; }
.stat-card{ background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r); padding:18px; box-shadow:var(--shadow); }
.stat-card .value{ font-family:var(--font-display); font-size:1.9rem; font-weight:800; }
.stat-card .label{ color:var(--ink-soft); font-size:.86rem; font-weight:600; margin-top:4px; }
.stat-card.tone-green .value{ color:var(--signal-green); }
.stat-card.tone-amber .value{ color:var(--signal-amber); }
.stat-card.tone-red .value{ color:var(--signal-red); }
.stat-card.tone-steel .value{ color:var(--steel); }

.badge{ display:inline-block; padding:2px 10px; border-radius:999px; font-size:.78rem; font-weight:600; }
.badge.tone-green{ background:var(--signal-green-soft); color:var(--signal-green); }
.badge.tone-amber{ background:var(--signal-amber-soft); color:var(--signal-amber); }
.badge.tone-red{ background:var(--signal-red-soft); color:var(--signal-red); }
.badge.tone-steel{ background:var(--steel-soft); color:var(--steel); }

/* ---------- KPI command-center card (dashboard.html เท่านั้น — รอบ UX polish 15 ส.ค. 2569) ----------
   ใช้ .kpi-grid/.kpi-card แยกจาก .card-grid/.stat-card เดิมโดยตั้งใจ: .stat-card ถูกใช้ร่วมกับ deck.html/
   vendors_list.html/detail.html/workspace_overview.html ที่มี markup ภายในต่างกัน (การ์ดโครงการ/ผู้ขาย ไม่ใช่
   ตัวเลข KPI เดี่ยว) — แก้ .stat-card ตรงๆ จะกระทบหน้าอื่นที่ไม่ได้อยู่ในสโคปรอบนี้ จึงเพิ่มคลาสใหม่แทน */
.kpi-grid{ display:grid; grid-template-columns:repeat(3, 1fr); gap:16px; margin:20px 0; }
.kpi-card{
  display:flex; align-items:flex-start; gap:14px; background:var(--ground-raised); border:1px solid var(--line);
  border-radius:var(--r); padding:18px; box-shadow:var(--shadow);
}
.kpi-icon{
  display:flex; align-items:center; justify-content:center; flex:0 0 auto; width:44px; height:44px;
  border-radius:var(--r-sm); background:var(--steel-soft); color:var(--steel);
}
.kpi-icon .ic{ width:22px; height:22px; }
.kpi-card.tone-amber .kpi-icon{ background:var(--signal-amber-soft); color:var(--signal-amber); }
.kpi-card.tone-red .kpi-icon{ background:var(--signal-red-soft); color:var(--signal-red); }
.kpi-card.tone-green .kpi-icon{ background:var(--signal-green-soft); color:var(--signal-green); }
.kpi-body{ min-width:0; }
.kpi-label{ color:var(--ink-soft); font-size:.78rem; font-weight:700; letter-spacing:.02em; }
.kpi-value{ font-family:var(--font-display); font-size:1.7rem; font-weight:800; margin-top:2px; line-height:1.15; }
.kpi-value .kpi-unit{ font-size:.85rem; font-weight:700; color:var(--ink-soft); margin-left:4px; }
.kpi-note{ color:var(--ink-soft); font-size:.78rem; margin-top:4px; }
.kpi-card.tone-red .kpi-note{ color:var(--signal-red); font-weight:600; }
@media (max-width:1200px){ .kpi-grid{ grid-template-columns:repeat(2, 1fr); } }
@media (max-width:560px){ .kpi-grid{ grid-template-columns:1fr; gap:10px; } .kpi-card{ padding:14px; } }

/* ตัวเลขเทรนด์ ▲▼ เทียบเดือนก่อน (KPI4 lead time / KPI6 ยอดสั่งซื้อ — Dashboard ชุด KPI เต็ม 15 ส.ค. 2569) */
.kpi-trend{ display:inline-flex; align-items:center; gap:2px; font-weight:700; }
.kpi-trend .ic{ width:13px; height:13px; }
.kpi-trend.tone-green{ color:var(--signal-green); }
.kpi-trend.tone-red{ color:var(--signal-red); }
.kpi-trend.tone-amber{ color:var(--signal-amber); }
.kpi-trend.tone-steel{ color:var(--ink-soft); }

/* ---------- Dashboard ชุด KPI เต็ม (15 ส.ค. 2569, mockup Dashboard.html) — แถว 2-5 ----------
   ธีมใช้ token ล้วน (ตามกติกา) ไม่มี hex การ์ดแถว 2/3/5 ใช้โครง 2fr/1fr เดียวกันหมด */
.dash-row{ display:grid; grid-template-columns:2fr 1fr; gap:16px; margin-top:16px; align-items:start; }
@media (max-width:960px){ .dash-row{ grid-template-columns:1fr; } }

/* กราฟแท่ง PO รายเดือน 12 เดือน — SVG ล้วน (ไม่มี JS chart lib) เรขาคณิตคำนวณจาก
   dashboard_metrics.build_monthly_chart() สีคุมด้วย CSS class ล้วน ไม่ inline fill hex */
.po-chart{ width:100%; height:auto; display:block; margin-top:10px; }
.chart-gridline{ stroke:var(--line); stroke-width:1; }
.chart-axis-label{ fill:var(--ink-soft); font-size:9px; }
.chart-avgline{ stroke:var(--ink-soft); stroke-width:1.4; stroke-dasharray:4 3; }
.chart-avg-label{ fill:var(--ink-soft); font-size:9px; font-weight:700; }
.chart-bar{ fill:var(--steel); }
.chart-bar.current{ fill:var(--accent-on-surface, var(--steel)); }
.chart-month-label{ fill:var(--ink-soft); font-size:9px; text-anchor:middle; }
.chart-month-label.current{ fill:var(--ink); font-weight:700; }
.chart-legend{ display:flex; align-items:center; gap:16px; margin-top:6px; font-size:.76rem; color:var(--ink-soft); }
.chart-legend .sw{ display:inline-block; width:10px; height:10px; border-radius:3px; margin-right:5px; vertical-align:-1px; }
.chart-legend .sw.current{ background:var(--accent-on-surface, var(--steel)); }
.chart-legend .sw.avg{ border-bottom:2px dashed var(--ink-soft); width:12px; height:0; border-radius:0; vertical-align:3px; }

/* แท่งแนวนอนใช้ร่วมกัน — PR ค้างตามอายุคิว (แถว 2 ขวา) + % ผูกพันสัญญาต่อโครงการ (แถว 3 ซ้าย) */
.hbar-track{ height:8px; background:var(--ground); border-radius:999px; overflow:hidden; }
.hbar-fill{ height:100%; border-radius:999px; }
.hbar-fill.tone-green{ background:var(--signal-green); }
.hbar-fill.tone-amber{ background:var(--signal-amber); }
.hbar-fill.tone-red{ background:var(--signal-red); }
.hbar-fill.tone-steel{ background:var(--steel); }

.aging-list{ display:flex; flex-direction:column; gap:12px; margin-top:12px; }
.aging-row-head{ display:flex; justify-content:space-between; gap:8px; font-size:.82rem; margin-bottom:4px; }
.aging-row-head .lbl{ color:var(--ink-soft); }
.aging-row-head .cnt{ font-weight:700; }
.aging-empty{ color:var(--ink-soft); font-size:.85rem; margin-top:10px; }

/* Top 5 โครงการ (แถว 3 ซ้าย) + Top 5 ผู้ขาย (แถว 3 ขวา) */
.top5-list{ display:flex; flex-direction:column; gap:14px; margin-top:12px; }
.top5-row{ display:block; text-decoration:none; color:inherit; }
.top5-row-head{ display:flex; justify-content:space-between; gap:8px; font-size:.85rem; margin-bottom:4px; }
.top5-row-head .name{ font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.top5-row-head .amt{ color:var(--ink-soft); font-size:.78rem; flex:0 0 auto; white-space:nowrap; }

.vendor-top-row{ display:flex; align-items:center; gap:10px; padding:9px 0; border-top:1px solid var(--line); }
.vendor-top-row:first-child{ border-top:none; padding-top:0; }
.vendor-top-row.is-blacklisted{ opacity:.6; }
.vt-name{ flex:1; min-width:0; }
.vt-name .n{ font-weight:600; font-size:.88rem; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vt-name .n.strike{ text-decoration:line-through; }
.vt-stats{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; font-size:.76rem; color:var(--ink-soft); flex:0 0 auto; }
.vt-star{ color:var(--signal-amber); display:inline-flex; align-items:center; gap:2px; }
.vt-star .ic{ width:12px; height:12px; }
.vt-grade{
  width:26px; height:26px; border-radius:7px; display:flex; align-items:center; justify-content:center;
  font-weight:800; font-size:.85rem; flex:0 0 auto;
}
.vt-grade.tone-green{ background:var(--signal-green-soft); color:var(--signal-green); }
.vt-grade.tone-amber{ background:var(--signal-amber-soft); color:var(--signal-amber); }
.vt-grade.tone-red{ background:var(--signal-red-soft); color:var(--signal-red); }
.vt-grade.tone-steel{ background:var(--steel-soft); color:var(--steel); }

/* แถว 4 — งานรอทำวันนี้ (แทนที่ Watchlist เดิมทั้งหมด) */
.task-list{ display:flex; flex-direction:column; gap:2px; margin-top:12px; }
.task-row{
  display:flex; align-items:center; gap:12px; padding:12px 10px; border-radius:var(--r-sm);
  border-left:3px solid transparent; text-decoration:none; color:inherit;
}
.task-row:hover{ background:var(--ground); }
.task-row.accent{ border-left-color:var(--signal-red); }
.task-icon{
  width:36px; height:36px; border-radius:var(--r-sm); display:flex; align-items:center; justify-content:center;
  flex:0 0 auto; background:var(--steel-soft); color:var(--steel);
}
.task-icon.tone-red{ background:var(--signal-red-soft); color:var(--signal-red); }
.task-icon.tone-amber{ background:var(--signal-amber-soft); color:var(--signal-amber); }
.task-icon.tone-green{ background:var(--signal-green-soft); color:var(--signal-green); }
.task-icon.tone-steel{ background:var(--steel-soft); color:var(--steel); }
.task-body{ flex:1; min-width:0; }
.task-title{ font-weight:600; font-size:.88rem; }
.task-sub{ color:var(--ink-soft); font-size:.78rem; margin-top:2px; }
.task-cta{ flex:0 0 auto; font-size:.8rem; font-weight:700; color:var(--accent); white-space:nowrap; }

/* แถว 5 — mini Kanban summary (ย้ายจากการ์ด hero เดิม) + ความเคลื่อนไหวล่าสุด */
.mini-kanban-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(96px,1fr)); gap:10px; margin-top:14px; }
.mini-kanban-tile{ background:var(--ground-raised); border-radius:10px; padding:8px 12px; }
.mini-kanban-tile.warn{ background:var(--signal-amber-soft); border:1px solid var(--signal-amber); }
.mkt-count{ font-size:1.1rem; font-weight:700; }
.mkt-label{ font-size:.72rem; color:var(--ink-soft); }
.mkt-total{ font-size:.72rem; color:var(--ink-soft); margin-top:2px; }

.activity-list{ list-style:none; margin:12px 0 0; padding:0; display:flex; flex-direction:column; gap:10px; }
.activity-item{ display:flex; gap:10px; align-items:flex-start; font-size:.84rem; }
.activity-dot{ width:8px; height:8px; border-radius:50%; margin-top:6px; flex:0 0 auto; }
.activity-dot.tone-green{ background:var(--signal-green); }
.activity-dot.tone-steel{ background:var(--steel); }
.activity-text{ flex:1; min-width:0; }
.activity-date{ display:block; color:var(--ink-soft); font-size:.72rem; margin-top:2px; }

/* ---------- segmented status tabs (pr_registry.html/po_registry.html — รอบ UX polish 15 ส.ค. 2569) ----------
   presentation ล้วน: status_tabs (label/count/active/url) มาจาก service.get_pr_registry_context /
   get_po_registry_context เดิมทุกประการ ไม่แตะ logic นับ/กรอง */
.seg-tabs{
  display:flex; flex-wrap:wrap; gap:4px; background:var(--ground); border:1px solid var(--line);
  border-radius:999px; padding:4px; margin:16px 0;
}
.seg-tab{
  display:inline-flex; align-items:center; padding:7px 14px; border-radius:999px; font-size:.82rem;
  font-weight:700; color:var(--ink-soft); text-decoration:none; white-space:nowrap;
}
.seg-tab:hover{ color:var(--ink); }
.seg-tab.active{ background:var(--ground-raised); color:var(--ink); box-shadow:var(--shadow); }

/* ---------- pill สถานะแบบทึบสี (DashStack) — ใช้ในตารางเอกสารล่าสุดหน้าแรก ---------- */
.pill{ display:inline-block; min-width:78px; text-align:center; color:#fff; font-weight:700; font-size:.72rem; border-radius:8px; padding:4px 10px; }
.pill.g{ background:var(--pill-green); }
.pill.p{ background:var(--pill-purple); }
.pill.r{ background:var(--pill-red); }
.pill.gr{ background:var(--pill-gray); }

table{ width:100%; border-collapse:separate; border-spacing:0; margin-top:12px; }
th, td{ text-align:left; padding:10px 12px; border-bottom:1px solid var(--line); font-size:.92rem; }
th{ background:var(--ground); color:var(--ink); font-weight:800; font-size:.78rem; letter-spacing:.02em; border-bottom:none; }
th:first-child{ border-radius:8px 0 0 8px; }
th:last-child{ border-radius:0 8px 8px 0; }
tr:hover td{ background:var(--accent-soft); }

.filters{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:16px; }
.filters select, .filters input{
  padding:8px 12px; border-radius:10px; border:1px solid var(--line); background:var(--ground-raised);
  color:var(--ink); font-family:var(--font-body); font-size:.9rem;
}

.module-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(280px,1fr)); gap:12px; }
.module-tile{
  position:relative; display:flex; align-items:center; gap:16px; text-decoration:none; color:var(--ink);
  background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r); padding:14px 16px;
  min-height:40px;
}
.module-tile.live:hover{ border-color:var(--accent); box-shadow:var(--shadow); cursor:pointer; }
.module-tile.soon{ opacity:.65; cursor:pointer; }
.tools-group{ padding:18px 0 2px; font-size:.72rem; font-weight:800; letter-spacing:.08em; color:var(--ink-soft); text-transform:uppercase; }
.tools-group:first-of-type{ padding-top:4px; }
details.soon-details{ margin-top:16px; }
details.soon-details summary{ cursor:pointer; font-size:.82rem; color:var(--ink-soft); font-weight:700; user-select:none; padding:4px 0; }
details.soon-details .soon-tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.soon-tag{ font-size:.78rem; color:var(--ink-soft); border:1px dashed var(--line); border-radius:999px; padding:4px 12px; }

.brand-logo{ height:26px; width:auto; vertical-align:middle; margin-right:2px; }

.login-wrap{ display:flex; align-items:center; justify-content:center; min-height:100vh; }
.login-card{ text-align:center; max-width:360px; padding:40px; }
.login-logo{ height:56px; width:auto; margin-bottom:12px; }
.login-card h1{ font-size:1.4rem; }
.login-card .g-btn-slot{ margin:24px 0; }

.table-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }

/* ---------- ตารางกรอกรายการ PR แบบ Excel-like (บรีฟเจ้าของ 13 ส.ค. 2569) — ใช้กับ #prItemsTable ใน
   _pr_item_rows.html (partial ที่ pr_new.html/pr_edit_items.html include ร่วมกัน) เซลล์มีเส้นกริด, input เต็ม
   เซลล์ไร้ขอบ, ไฮไลต์แถวที่กำลังโฟกัส/วาง ---------- */
.pr-grid{ table-layout:fixed; border-collapse:collapse; margin-top:12px; }
.pr-grid th, .pr-grid td{ border:1px solid var(--line); }
.pr-grid th{ padding:8px 10px; }
.pr-grid td{ padding:0; }
.pr-grid td.pr-item-seq{ padding:8px 10px; text-align:center; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.pr-grid td:last-child{ padding:4px; text-align:center; }
.pr-grid tr.pr-item-row:focus-within td{ background:var(--accent-soft); }
.pr-grid input[type="text"], .pr-grid input[type="number"], .pr-grid input[type="date"]{
  display:block; width:100%; box-sizing:border-box; border:none; background:transparent;
  padding:8px 10px; font:inherit; color:var(--ink); border-radius:0;
}
.pr-grid input[type="text"]:focus, .pr-grid input[type="number"]:focus, .pr-grid input[type="date"]:focus{
  outline:none; background:var(--surface); box-shadow:inset 0 0 0 2px var(--accent);
}
.pr-grid input[name="item_qty"], .pr-grid input[name="item_est_unit_price"]{ text-align:right; }
.pr-grid .pr-item-remove{
  border:none; background:transparent; color:var(--ink-soft); cursor:pointer; font-size:.95rem;
  padding:4px 6px; border-radius:var(--r-sm); line-height:1;
}
.pr-grid .pr-item-remove:hover{ color:var(--signal-red); background:var(--signal-red-soft); }

/* ---------- GPMS dashboard: bar chart / breakdown list / alert card (ดึงโครงจาก GPMS prototype S1
   00_GPMS_แผนระบบบริหารโครงการ\build\prototype\gpms_demo.html แต่ใช้ token สีเดิมของ WC Portal ไม่ใช่ธีม
   น้ำเงินของ prototype เพื่อให้เข้ากับ shell เดียวกันทั้งระบบ) ---------- */
.bar-row{ display:flex; align-items:center; gap:10px; margin-bottom:10px; font-size:.85rem; }
.bar-row:last-child{ margin-bottom:0; }
.bar-label{ width:150px; flex:0 0 150px; color:var(--ink-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bar-track{ flex:1; background:var(--ground); border-radius:8px; height:16px; position:relative; overflow:hidden; }
.bar-fill{ background:var(--steel); height:100%; border-radius:8px; }
.bar-val{ width:110px; flex:0 0 110px; text-align:right; color:var(--ink); font-variant-numeric:tabular-nums; }

.status-legend{ list-style:none; margin:0; padding:0; font-size:.85rem; }
.status-legend li{ display:flex; align-items:center; gap:8px; padding:6px 0; border-top:1px solid var(--line); }
.status-legend li:first-child{ border-top:none; }
.status-legend .dot{ width:10px; height:10px; border-radius:3px; flex:0 0 10px; }
.status-legend .dot.tone-steel{ background:var(--steel); }
.status-legend .dot.tone-red{ background:var(--signal-red); }
.status-legend .dot.tone-amber{ background:var(--signal-amber); }
.status-legend .dot.tone-green{ background:var(--signal-green); }
.status-legend .name{ flex:1; }
.status-legend .count{ color:var(--ink-soft); font-variant-numeric:tabular-nums; }

.alert-card, .stale-card{ border-radius:16px; padding:16px 18px; }
.alert-card{ background:var(--signal-red-soft); border:1px solid var(--signal-red); }
.alert-card h3{ margin:0 0 10px; font-size:.95rem; color:var(--signal-red); }
.stale-card{ background:var(--signal-amber-soft); border:1px solid var(--signal-amber); }
.stale-card h3{ margin:0 0 10px; font-size:.95rem; color:var(--signal-amber); }
.alert-list, .stale-list{ font-size:.83rem; }
.alert-list .row, .stale-list .row{
  display:flex; justify-content:space-between; gap:10px; padding:7px 0; border-top:1px dashed rgba(0,0,0,.12);
}
.alert-list .row:first-child, .stale-list .row:first-child{ border-top:none; }
.alert-list .row .r, .stale-list .row .r{ text-align:right; white-space:nowrap; color:var(--ink-soft); }
.alert-note{ font-size:.76rem; color:var(--ink-soft); margin-top:10px; }
.empty-row{ color:var(--ink-soft); font-size:.83rem; padding:4px 0; }

.lg-tiles{ display:grid; grid-template-columns:repeat(3,1fr); gap:12px; }
@media (max-width:700px){ .lg-tiles{ grid-template-columns:1fr; } }

.lg-tile{ border-radius:10px; padding:14px 16px; background:var(--ground); border:1px solid var(--line); }
.lg-tile .lg-num{ font-size:1.3rem; font-weight:600; color:var(--ink-soft); font-family:var(--font-display); }
.lg-tile .lg-lbl{ font-size:.85rem; margin-top:2px; }
.lg-tile .lg-sub{ font-size:.75rem; color:var(--ink-soft); margin-top:4px; }

/* จอแท็บเล็ต (681–1024px, เช่น iPad ตั้ง/นอน) — sidebar พับเป็น drawer (ปุ่ม ☰), เนื้อหาเต็มความกว้าง */
@media (min-width: 681px) and (max-width: 1024px){
  main{ padding:24px 20px 50px; }
  .topheader{ padding:0 18px; gap:12px; }
  .card-grid{ grid-template-columns:repeat(3, 1fr); }
}

/* จอแคบกว่า 900px — เว้นที่ให้ปุ่ม ☰/โลโก้/โปรไฟล์พอในแถวเดียว */
@media (max-width: 900px){
  main{ padding:18px 16px 50px; }
}

/* จอมือถือ (≤480px ตามสเปก responsive) — stat cards ย่อคอลัมน์, การ์ดเครื่องมือคอลัมน์เดียว, topbar ไม่ล้น,
   โปรไฟล์ย่อเหลือ avatar (ทำผ่าน .profile-chip .who ที่ซ่อนไว้แล้วต่ำกว่า 640px) */
@media (max-width: 680px){
  main{ padding:16px 12px 40px; }
  .topheader{ padding:0 12px; gap:8px; }
  /* 3 ส.ค. 2569: บนจอ 375px แถบบนกว้างเกินจอ 16px ทำให้ "ทุกหน้า" เลื่อนซ้าย-ขวาได้ (วัดจริงบนเดโม:
     scrollWidth 391 > clientWidth 375) — โลโก้ยอมย่อได้ + ปุ่มขวาห้ามถูกบีบ จบปัญหาที่ต้นเหตุ */
  .topheader-logo{ flex:0 1 auto; min-width:0; overflow:hidden; }  /* ต้อง 0 1 auto ไม่ใช่ 0 0 auto ไม่งั้นย่อไม่ได้ */
  .topheader-logo .t1{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .topheader-right{ flex:0 0 auto; }
  .icon-btn{ width:36px; height:36px; }
  .avatar{ width:34px; height:34px; }

  .card{ padding:14px; }
  .card-grid{ grid-template-columns:repeat(2, 1fr); gap:10px; }
  .stat-card{ padding:12px; }
  .stat-card .value{ font-size:1.5rem; }
  .module-launcher{ grid-template-columns:1fr; gap:12px; }
  .module-grid{ grid-template-columns:1fr; }
  .mod-header{ flex-direction:column; align-items:flex-start; gap:12px; padding:18px; }

  .filters{ flex-direction:column; align-items:stretch; }
  .filters select, .filters input, .filters button{ width:100%; }

  .table-wrap, .table-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  table{ font-size:.85rem; min-width:520px; } /* min-width บังคับให้ scroll ในกล่องตัวเองแทนบีบตัวอักษรจนอ่านไม่ออก —
    ห่อด้วย .table-wrap/.table-scroll เสมอกัน body เลื่อนแนวนอน */
  th, td{ padding:8px; }
}
@media (max-width: 480px){
  .card-grid{ grid-template-columns:repeat(2, 1fr); gap:8px; }
}

/* GPMS dashboard 2-คอลัมน์ (bar chart/status legend, alert/stale card) — วางท้ายไฟล์เสมอ กันโดน .card-grid
   breakpoint เดิมทับ (cascade แพ้ถ้าอยู่ก่อนบล็อก media query อื่นที่ specificity เท่ากัน) */
.dash-col-wide{ grid-template-columns:1.3fr 1fr; }
.dash-col-even{ grid-template-columns:1fr 1fr; }
@media (max-width:900px){ .dash-col-wide, .dash-col-even{ grid-template-columns:1fr; } }

/* ---------- Project 360: stepper + key-value facts ---------- */
.p360-head{ display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:10px; margin-bottom:16px; }
.p360-head h2{ margin:0 0 4px; font-size:1.2rem; }
.p360-head .code{ color:var(--ink-soft); font-size:.85rem; }
.back-link{ background:none; border:none; color:var(--steel); cursor:pointer; font-size:.85rem; padding:0; margin-bottom:10px; font-family:inherit; text-decoration:none; display:inline-block; }

.stepper{ display:flex; align-items:flex-start; margin:10px 0 6px; overflow-x:auto; }
.step{ display:flex; flex-direction:column; align-items:center; flex:1; min-width:90px; position:relative; }
.step .dot{
  width:24px; height:24px; border-radius:50%; background:var(--ground); border:1px solid var(--line);
  color:var(--ink-soft); display:flex; align-items:center; justify-content:center; font-size:.72rem; font-weight:700;
  z-index:1; flex:0 0 auto;
}
.step .lbl{ font-size:.72rem; color:var(--ink-soft); margin-top:6px; text-align:center; }
.step::before{ content:''; position:absolute; top:12px; left:-50%; width:100%; height:2px; background:var(--line); z-index:0; }
.step:first-child::before{ display:none; }
.step.done .dot{ background:var(--signal-green); border-color:var(--signal-green); color:#fff; }
.step.done::before{ background:var(--signal-green); }
.step.current .dot{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); box-shadow:0 0 0 4px var(--accent-soft); }

.kv{ display:grid; grid-template-columns:170px 1fr; row-gap:10px; font-size:.88rem; }
.kv .k{ color:var(--ink-soft); }

.doc-link-card{ text-align:center; padding:22px; }
.doc-link-card .doc-icon{ font-size:2rem; margin-bottom:8px; }
.doc-link-card p{ color:var(--ink-soft); font-size:.85rem; margin:6px 0 14px; }

.profit-hero{ text-align:center; padding:40px 24px; }
.profit-hero .big-icon{ font-size:2.6rem; margin-bottom:10px; }
.profit-hero h2{ margin:0 0 8px; }
.profit-hero p{ color:var(--ink-soft); max-width:520px; margin:0 auto 4px; font-size:.92rem; }
.profit-skeleton-table{ opacity:.5; margin-top:22px; }
.profit-skeleton-table table{ pointer-events:none; }

/* ---------- Project 360: ความคืบหน้า / Gantt / WBS ---------- */
.p360-actions{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:16px; }
.p360-actions a, .p360-actions span.disabled{
  font-size:.82rem; padding:7px 13px; border-radius:6px; border:1px solid var(--line);
  color:var(--ink); text-decoration:none; background:var(--paper); display:inline-block;
}
.p360-actions a:hover{ border-color:var(--steel); }
.p360-actions span.disabled{ color:var(--ink-soft); background:var(--ground); cursor:not-allowed; }

/* ---------- Unified Project + PMO: professional information hierarchy ---------- */
.project-jump{
  display:flex; gap:6px; flex-wrap:wrap; margin:-4px 0 16px; padding:6px;
  width:max-content; max-width:100%; border:1px solid var(--line); border-radius:9px; background:var(--ground);
}
.project-edit-action{ border-color:var(--steel) !important; color:var(--steel) !important; font-weight:700; }
.project-save-success,.project-form-error{ margin:0 0 16px; padding:11px 14px; border-radius:8px; font-size:.86rem; }
.project-save-success{ color:var(--signal-green); border:1px solid var(--signal-green); background:color-mix(in srgb,var(--signal-green) 8%,transparent); }
.project-form-error{ color:var(--signal-red); border:1px solid var(--signal-red); background:color-mix(in srgb,var(--signal-red) 8%,transparent); }
.project-edit-head{ display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin:8px 0 18px; }
.project-edit-head h2{ margin:3px 0 4px; }
.project-edit-head p{ margin:0; color:var(--ink-soft); font-size:.85rem; }
.project-edit-form{ max-width:1040px; }
.project-form-section + .project-form-section{ margin-top:22px; padding-top:20px; border-top:1px solid var(--line); }
.project-form-section h3{ margin:0 0 12px; font-size:.96rem; }
.project-form-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.project-form-grid label{ display:flex; flex-direction:column; gap:6px; color:var(--ink-soft); font-size:.78rem; }
.project-form-grid label b{ color:var(--signal-red); }
.project-form-grid .span-2{ grid-column:1/-1; }
.project-form-grid input,.project-form-grid select,.project-form-grid textarea{ width:100%; box-sizing:border-box; color:var(--ink); background:var(--ground); border:1px solid var(--line); border-radius:7px; padding:10px 11px; font:inherit; font-size:.86rem; }
.project-form-grid textarea{ resize:vertical; line-height:1.5; }
.project-form-grid small{ color:var(--ink-soft); line-height:1.45; }
.project-edit-note{ margin-top:20px; padding:11px 13px; border-radius:7px; background:var(--ground); color:var(--ink-soft); font-size:.8rem; line-height:1.55; }
.project-form-actions{ display:flex; justify-content:flex-end; align-items:center; gap:10px; margin-top:18px; }
.project-form-actions a{ color:var(--ink-soft); text-decoration:none; padding:9px 13px; }
.project-form-actions button{ border:0; border-radius:7px; padding:10px 16px; color:white; background:var(--steel); font-weight:700; cursor:pointer; }
@media (max-width:700px){
  .project-edit-head{ flex-direction:column; }
  .project-form-grid{ grid-template-columns:1fr; }
  .project-form-grid .span-2{ grid-column:auto; }
}
.project-jump a{ color:var(--ink-soft); text-decoration:none; font-size:.78rem; padding:6px 10px; border-radius:6px; }
.project-jump a:hover{ color:var(--ink); background:var(--paper); }
.executive-summary{ margin:18px 0; }
.section-heading{ display:flex; align-items:flex-end; justify-content:space-between; gap:12px; margin-bottom:10px; }
.section-heading h3{ margin:2px 0 0; font-size:1.08rem; }
.section-eyebrow{ color:var(--steel); font-size:.68rem; font-weight:700; letter-spacing:.12em; }
.executive-grid{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:12px; }
.executive-grid .pmo-insight{ margin:0; min-height:100%; }
.executive-ai .pmo-source{ margin:10px 0 0; }
.project-section{
  margin-bottom:12px; border:1px solid var(--line); border-radius:12px; background:var(--ground-raised); overflow:hidden;
}
.project-section > summary{
  display:flex; align-items:center; gap:12px; padding:15px 18px; cursor:pointer; list-style:none; user-select:none;
}
.project-section > summary::-webkit-details-marker{ display:none; }
.project-section > summary::after{ content:'+'; margin-left:4px; color:var(--ink-soft); font-size:1.25rem; line-height:1; }
.project-section[open] > summary::after{ content:'−'; }
.project-section[open] > summary{ border-bottom:1px solid var(--line); }
.project-section > summary > span:nth-child(2){ display:flex; flex:1; min-width:0; flex-direction:column; gap:2px; }
.project-section > summary b{ color:var(--ink); font-size:.94rem; }
.project-section > summary small{ color:var(--ink-soft); font-size:.72rem; }
.section-index{ color:var(--steel); font-size:.72rem; font-weight:700; letter-spacing:.08em; }
.section-meta{ color:var(--ink-soft); font-size:.75rem; text-align:right; }
.project-section-accent{ border-left:3px solid var(--steel); }
.project-section-body{ padding:16px; }
.project-section-body > :last-child{ margin-bottom:0 !important; }
.project-section-body .pmo-dim:first-of-type{ margin-top:0; }
@media (max-width:800px){
  .executive-grid{ grid-template-columns:1fr; }
  .section-meta{ display:none; }
  .project-section > summary{ padding:13px 14px; }
  .project-section-body{ padding:12px; }
}

.prog-row{ display:flex; justify-content:space-between; font-size:.85rem; color:var(--ink-soft); margin:10px 0 4px; }
.prog-row b{ color:var(--ink); }
.prog-track{ height:10px; border-radius:99px; background:var(--ground); overflow:hidden; }
.prog-fill{ height:100%; border-radius:99px; }
.prog-fill.plan{ background:var(--steel); }
.prog-fill.actual{ background:var(--signal-green); }
.sync-note{ font-size:.82rem; color:var(--ink-soft); background:var(--ground); border-radius:6px; padding:10px 12px; margin-top:12px; line-height:1.6; }

/* 6 ส.ค. 2569: เจ้าของสั่งให้ Gantt โชว์ "ชื่อเต็ม" ของงาน (เดิม .g-lbl ตัด ellipsis จนอ่านไม่รู้เรื่อง)
   + ให้เลื่อน scrollbar แนวนอนได้แทนบีบทุกอย่างจนอ่านไม่ออก — ครอบด้วย .gantt-scroll (overflow-x:auto)
   + .gantt มี min-width คงที่ ส่วนคอลัมน์ชื่องาน (.g-lbl) sticky ซ้ายไว้ตอนเลื่อน */
.gantt-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
.gantt{ font-size:.78rem; min-width:640px; }
.g-row{ display:grid; grid-template-columns:230px 1fr; gap:10px; align-items:center; }
.g-row + .g-row{ margin-top:3px; }
.g-lbl{
  color:var(--ink-soft); white-space:normal; word-break:break-word; overflow-wrap:break-word; line-height:1.3;
  position:sticky; left:0; z-index:1; background:var(--ground-raised); padding:2px 8px 2px 0;
}
.g-lbl span{ color:var(--ink); }
.g-track{ position:relative; height:19px; background:var(--ground); border-radius:3px; }
.g-head .g-track{ background:none; height:auto; display:flex; border-bottom:1px solid var(--line); padding-bottom:3px; }
.g-head .g-lbl{ background:var(--ground-raised); }
.g-month{ color:var(--ink-soft); overflow:hidden; }
.g-bar{ position:absolute; top:4px; height:11px; border-radius:3px; background:var(--steel); }
.g-bar.major{ top:2px; height:15px; background:var(--accent); }
.g-bar.over{ background:var(--signal-red); }
.g-today{ position:absolute; top:0; bottom:0; width:1px; background:var(--signal-red); }
@media (max-width:700px){ .g-row{ grid-template-columns:160px 1fr; } .gantt{ min-width:520px; } }

.wbs-group, .wbs-child{ display:flex; align-items:center; gap:10px; font-size:.85rem; padding:7px 9px; }
.wbs-group > summary{ display:flex; align-items:center; gap:10px; cursor:pointer; list-style:none; padding:7px 9px; background:var(--ground); border-radius:6px; }
.wbs-group{ display:block; padding:0; margin-bottom:3px; }
.wbs-group.solo{ display:flex; background:var(--ground); border-radius:6px; margin-bottom:3px; }
.wbs-group > summary::-webkit-details-marker{ display:none; }
.wbs-group > summary::before{ content:'▸'; color:var(--ink-soft); }
.wbs-group[open] > summary::before{ content:'▾'; }
.wbs-child{ padding-left:34px; color:var(--ink-soft); }
.wbs-child.flat{ padding-left:9px; border-bottom:1px solid var(--line); }
.w-key{ color:var(--ink-soft); min-width:44px; }
.w-name{ flex:1; color:var(--ink); overflow:hidden; text-overflow:ellipsis; }
.w-derived{ color:var(--ink-soft); font-size:.72rem; border:1px solid var(--line); border-radius:99px; padding:1px 7px; }
.w-count{ color:var(--ink-soft); }
.w-dates{ color:var(--ink-soft); font-size:.78rem; white-space:nowrap; }
.w-wt{ min-width:58px; text-align:right; color:var(--ink); }

/* Portfolio Dashboard (1 ส.ค. 2569) — ต่อจากบล็อค .gantt เดิม: สีแถบตามสถานะจริงของโครงการ (ไม่ใช่
   ตามน้ำหนักงานแบบ Gantt โครงการเดียว) + คอลัมน์ 'โครงการตามสถานะ' แบบ kanban เบาๆ ไม่ลากไลบรารีใหม่ */
.g-bar.tone-steel{ background:var(--steel); }
.g-bar.tone-green{ background:var(--signal-green); }
.g-bar.tone-amber{ background:var(--signal-amber); }
.g-bar.tone-red{ background:var(--signal-red); }
.portfolio-gantt .g-lbl a{ color:inherit; text-decoration:none; }
.portfolio-gantt .g-lbl a:hover{ text-decoration:underline; }

/* 6 ส.ค. 2569: เจ้าของสั่งให้แถว Gantt ของ Portfolio (รวมทั้งพอร์ต ไม่ใช่รายงานเดียว) โชว์รหัส+short_name
   คู่กัน แทนรหัสเปล่าๆ ที่อ่านไม่รู้เรื่อง — ต่างจาก .g-lbl ของ Gantt รายโครงการด้านบนที่เจ้าของสั่งวันเดียวกัน
   ให้ตัดกลับมาโชว์ชื่อเต็มไม่ตัด (ที่นั่นแถวน้อยกว่า ชื่องานยาวเป็นปกติ) ที่นี่ตรงข้าม: มีเป็นสิบๆ แถวพร้อมกัน ป้าย
   ยาวเกินจะดันแถบเวลาให้แคบจนอ่านไม่ออก จึงตัดด้วย ellipsis + title โชว์เต็มตอน hover แทน คอลัมน์ label ก็กว้าง
   ขึ้นจาก 230px เป็น 270px ให้พอมีที่ให้ short_name สั้นๆ ทั่วไปแสดงไม่ตัด (ยังอยู่ใน .gantt-scroll เดิมที่ scroll
   แนวนอนได้เฉพาะกล่อง Gantt ไม่ใช่ทั้งหน้า) */
.gantt.portfolio-gantt .g-row{ grid-template-columns:270px 1fr; }
.gantt.portfolio-gantt .g-lbl{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.gantt.portfolio-gantt .g-lbl a{ display:block; overflow:hidden; text-overflow:ellipsis; }
@media (max-width:700px){ .gantt.portfolio-gantt .g-row{ grid-template-columns:190px 1fr; } }

.status-cols{ display:grid; grid-template-columns:repeat(auto-fit, minmax(180px,1fr)); gap:12px; }
.status-col{ background:var(--ground); border-radius:10px; padding:10px 12px; font-size:.83rem; }
.status-col-head{ display:flex; align-items:center; gap:6px; font-weight:600; margin-bottom:8px; }
.status-col-head .dot{ width:9px; height:9px; border-radius:3px; flex:0 0 9px; }
.status-col-head .dot.tone-steel{ background:var(--steel); }
.status-col-head .dot.tone-red{ background:var(--signal-red); }
.status-col-head .dot.tone-amber{ background:var(--signal-amber); }
.status-col-head .dot.tone-green{ background:var(--signal-green); }
.status-col-head .name{ flex:1; }
.status-col-head .count{ color:var(--ink-soft); }
.status-col-item{ display:block; color:var(--ink); text-decoration:none; padding:4px 0; border-top:1px solid var(--line); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.status-col-item:first-of-type{ border-top:none; }
.status-col-item:hover{ color:var(--steel); }

/* ---------------------------------------------------------------------------
   Hover micro-interactions — "border-draw" (โน้ตเจ้าของ 9 ส.ค. 2569, ดู
   00_GPMS_แผนระบบบริหารโครงการ/procurement_process_v2_2569-08.md ท้ายไฟล์) — สไตล์กลางของ Portal แต่ผูกแบบ
   opt-in class .hv-card / .hv-btn เท่านั้น (ไม่ restyle การ์ด/ปุ่ม/ลิงก์เดิมทั้งระบบแบบ blanket — เสี่ยงกระทบ
   ทุกโมดูลที่มีอยู่แล้วโดยไม่ได้ตรวจทีละหน้า) ติด class นี้เพิ่มบนองค์ประกอบที่ต้องการ hover เท่านั้น (ตอนนี้ใช้
   ในจอ v2 ของ gpms_procurement — ดูคู่มือเพิ่มโมดูลใหม่.md ถ้าจะขยายไปโมดูลอื่นภายหลัง)
   กติกา animation: ใช้ pseudo-element ::after วาดกรอบด้วย transform:scale + opacity ล้วน (ไม่แตะ width/border/
   box-shadow ที่ trigger layout หรือ repaint หนัก) ระยะ ~0.25s ตามโน้ตเจ้าของ + ปิด transition เสมอเมื่อ
   prefers-reduced-motion: reduce (ยังคง opacity/scale ปลายทางไว้ แค่ตัดระยะเปลี่ยนผ่านออก) */
.hv-card, .hv-btn{ position:relative; isolation:isolate; }
.hv-card::after, .hv-btn::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  border:1.5px solid var(--accent); pointer-events:none;
  opacity:0; transform:scale(.96);
  transition:opacity .25s ease, transform .25s ease;
}
.hv-card:hover::after, .hv-btn:hover::after,
.hv-card:focus-visible::after, .hv-btn:focus-visible::after{
  opacity:1; transform:scale(1);
}
@media (prefers-reduced-motion: reduce){
  .hv-card::after, .hv-btn::after{ transition:none; }
}

/* .hero-cta — ปุ่ม CTA เด่น ใช้ 27 จุดทั่ว service นี้ (เช่น "+ ลงทะเบียนผู้ขายรายใหม่") แต่ไม่เคยมี rule
   กำหนดไว้จริงมาก่อน (แก้ 13 ส.ค. 2569) — ก็อปมาจาก portal/app/static/style.css บรรทัด 713-718 เป๊ะๆ
   ทุก token ที่ใช้ (--r-sm, --accent, --accent-ink, --font-body) มีประกาศอยู่แล้วใน
   app/static/design/tokens.css ของ service นี้ */
.hero-cta{
  display:inline-flex; align-items:center; gap:8px; padding:10px 20px; border-radius:var(--r-sm); border:none;
  background:var(--accent); color:var(--accent-ink); font-family:var(--font-body); font-weight:700;
  font-size:.9rem; cursor:pointer; text-decoration:none;
}
.hero-cta:hover{ opacity:.92; }
.status-col-more{ color:var(--ink-soft); font-size:.76rem; padding-top:4px; }

/* ---------------------------------------------------------------------------
   Vendor Profile 5 แท็บ (12 ส.ค. 2569) — ใช้เฉพาะ vendor_detail.html
   ทุกสีอ้าง CSS variable เดิมทั้งหมด (ตระกูล --signal- / --steel / --line / --ink) จึงได้ dark mode ที่มี
   อยู่แล้วฟรี ไม่ประกาศตัวแปรสีใหม่สักตัว · accent ของแท็บที่เลือก = --signal-amber (tone-amber เดิมของระบบ)
   ⚠ ห้ามพิมพ์เครื่องหมายดอกจันติดทับ (ปิดคอมเมนต์) กลางคอมเมนต์นี้ — เคยพลาดมาแล้ว 12 ส.ค. 2569: เขียน
   ชื่อตัวแปรแบบ wildcard ทำให้คอมเมนต์จบก่อนเวลา แล้ว CSS ของหัวหน้าผู้ขายหายไปทั้งชุดแบบเงียบๆ */
.vendor-head{
  display:flex; justify-content:space-between; align-items:flex-start; gap:16px; flex-wrap:wrap;
  background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r);
  padding:18px; box-shadow:var(--shadow);
}
.vh-name{ margin:0 0 8px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.vh-tags{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:8px; }
.vh-tag{
  font-size:.8rem; color:var(--ink-soft); background:var(--ground);
  border:1px solid var(--line); border-radius:999px; padding:2px 10px;
}
.vh-contact{ display:flex; gap:18px; flex-wrap:wrap; align-items:center; color:var(--ink-soft); font-size:.9rem; }
.vh-copy{ display:inline-flex; align-items:center; gap:6px; }
.vh-muted{ color:var(--ink-soft); opacity:.75; }

.vtabs{ display:flex; gap:4px; flex-wrap:wrap; margin:20px 0 0; border-bottom:1px solid var(--line); }
.vtab{
  background:none; border:none; border-bottom:3px solid transparent; cursor:pointer;
  padding:10px 14px; font-family:inherit; font-size:.92rem; font-weight:600;
  color:var(--ink-soft); border-radius:var(--r-sm) var(--r-sm) 0 0;
}
.vtab:hover{ color:var(--ink); background:var(--ground); }
.vtab.active{ color:var(--signal-amber); border-bottom-color:var(--signal-amber); background:var(--signal-amber-soft); }
.vtab-panel{ margin-top:16px; }
.vtab-panel[hidden]{ display:none; }

.vpanel-head{ display:flex; justify-content:space-between; align-items:flex-start; gap:12px; flex-wrap:wrap; }
.var-cell{ font-weight:700; white-space:nowrap; }
.var-cell small{ font-weight:400; opacity:.8; }
.var-cell.tone-green{ color:var(--signal-green); }
.var-cell.tone-red{ color:var(--signal-red); }
.var-cell.tone-steel{ color:var(--steel); }

/* แท็บประเมิน — ฟอร์ม (ซ้าย) / ประวัติ+กราฟแท่ง (ขวา) */
.veval-grid{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.2fr); gap:16px; align-items:start; }
.score-row{ display:grid; grid-template-columns:150px 1fr 40px; align-items:center; gap:10px; margin-top:12px; }
.score-row label{ font-size:.88rem; font-weight:600; }
.score-slider{ width:100%; accent-color:var(--accent); }
.score-out{
  text-align:center; font-family:var(--font-display); font-weight:800; font-size:1.1rem;
  color:var(--accent);
}
.evalbars{ display:flex; align-items:flex-end; gap:10px; overflow-x:auto; padding:8px 0 0; }
.evalbar{ flex:0 0 44px; text-align:center; }
.eb-track{
  height:110px; background:var(--ground); border:1px solid var(--line); border-radius:var(--r-sm);
  display:flex; align-items:flex-end; overflow:hidden;
}
.eb-fill{ width:100%; border-radius:var(--r-sm) var(--r-sm) 0 0; }
.eb-fill.tone-green{ background:var(--signal-green); }
.eb-fill.tone-amber{ background:var(--signal-amber); }
.eb-fill.tone-red{ background:var(--signal-red); }
.eb-fill.tone-steel{ background:var(--steel); }
.eb-score{ font-weight:700; font-size:.82rem; margin-top:4px; }
.eb-date{ color:var(--ink-soft); font-size:.68rem; word-break:break-all; }

/* แท็บเอกสาร — การ์ด + ไฟจราจรตามวันหมดอายุ */
.doc-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(240px,1fr)); gap:14px; margin-top:12px; }
.doc-card{
  background:var(--ground); border:1px solid var(--line); border-radius:var(--r);
  padding:14px; display:flex; flex-direction:column; gap:6px;
}
.doc-card.is-iso{ border-left:4px solid var(--signal-green); }
.doc-top{ display:flex; align-items:center; gap:8px; }
.doc-light{ width:12px; height:12px; border-radius:50%; flex:0 0 auto; background:var(--steel); }
.doc-light.tone-green{ background:var(--signal-green); }
.doc-light.tone-amber{ background:var(--signal-amber); }
.doc-light.tone-red{ background:var(--signal-red); }
.doc-light.tone-steel{ background:var(--steel); }
.doc-type{ font-weight:700; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.doc-no, .doc-meta{ color:var(--ink-soft); font-size:.82rem; }
.doc-foot{ margin-top:auto; padding-top:6px; font-size:.85rem; }

/* ฟิลด์ฟอร์ม wizard (.wz-*) — เดิมประกาศเฉพาะใน <style> ของ vendor_new.html หน้าเดียว ย้ายชุดที่ใช้ร่วมกันมาไว้
   ที่นี่ (13 ส.ค. 2569 — บรีฟเจ้าของข้อ 5) เพื่อให้ vendor_detail.html (ฟอร์ม "+ เพิ่มเอกสารรับรองและมาตรฐาน"
   ในแท็บเอกสาร) ใช้ร่วมกับ vendor_new.html (wizard ขั้น 4) ได้โดยไม่ duplicate กฎ — ส่วนที่เหลือของ wizard
   (stepper/panel/toast/actions/btn/contact-row/review) ยังเป็นของเฉพาะหน้า อยู่ใน <style> ของ vendor_new.html
   เหมือนเดิม เพราะไม่มีหน้าอื่นใช้ */
.wz-field{ display:flex; flex-direction:column; gap:4px; margin-bottom:12px; }
.wz-field label{ font-size:.85rem; color:var(--ink-soft); font-weight:600; }
.wz-field .req{ color:var(--signal-red); }
.wz-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:12px; }
.wz-iso-block{ border:1px solid var(--line); border-radius:var(--r); padding:12px; margin-bottom:10px; }

/* แท็บแก้ไขข้อมูล */
.form-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(220px,1fr)); gap:12px; }
.form-grid label{ display:flex; flex-direction:column; gap:4px; font-size:.85rem; font-weight:600; color:var(--ink-soft); }
.form-grid input{
  padding:9px 11px; border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--ground-raised); color:var(--ink); font-family:inherit; font-size:.92rem;
}
.form-grid input:disabled{ opacity:.6; }
.form-grid textarea{
  padding:9px 11px; border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--ground-raised); color:var(--ink); font-family:inherit; font-size:.92rem; resize:vertical;
}
/* (13 ส.ค. 2569 รอบ 2 — บรีฟเจ้าของ) ขยายสูงตามเนื้อหา ไม่โชว์ scrollbar — JS ในเทมเพลตตั้ง height =
   scrollHeight ตอนโหลด/ตอนพิมพ์ overflow:hidden กันแถบเลื่อนโผล่ระหว่างที่ยังไม่ resize, resize:vertical
   ยังลากขยายเองเพิ่มได้ตามเดิม */
.form-grid textarea.vp-autogrow{ overflow:hidden; resize:vertical; }
/* แท็บแก้ไขข้อมูล — รายชื่อผู้ติดต่อหลายคน (มิเรอร์ .wz-contact-row ของ vendor_new.html) */
.vc-contact-row{ display:grid; grid-template-columns:1.2fr 1fr 1.2fr auto; gap:8px; align-items:center; margin-bottom:8px; }
.vc-contact-row .vc-del{
  background:none; border:1px solid var(--line); border-radius:8px; cursor:pointer;
  padding:8px 10px; color:var(--signal-red); transition:all .15s ease;
}
.vc-contact-row .vc-del:hover{ background:var(--signal-red-soft); border-color:var(--signal-red); }

/* แท็บตั้งค่าขั้นสูง — Danger Zone */
.danger-zone{ border:2px solid var(--signal-red); background:var(--signal-red-soft); }
.switch-row{ display:flex; align-items:center; gap:10px; font-weight:600; margin:10px 0; }
.switch{ position:relative; display:inline-block; width:46px; height:26px; flex:0 0 auto; }
.switch input{ position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer; z-index:1; }
.switch-track{
  position:absolute; inset:0; background:var(--line); border-radius:999px; transition:background .2s ease;
}
.switch-track::before{
  content:""; position:absolute; top:3px; left:3px; width:20px; height:20px; border-radius:50%;
  background:var(--ground-raised); transition:transform .2s ease;
}
.switch input:checked + .switch-track{ background:var(--signal-red); }
.switch input:checked + .switch-track::before{ transform:translateX(20px); }
.dz-field{ display:flex; flex-direction:column; gap:4px; margin-top:10px; font-size:.85rem; font-weight:600; }
.dz-field textarea{
  padding:9px 11px; border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--ground-raised); color:var(--ink); font-family:inherit; font-size:.92rem; resize:vertical;
}
#blacklistSubmit:disabled{ opacity:.5; cursor:not-allowed; }
@media (prefers-reduced-motion: reduce){
  .switch-track, .switch-track::before{ transition:none; }
}
@media (max-width: 900px){
  .veval-grid{ grid-template-columns:1fr; }
  .score-row{ grid-template-columns:120px 1fr 32px; }
}

/* ---------------------------------------------------------------------------
   ทะเบียนผู้ขายแบบ accordion (12 ส.ค. 2569) — ใช้เฉพาะ vendors_list.html
   ทุกสีอ้าง CSS variable เดิม (--ground / --ground-raised / --line / --ink / --accent / --signal- / --steel)
   จึงได้ dark mode ฟรี ไม่ประกาศตัวแปรสีใหม่ · accent ปุ่ม primary = --accent (ส้ม terracotta ของระบบ)
   hover border-draw ใช้คลาส .hv-card เดิม (opt-in) ที่ประกาศไว้ด้านบน ไม่ทำซ้ำที่นี่ */
.vlist-head{
  display:flex; justify-content:space-between; align-items:flex-end; gap:12px; flex-wrap:wrap;
  margin-bottom:8px;
}

.vlist-toolbar{
  display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;
  margin:16px 0;
}
.vsearch{
  flex:1 1 260px; min-width:0; padding:10px 14px; border:1px solid var(--line); border-radius:999px;
  background:var(--ground-raised); color:var(--ink); font-family:inherit; font-size:.92rem;
}
.vsearch:focus{
  outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);
}
/* (13 ส.ค. 2569) — filter pills เดิมเปลี่ยนเป็น <select> เดียว (บรีฟเจ้าของ) ใช้ baseline สไตล์ select กลาง
   จาก design/base-controls.css อยู่แล้ว แค่คุม flex-basis ให้เข้าแถวเดียวกับช่องค้นหาสวยๆ */
.vfilter-select{ flex:0 0 auto; min-width:200px; }

.vacc{ display:flex; flex-direction:column; gap:10px; }
.vacc-card{
  background:var(--ground-raised); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow); overflow:hidden;
}
/* (13 ส.ค. 2569 รอบ 2, บรีฟเจ้าของหลังทดสอบ) — การ์ดยุบโชว์ข้อมูลย่อครบใน head: avatar /
   ชื่อ(+พื้นที่ให้บริการ) + ประเภท(+รายละเอียดสินค้าตัดสั้น) / ยอดซื้อสะสม / Grade / ลูกศร
   — .vacc-id (flex:1 1 auto) กินพื้นที่ว่างดัน money/grade/chevron ไปชิดขวาเอง ไม่ต้อง space-between */
.vacc-head{
  width:100%; display:flex; align-items:center; gap:14px; padding:14px 18px;
  background:none; border:none; cursor:pointer; text-align:left; font-family:inherit; color:var(--ink);
}
.vacc-avatar{
  flex:0 0 auto; width:42px; height:42px; border-radius:50%; display:flex; align-items:center;
  justify-content:center; font-family:var(--font-display); font-weight:800; font-size:1rem;
  background:var(--steel-soft); color:var(--steel);
}
.vacc-avatar.tone-green{ background:var(--signal-green-soft); color:var(--signal-green); }
.vacc-avatar.tone-amber{ background:var(--signal-amber-soft); color:var(--signal-amber); }
.vacc-avatar.tone-red{ background:var(--signal-red-soft); color:var(--signal-red); }
.vacc-avatar.tone-steel{ background:var(--steel-soft); color:var(--steel); }
.vacc-id{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
/* (13 ส.ค. 2569 รอบ 2) — แถวชื่อ: ลิงก์ชื่อผู้ขาย + (พื้นที่ให้บริการ) + badge blacklist เรียงบรรทัดเดียว (wrap ได้) */
.vacc-name-row{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-width:0; }
.vacc-name{
  font-weight:700; font-size:.98rem; display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  color:inherit; text-decoration:none;
}
.vacc-name:hover, .vacc-name:focus-visible{ text-decoration:underline; }
.vacc-name.is-blacklisted{ color:var(--signal-red); }
.vacc-chevron{
  flex:0 0 auto; color:var(--ink-soft); font-size:1rem; transition:transform .2s ease;
}
.vacc-card.is-open .vacc-chevron{ transform:rotate(180deg); }

.vacc-body{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:18px;
  padding:16px 18px 18px; border-top:1px solid var(--line); background:var(--ground);
}
/* (13 ส.ค. 2569 — บั๊กยุบ/ขยายไม่ได้) .vacc-body{display:grid} ข้างบนทับ UA rule [hidden]{display:none} เพราะ
   specificity เท่ากัน (0,1,0) แต่กฎ author ที่มาทีหลังชนะ — body การ์ดเลยโผล่ตลอดแม้ JS จะเซ็ต hidden attribute
   ไว้ถูกต้องแล้ว ต้องมีกฎเฉพาะ [hidden] ที่ specificity สูงกว่า (0,2,0) มาชนะแทน */
.vacc-body[hidden]{ display:none; }
/* ป้ายประเภท/ยอดซื้อสะสม/Grade อยู่ใน .vacc-head (การ์ดยุบ) — bare selector ใช้ได้ทุกที่ที่ element ปรากฏ */
.vacc-type{ color:var(--ink-soft); font-size:.82rem; }
.vacc-money{ flex:0 0 auto; text-align:right; display:flex; flex-direction:column; }
.vacc-money-label{ color:var(--ink-soft); font-size:.72rem; font-weight:600; }
.vacc-money-value{ font-family:var(--font-display); font-weight:800; font-size:1.05rem; }
.vacc-grade{ flex:0 0 auto; }
.vacc-col{ display:flex; flex-direction:column; gap:8px; min-width:0; }
.vacc-col-title{
  margin:0 0 2px; font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
  color:var(--ink-soft);
}
.vacc-kpi{ display:flex; justify-content:space-between; align-items:baseline; gap:10px; }
.vacc-kpi-label{ color:var(--ink-soft); font-size:.85rem; }
.vacc-kpi-value{ font-weight:700; font-size:.92rem; }
.vacc-muted{ color:var(--ink-soft); }
.vacc-iso{ display:flex; flex-direction:column; gap:6px; }
.vacc-iso-chip{
  display:inline-flex; align-items:center; gap:8px; padding:5px 10px; border-radius:999px;
  border:1px solid var(--line); background:var(--ground-raised); font-size:.82rem; font-weight:600;
}
.vacc-iso-chip.is-absent{ opacity:.5; }
.vacc-iso-code{ white-space:nowrap; }
.vacc-actions{ justify-content:center; gap:10px; }
.vacc-btn{
  display:block; text-align:center; text-decoration:none; padding:10px 14px; border-radius:var(--r-sm);
  font-family:inherit; font-weight:700; font-size:.9rem; cursor:pointer; border:1px solid var(--line);
}
.vacc-btn.secondary{ background:var(--ground-raised); color:var(--ink); }
.vacc-btn.primary{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }

@media (max-width: 720px){
  .vacc-body{ grid-template-columns:1fr; }
  /* (13 ส.ค. 2569 รอบ 2) — money/grade คงไว้ใน head ตามบรีฟเจ้าของ (โชว์ตอนย่อ) · .vacc-id min-width:0
     ยอมให้ชื่อหด/ตัดบนจอแคบ money/grade จึงไม่ถูกเบียดตก */
  .vfilter-select{ width:100%; }
}

/* ---------- modal "+PR" (13 ส.ค. 2569, บรีฟ PU) — ครอบ iframe ของ /pr/new?embed=1 แทนเด้งไปหน้าใหม่
   (_pr_new_modal.html) — z-index สูงกว่า .pinned-sidebar (35) เพราะต้องลอยทับแถบข้างของหน้าที่เปิดอยู่ด้วย ----------*/
.pr-modal-overlay{
  position:fixed; inset:0; background:rgba(20,22,26,.55); z-index:200;
  display:flex; align-items:center; justify-content:center; padding:20px;
}
.pr-modal-overlay[hidden]{ display:none; }
body.pr-modal-open{ overflow:hidden; }
.pr-modal-panel{
  width:min(1100px, 92vw); height:90vh; background:var(--ground-raised); border-radius:var(--r);
  box-shadow:var(--shadow); display:flex; flex-direction:column; overflow:hidden;
}
.pr-modal-head{
  display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 18px;
  border-bottom:1px solid var(--line); flex:0 0 auto;
}
.pr-modal-head h3{ margin:0; font-size:1rem; }
.pr-modal-close{
  border:1px solid var(--line); background:var(--ground); color:var(--ink); border-radius:var(--r-sm);
  width:32px; height:32px; font-size:1rem; line-height:1; cursor:pointer;
}
.pr-modal-close:hover{ background:var(--signal-red-soft); color:var(--signal-red); border-color:var(--signal-red); }
.pr-modal-frame{ border:none; width:100%; height:100%; flex:1 1 auto; }
