
/* ===========================================================================
   VERSE — sales deck
   ---------------------------------------------------------------------------
   ตอนนี้มีสองหน้า: หน้าแรก (5 หน่วยธุรกิจ) → หน้าหน่วย (หมวดหมู่)
   ชั้นผลงานจะมาทีหลัง โครงข้อมูลข้างล่างเตรียมที่ไว้ให้แล้ว

   Token ทั้งหมดคัดลอกมาจาก verse web (src/app/globals.css) เพื่อไม่ให้เด็คขายงาน
   กับเว็บสาธารณะเพี้ยนออกจากกัน
   =========================================================================== */
/* --------------------------------------------------------------------------
   ตัวอักษร — DIN Pro สำหรับอังกฤษ, Prompt สำหรับไทย

   DIN Pro วางไฟล์ไว้ในโปรเจกต์เอง ไม่ดึงจาก Google ได้เปรียบกว่าของเดิมตรงที่
   ใช้ได้แม้ไม่มีเน็ต ซึ่งเป็นสถานการณ์จริงของห้องประชุมลูกค้าบ่อยกว่าที่คิด
   ต่างจาก Anton กับ Inter เดิมที่ต้องโหลดจาก Google ทุกครั้ง ถ้าเน็ตไม่มา
   ตัวอักษรจะตกไปใช้ฟอนต์ระบบทั้งเด็ค

   ข้อจำกัดที่ต้องรู้: DIN Pro ไม่มีอักขระไทยเลยสักตัว (ตรวจไฟล์แล้วได้ 0 จาก 127)
   Prompt จึงต้องอยู่ในสแตกทุกจุด เบราว์เซอร์จะสลับให้เองทีละอักขระ ส่วนป้ายที่มี
   ไทยปนอังกฤษ ยังใช้กติกาเดิมคือสลับทั้งป้ายเป็น Prompt ไม่ปล่อยให้ฟอนต์สองตัว
   คนละสัดส่วนชนกันกลางประโยค

   font-display:swap — ระหว่างที่ฟอนต์ยังโหลดไม่เสร็จให้แสดงด้วยฟอนต์สำรองไปก่อน
   ดีกว่าปล่อยตัวอักษรหายไปเฉย ๆ ตอนเปิดหน้าแรกต่อหน้าลูกค้า
   -------------------------------------------------------------------------- */
@font-face{
  font-family:"DIN Pro";
  src:url("../fonts/dinpro.otf") format("opentype");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"DIN Pro";
  src:url("../fonts/dinpro_medium.otf") format("opentype");
  font-weight:500;font-style:normal;font-display:swap;
}
/*
  ประกาศ 600 ให้ชี้ไปที่ Bold ด้วย

  CSS ในไฟล์นี้ใช้ 600 อยู่สิบจุด (บรรทัดบทบาท คีย์ลัด หัวข้อย่อย) ถ้าไม่ประกาศไว้
  เบราว์เซอร์ก็จะไปหยิบ 700 มาใช้แทนอยู่ดีตามกติกาการจับคู่น้ำหนัก การเขียนให้ชัด
  ตรงนี้ทำให้อ่านโค้ดแล้วรู้ทันทีว่าจะได้อะไร ไม่ต้องไปนึกกฎในหัว
*/
@font-face{
  font-family:"DIN Pro";
  src:url("../fonts/dinpro_bold.otf") format("opentype");
  font-weight:600 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"DIN Pro";
  src:url("../fonts/dinpro_black.otf") format("opentype");
  font-weight:800 900;font-style:normal;font-display:swap;
}
/*
  ตัวแคบไว้ใช้กับป้ายตัวใหญ่ แทนที่ Anton เดิม

  Anton เป็นตัวแคบและหนามาก ซึ่งเป็นเหตุผลที่ชื่อผลงานยาว ๆ ลงในปุ่มได้โดยไม่ตกบรรทัด
  ถ้าใช้ DIN Pro ตัวปกติแทน ป้ายจะกว้างขึ้นแล้วดันชื่อยาวตกบรรทัด
  DIN Pro Condensed Black จึงเป็นตัวที่ทำหน้าที่เดิมได้ใกล้ที่สุดในตระกูลนี้
*/
@font-face{
  font-family:"DIN Pro Cond";
  src:url("../fonts/dinpro_condensedblack.otf") format("opentype");
  font-weight:400 900;font-style:normal;font-display:swap;
}

:root{
  --ink:#0a0a0a;
  --paper:#f5f4f1;
  --surface:#151515;
  --surface-hi:#1e1e1e;
  --line:#2b2b2b;
  --line-hi:#3d3d3d;
  --muted:#a3a09a;

  /* สีแบรนด์ย่อยแบบยกความสว่างแล้ว สำหรับใช้บนพื้นดำ
     ค่าที่วาดไว้ในไฟล์โลโก้ (#5308a8, #ff2e00, #ffb300, #f0005a) ใช้กับตัวโลโก้เท่านั้น
     — #5308a8 บนพื้น #0a0a0a ได้ contrast แค่ 1.6:1 แบกตัวหนังสือหรือเส้นไม่ไหว */
  --violet-lit:#a06bff;
  --vermillion-lit:#ff6038;
  --mustard-lit:#ffc233;
  --magenta-lit:#ff4d85;

  /* สีแบรนด์ตาม Colorlist ของ UI Set 4 — ใช้กับองค์ประกอบภาพตามเรฟ
     ส่วนสี lit ด้านบนยังคงไว้สำหรับ focus/ข้อความที่ต้องอ่านบนพื้นดำ */
  --brand-violet:#4c12a1;
  /* UI Set 5 แก้สีม่วงสำหรับ "ตัวหนังสือ" โดยเฉพาะ
     #4c12a1 บนพื้นดำได้ contrast 1.6:1 อ่านไม่ออก เรฟชุดใหม่จึงยกความสว่าง
     ขึ้นเป็น #9960ed (4.9:1) ส่วน #4c12a1 ยังใช้กับตัวโลโก้ตามเดิม
     อีกสามหน่วยใช้ค่าเดียวกับ Colorlist อยู่แล้ว ไม่ต้องแก้ */
  --brand-violet-role:#9960ed;
  --brand-vermillion:#fa4616;
  --brand-mustard:#ffb600;
  --brand-magenta:#db0b5b;

  /* สเกลตัวอักษรสำหรับการพรีเซนต์ ตั้งใจให้ใหญ่กว่าเว็บอ่านทั่วไป
     ค่าต่ำสุดตั้งจากโน้ตบุ๊กที่หันจอให้คนอีกฝั่งโต๊ะ ค่าสูงสุดจากจอในห้องประชุม */
  --fs-hero:clamp(2.5rem,6.5vw,5.25rem);
  --fs-unit:clamp(1.875rem,4.2vw,3.5rem);
  --fs-body:clamp(0.9375rem,1.1vw,1.125rem);
  --fs-label:clamp(0.6875rem,0.82vw,0.8125rem);

  /*
    หัวข้อทุกหน้าอ้างตัวแปรนี้ตัวเดียว — เปลี่ยนฟอนต์หัวข้อทั้งเว็บที่บรรทัดเดียว

    Typography Guide ระบุหัวข้อเป็น TT Autonomous แต่ทีมยืนยันว่าไม่มีไฟล์
    ให้ใช้ DIN แทน จึงถอดการประกาศ @font-face ที่ชี้ไปไฟล์ที่ไม่มีอยู่ออก
    ไม่งั้นจะเหลือ 404 ทุกครั้งที่เปิดหน้า โดยไม่มีวันที่มันจะหาไฟล์เจอ

    ใช้ DIN Pro ตัวปกติ ไม่ใช่ตัวแคบ เพราะหัวข้อในอาร์ตบอร์ด UI Set 5
    เป็นตัวกว้าง น้ำหนัก 900 จะไปหยิบ dinpro_black.otf เอง
  */
  --font-display:"DIN Pro","Prompt","Segoe UI","Leelawadee UI",sans-serif;

  /*
    Clear space ตาม Brand Guideline

    กติกาคือ "เว้นรอบโลโก้เท่ากับสองเท่าของความหนาสี่เหลี่ยมในมอโนแกรม V"
    วัดจากไฟล์จริง สี่เหลี่ยมกว้าง 131px ทั้งสองล็อกอัพ — clear space = 262px

    แปลงเป็นอัตราส่วนต่อ "ความสูง" ของโลโก้ เพราะทุกที่ในไฟล์นี้คุมโลโก้ด้วย
    ความสูง ไม่ใช่ความกว้าง อัตราส่วนจึงคงที่ไม่ว่าโลโก้จะถูกย่อขยายเท่าไร
      ล็อกอัพตั้ง  426x523  ->  262/523 = 0.501
      ล็อกอัพนอน  1536x394 ->  262/394 = 0.665

    ใช้คู่กับ max() เสมอ เพราะ clear space เป็น "ระยะขั้นต่ำ" ไม่ใช่ระยะตายตัว
    ที่ไหนออกแบบให้ห่างกว่านี้อยู่แล้วต้องไม่ถูกบีบให้แคบลง
  */
  --clear-ratio-stack:.501;
  --clear-ratio-wide:.665;

  /* ล็อกอัพตั้งบนหน้าหน่วย/หมวด/ผลงาน — ประกาศที่นี่เพราะทั้งตัวโลโก้เอง
     และ padding หัวหน้า (ที่ต้องกันแถบนำทางไม่ให้ล้ำ clear space) ต้องใช้ค่าเดียวกัน */
  --lockup-h:clamp(78px,13vw,140px);
  --lockup-clear:calc(var(--clear-ratio-stack) * var(--lockup-h));

  --nav-h:4.5rem;
  --gutter:clamp(1.25rem,4vw,4rem);
  --radius:14px;

  --accent:var(--paper);   /* เปลี่ยนตามหน่วยธุรกิจที่เปิดอยู่ */
}

*,*::before,*::after{box-sizing:border-box}
html{background:var(--ink);color-scheme:dark}
body{
  margin:0;
  min-height:100dvh;
  background:var(--ink);
  color:var(--paper);
  font-family:"DIN Pro","Prompt","Segoe UI","Leelawadee UI",system-ui,sans-serif;
  font-size:var(--fs-body);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
}
img{max-width:100%;display:block}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer;text-align:left}

/* ต้องอ่านออกทั้งบนพื้นดำและบนแผ่นสีสว่าง */
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:6px}
/*
  ตัวหน้าไม่ต้องมีวงแหวนโฟกัส

  โค้ดย้ายโฟกัสมาที่ตัวหน้าทุกครั้งที่เปลี่ยนจอ เพื่อให้ screen reader รู้ว่า
  เนื้อหาเปลี่ยนแล้ว ไม่ใช่เพื่อให้คนกดอะไรตรงนี้ Chromium ไม่วาดวงแหวนให้
  แต่ Safari บน iPhone วาด — ได้กรอบขาวหนา 3px ล้อมทั้งหน้า ซึ่งขอบล่างของมัน
  โผล่เป็นเส้นขาวพาดขวางจอ

  ถอดเฉพาะตัวหน้าเท่านั้น ปุ่มและลิงก์ทุกตัวยังมีวงแหวนครบเหมือนเดิม
*/
.screen:focus,.screen:focus-visible{outline:none}
::selection{background:#ff2e00;color:#fff}

/* ข้อความสำหรับ screen reader อย่างเดียว — ลิงก์ QR เป็นภาพล้วน
   ถ้าไม่มีชื่อกำกับ จะถูกอ่านว่า "ลิงก์" เฉยๆ โดยไม่รู้ว่าไปไหน */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

.skip{
  position:absolute;top:0;left:0;z-index:200;
  transform:translateY(-120%);
  background:var(--paper);color:var(--ink);
  padding:.75rem 1.25rem;font-weight:600;border-radius:0 0 var(--radius) 0;
  transition:transform .15s ease;
}
.skip:focus{transform:translateY(0)}

/* --------------------------------------------------------------------------
   แถบนำทางล่างจอ — พวงมาลัยของคนพรีเซนต์

   อยู่ล่างเพราะนิ้วโป้งไปถึงได้จริงตอนถือมือถือมือเดียว มุมบนซ้ายเป็นจุดที่
   ไกลที่สุดของจอ ซึ่งเป็นที่ที่ปุ่มย้อนกลับมักถูกวางไว้ตามธรรมเนียมเว็บ

   ใช้แถบเดียว ไม่แยกเป็นบนล่าง สองแถบลอยกินความสูงจอมือถือไปเปล่าๆ
   และเบียดปุ่มจนต้องเลื่อน
   -------------------------------------------------------------------------- */
/*
  สามช่อง ซ้าย–กลาง–ขวา ใช้ grid ไม่ใช่ flex

  ปุ่มกลางต้องอยู่กึ่งกลางจอจริง ไม่ใช่กึ่งกลางของที่ว่างที่เหลือ ถ้าใช้ flex
  ตำแหน่งมันจะขยับตามความยาวชื่อหน่วยที่อยู่ทางซ้าย ซึ่งเปลี่ยนไปทุกหน้า
  1fr auto 1fr ล็อกให้ช่องซ้ายกับขวากว้างเท่ากันเสมอ ปุ่มกลางจึงนิ่ง

  ค่าตั้งต้นคือติดขอบล่าง สำหรับมือถือที่นิ้วโป้งต้องไปถึง
  ส่วนบนจอคอมย้ายขึ้นบนใน media query ข้างล่าง ตามที่คนคาดหวังจากเว็บ
*/
.navbar{
  position:fixed;left:0;right:0;bottom:0;z-index:100;
  min-height:var(--nav-h);
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:.5rem;
  padding-inline:var(--gutter);
  /* เผื่อแถบ home indicator ของ iOS ไม่งั้นปุ่มจะไปอยู่ใต้เส้นที่ปัดขึ้นได้
     กลายเป็นกดทีไรเด้งออกจากเว็บ */
  padding-bottom:env(safe-area-inset-bottom,0px);
  background:rgba(10,10,10,.9);
  backdrop-filter:blur(12px);
  border-top:1px solid var(--line);
}
.navbar__btn{
  display:flex;align-items:center;gap:.5rem;flex:none;
  /* ระยะขอบแคบลงเพื่อคืนความกว้างให้ป้าย — ช่องซ้ายกับขวากว้างเท่ากันเสมอ
     ตามกริดที่ล็อกปุ่มกลางไว้ แต่ป้าย "ค้นหา" ยาวกว่า "Back" จึงโดนตัด 5-6px
     พื้นที่กดยังสูง 44px เท่าเดิม ไม่ได้เล็กลงในแง่การใช้นิ้ว */
  min-height:44px;padding:.375rem .5rem;
  border-radius:10px;
  font-weight:600;letter-spacing:-.01em;
  transition:background .18s ease,color .18s ease;
}
.navbar__btn:hover{background:var(--surface-hi)}
.navbar__btn svg{flex:none;width:18px;height:18px}
.navbar__btn[hidden]{display:none}
.navbar__side{display:flex;align-items:center;gap:.5rem;min-width:0}
.navbar__side--end{justify-content:flex-end}
.navbar__side .navbar__btn span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/*
  ปุ่มข้างต้องหดได้ ปุ่มกลางต้องไม่หด

  ป้ายบนปุ่มซ้ายเป็นชื่อหมวดจริง ซึ่งยาวไม่เท่ากันทุกหน้า ถ้าไม่ยอมหด
  มันจะล้นออกนอกช่องไปทับปุ่มกลาง โดยที่กริดไม่ฟ้องอะไรเลย
*/
.navbar__side .navbar__btn{flex:0 1 auto;color:var(--muted);min-width:0}
.navbar__side .navbar__btn:hover{color:var(--paper)}
/* หน้าแรกไม่มีอะไรอยู่ในแถบนี้ ถ้าปล่อยไว้จะเหลือแถบดำว่างคาดขอบจอ
   ซึ่งอ่านเหมือนเว็บค้างมากกว่าการออกแบบ */
.navbar[hidden]{display:none}

/* แถบสลับหน่วย — วิธีตอบคำถาม "แล้วฝั่ง AI ล่ะ" โดยไม่ต้องอ้อมกลับหน้าแรก */
.rail{display:flex;gap:.25rem;overflow-x:auto;scrollbar-width:none}
.rail::-webkit-scrollbar{display:none}
.rail[hidden]{display:none}
.rail__btn{
  min-height:44px;padding:.5rem .875rem;border-radius:10px;
  font-size:var(--fs-label);font-weight:600;
  letter-spacing:.05em;color:var(--muted);white-space:nowrap;
  transition:color .18s ease,background .18s ease;
}
.rail__btn:hover{color:var(--paper);background:var(--surface-hi)}
.rail__btn[aria-current="true"]{color:#0a0a0a;background:var(--rail-accent)}

/* --------------------------------------------------------------------------
   ค้นหา — ลอยเหนือแถบล่าง ไม่ใช่หน้าใหม่

   เป็นการแทรกกลางบทสนทนา ปิดแล้วต้องกลับมาที่เดิมทันที ถ้าทำเป็นหน้าใหม่
   คนพรีเซนต์จะต้องเดินทางกลับ ซึ่งเสียจังหวะกว่าคำถามที่เพิ่งตอบไป
   -------------------------------------------------------------------------- */
.search{
  position:fixed;inset:0;z-index:120;
  display:flex;flex-direction:column;justify-content:flex-end;
  background:rgba(10,10,10,.72);
  backdrop-filter:blur(6px);
}
.search[hidden]{display:none}
.search__panel{
  display:flex;flex-direction:column;
  /* อิงความสูงของแผ่นครอบ ไม่ใช่ของจอ เพราะแผ่นครอบหดลงเมื่อคีย์บอร์ดขึ้นมา
     ถ้าอิง dvh แผ่นจะสูงเกินพื้นที่ที่เหลือแล้วดันช่องพิมพ์ทะลุออกไป */
  max-height:100%;
  padding:1rem var(--gutter);
  padding-bottom:calc(1rem + env(safe-area-inset-bottom,0px));
  background:var(--ink);
  border-top:1px solid var(--line-hi);
  animation:sheet .28s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes sheet{from{transform:translateY(16px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.search__panel{animation:none}}

.search__bar{
  display:flex;align-items:center;gap:.625rem;flex:none;
  padding:.5rem .875rem;
  background:var(--surface);
  border:1px solid var(--line-hi);
  border-radius:12px;
}
.search__bar svg{flex:none;width:19px;height:19px;color:var(--muted)}
#search-input{
  flex:1;min-width:0;
  background:none;border:none;outline:none;
  color:var(--paper);
  /*
    เขียนแยกทีละ property ห้ามรวบเป็น shorthand `font:`

    ของเดิมเขียนว่า `font:600 16px/1.4 inherit` ซึ่ง "ดูเหมือน" ถูก แต่ผิดกติกา
    CSS — คำอย่าง inherit/initial/unset ใช้ได้เฉพาะตอนเป็นค่าทั้งก้อนของ property
    เท่านั้น เอามาแทรกเป็นชิ้นส่วนใน shorthard ไม่ได้ เบราว์เซอร์จึงทิ้งทั้งบรรทัด

    ผลคือช่องค้นหาไม่ได้อะไรจากบรรทัดนี้เลยสักอย่าง ตกไปใช้ค่าตั้งต้นของ
    เบราว์เซอร์แทน = Arial 13.33px น้ำหนัก 400 ซึ่งพังสองชั้น

    1. เล็กกว่า 16px → iOS ซูมจอเข้าเองตอนกดช่องพิมพ์ แล้วไม่ซูมกลับตอนออก
       จอค้างอยู่อย่างนั้นกลางการพรีเซนต์ต่อหน้าลูกค้า
    2. เป็น Arial → ภาษาไทยในช่องค้นหาหลุดไปใช้ฟอนต์สำรองของระบบ
       คนละตัวกับทั้งเว็บ

    บรรทัดนี้คือเหตุผลว่าทำไมคอมเมนต์เดิมที่เตือนเรื่อง 16px ถึงไม่เคยได้ผลจริง
  */
  font-family:inherit;
  font-weight:600;
  font-size:16px;
  line-height:1.4;
}
#search-input::placeholder{color:var(--line-hi);font-weight:500}
#search-input::-webkit-search-cancel-button{display:none}
.search__close{
  flex:none;display:grid;place-items:center;
  width:36px;height:36px;margin-right:-.375rem;
  border-radius:8px;color:var(--muted);
}
.search__close:hover{background:var(--surface-hi);color:var(--paper)}
.search__close svg{width:17px;height:17px}

.search__status{
  flex:none;margin:.875rem 0 0;
  font-size:var(--fs-label);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
}
.search__results{
  overflow-y:auto;margin-top:.75rem;
  display:flex;flex-direction:column;gap:.375rem;
}
.hit{
  display:flex;align-items:center;gap:.875rem;
  min-height:56px;padding:.625rem .875rem;
  border-radius:10px;border:1px solid transparent;
  transition:background .15s ease,border-color .15s ease;
}
.hit:hover,.hit:focus-visible{background:var(--surface);border-color:var(--line)}
.hit__dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--hit-accent)}
.hit__text{min-width:0}
.hit__name{
  display:block;font-weight:700;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* บอกที่อยู่ของผลลัพธ์เสมอ เพราะชื่อลูกค้าเดียวกันโผล่ได้หลายหน่วย
   เช่น Water Cycle อยู่ทั้ง Verse Lab และ Verse Education */
.hit__where{
  display:block;margin-top:.125rem;
  font-size:var(--fs-label);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* --------------------------------------------------------------------------
   หน้าที่ 4 · ผลงานรายชิ้น
   -------------------------------------------------------------------------- */
.work{
  display:flex;flex-direction:column;align-items:center;
  padding-block:clamp(1.5rem,4vh,3rem)
               calc(var(--nav-h) + env(safe-area-inset-bottom,0px) + 1rem);
}
.work__logo{margin-bottom:clamp(1rem,2.5vh,1.75rem)}
/* ขนาดเดียวกับบรรทัดใต้โลโก้บนหน้าแรก — ทุกหน้าจึงมีจังหวะเดียวกันคือ
   โลโก้เป็นตัวเปิด แล้วบรรทัดเล็กบอกว่ากำลังดูอะไรอยู่ */
.work__title{
  margin:0 0 clamp(1rem,2.5vh,1.75rem);
  max-width:30ch;
  font-family:var(--font-display);
  font-weight:400;
  font-size:clamp(1rem,2vw,1.5rem);
  line-height:1.2;letter-spacing:.02em;
  text-transform:uppercase;text-align:center;text-wrap:balance;
}
.work__title--th{
  font-family:"Prompt","DIN Pro",sans-serif;
  font-weight:700;letter-spacing:0;line-height:1.3;
}

.work__media{
  position:relative;display:block;width:100%;max-width:960px;
  aspect-ratio:16/9;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);
  background:linear-gradient(145deg,
    color-mix(in srgb,var(--accent) 22%,var(--ink)),
    color-mix(in srgb,#a06bff 16%,var(--ink)));
}
.work__media img,.work__media video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
}
/* ปุ่มขยายบอกว่ากดได้ ไม่ใช่แค่ภาพประกอบ — ไม่งั้นไม่มีอะไรชวนให้กดเลย */
.work__expand{
  position:absolute;top:.75rem;right:.75rem;z-index:2;
  display:grid;place-items:center;width:38px;height:38px;
  border-radius:9px;
  background:rgba(10,10,10,.6);backdrop-filter:blur(6px);
  color:var(--paper);
  transition:background .18s ease,transform .18s ease;
}
.work__media:hover .work__expand{background:rgba(10,10,10,.85);transform:scale(1.06)}
.work__expand:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
.work__expand-icon{width:17px;height:17px}
.work__expand-icon--exit{display:none}
.work__media[data-fullscreen="true"] .work__expand-icon--enter,
.work__media.is-expanded .work__expand-icon--enter{display:none}
.work__media[data-fullscreen="true"] .work__expand-icon--exit,
.work__media.is-expanded .work__expand-icon--exit{display:block}
/* เต็มจอต้องเห็นภาพครบ ไม่ใช่ครอป เพราะเป็นผลงานที่กำลังโชว์ให้ลูกค้าดู */
.work__media:fullscreen{max-width:none;aspect-ratio:auto;border:0;border-radius:0;background:#000}
.work__media:fullscreen img,.work__media:fullscreen video{object-fit:contain}
.work__media:fullscreen .work__expand{
  display:grid;
  top:max(.75rem,env(safe-area-inset-top,0px));
  right:max(.75rem,env(safe-area-inset-right,0px));
}

/*
  เต็มจอแบบทำเอง สำหรับเครื่องที่ไม่มี Fullscreen API ให้ใช้

  iPhone ไม่รองรับการสั่งเต็มจอกับ element ทั่วไป รองรับเฉพาะกับตัววิดีโอ
  ผ่านคำสั่งเฉพาะของ Apple เท่านั้น ส่วนภาพนิ่งไม่มีทางเลยทั้งเครื่อง
  การขยายด้วย CSS ไม่พึ่ง API ใด จึงทำงานได้ทุกเครื่องเป็นทางสำรองสุดท้าย
*/
/* ระบุความสูงตรง ๆ ด้วย ไม่พึ่ง inset อย่างเดียว — พอมี width:100% เข้ามา
   การคำนวณจากขอบบนล่างจะไม่ทำงาน ได้ความสูงเท่าเนื้อหาแทนที่จะเต็มจอ */
.work__media.is-expanded{
  position:fixed;inset:0;z-index:200;
  width:100%;height:100%;max-width:none;aspect-ratio:auto;
  border:0;border-radius:0;background:#000;
}
.work__media.is-expanded img,
.work__media.is-expanded video{object-fit:contain}
.work__media.is-expanded .work__expand{
  top:max(.75rem,env(safe-area-inset-top,0px));
  right:max(.75rem,env(safe-area-inset-right,0px));
}

/* ---- บล็อกติดต่อ ---------------------------------------------------------- */
.contact{
  display:flex;align-items:center;gap:clamp(1rem,3vw,1.75rem);
  margin-top:clamp(1.5rem,3.5vh,2.5rem);
  padding:clamp(1rem,2vw,1.25rem) clamp(1.125rem,2.5vw,1.75rem);
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);
}
/*
  QR ต้องมีพื้นขาวรองเสมอ

  ตัว QR เป็นสีดำบนพื้นโปร่ง วางบนหน้าจอสีดำแล้วกล้องอ่านไม่ออก
  ซึ่งเป็นความล้มเหลวที่เห็นก็ต่อเมื่อลูกค้ายกมือถือขึ้นสแกนแล้วไม่ติด
*/
.qr{
  /* ครอปเฉพาะส่วน QR ออกจากไฟล์ที่รวมข้อความมาด้วย
     ค่าพิกัดวัดจากพิกเซลจริง เผื่อขอบขาวรอบ QR ไว้ 10px ตามที่มาตรฐานต้องการ */
  --qr-src-x:52; --qr-src-y:42; --qr-src-w:160;
  --qr-size:clamp(92px,14vw,116px);
  flex:none;display:block;
  width:var(--qr-size);height:var(--qr-size);
  border-radius:10px;background:#fff;
  transition:transform .18s ease;
}
.qr:hover{transform:scale(1.04)}
.qr__img{
  display:block;width:100%;height:100%;
  background-image:url("../img/contact/qr-sales.png");
  background-repeat:no-repeat;
  background-size:calc(712 * var(--qr-size) / var(--qr-src-w)) auto;
  background-position:
    calc(-1 * var(--qr-src-x) * var(--qr-size) / var(--qr-src-w))
    calc(-1 * var(--qr-src-y) * var(--qr-size) / var(--qr-src-w));
}
.contact__text{display:flex;flex-direction:column;gap:.125rem;min-width:0}
.contact__role{
  font-size:var(--fs-label);font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
}
.contact__name{font-weight:700;letter-spacing:-.01em}
.contact__tel{
  align-self:flex-start;
  margin-top:.25rem;margin-left:-.5rem;
  min-height:44px;display:inline-flex;align-items:center;
  padding:.25rem .5rem;border-radius:8px;
  color:var(--accent);font-weight:700;font-size:1.0625rem;
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
  text-decoration:none;
  transition:background .18s ease;
}
.contact__tel:hover{background:var(--surface-hi)}

@media (max-width:340px){
  .contact{flex-direction:column;align-items:flex-start}
}

/* --------------------------------------------------------------------------
   จอ
   -------------------------------------------------------------------------- */
.screen{display:none}
/*
  ใช้ backwards ไม่ใช่ both

  both สั่งให้ค้างสถานะสุดท้ายของอนิเมชันไว้ตลอด ซึ่งแม้เฟรมสุดท้ายจะเขียนว่า
  transform:none เบราว์เซอร์ก็เก็บเป็นเมทริกซ์เอกลักษณ์ matrix(1,0,0,1,0,0)
  ค้างไว้ — ไม่ขยับอะไรเลยแต่ยังนับว่า "มี transform"

  ผลที่ตามมาคือ element นี้กลายเป็นกรอบอ้างอิงของ position:fixed ทุกตัวข้างใน
  วิดีโอที่สั่งให้เต็มจอจึงเต็มแค่เท่ากล่องหน้านี้ ไม่ใช่เต็มจอจริง

  backwards ใช้เฟรมแรกก่อนอนิเมชันเริ่ม (กันภาพกระพริบ) แต่ไม่ค้างอะไรหลังจบ
*/
.screen.is-active{display:block;animation:rise .34s cubic-bezier(.2,.8,.2,1) backwards}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.wrap{max-width:1600px;margin-inline:auto;padding-inline:var(--gutter)}

/* แสงนวลๆ ไม่ให้พื้นดำแบนราบ เปลี่ยนสีตามหน่วยที่เปิดอยู่ */
.glow{
  position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(58rem 32rem at 50% -6%,
    color-mix(in srgb,var(--accent) 12%,transparent),transparent 70%);
  transition:background .5s ease;
}

/* --------------------------------------------------------------------------
   หน้าปก — สนามกล่อง 3D ที่สลายเป็นเส้น

   ทำไมเป็น CSS 3D ไม่ใช่ WebGL: เด็คนี้เปิดค้างทั้งการประชุมบนโน้ตบุ๊ก และเรา
   ฝังฟอนต์ไว้เองเพื่อให้ใช้ได้ตอนไม่มีเน็ต การลากไลบรารีสามมิติเข้ามาเพื่อวาด
   กล่องที่ไม่ต้องคำนวณอะไรต่อเฟรม ขัดกับทั้งสองเรื่อง

   ต้นทุนต่อเฟรมของทั้งฉากคือ transform ตัวเดียวบน .cover__drift กล่องทุกใบ
   ติดไปด้วยโดยไม่มีใครต้องคิดเลขเอง
   -------------------------------------------------------------------------- */
.cover{
  position:relative;
  min-height:100dvh;
  overflow:hidden;          /* กล่องที่ลอยพ้นขอบต้องถูกตัด ไม่ใช่ดันให้จอเลื่อน */
  isolation:isolate;
}

/*
  perspective อยู่ที่ชั้นนี้ชั้นเดียว ไม่ใส่ซ้ำที่ลูก

  จุดมองเยื้องไปทางขวา (72%) ให้ตรงกับฝั่งที่กล่องแน่น ตากวาดจากโลโก้ซ้ายบน
  ไปจบที่มวลกล่องขวา ซึ่งเป็นทิศเดียวกับที่แบบร่างวางไว้
*/
.cover__field{
  position:absolute;inset:0;z-index:0;
  perspective:1200px;
  perspective-origin:72% 45%;
  pointer-events:none;
}

/*
  แต่ละกล่องวิ่งตามเส้นทางโค้งของตัวเอง ไม่ใช่เลื่อนทั้งแผงขึ้นพร้อมกัน

  ใช้ offset-path ซึ่งเป็นของที่ CSS มีมาให้ตรงเรื่องนี้อยู่แล้ว เบราว์เซอร์คำนวณ
  ตำแหน่งบนเส้นโค้งให้เอง ไม่ต้องมี JS คอยขยับต่อเฟรม

  offset-rotate:0deg สำคัญ — ค่าตั้งต้นคือหมุนตามทิศของเส้นทาง ซึ่งจะทำให้กล่อง
  ตีลังกาตามโค้ง ต้องล็อกไว้ให้กล่องคงมุมไอโซเมตริกเดิมตลอดทาง

  เส้นทางแบนและสั้นที่ฝั่งซ้าย แล้วชันขึ้นเรื่อย ๆ ไปทางขวา ตามที่ร่างไว้
  ผลพลอยได้คือกล่องอยู่ในโซนเดิมของมันตลอด ไล่ระดับทึบ-เส้นจึงไม่พัง
*/
.cube{position:absolute;transform-style:preserve-3d;offset-rotate:0deg}

/*
  ขยับที่ "กลุ่ม" ไม่ใช่ทีละกล่อง

  วัดแล้วชัด: สนามนิ่ง 1,666 กล่องได้ 59 fps แต่พอสั่งอนิเมชันแยกทีละใบเหลือ 25 fps
  ตัวที่หนักคือจำนวนอนิเมชันที่ต้องคำนวณต่อเฟรม ไม่ใช่จำนวน element

  แบ่งกล่องเป็นสี่กลุ่ม แล้วขยับแค่กล่องบรรจุสี่ใบ กล่องทุกใบติดไปด้วยฟรี
  เหลืออนิเมชันห้าชุดทั้งฉาก จาก 1,666 ชุด

  จุดหมุนอยู่ที่โพรง การขยายจึงดันกล่องออกจากศูนย์กลางตามแนวรัศมี
  ซึ่งคือการลอยออกที่ต้องการ

  alternate ไม่ใช่ infinite ทางเดียว — ขากลับทำให้ไม่มีรอยกระตุกตอนวนรอบเลย
  สักครั้ง ส่วนการจางหัวท้ายทำไม่ได้ เพราะ opacity บนกลุ่มที่มีลูกเป็น 3D
  จะแบนลูกทั้งหมด ซึ่งเป็นกับดักเดียวกับ filter
*/
/*
  ลอยขึ้นช้า ๆ พร้อมซูมเข้านิดเดียว ไม่ใช่กระจายออกจากศูนย์กลาง

  วัดจากวิดีโอด้วยการจับคู่บล็อกระหว่างเฟรมที่ห่างกันหนึ่งวินาที ได้ว่ามวลกล่อง
  เลื่อนขึ้นราว 2-4 พิกเซลต่อวินาทีบนภาพกว้าง 960 พร้อมมีการกระจายออกเล็กน้อย
  ซึ่งเป็นลายเซ็นของกล้องที่ค่อย ๆ เคลื่อนเข้าหาฉาก

  ช้ากว่าที่ผมทำไว้รอบก่อนหลายเท่า ตัวเลขนี้มาจากการวัด ไม่ใช่การกะ
*/
@keyframes cover-swell{
  from{transform:translate3d(0,0,0) scale(1)}
  to  {transform:translate3d(0,-9%,0) scale(1.06)}
}
.cover__grp{
  position:absolute;inset:0;
  transform-style:preserve-3d;
  transform-origin:50% 46%;
  animation:cover-swell var(--dur) ease-in-out var(--del) infinite alternate;
}
/*
  สามหน้า ไม่ใช่หก

  กล้องอยู่มุมคงที่ กล่องหนึ่งใบเห็นได้มากสุดสามหน้า อีกสามหน้าหันหนีตลอด
  ไม่มีวันถูกมอง การไม่สร้างมันคือการลด DOM ลงครึ่งหนึ่งโดยไม่เสียอะไรเลย
*/
.cube__f{position:absolute;inset:0;backface-visibility:hidden}

/*
  ไล่เฉดสามระดับต่อกล่อง ทำให้อ่านเป็นทรงตัน ไม่ใช่สี่เหลี่ยมแบนสามชิ้นทับกัน

  ห้ามใช้ filter:brightness() ทำเรื่องนี้เด็ดขาด

  filter บน element ใด ๆ บังคับให้ element นั้นเป็น flat แล้วตัดมันออกจาก 3D
  context ที่พ่อสร้างไว้ หน้ากล่องจะถูกวาดเป็นภาพแบนที่ถูกหมุน ไม่ใช่ระนาบใน
  สเปซสามมิติ ผลคือทั้งสนามอ่านเป็นสี่เหลี่ยมเอียง ๆ ไม่ใช่ลูกบาศก์
  — อาการเดียวกับที่ transform บนบรรพบุรุษทำกับลูกทั้งชั้น

  ใช้ color-mix ผสมสีลงไปในพื้นตรง ๆ แทน ไม่แตะ 3D context เลย
*/
/*
  ความโปร่งอยู่ที่หน้ากล่อง ไม่ใช่ที่ตัวกล่อง

  opacity บน element ที่มีลูกเป็น 3D บังคับให้เบราว์เซอร์เรนเดอร์มันลงบัฟเฟอร์
  แยกแล้ว "แบน" ลูกทั้งหมดลงระนาบเดียว — เป็นกับดักตระกูลเดียวกับ filter
  ตอนแรกผมตั้ง opacity ไว้ที่ตัวกล่อง สนามทั้งผืนจึงแบนทั้งที่กล่องเดี่ยว ๆ
  ที่เอามาทดสอบเป็นสามมิติถูกต้อง

  ย้ายมาผสมความโปร่งลงในสีพื้นของแต่ละหน้าแทน หน้ากล่องไม่มีลูกเป็น 3D
  จึงไม่มีอะไรให้แบน และได้ผลพลอยได้คือกล่องที่ซ้อนกันมองทะลุกันได้
  เหมือนแก้ว ซึ่งตรงกับแบบที่ทีมส่งมามากกว่าสีทึบตัดกับดำ
*/
/*
  โทนสีคำนวณกลับจากวิดีโออ้างอิง ไม่ได้เลือกด้วยตา

  วัดพิกเซลในเฟรมจริงได้: ความอิ่มสีอยู่ที่ 0.1-0.2 เท่านั้น ความสว่างที่
  เปอร์เซ็นไทล์ 99 อยู่ที่ 129 จาก 255 และค่ามัธยฐานทั้งเฟรมคือ 12
  แปลว่ากล่องในวิดีโอเป็นม่วงหม่นเกือบเทา ไม่ใช่ม่วงสด และมืดกว่าที่ตาจำ

  ยังใช้ token ของแบรนด์เป็นต้นทาง แค่ผสมเข้าหา --ink เพื่อลดความอิ่มสีและ
  ความสว่างลงมา วันที่แบรนด์เปลี่ยนสี หน้าปกยังเปลี่ยนตาม ไม่ได้ฝังเลขสีใหม่
*/
.cube__f{--tone:color-mix(in srgb, currentColor 30%, var(--ink))}
.cube--solid .cube__f{
  background:color-mix(in srgb, var(--tone) var(--a,72%), transparent);
}
.cube--solid .cube__f--top {--tone:color-mix(in srgb, currentColor 46%, #6d6478)}
.cube--solid .cube__f--side{--tone:color-mix(in srgb, currentColor 18%, var(--ink))}

/* โซนกลาง — หน้าหายไป เหลือแต่ขอบ */
/*
  ฝุ่นอยู่คนละชั้นกับกล่อง และชั้นนั้นไม่มี preserve-3d

  วัดแล้ว: ทุก element ที่อยู่ในซับทรี 3D ทำให้เบราว์เซอร์ต้องฉายภาพใหม่ทุกเฟรม
  550 ชิ้นได้ 60 fps แต่ 900 ชิ้นเหลือ 26 จุดกลมแบน ๆ ไม่ได้ใช้ความเป็นสามมิติ
  เลยสักนิด การเอามันออกจากซับทรีนั้นคือการได้ความหนาแน่นกลับมาฟรี
*/
.cover__dust{position:absolute;inset:0;z-index:0;pointer-events:none}
.dust{position:absolute;border-radius:50%;background:currentColor}
.cube--wire .cube__f{
  background:none;
  border:1px solid color-mix(in srgb,currentColor var(--a,70%),transparent);
}

/*
  โซนซ้าย — เส้นกับจุด เป็นวัตถุ 3D จริง ไม่ใช่เส้นวาดทับ

  มันจึงหดสั้นตามเปอร์สเปกทีฟและเอียงตามมุมกล้องเหมือนกล่อง ซึ่งเป็นสิ่งที่ทำให้
  ทั้งฉากอ่านว่าเป็นสามมิติ ถ้าวาดเป็นเส้นแบนทับลงไป ตาจับได้ทันทีว่าเป็นลวดลาย
*/
.cube--line,.cube--dot{position:absolute}

/* หมอกเรืองแสงชั้นเดียวหลังกลุ่มกล่อง แทนการใส่แสงให้กล่องทีละใบสี่ร้อยครั้ง
   ได้บรรยากาศฟุ้งแบบในแบบที่ส่งมา โดยจ่ายค่าวาดแค่ครั้งเดียว */
.cover__video{
  position:absolute;inset:0;z-index:0;
  width:100%;height:100%;
  /* cover ไม่ใช่ contain — พื้นหลังต้องเต็มกรอบทุกสัดส่วนจอ ยอมให้ครอปได้
     เพราะโพรงมืดกลางภาพกว้างพอจะรับการครอปโดยที่โลโก้ยังอยู่บนพื้นดำ */
  object-fit:cover;
  pointer-events:none;
}

.cover__haze{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(46rem 36rem at 80% 50%, color-mix(in srgb,var(--violet-lit) 9%,transparent), transparent 72%),
    radial-gradient(30rem 26rem at 24% 82%, color-mix(in srgb,var(--magenta-lit) 7%,transparent), transparent 74%);
}
.cover__veil{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  /* ม่านสองชั้น: ชั้นแรกกดฝั่งซ้ายให้ดำสนิทรับโลโก้ ชั้นสองกดขอบล่าง
     ให้บรรทัดท้ายมีพื้นอ่านออก ทั้งคู่เป็นเรื่องคอนทราสต์ ไม่ใช่ของตกแต่ง */
  background:
    linear-gradient(100deg, var(--ink) 14%, color-mix(in srgb,var(--ink) 55%,transparent) 42%, transparent 68%),
    linear-gradient(to top, color-mix(in srgb,var(--ink) 82%,transparent) 0%, transparent 26%);
}

.cover__content{
  position:relative;z-index:2;
  min-height:100dvh;
  display:grid;
  grid-template-rows:1fr auto;

  --cover-pad:clamp(1.75rem,5vh,4rem);
  /*
    ระยะจากขอบจอถึงโลโก้ — ค่าเดียวใช้ทั้งด้านบนและด้านซ้าย จึงเท่ากันเสมอ

    ไม่ได้ใช้ clear space มาเว้นจากขอบจอ เพราะกติกาแบรนด์ห้าม "วางองค์ประกอบอื่น"
    ในเขตนั้น ขอบจอไม่ใช่องค์ประกอบ — ตัวที่ต้องกันจริงคือปุ่ม explore ข้างล่าง
    ซึ่งคุมด้วย margin-bottom ของโลโก้อยู่แล้ว
  */
  --cover-inset:clamp(2.5rem,15vw,6rem);
  /* 523/426 — สัดส่วนไฟล์ล็อกอัพตั้ง ใช้แปลงความกว้างเป็นความสูง */
  --mark-ar:1.2277;
  /*
    ความกว้างโลโก้หน้าปก — สามค่าแข่งกัน หยิบค่าน้อยสุด

    สองค่าแรกคือขนาดที่ตั้งใจให้เห็น ค่าที่สามคือเพดานที่ clear space บังคับ:
    ใต้โลโก้ต้องว่างเท่า clear space ก่อนถึงปุ่ม explore ความสูงที่กินจริง
    จึงเป็น (1 + 0.501) = 1.501 เท่าของตัวโลโก้ ส่วน 6rem คือที่ที่กันไว้
    ให้ปุ่มกับบรรทัดท้าย

    ผลคือจอยิ่งเตี้ย โลโก้ยิ่งเล็กลงเอง แทนที่จะไปเบียดปุ่ม
  */
  --mark-w:min(
    52vw,
    clamp(200px,32vw,420px),
    calc((100dvh - var(--cover-inset) - var(--cover-pad) - 6rem) / 1.501 / var(--mark-ar))
  );
  /* 262/426 — clear space เทียบกับความกว้างโลโก้ (ดู --clear-ratio-stack ที่ :root) */
  --mark-clear:calc(.615 * var(--mark-w));

  /*
    ขอบซ้ายเดียวกันทั้งหน้า — โลโก้ ปุ่ม และบรรทัดท้ายเริ่มที่เส้นเดียวกัน

    เดิมโลโก้ถูกดันเข้ามาด้วย margin ของตัวเอง ส่วนอีกสองชิ้นยังอิง --gutter
    ทำให้มีขอบซ้ายสองเส้นห่างกัน 36px ซึ่งตาอ่านเป็นความผิดพลาด ไม่ใช่จังหวะ
    ย้ายมาคุมที่ padding ของกล่องแทน ทุกชิ้นในกล่องจึงได้เส้นเดียวกันโดยอัตโนมัติ
  */
  padding:var(--cover-pad) var(--cover-inset);
}
.cover__mark{
  align-self:start;
  width:var(--mark-w);
  height:auto;
  /*
    ด้านซ้าย padding ของกล่องจัดการให้แล้ว เหลือแค่ด้านบนที่ยังต้องเติม
    เพราะ --cover-pad กับ --cover-inset คนละค่า — หักส่วนที่ padding ให้มาแล้ว
    ระยะจากขอบจอจริงจึงเท่ากับด้านซ้ายพอดี
  */
  margin-top:max(0px,calc(var(--cover-inset) - var(--cover-pad)));
  /* กันปุ่ม explore ไม่ให้ขึ้นมาล้ำ clear space ด้านล่าง */
  margin-bottom:var(--mark-clear);
}

/* ---- ปุ่มเข้าเด็ค ---------------------------------------------------------
   เส้นใต้เป็นสิ่งเดียวที่บอกว่ากดได้ จึงต้องหนาขึ้นตอน hover ไม่ใช่แค่เปลี่ยนสี
   ซึ่งคนตาบอดสีจับความต่างไม่ได้ */
.cover__cta{
  justify-self:start;align-self:end;
  padding:.35em 0;
  font-size:clamp(1.5rem,3.4vw,2.75rem);
  font-weight:500;letter-spacing:.01em;line-height:1.1;
  color:var(--paper);
  background:none;border:0;
  border-bottom:2px solid color-mix(in srgb,var(--paper) 70%,transparent);
  transition:border-color .18s ease,border-width .18s ease,text-shadow .22s ease;
}
.cover__cta:hover{
  border-bottom-color:var(--paper);
  text-shadow:0 0 24px color-mix(in srgb,var(--magenta-lit) 65%,transparent);
}
.cover__cta:active{transform:translateY(1px)}
.cover__cta:focus-visible{outline:3px solid var(--paper);outline-offset:6px}

.cover__byline{
  grid-column:1;justify-self:end;align-self:end;
  display:flex;align-items:center;gap:.6rem;
  margin:1.25rem 0 0;
  font-size:var(--fs-label);font-weight:500;
  letter-spacing:.08em;
  color:var(--paper);
}
.cover__byline[hidden]{display:none!important}
.cover__node{flex:none;width:22px;height:22px}

/* โหมดวิดีโอ: ปิดชั้นที่สร้างด้วยโค้ดทั้งหมด ไม่ให้ซ้อนทับกันสองพื้นหลัง */
.cover--video .cover__haze,
.cover--video .cover__dust,
.cover--video .cover__field{display:none}
/* โหมดสนามกล่อง: ไม่ต้องมีวิดีโอ */
.cover:not(.cover--video) .cover__video{display:none}

/*
  หน้าปกเข้าด้วยการจางอย่างเดียว ไม่ใช้ rise เหมือนหน้าอื่น

  rise ใส่ transform ให้ <section> ซึ่งจะทำให้ 3D context ของลูกทั้งหมดแบนลง
  กล่องจะกลายเป็นสองมิติตลอด 0.34 วินาทีแรกแล้วเด้งกลับเป็นสามมิติ
  ไฟล์นี้เคยโดนบั๊กตระกูลเดียวกันมาแล้วตอนวิดีโอเต็มจอ
*/
#screen-cover.is-active{animation:cover-in .5s ease both}
@keyframes cover-in{from{opacity:0}to{opacity:1}}

@media (max-width:679px){
  /* แนวตั้ง — องค์ประกอบจัดใหม่ ไม่ใช่ย่อ บรรทัดท้ายลงมาอยู่ใต้ปุ่ม
     เพราะมุมขวาล่างบนมือถือคือที่ที่นิ้วโป้งบังพอดี */
  .cover__byline{justify-self:start}
  .cover__field{perspective-origin:62% 40%}
}

/* ลดการเคลื่อนไหว — หยุดสนามกล่องสนิท ไม่ใช่แค่ช้าลง */
@media (prefers-reduced-motion:reduce){
  /* อนิเมชันอยู่ที่กลุ่ม ไม่ใช่ที่ตัวกล่อง — ต้องหยุดตรงที่มันอยู่จริง
     สนามยังอยู่ครบทุกใบ แค่ไม่ขยับ ซึ่งคือสิ่งที่คนตั้งค่านี้ต้องการ */
  .cover__grp{animation:none!important}
  /* วิดีโอหยุดด้วย แต่ยังค้างเฟรมแรกไว้ ไม่ใช่จอดำเปล่า — สั่งหยุดในสคริปต์ */
}

/* ---- หน้าที่ 1 · หน้าแรก ----------------------------------------------------
   เมนูต้องอยู่ครบในจอเดียวทุกขนาด การเลื่อนหาปุ่มที่หกที่ไม่มีอยู่จริง
   คือวินาทีที่เสียจังหวะที่สุดตอนเปิดคุยกับลูกค้า */
.home{
  /* เพดานความกว้างของกลุ่มปุ่มหน้าแรก คิดจากที่ว่างแนวตั้งจริง (ที่มาของสูตร
     อธิบายไว้ที่จุดใช้งานในบล็อก 680px) เก็บเป็นตัวแปรเพราะแถบคีย์ลัดต้องกว้าง
     เท่ากันเป๊ะ ไม่งั้นเส้นคั่นจะยาวเลยกลุ่มปุ่มออกไปคนละระยะในแต่ละขนาดจอ */
  --home-max:calc((100dvh - 24rem) / 3 * 7.5);
  min-height:100dvh;
  display:flex;flex-direction:column;align-items:center;
  padding-block:clamp(1.5rem,4vh,4rem) clamp(1rem,2.5vh,2rem);
  text-align:center;
}
/*
  โลโก้กำหนดด้วยความกว้าง ไม่ใช่ความสูง

  ลockup นี้เป็น 3.9:1 ถ้ากำหนดความสูงให้ใหญ่พอจะเด่นบนเดสก์ท็อป มันจะกว้าง
  เกินจอมือถือ การคุมความกว้างจึงเป็นด้านที่บีบจริง ส่วนความสูงตามสัดส่วนไปเอง
*/
.home__logo{
  /* ลดลง 40% จากรอบก่อน โดยหารทั้งสามค่าเท่ากัน (240→144, 80vw→48vw, 560→336)
     ถ้าลดแค่ค่าใดค่าหนึ่ง สัดส่วนจะเพี้ยนคนละแบบในแต่ละขนาดจอ */
  width:min(100%,clamp(144px,48vw,336px));
  height:auto;object-fit:contain;
}
/*
  หัวข้อเล็กลงจากเดิมมาก เพราะโลโก้ขึ้นมาเป็นตัวเปิดแทน

  ถ้าปล่อยไว้ที่ขนาดเดิม สองอย่างจะแย่งกันเป็นพระเอกแล้วไม่มีอะไรเด่นสักอย่าง
  ตัวหนังสือถอยมาเป็นคำอธิบายว่าหน้านี้คืออะไร ไม่ใช่ตัวประกาศว่าใครพูด
*/
/*
  วัดกันที่ความกว้างของบรรทัด ไม่ใช่ความสูงตัวอักษร

  ก่อนหน้านี้ตัวอักษรสูง 22px เทียบกับโลโก้สูง 46px ซึ่งเล็กกว่าอยู่แล้วบนกระดาษ
  แต่บรรทัดมันกว้าง 215px ขณะที่โลโก้กว้าง 180px ตาเลยอ่านว่าตัวหนังสือใหญ่กว่า
  ขนาดใหม่ทำให้บรรทัดสั้นกว่าโลโก้จริงทุกขนาดจอ
*/
.home h1{
  margin:clamp(.75rem,1.6vh,1.25rem) 0 0;
  font-size:clamp(1rem,2vw,1.5rem);
  font-weight:600;line-height:1.2;letter-spacing:-.01em;
  color:var(--muted);
  text-wrap:balance;
}

/*
  เมนู 5 ปุ่ม ล็อกจำนวนคอลัมน์แทนการใช้ auto-fit

  ปุ่มทรงนี้กว้างกว่าการ์ดเดิมมาก auto-fit จะจัดได้ 4 คอลัมน์บนจอ 1440px
  แล้วเหลือปุ่มที่ห้าห้อยเดี่ยวอยู่แถวล่าง ซึ่งอ่านเหมือนวางผิดมากกว่าตั้งใจ
  3 คอลัมน์ลงตัวเป็น 3+2 และยังอยู่ในจอเดียวโดยไม่ต้องเลื่อน
*/
.units{
  display:grid;gap:clamp(.75rem,1.4vw,1.25rem);
  grid-template-columns:1fr;
  /* หัวจอจัดกึ่งกลาง แต่กริดต้องกางเต็มความกว้างเหมือนเดิม
     ไม่งั้น align-items:center ของพ่อจะบีบมันให้เท่าความกว้างเนื้อหา */
  width:100%;align-self:stretch;text-align:left;
  margin-top:clamp(1.25rem,3.5vh,3rem);
}
/*
  คอลัมน์เดียว = ห้าแถวซ้อนกัน ซึ่งเป็นกรณีเดียวที่ความสูงรวมล้นจอ
  จึงให้กริดกินที่ว่างที่เหลือแล้วหารความสูงเท่ากันห้าแถว ปุ่มจะยืดหดเองตามจอ
  แทนที่จะตั้งความสูงตายตัวแล้วมาลุ้นว่าเครื่องไหนพอดี
*/
/* ปุ่มมีสัดส่วนตายตัว 912x243 แล้ว จึงไม่ยืดตามที่ว่างเหมือนปุ่มแบบเดิม
   ห้าใบเรียงลงมาได้ความสูงที่คำนวณได้แน่นอนตั้งแต่ต้น */
@media (max-width:679px){.units{grid-auto-rows:auto}}
/*
  ตั้งกริดเป็นคอลัมน์ย่อยแล้วให้ปุ่มกินทีละสองช่อง แทนการตั้ง 2 หรือ 3 คอลัมน์ตรง ๆ

  ห้าปุ่มลงกริดสามคอลัมน์ได้ 3+2 ซึ่งเหลือช่องว่างค้างอยู่มุมขวาล่างเสมอ
  ตาอ่านช่องนั้นว่า "ปุ่มที่หกโหลดไม่ขึ้น" มากกว่าอ่านว่าจบแค่ห้าหน่วย
  การหั่นเป็นคอลัมน์ย่อยเท่าตัวทำให้เลื่อนแถวล่างเข้ามาได้ทีละครึ่งปุ่มพอดี
  ช่องว่างจึงถูกแบ่งเท่ากันสองข้างแล้วอ่านเป็นทรงพีระมิดที่ตั้งใจวาง

  ระยะเลื่อนที่ต้องการคือ (ความกว้างปุ่ม + gap)/2 ซึ่งเท่ากับ (2คอลัมน์ย่อย + 2gap)/2
  = คอลัมน์ย่อย + gap = จุดเริ่มของคอลัมน์ย่อยที่ 2 พอดี ไม่ต้องคำนวณด้วยมือ
*/
@media (min-width:680px){
  .units{grid-template-columns:repeat(4,1fr)}
  /*
    เพดานความกว้างกริดผูกกับความสูงจอ ไม่ใช่ความกว้างอย่างเดียว

    ปุ่มมีสัดส่วนตายตัว 3.75:1 ความกว้างจึงเป็นตัวกำหนดความสูงโดยตรง บนจอที่
    กว้างแต่เตี้ย (1600x900 เป็นเคสจริง) ปุ่มกว้าง 719px กลายเป็นสูง 191px
    คูณสามแถวแล้วเกินจอไป 13px ทั้งที่ 1440x900 ซึ่งเตี้ยเท่ากันยังพอดี
    — ตัวที่ต่างคือความกว้าง ไม่ใช่ความสูง

    สูตรนี้คิดกลับจากที่ว่างจริง: ความสูงที่เหลือหลังหักหัวจอกับระยะขอบ (24rem)
    หารสามแถว แล้วคูณ 7.5 (สองปุ่มที่สัดส่วน 3.75:1) ได้ความกว้างกริดที่มากที่สุด
    ที่ยังลงสามแถวพอดี
  */
  /* margin-inline:auto สำคัญ — align-self:stretch ที่กฎฐานตั้งไว้จะดันกริดชิดซ้าย
     เมื่อถูกเพดานบีบให้แคบกว่าพ่อ ที่ว่างจะไปกองข้างขวาข้างเดียว 246px ที่ 1600px */
  .units{max-width:var(--home-max);margin-inline:auto}
  .units > .tag{grid-column:span 2}
  .units > .tag:nth-child(5){grid-column:2/span 2}
}
/*
  สามคอลัมน์เฉพาะตอนจอเตี้ย

  ค่าตั้งต้นคือสองคอลัมน์ ซึ่งใกล้แบบร่างที่ทีมออกแบบวางมามากกว่า (แบบร่างเป็น
  คอลัมน์เดียวเต็มความกว้าง แต่ห้าใบเรียงลงมาบนจอแนวนอนจะสูงเกิน 1700px)
  ปุ่มสองคอลัมน์กว้างราว 700px ที่ 1080p อ่านชื่อหน่วยได้สบาย

  แต่ห้าใบสองคอลัมน์คือสามแถว ซึ่งที่ความสูง 720-819px รวมกับหัวจอแล้วเกินจอ
  ตรงนั้นถอยไปสามคอลัมน์ให้เหลือสองแถว ปุ่มเล็กลงแต่ยังจบในจอเดียว

  เกณฑ์ผูกกับความสูงจอ ไม่ใช่ความกว้าง เพราะสิ่งที่ล้นคือแนวตั้ง
*/
@media (min-width:1100px) and (max-height:819px){
  /* สามคอลัมน์เหลือสองแถว เพดานที่คิดจากสามแถวข้างบนจึงไม่ใช้แล้ว
     ถ้าไม่ปลด กริดจะถูกบีบแคบกว่าที่จำเป็นมาก */
  .units{max-width:none;grid-template-columns:repeat(6,1fr)}
  .units > .tag:nth-child(4){grid-column:2/span 2}
  /* คืนค่าให้ปุ่มที่ห้าไหลตามปกติ ไม่งั้นกฎ 680px ข้างบนจะยังล็อกมันไว้ที่คอลัมน์ 2 */
  .units > .tag:nth-child(5){grid-column:auto/span 2}
}

/* ---- หน้าที่ 2 · หน่วยธุรกิจ → หมวดหมู่ ------------------------------------- */
/* โลโก้อยู่บน บรรทัดบทบาทอยู่ล่าง จัดกึ่งกลางทั้งคู่
   บรรทัดบทบาทตามโลโก้ไปด้วย เพราะถ้าจัดกึ่งกลางแค่ชิ้นเดียวจากสองชิ้น
   ที่ซ้อนกันอยู่ จะอ่านเหมือนวางพลาดมากกว่าตั้งใจ */
/*
  ระยะห่างรอบหัวจอบีบลง เพื่อดึงแถวปุ่มขึ้นมา

  หน้า Verse มี 6 หมวด ซึ่งล้นจอ 51px ที่คอลัมน์เดียว การเพิ่มคอลัมน์แก้ได้
  แต่ทำให้ชื่อยาวถูกหั่นกลางคำ ที่ว่างด้านบนจึงเป็นแหล่งเดียวที่หยิบมาได้
  โดยไม่แตะทั้งขนาดปุ่มและจำนวนคอลัมน์
*/
.unit-head{
  display:flex;flex-direction:column;align-items:center;gap:1rem;
  padding-block:clamp(.875rem,2vh,1.75rem) clamp(.625rem,1.4vh,1.125rem);
  border-bottom:1px solid var(--line);
  text-align:center;
}
/*
  ขนาดเท่าโลโก้หน้าแรก โดยเทียบที่ตัวอักษร "verse." ไม่ใช่ที่กรอบภาพ

  ยังกำหนดด้วยความสูง เพราะสัดส่วนแต่ละไฟล์ไม่เท่ากัน (Verse 3.90:1 ส่วนอีกสี่
  หน่วย 2.59:1 เพราะมีบรรทัดชื่อหน่วยเพิ่มมา) ถ้าล็อกความกว้างเท่ากันหมด
  คำว่า "verse." จะออกมาคนละขนาดทั้งที่เป็นชุดเดียวกัน

  ค่าที่ได้: หน้าแรกสูง clamp(37px,12.3vw,86px) หารด้วย 0.66 ซึ่งเป็นอัตราส่วน
  ที่ทำให้ wordmark ของสองชุดเท่ากัน แล้ว --logo-scale ของหน่วยหลักคูณ 0.66
  กลับเข้าไป จึงลงเอยเท่าหน้าแรกพอดี ส่วนอีกสี่หน่วยได้ wordmark ขนาดเดียวกัน
  ผลพลอยได้คือโลโก้ทุกใบกว้างราว 180px เท่ากันบนมือถือ
*/
.unit-head__logo{
  height:calc(clamp(56px,18.6vw,131px) * var(--logo-scale,1));
  width:auto;max-width:100%;object-fit:contain;
}
/*
  ชื่อหน่วยยังอยู่ในโครงสร้างหน้า แต่ไม่แสดงผล

  โลโก้ชุดแนวนอนเขียนชื่อหน่วยไว้ในตัวมันเองแล้ว ("verse. EDUCATION")
  การมีหัวข้อตัวใหญ่ซ้ำข้างๆ คือการพูดชื่อเดียวกันสองครั้งในบรรทัดเดียว
  ลบ h1 ทิ้งไม่ได้เพราะจะเหลือหน้าที่ไม่มีหัวข้อ ผู้ใช้ screen reader
  จะไม่รู้ว่าเปลี่ยนมาอยู่หน้าไหน จึงซ่อนเฉพาะทางสายตา
*/
.unit-head h1{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
/* หมวดที่เปิดอยู่บนหน้าผลงาน จำกัดความกว้างให้เท่าหนึ่งคอลัมน์ของกริดข้างล่าง
   ปล่อยเต็มความกว้างจะยืดเป็นแถบยาวจนรูปกับชื่อไปอยู่คนละฝั่งจอ */
.cat-active{
  max-width:min(100%,420px);
  margin-top:clamp(1.25rem,3vh,2rem);
}

.section-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  margin-top:clamp(.75rem,1.6vh,1.5rem);margin-bottom:.75rem;
}

.section-head h2{
  margin:0;font-size:clamp(1.125rem,1.6vw,1.5rem);
  font-weight:700;letter-spacing:-.015em;
}
.section-head__count{
  font-size:var(--fs-label);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  font-variant-numeric:tabular-nums;
}

/* --------------------------------------------------------------------------
   ปุ่ม — รูปอยู่ซ้าย ชื่ออยู่ขวา มุมตัดเฉียง ขอบเรืองแสง

   ตัวเดียวใช้ทั้งเมนูหน้าแรกและหมวดหมู่ในหน้าหน่วย ต่างกันแค่ตัวแปรผัน
   ถ้าแยกเป็นสองคอมโพเนนต์ วันหนึ่งจะแก้ทีละที่แล้วสองหน้าเพี้ยนจากกัน

   เรียงเป็นกริดแทนการวางเรียงเดี่ยวลงมาตามภาพอ้างอิง เพราะเด็คนี้กางบนจอแนวนอน
   แถบเดียวเต็มความกว้าง 1440px จะยืดจนรูปกับชื่อห่างกันคนละฝั่งจอ
   ทรงปุ่ม สัดส่วน และน้ำหนักตัวอักษรยังเป็นไปตามภาพอ้างอิงทุกอย่าง
   -------------------------------------------------------------------------- */
.cats{
  display:grid;gap:clamp(.875rem,1.4vw,1.25rem);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,352px),1fr));
  /* หน้าหมวดหมู่ไม่มีหัวข้อคั่นแล้ว กริดจึงต้องมีระยะห่างจากเส้นใต้หัวจอเอง */
  margin-top:clamp(.875rem,1.8vh,1.5rem);
  /* เว้นเท่าความสูงแถบพอดี ไม่บวกเพิ่ม — ปุ่มใบสุดท้ายจะมาหยุดที่ขอบแถบพอดี
     ส่วน safe area ยังต้องบวก เพราะเป็นพื้นที่ที่เครื่องกันไว้จริง ไม่ใช่ระยะห่างที่เลือกได้ */
  padding-bottom:calc(var(--nav-h) + env(safe-area-inset-bottom,0px));
}

/* มุมตัดต้องเท่ากันทั้งขอบนอกและพื้นใน ไม่งั้นเส้นขอบจะหนาไม่เท่ากันตรงมุม */
.tag{
  --chamfer:18px;
  /* ความหนาเส้นขอบ ปรับที่นี่ที่เดียว มีผลทั้งเมนูหน้าแรกและหมวดหมู่ */
  --edge-w:1px;
  --edge-a:var(--accent);
  --edge-b:#a06bff;
  /*
    grid ไม่ใช่ block เพื่อให้กล่องด้านในยืดเต็มความสูงปุ่มเสมอ

    พื้นไล่สีของปุ่มคือ "เส้นขอบ" ที่มองเห็น มันจะหนาเท่า padding ก็ต่อเมื่อ
    กล่องด้านในปิดทับพื้นที่ที่เหลือหมด ตอนแถวปุ่มถูกยืดด้วย 1fr บนมือถือ
    ปุ่มสูงขึ้นแต่กล่องในสูงเท่าเนื้อหา พื้นไล่สีเลยโผล่บน-ล่างข้างละ 13px
    กลายเป็นกรอบหนา ทั้งที่ padding ตั้งไว้ 1px
  */
  position:relative;display:grid;width:100%;padding:var(--edge-w);
  background:linear-gradient(112deg,var(--edge-a),var(--edge-b));
  clip-path:polygon(
    var(--chamfer) 0, 100% 0,
    100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%,
    0 100%, 0 var(--chamfer));
  /* box-shadow ไม่เดินตาม clip-path จึงต้องใช้ drop-shadow เพื่อให้แสงตามทรงมุมตัด
     แสงฟุ้งนับรวมเป็นความหนาที่ตาเห็นด้วย ไม่ใช่แค่เส้นขอบ ถ้าตั้งแรงไว้
     เส้น 1px จะอ่านออกมาเป็นกรอบหนา แทนที่จะเป็นเส้นบางเรืองแสงตามภาพอ้างอิง */
  filter:drop-shadow(0 0 8px color-mix(in srgb,var(--edge-b) 22%,transparent));
  transition:filter .22s ease,transform .22s ease;
}
.tag:hover:not(.tag--static),
.tag:focus-visible{
  transform:translateY(-2px);
  filter:drop-shadow(0 0 16px color-mix(in srgb,var(--edge-b) 45%,transparent));
}
.tag:active:not(.tag--static){transform:translateY(0)}
/* แผ่นที่ยังไม่มีอะไรอยู่ข้างใน ไม่ต้องชวนให้กด */
.tag--static{cursor:default}
/* clip-path ตัดวงแหวนโฟกัสทิ้ง จึงย้ายไปวาดเป็นเงาแทน ไม่งั้นคีย์บอร์ดจะหาย */
.tag:focus-visible{outline:none}
.tag:focus-visible .tag__inner{box-shadow:inset 0 0 0 3px var(--paper)}

/*
  ช่องข้อความต้องเป็น minmax(0,1fr) ไม่ใช่ 1fr เฉย ๆ

  1fr มีขนาดต่ำสุดเท่าเนื้อหา ซึ่งก็คือคำที่ยาวที่สุดในป้าย พอคอลัมน์แคบลง
  คำอย่าง "COMMERCIAL" จึงดันช่องให้กว้างเกินปุ่มแล้วล้นออกไปแทนที่จะหด
  minmax(0,...) อนุญาตให้หดได้ แล้วค่อยให้ overflow-wrap เป็นคนตัดคำ
*/
.tag__inner{
  display:grid;grid-template-columns:40% minmax(0,1fr);align-items:stretch;
  min-height:clamp(88px,8.5vw,116px);
  background:var(--ink);
  clip-path:polygon(
    var(--chamfer) 0, 100% 0,
    100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%,
    0 100%, 0 var(--chamfer));
}

.tag__thumb{
  position:relative;overflow:hidden;
  background:linear-gradient(145deg,
    color-mix(in srgb,var(--accent) 30%,var(--ink)),
    color-mix(in srgb,#a06bff 22%,var(--ink)));
}
/* ภาพกับวิดีโอใช้กติกาเดียวกันทั้งคู่ ครอปเต็มกรอบ ไม่บิดสัดส่วน
   ช่องนี้รับไฟล์ได้สองแบบ จึงต้องเขียนกฎให้ครอบทั้งสอง ไม่ใช่เฉพาะ img */
.tag__thumb img,
.tag__thumb video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .4s cubic-bezier(.2,.8,.2,1);
}
.tag:hover:not(.tag--static) .tag__thumb img,
.tag:hover:not(.tag--static) .tag__thumb video{transform:scale(1.05)}

.tag__body{
  display:flex;flex-direction:column;justify-content:center;gap:.3rem;
  padding:.75rem clamp(.875rem,1.4vw,1.25rem);
  min-width:0;
}
.tag__label{
  /* ตัดคำเมื่อยาวเกินบรรทัดจริง ๆ เท่านั้น ไม่ตัดพร่ำเพรื่อ
     ภาษาไทยไม่มีช่องว่างระหว่างคำ ถ้าไม่ใส่ ทั้งชื่อจะถูกนับเป็นคำเดียวแล้วล้น */
  overflow-wrap:break-word;
  font-family:var(--font-display);
  font-weight:400;
  font-size:clamp(1.0625rem,1.75vw,1.625rem);
  line-height:1.06;letter-spacing:.005em;
  text-transform:uppercase;text-wrap:balance;
  color:var(--paper);
}
/*
  ชื่อที่มีภาษาไทยใช้ Prompt ทั้งป้าย ไม่ปล่อยให้ fallback ทีละตัวอักษร

  ถ้าปล่อยตามลำดับ fallback ปกติ ป้ายอย่าง "โครงการพัฒนาบุคลากรด้าน Virtual
  Production" จะได้ไทยเป็น Prompt ส่วนอังกฤษเป็น DIN Pro Cond อยู่ในบรรทัดเดียวกัน
  สองฟอนต์คนละสัดส่วนชนกันกลางประโยค อ่านเหมือนพิมพ์ผิดมากกว่าการออกแบบ
*/
.tag__label--th{
  font-family:"Prompt","DIN Pro","Segoe UI","Leelawadee UI",sans-serif;
  font-weight:700;letter-spacing:0;line-height:1.25;
}
/* บรรทัดบอกบทบาท มีเฉพาะเมนูหน้าแรก — คือสิ่งที่แยกห้าหน่วยออกจากกัน
   และเป็นคำที่ sale ใช้เปิดประโยคจริง จึงไม่ตัดทิ้งเพื่อความเหมือนเป๊ะ */
/* ใช้สีประจำหน่วย ไม่ใช่สีขอบ — สองค่านี้ไม่เท่ากันสำหรับ Verse ซึ่งเป็นขาว
   ส่วนขอบไล่ชมพูไปม่วงตามภาพอ้างอิง ถ้าผูกกับขอบ บรรทัดนี้จะกลายเป็นชมพู
   แล้วขัดกับหัวหน้าหน่วยที่ใช้ขาว ทั้งที่เป็นข้อความเดียวกัน */
.tag__role{
  font-size:var(--fs-label);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--role-color,var(--edge-a));
}

/* --------------------------------------------------------------------------
   เมนูหน้าแรก — ปุ่มเป็นภาพสำเร็จจากทีมออกแบบ (M1-M5)

   ต่างจากปุ่มหน้าอื่นทั้งหมดในไฟล์นี้ ที่ประกอบจากกรอบไล่สี + ช่องรูป + ป้ายชื่อ
   ด้วย CSS ภาพชุดนี้มีครบทั้งสามอย่างอยู่ในไฟล์แล้ว กฎข้างล่างจึงเป็นการ "ถอด"
   ของที่ .tag ใส่มาให้ออกทั้งหมด ไม่ใช่การเพิ่มอะไรใหม่ — ถ้าไม่ถอด จะได้กรอบ
   สองชั้นซ้อนกันและมุมตัดที่เฉือนกินภาพจริงเข้าไป
   -------------------------------------------------------------------------- */
.tag--home{
  padding:0;
  background:none;
  clip-path:none;
  /* สัดส่วนตามไฟล์จริง 912x243 — ล็อกไว้เพื่อให้ทุกใบสูงเท่ากันเป๊ะทุกความกว้างจอ
     และกริดคำนวณความสูงแถวได้ตั้งแต่ก่อนภาพโหลดเสร็จ ไม่กระตุกตอนเปิดหน้า */
  aspect-ratio:912/243;
  filter:none;
}
/* clip-path ถูกถอดออกแล้ว วงแหวนโฟกัสจึงวาดได้ตามปกติ ไม่ต้องหลบไปใช้เงา
   เหมือนปุ่มแบบอื่น — คืน outline ที่กฎฐานปิดไว้ */
.tag--home:focus-visible{outline:3px solid var(--paper);outline-offset:4px}
.tag--home:hover,
.tag--home:focus-visible{
  transform:translateY(-2px);
  filter:drop-shadow(0 0 18px color-mix(in srgb,var(--edge-b) 42%,transparent));
}
.tag__card{
  display:block;width:100%;height:100%;
  /* contain ไม่ใช่ cover — กรอบไล่สีอยู่ริมภาพพอดี ถ้าครอปแม้แต่นิดเดียว
     ขอบจะขาดหายไปคนละด้านกันในแต่ละใบ */
  object-fit:contain;
}

/* ---- คีย์ลัดสำหรับคนพรีเซนต์ ------------------------------------------------
   จางและถอยเองเมื่อเริ่มใช้งาน มีประโยชน์กับคนขับ แต่ไม่รบกวนสายตาลูกค้า */
.hints{
  display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;align-items:center;
  width:100%;align-self:stretch;text-align:left;
  margin-top:auto;padding-top:1.25rem;
  border-top:1px solid var(--line);
  /* --line-hi บนพื้นดำได้แค่ 1.82:1 ซึ่งต่ำกว่าเกณฑ์ตัวหนังสือ 4.5:1 อยู่มาก
     --muted ได้ 7.4:1 ยังดูจางพอจะไม่แย่งสายตา แต่คนอ่านออกจริง */
  font-size:var(--fs-label);color:var(--muted);
  transition:opacity .5s ease,visibility .5s;
}
/*
  ซ่อนสนิท ไม่ใช่หรี่ให้จาง

  ของเดิมหรี่เหลือ 25% ซึ่งทำให้คอนทราสต์ตกลงไปอีกจนอ่านไม่ออกอยู่ดี
  กลายเป็นตัวหนังสือที่ยังกินพื้นที่และยังถูก screen reader อ่าน แต่คนมองไม่เห็น
  ในเมื่อจุดประสงค์คือให้มันหายไปหลังคนขับจำได้แล้ว ก็ให้หายไปจริง ๆ
*/
.hints.is-faded{opacity:0;visibility:hidden}
kbd{
  display:inline-block;min-width:1.6em;padding:.15em .45em;margin-right:.35em;
  border:1px solid var(--line-hi);border-radius:5px;background:var(--surface);
  font-family:inherit;font-size:.95em;font-weight:600;text-align:center;color:var(--muted);
}

/*
  ซ่อนแถบสลับหน่วยตั้งแต่ยังไม่ถึงจอมือถือ

  แถบนี้เลื่อนแนวนอนได้แต่ซ่อนแถบเลื่อนไว้ พอความกว้างไม่พอวางครบห้าหน่วย
  ชื่อสุดท้ายจะโดนตัดกลางคำโดยไม่มีอะไรบอกว่ายังมีต่อ ตัดทิ้งไปเลยตรงไปตรงกว่า
  — ปุ่มย้อนกลับยังอยู่ และคีย์ลัดเลข 1-5 กับลูกศรยังใช้ได้ทุกความกว้าง
*/
/* --------------------------------------------------------------------------
   จอคอม — แถบนำทางย้ายขึ้นบน

   บนมือถือแถบอยู่ล่างเพราะนิ้วโป้งไปถึง แต่บนคอมไม่มีเหตุผลนั้น และคนคาดหวัง
   ว่าแถบนำทางอยู่บนตามธรรมเนียมเว็บ ตัดที่ 900px ให้ตรงกับจุดที่แถบสลับหน่วย
   โผล่พอดี แถบจึงเปลี่ยนหน้าตาครั้งเดียว ไม่ใช่ทยอยเปลี่ยนทีละส่วน
   -------------------------------------------------------------------------- */
@media (min-width:900px){
  /*
    เปลี่ยนจากกริดสามช่องเท่ากันเป็นแถวยืดหยุ่น

    การล็อกปุ่มกลางไว้กึ่งกลางจอมีเหตุผลเดียวคือให้นิ้วโป้งกดด้วยความเคยชิน
    บนคอมไม่มีเหตุผลนั้น แต่มีต้นทุนจริง — ช่องขวาถูกบังคับให้กว้างเท่าช่องซ้าย
    ทั้งที่ต้องใส่ทั้งแถบสลับห้าหน่วยและปุ่มค้นหา ผลคือชื่อถูกตัดเป็น
    "Verse Educati…" กับ "ค้…"
  */
  .navbar{
    top:0;bottom:auto;
    display:flex;gap:.75rem;
    padding-bottom:0;
    border-top:0;border-bottom:1px solid var(--line);
  }
  .navbar__side{flex:none}
  .navbar__side--end{flex:1;justify-content:space-between;gap:1rem}
  /* เนื้อหาเว้นที่ให้แถบด้านบนแทนด้านล่าง หน้าแรกไม่ต้องเว้นเพราะซ่อนแถบอยู่ */
  #screen-unit > .wrap,
  #screen-cat  > .wrap,
  #screen-work > .wrap{padding-top:var(--nav-h)}
  .cats{padding-bottom:clamp(2rem,5vh,4rem)}
  .work{padding-bottom:clamp(2rem,5vh,4rem)}

  /* แผ่นค้นหาต้องออกมาจากทิศเดียวกับปุ่มที่กด ไม่งั้นมันจะโผล่มาจากคนละมุมจอ
     กับที่นิ้วเพิ่งแตะ ซึ่งอ่านเหมือนของสองอย่างที่ไม่เกี่ยวกัน */
  .search{justify-content:flex-start}
  /* แผ่นทับแถบนำทางไปเลย ไม่ต้องเว้นที่ให้ เพราะมันซ้อนอยู่ข้างบนอยู่แล้ว
     ถ้าเว้นจะได้แถบดำว่างคาดหัวจอที่ไม่มีอะไรอยู่ */
  .search__panel{
    border-top:0;border-bottom:1px solid var(--line-hi);
    padding-bottom:1rem;
  }
  @keyframes sheet{from{transform:translateY(-16px);opacity:0}to{transform:none;opacity:1}}
}

/* --------------------------------------------------------------------------
   จอคอม — ปุ่มต้องโตตามความสูงจอด้วย ไม่ใช่ตามความกว้างอย่างเดียว

   เพดานความสูงปุ่มถูกล็อกไว้ที่ 136px ด้วย clamp ที่อ้างอิง vw ล้วน พอกางบนจอ
   1920x1080 ปุ่มทั้งห้าจึงกินพื้นที่แค่ราวหนึ่งในสามของจอ แล้วเหลือพื้นดำล้วน
   ใต้แถวล่างอีกกว่า 500px ซึ่งลูกค้าที่นั่งอีกฝั่งโต๊ะอ่านว่าหน้ายังโหลดไม่เสร็จ
   ไม่ใช่ว่าเมนูจบแค่ห้าหน่วย

   แก้สองทางพร้อมกัน — ผูกความสูงปุ่มเข้ากับ vh เพิ่มจากเดิม และจัดทั้งชุด
   กึ่งกลางแนวตั้ง ที่ว่างที่เหลือจึงถูกแบ่งบน-ล่างเท่ากันแทนที่จะกองอยู่ข้างล่าง
   -------------------------------------------------------------------------- */
@media (min-width:900px){
  .home{
    position:relative;
    justify-content:center;
    /* ล่างเผื่อไว้มากกว่าบน 3rem — เป็นที่ของแถบคีย์ลัดที่ถูกถอดออกจากแถวแล้ว
       และเผื่อไว้หน้าต่างที่ย่อจนเตี้ยมาก ๆ ไม่ให้ปุ่มกับคีย์ลัดทับกัน */
    padding-block:clamp(2rem,5vh,4rem) calc(clamp(2rem,5vh,4rem) + 3rem);
  }
  /*
    ถอดแถบคีย์ลัดออกจากแถวหลัก ไปเกาะขอบล่างแทน

    เดิมมันเป็นสมาชิกตัวที่สี่ของแถว แล้ว margin-top:auto ดูดที่ว่างทั้งหมด
    มาไว้เหนือตัวเอง ซึ่งเป็นตัวเดียวที่ทำให้ justify-content:center ไม่มีผล

    ที่สำคัญกว่านั้นคือมันจางหายไปเองหลังคนขับเริ่มใช้งาน ถ้ายังนับเป็นสมาชิก
    ของแถว กล่องที่มองไม่เห็นสูง 89px จะยังถูกนับตอนหาจุดกึ่งกลาง ทั้งชุดจึง
    ดูเบี้ยวขึ้นบนทันทีที่คีย์ลัดหาย ทั้งที่ไม่มีอะไรบนจอขยับเลย

    left/right ผูกกับ --gutter เพราะ absolute อ้างอิงกรอบ padding ของ .wrap
    ซึ่งกว้างกว่าเนื้อหาอยู่ข้างละหนึ่ง gutter — ถ้าใช้ 0 เส้นคั่นจะยาวเกินกริด
  */
  .hints{
    position:absolute;
    /* กว้างเท่ากลุ่มปุ่มพอดี ไม่ใช่เต็มความกว้างเนื้อหา — เส้นคั่นด้านบนของแถบนี้
       จะได้จบตรงขอบปุ่มพอดีทั้งสองข้าง ไม่ยื่นเลยออกไปข้างเดียว */
    left:50%;right:auto;transform:translateX(-50%);
    width:min(100% - var(--gutter) * 2, var(--home-max));
    bottom:clamp(1.25rem,3vh,2.25rem);
    margin-top:0;
  }

  /* ---- หน้าหน่วยธุรกิจ · จำนวนคอลัมน์มาจากจำนวนหมวด ------------------------
     auto-fit ตัดสินใจจากความกว้างอย่างเดียว หน่วยที่มีสี่หมวดจึงได้ 3+1
     เหลือปุ่มเดี่ยวห้อยแถวล่าง ทั้งที่ 2x2 หรือแถวเดียวสี่ใบลงตัวพอดี
     จำนวนหมวดเป็นข้อมูลที่ JS รู้อยู่แล้ว ส่งมาให้ CSS ตัดสินดีกว่าให้เดาเอง */
  #screen-unit > .wrap{
    min-height:100dvh;
    display:flex;flex-direction:column;
    padding-bottom:clamp(2rem,5vh,4rem);
  }
  /* min-height ไม่ใช่ height — ถ้าหมวดเยอะจนล้นจอ ที่ว่างเหลือศูนย์
     margin auto จึงคิดออกมาเป็นศูนย์เอง ไม่ดันเนื้อหาหลุดขอบบนแบบที่
     การจัดกึ่งกลางบนกล่องความสูงตายตัวมักพัง */
  #cats{margin-block:auto;padding-bottom:0}
  #cats{grid-template-columns:repeat(2,1fr)}
  #cats[data-count="1"]{grid-template-columns:minmax(0,520px);justify-content:center}
  #cats[data-count="3"]{grid-template-columns:repeat(3,1fr)}
  /*
    หมวดเยอะ (เจ็ดขึ้นไป) ขึ้นเป็นสามคอลัมน์ตั้งแต่ 900px ไม่รอถึง 1280px

    Verse Education มีเก้าหมวด ถ้าปล่อยเป็นสองคอลัมน์จะกลายเป็นห้าแถว ซึ่งไม่มี
    ทางลงจอสูง 768px ได้เลยนอกจากจะย่อปุ่มลงเหลือ 90px จนกดยากและอ่านชื่อไม่ทัน
    สามคอลัมน์ทำให้เหลือสามแถว ปุ่มแคบลงแต่ยังสูงพอ และทั้งหน้าจบในจอเดียว

    :has(> :nth-child(7)) คือ "มีลูกคนที่เจ็ด" — ใช้แทนการไล่เขียน data-count
    ทีละเลข เพราะจำนวนหมวดจะเพิ่มได้อีกเมื่อทีมส่งข้อมูลมาเติม
  */
  #cats:has(> :nth-child(7)){grid-template-columns:repeat(3,1fr)}
  /*
    ความสูงปุ่มตั้งตามจำนวนแถว ไม่ใช่ตั้งค่าเดียวแล้วใช้ทุกหน่วย

    จำนวนแถวคือ จำนวนหมวด หารด้วยจำนวนคอลัมน์ ซึ่งทั้งสองค่าเป็นที่รู้แล้วตรงนี้
    ค่าฐานข้างล่างจึงตั้งไว้เผื่อกรณีที่แถวเยอะที่สุด — Verse Education มี 9 หมวด
    เป็นสามแถว ถ้าใช้ค่าเดียวกับหน่วยสองแถว ความสูงรวมจะเกินจอ 20px แล้วเด็ค
    ที่ตั้งใจให้จบในจอเดียวก็กลายเป็นต้องเลื่อน

    หน่วยที่แถวน้อยกว่าค่อยเพิ่มความสูงกลับเข้าไปทีละกรณีข้างล่าง
  */
  #screen-unit .tag__inner{min-height:clamp(96px,15vh,190px)}
  /* แถวเดียวสามใบเติมความสูงจอไม่ได้ด้วยขนาดปกติ ใบจึงสูงขึ้นเป็นพิเศษ
     ช่องภาพที่โตขึ้นคือสิ่งที่ลูกค้ามองอยู่แล้ว ไม่ใช่ที่ว่างที่ยืดเปล่า ๆ */
  #cats[data-count="3"] .tag__inner{min-height:clamp(150px,30vh,340px)}
}

@media (min-width:1280px){
  /* กว้างพอให้สามคอลัมน์แล้ว ตรงกับจุดที่ auto-fit เดิมเปลี่ยนพอดี */
  #cats{grid-template-columns:repeat(3,1fr)}
  /* สี่หมวดวางแถวเดียวสี่ใบ ไม่ใช่ 2x2 — ที่ความกว้าง 1600px ปุ่มแบบ 2x2
     จะกว้างใบละ 790px แล้วช่องข้อความเหลือที่ว่างเปล่ากว่าครึ่งใบ */
  #cats[data-count="4"]{grid-template-columns:repeat(4,1fr)}
  /* ห้าหมวดใช้ทรงพีระมิดชุดเดียวกับเมนูหน้าแรก */
  #cats[data-count="5"]{grid-template-columns:repeat(6,1fr)}
  #cats[data-count="5"] > .tag{grid-column:span 2}
  #cats[data-count="5"] > .tag:nth-child(4){grid-column:2/span 2}

  /*
    ความสูงที่เพิ่มกลับให้หน่วยที่แถวน้อย — อยู่ในบล็อกนี้ไม่ใช่บล็อก 900px
    เพราะจำนวนคอลัมน์ที่ใช้คำนวณแถวเพิ่งมาแน่ที่ 1280px ต่ำกว่านี้ยังเป็น
    สองคอลัมน์ ซึ่งทำให้สี่หมวดกลายเป็นสองแถวและหกหมวดกลายเป็นสามแถว
  */
  /* แถวเดียวสี่ใบ — ต่ำกว่ากรณีสามหมวดเล็กน้อยเพราะใบแคบกว่า
     ถ้าใช้ค่าเดียวกันจะได้ปุ่มทรงเกือบจัตุรัส */
  #cats[data-count="4"] .tag__inner{min-height:clamp(150px,26vh,300px)}
  /* สองแถว */
  /*
    ทุกค่าในบล็อกนี้ถูกไล่วัดกับความละเอียดจริงบน Windows ไม่ได้ปัดให้สวย
    1920x1080 / 1600x900 / 1440x900 / 1366x768 / 1280x720 / 1024x768 / 900x600

    ตัวที่บีบที่สุดคือ 1280x720 — 22vh ทำให้สองแถวรวมหัวจอเกินไป 7px พอดี
    แล้วได้แถบเลื่อนมาทั้งแถบ ทั้งที่ขาดอีกไม่ถึงหนึ่งบรรทัด
  */
  #cats[data-count="5"] .tag__inner,
  #cats[data-count="6"] .tag__inner{min-height:clamp(120px,22vh,270px)}
}

/*
  ปุ่มเมนูหน้าแรกโตขึ้นเฉพาะตอนที่กริดเหลือสองแถว

  ที่ 900-1099px กริดยังเป็นสองคอลัมน์ คือสามแถว ถ้าใช้ค่าชุดเดียวกันความสูงรวม
  จะเกิน 78vh แล้วดันคีย์ลัดตกขอบจอ ค่าชุดนี้จึงเริ่มที่ 1100px ซึ่งเป็นจุดที่
  กริดเปลี่ยนเป็นสามคอลัมน์พอดี ไม่ใช่เลขที่ตั้งขึ้นมาลอย ๆ

  บล็อกนี้ต้องอยู่หลังกฎฐานของ .tag — media query ไม่เพิ่ม specificity
  ถ้าวางไว้ก่อน กฎฐานที่มาทีหลังจะชนะกลับโดยไม่มีอะไรฟ้อง
*/


/* หยุดที่ 899 ไม่ใช่ 900 — ไม่งั้นที่ความกว้าง 900 พอดี กฎทั้งสองชุดจะทำงาน
   พร้อมกัน ได้แถบอยู่บนแต่ซ่อนแถบสลับหน่วยไปด้วย */
@media (max-width:899px){
  .rail{display:none}

  /*
    บนมือถือ ช่องพิมพ์อยู่ "ล่างสุด" ของแผ่น ไม่ใช่บนสุด

    แผ่นค้นหาเปิดจากปุ่มที่มุมล่างขวา และมันสูงเต็มจอเสมอ เพราะตอนยังไม่ได้พิมพ์
    อะไรมันโชว์ทั้ง 133 รายการ ช่องพิมพ์ที่เป็นลูกคนแรกจึงไปโผล่ที่ขอบบนจอ
    — วัดจริงบนจอ 375x812 ได้ช่องพิมพ์อยู่ที่ y=17 ส่วนปุ่มที่เพิ่งแตะอยู่ y=748
    ห่างกันเกือบทั้งจอ และเป็นมุมที่ถือมือถือมือเดียวแล้วเอื้อมไม่ถึง

    ที่ขัดกันชัดคือแผ่นนี้ตั้งใจให้เลื่อนขึ้นมาจากขอบล่าง (justify-content:flex-end)
    เพื่อให้ออกมาจากทิศเดียวกับปุ่มที่กด แต่พอแผ่นสูงเต็มจอ ทิศนั้นก็ไม่เหลือ
    ความหมาย เพราะขอบบนกับขอบล่างของแผ่นคือขอบจอทั้งคู่

    column-reverse ย้ายช่องพิมพ์ลงไปอยู่ล่างสุด ซึ่งบนเครื่องจริงคือตำแหน่ง
    เหนือคีย์บอร์ดพอดี (โค้ด syncKeyboard ดันขอบล่างขึ้นตามคีย์บอร์ดอยู่แล้ว)
    ผลลัพธ์ไหลขึ้นข้างบนเหมือนแอปแชท ซึ่งเป็นทิศที่นิ้วกับตาคาดหวังอยู่แล้ว

    ลำดับใน DOM ยังเป็น ช่องพิมพ์ → สถานะ → ผลลัพธ์ เหมือนเดิม คนใช้คีย์บอร์ด
    และ screen reader จึงยังเจอช่องพิมพ์ก่อน ซึ่งเป็นลำดับที่ถูกอยู่แล้ว
    — กลับแค่ทิศที่ตาเห็น ไม่ได้กลับลำดับของเนื้อหา
  */
  .search__panel{flex-direction:column-reverse}
  /* margin เดิมเว้นไว้ด้านบนของแต่ละก้อน พอกลับทิศแล้วมันไปเปิดช่องว่างผิดด้าน */
  .search__status{margin:0 0 .875rem}
  .search__results{margin-top:0;margin-bottom:.75rem}
  /* คีย์ลัดไม่มีความหมายบนเครื่องที่ไม่มีคีย์บอร์ด และเป็นบล็อกที่กินความสูง
     มากที่สุดรองจากตัวปุ่ม ตัดออกคือที่ว่างที่ทำให้ห้าปุ่มลงครบในจอเดียว */
  .hints{display:none}
}
/*
  พื้นความสูงของปุ่มลดลงในโหมดคอลัมน์เดียว เพราะ 1fr เป็นตัวกำหนดความสูงจริงแล้ว
  ค่านี้เหลือไว้เป็นตาข่ายกันพังเท่านั้น ถ้าตั้งสูงกว่านี้มันจะกลายเป็นตัวดันให้
  ปุ่มที่ห้าตกขอบจอบนมือถือเตี้ยอย่าง 360x640

  บล็อกนี้ต้องอยู่หลังกฎฐานของ .tag ด้านบน — media query ไม่เพิ่ม specificity
  ถ้าวางไว้ก่อน กฎฐานที่มาทีหลังจะชนะกลับโดยไม่มีอะไรฟ้อง
*/
@media (max-width:640px){
  :root{--nav-h:4rem}
}

/* ทุกการเคลื่อนไหวถูกข้ามหรือแสดงในสถานะสุดท้ายเมื่อผู้ใช้ขอลดการเคลื่อนไหว */
@media (prefers-reduced-motion:reduce){
  .screen.is-active{animation:none}
  *,*::before,*::after{
    transition-duration:.01ms!important;
    animation-duration:.01ms!important;
    animation-iteration-count:1!important;
  }
}
