/*
Theme Name: Cyber Spotter Thailand
Theme URI: https://gitlab.com/appintouchdev/cyber-spotter-thailand-website
Author: AppInTouch Dev Team
Description: ธีมสำหรับเว็บไซต์ Cyber Spotter Thailand — WWF ประเทศไทย
Version: 1.0.0
Requires at least: 6.0
Requires PHP: 8.2
License: GNU General Public License v2 or later
Text Domain: cyberspotter
*/

/* ============================================================
   1. DESIGN TOKENS
   ปรับสีได้จากที่เดียว — ภายหลังจะผูกกับ ACF Options Page
   ============================================================ */
:root {
	/* สีแบรนด์ (ดึงจากเว็บ Cyber Spotter Singapore) */
	--cs-yellow: #fef100;
	--cs-red: #ff0000;
	--cs-black: #000000;
	--cs-dark: #222222;
	--cs-white: #ffffff;
	--cs-grey: #7a7a7a;
	/* สีลิงก์นโยบายความเป็นส่วนตัวท้ายเว็บ — วัดจาก SG ได้ rgb(204,51,102) */
	--cs-link: #cc3366;
	/* พื้นหลัง footer — วัดจาก SG ได้ rgb(51,51,51) อ่อนกว่า --cs-dark (#222) ที่ใช้ที่อื่น */
	--cs-footer: #333333;

	/* ฟอนต์ — Prompt คือฟอนต์ที่ wwffoundation.org ใช้อยู่
	   TODO: รอ WWF ยืนยัน แล้วเปลี่ยนมา self-host เพื่อความสอดคล้อง PDPA */
	--cs-font: "Prompt", "Noto Sans Thai", system-ui, -apple-system, sans-serif;

	/* ระยะห่าง — clamp() ปรับตามขนาดจอเองโดยไม่ต้องเขียน media query */
	/*
	 * ระยะบน-ล่างของทุก section — ใส่ทั้งบนและล่าง ระหว่าง section จึงได้ 2 เท่าของค่านี้
	 * เดิม 7rem (112px) ทำให้ช่องว่างระหว่าง section = 238px ส่วนต้นฉบับ SG ห่างแค่ 70px
	 */
	--cs-section-y: clamp(2rem, 4vw, 2.5rem);
	--cs-gutter: clamp(1rem, 4vw, 3rem);
	--cs-max-width: 1200px;

	/* ความสูง navbar — วัดจากต้นฉบับ SG จริง (82px) ใช้ชดเชยตอน scroll ไป anchor */
	--cs-nav-height: 82px;
}

/*
 * Disket Mono Bold — ฟอนต์ label ตัวพิมพ์ใหญ่ (ใช้กับ navbar เป็นหลัก)
 * เดียวกับที่เว็บ SG ต้นฉบับใช้ (self-host เอง ไม่ hotlink)
 * License: ฟรีทั้งใช้ส่วนตัวและเชิงพาณิชย์ โดย Mariano Diez
 *   ที่มา: https://www.behance.net/gallery/86075963/Disket-Mono-Free-font
 * ⚠️ ไม่ใช่ OFL ทางการ — ถ้าต้องการความชัดเจนด้าน license มากกว่านี้
 *    ให้ติดต่อผู้ออกแบบยืนยันเป็นลายลักษณ์อักษรก่อนขึ้น production จริง
 */
@font-face {
	font-family: "Disket Mono";
	src: url("assets/fonts/disket-mono-bold.woff2") format("woff2");
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* ============================================================
   2. RESET & BASE
   ============================================================ */
*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	font-family: var(--cs-font);
	font-weight: 400;
	/* ภาษาไทยต้องการ line-height สูงกว่าอังกฤษ เพราะมีสระบน-ล่าง */
	line-height: 1.75;
	color: var(--cs-white);
	background: var(--cs-black);
	-webkit-font-smoothing: antialiased;
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: var(--cs-yellow);
	text-decoration: none;
}

a:hover,
a:focus-visible {
	text-decoration: underline;
}

/* Focus ต้องมองเห็นชัด — เกณฑ์ WCAG 2.1 AA */
:focus-visible {
	outline: 3px solid var(--cs-yellow);
	outline-offset: 3px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-weight: 600;
	line-height: 1.3;
	margin: 0 0 0.5em;
}

/* เคารพการตั้งค่าของผู้ใช้ที่ไม่ต้องการ animation */
@media (prefers-reduced-motion: reduce) {

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

html {
	scroll-behavior: smooth;
	/* ชดเชยความสูง navbar ตอนกด anchor link */
	scroll-padding-top: var(--cs-nav-height);
}

/* ============================================================
   3. LAYOUT
   ============================================================ */
.cs-container {
	width: 100%;
	max-width: var(--cs-max-width);
	margin-inline: auto;
	padding-inline: var(--cs-gutter);
}

.cs-section {
	padding-block: var(--cs-section-y);
}

.cs-section--light {
	background: var(--cs-white);
	color: var(--cs-dark);
}

.cs-section--light a {
	color: var(--cs-red);
}

/*
 * พื้นผิวกระดาษยับสีดำ — ใช้ตัวแปรเดียวกับ navbar (ตั้งค่าจาก Customizer)
 * เพื่อให้เปลี่ยนภาพที่เดียวแล้วอัปเดตทุก section พร้อมกัน
 *
 * ⚠️ ใช้ background-color/-image แยก ไม่ใช้ shorthand "background"
 *    (บทเรียนจาก .cs-header.is-scrolled ที่เคยรีเซ็ตภาพทิ้งเพราะใช้ shorthand)
 */
.cs-bg-texture {
	position: relative;
	background-color: var(--cs-black);
	background-image: var(--cs-header-bg-image, none);
	background-position: center;
	background-size: cover;
}

.cs-bg-texture::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: rgb(0 0 0 / 20%);
}

.cs-bg-texture>.cs-container {
	position: relative;
	z-index: 1;
}

/*
 * ห่อ 3 section ต่อเนื่องกัน (ไทม์ไลน์/แผนที่/สินค้า) ด้วยพื้นผิวผืนเดียว
 * แทนที่จะให้แต่ละ section มี .cs-bg-texture ของตัวเอง — ดูเหตุผลใน front-page.php
 * โครงสร้างเหมือน .cs-bg-texture ทุกอย่าง ต่างแค่ z-index ไปอยู่ที่ <section> แทน .cs-container
 * เพราะตอนนี้มีชั้นซ้อนเพิ่มมา 1 ชั้น (group > section > container)
 */
.cs-bg-texture-group {
	position: relative;
	background-color: var(--cs-black);
	background-image: var(--cs-header-bg-image, none);
	background-position: center;
	background-size: cover;
}

.cs-bg-texture-group::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: rgb(0 0 0 / 20%);
}

.cs-bg-texture-group>section {
	position: relative;
	z-index: 1;
}

/* สำหรับ screen reader เท่านั้น — ไม่แสดงบนจอ */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ปุ่มข้ามไปเนื้อหาหลัก — โผล่เมื่อกด Tab */
.cs-skip-link {
	position: absolute;
	left: -9999px;
	z-index: 999;
	padding: 1em;
	background: var(--cs-yellow);
	color: var(--cs-black);
	font-weight: 600;
}

.cs-skip-link:focus {
	left: 1rem;
	top: 1rem;
}

/*
 * เน้นคำสีแดง — ใช้คู่กับ cs_highlight() ใน inc/helpers.php
 * เช่น "2.0" ในป้าย hero, "อาสาสมัคร" ในปุ่ม CTA (ตรงกับต้นฉบับ SG)
 */
.cs-text-accent {
	color: var(--cs-red);
}

/*
 * ⚠️ #FF0000 ตรงๆ บนพื้นเหลืองนี้ contrast ต่ำกว่าเกณฑ์ WCAG AA (~3.6:1 จากที่ต้องการ 4.5:1)
 * ยืนยันแล้วว่าต้องการสีนี้ตามแบรนด์ ไม่ใช่เกณฑ์ accessibility — ใช้ตามที่ยืนยัน
 */
.cs-hero__badge .cs-text-accent,
.cs-btn .cs-text-accent {
	color: var(--cs-red);
}

/* ============================================================
   4. HEADER / NAV
   ============================================================ */
.cs-header {
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 100;
	min-height: var(--cs-nav-height);
	display: flex;
	align-items: center;
	overflow: hidden;

	/*
	 * --cs-header-bg-image ถูกตั้งค่าโดย wp_head() จาก Customizer
	 * (ดู inc/customizer.php) — ถ้าไม่ได้ตั้งไว้ ตัวแปรนี้จะไม่มีค่า
	 * และ background-image จะไม่แสดงอะไร (ไม่ error)
	 */
	background-color: var(--cs-black);
	background-image: var(--cs-header-bg-image, none);
	background-position: top center;
	background-size: cover;
	transition: background-color 0.3s;
}

/*
 * ทับด้วยสีทึบโปร่งแสงบาง ๆ เพื่อกันข้อความอ่านยากถ้าเปลี่ยนไปใช้ภาพที่สว่างกว่านี้
 *
 * ⚠️ ตั้งไว้เบามาก (20%) เพราะภาพลายกระดาษที่ใช้ตอนนี้มืดเกือบดำสนิทอยู่แล้ว
 *    ทับดำแรง ๆ ซ้อนบนภาพมืดจะกลืนลวดลายจนเห็นเป็นดำทึบไปเลย (เจอปัญหานี้มาแล้ว)
 *    ถ้าเปลี่ยนภาพเป็นภาพที่สว่างกว่านี้ อาจต้องปรับเลขนี้ขึ้น
 */
.cs-header::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: rgb(0 0 0 / 20%);
}

.cs-header__inner {
	position: relative;
	z-index: 1;
}

.cs-header.is-scrolled {
	/*
	 * ใช้ background-color เดี่ยว ๆ ไม่ใช่ shorthand "background"
	 * shorthand จะรีเซ็ต background-image/-position/-size ที่ตั้งไว้ใน .cs-header
	 * ให้กลับไปเป็นค่าเริ่มต้นทันที (แล้วภาพพื้นหลังจะหายตอนเลื่อนหน้า)
	 */
	background-color: var(--cs-black);
}

.cs-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	width: 100%;
	max-width: var(--cs-max-width);
	margin-inline: auto;
	padding-inline: var(--cs-gutter);
}

.cs-header__logo {
	font-family: "Disket Mono", var(--cs-font);
	font-weight: 700;
	font-size: 20px;
	letter-spacing: 0.08em;
	color: var(--cs-yellow);
	text-transform: uppercase;
}

.cs-header__logo:hover {
	text-decoration: none;
}

.cs-nav {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2.25rem);
}

.cs-nav ul {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2.25rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.cs-nav a {
	color: var(--cs-white);
	font-size: 0.95rem;
	white-space: nowrap;
	transition: color 0.2s;
}

.cs-nav a:hover {
	color: var(--cs-yellow);
	text-decoration: none;
}

/* ปุ่ม Join Us ในเมนู — ใส่ class "cs-nav-cta" ที่เมนูใน wp-admin */
.cs-nav .cs-nav-cta a {
	border: 2px solid var(--cs-yellow);
	border-radius: 999px;
	padding: 0.4em 1.6em;
	color: var(--cs-yellow);
	font-weight: 600;
}

.cs-nav .cs-nav-cta a:hover {
	background: var(--cs-yellow);
	color: var(--cs-black);
}

/* ปุ่ม hamburger — ซ่อนบนจอใหญ่ */
.cs-nav-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 44px;
	height: 44px;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
}

.cs-nav-toggle span {
	display: block;
	height: 2px;
	background: var(--cs-white);
	transition: transform 0.3s, opacity 0.2s;
}

.cs-nav-toggle[aria-expanded="true"] span:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.cs-nav-toggle[aria-expanded="true"] span:nth-child(2) {
	opacity: 0;
}

.cs-nav-toggle[aria-expanded="true"] span:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/*
 * 860px เดิม (ตามต้นฉบับสิงคโปร์ที่ใช้เมนูภาษาอังกฤษสั้น ๆ) แคบเกินไปสำหรับ
 * เมนูภาษาไทยที่ยาวกว่ามาก เลยเลื่อนจุดสลับเป็นเมนูแฮมเบอร์เกอร์ให้เร็วขึ้น
 * กันเมนูตกบรรทัดก่อนถึงจุดสลับ (ดู .cs-nav a { white-space: nowrap })
 */
@media (max-width: 1100px) {
	.cs-nav-toggle {
		display: flex;
	}

	/*
	 * ⚠️ ห้ามใช้ transform: translateY(-120%) ซ่อนเมนู — 120% คำนวณจากความสูง
	 * ของกล่องเอง ถ้าเมนูมีรายการเยอะ/ยาวขึ้น (เช่นตอนเพิ่มลิงก์แผนที่)
	 * ความสูงโตขึ้นจนดันขอบล่างของเมนูโผล่มาเหนือ header ตอนปิดอยู่
	 * ใช้ top:-100vh แทน ซึ่งพ้นจอเสมอไม่ว่าเนื้อหาจะสูงแค่ไหน
	 */
	.cs-nav {
		position: fixed;
		inset-inline: 0;
		top: -100vh;
		max-height: calc(100vh - var(--cs-nav-height));
		overflow-y: auto;
		flex-direction: column;
		padding: 2rem var(--cs-gutter);
		background: var(--cs-black);
		border-block-start: 1px solid rgb(255 255 255 / 15%);
		transition: top 0.3s;
	}

	.cs-nav.is-open {
		top: var(--cs-nav-height);
	}

	/*
	 * เมนูที่เปิดอยู่: ชิดซ้ายเต็มแถวเหมือนต้นฉบับ SG
	 *
	 * วัด SG ที่ 820px: กล่องเมนูไม่มี padding | แต่ละรายการเต็มแถว 820x40
	 * padding 10px 20px ข้อความเริ่มที่ x=20 | ปุ่มร่วมเป็นอาสาสมัครเต็มแถวเหมือนกัน
	 * เดิมของเราจัดกึ่งกลางเพราะ .cs-nav ตั้ง align-items: center ไว้สำหรับเมนูแนวนอนบนเดสก์ท็อป
	 *
	 * จอ ≤767px มีบล็อกของตัวเองอยู่ด้านล่าง ทับค่าพวกนี้ด้วยระยะของมือถือ (15px 30px)
	 */
	.cs-nav {
		align-items: stretch;
		/*
		 * เว้นซ้าย-ขวา-ล่าง 6px — ไม่งั้นขอบเหลืองของปุ่มร่วมเป็นอาสาสมัครชิดขอบกล่องเมนูพอดี
		 * ด้านบนไม่เว้น เพราะเมนูต่อจาก header เป็นผืนเดียวกัน (เหมือนบล็อกมือถือ)
		 */
		padding: 0 6px 6px;
		border-block-start: 0;
	}

	.cs-nav ul {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		width: 100%;
	}

	.cs-nav a {
		display: block;
		/* 14 + padding ของกล่องเมนู 6 = ข้อความเริ่มที่ x=20 เท่า SG */
		padding: 10px 14px;
	}

	.cs-nav .cs-nav-cta a {
		/* 29 + 2 (ขอบ) + 6 (padding กล่องเมนู) = ข้อความเริ่มที่ x=37 เท่า SG */
		padding: 6px 29px 10px;
		border-radius: 40px;
	}
}

/*
 * มือถือ: header ให้เหมือนต้นฉบับ SG (วัดที่ 390px)
 *   SG  header สูง 76 | โลโก้ 20px line-height 20px ตัวห่างปกติ w600 เริ่มที่ x=30
 *       ไอคอนเมนู กล่อง 33x33 เส้นกว้างราว 20px หนา ~3px ปลายมน ขอบขวาห่างจอ ~45px
 *   เดิมของเรา header 82 | โลโก้ line-height 35px (สืบทอด 1.75 จาก body) + ตัวห่าง 1.6px
 *       เส้นเมนูกว้าง 37px หนา 2px ชิดขอบขวา 15px — ดูโปร่งและใหญ่กว่า SG ชัดเจน
 *
 * ใช้เฉพาะจอ ≤767px — แท็บเล็ต/เดสก์ท็อปยังเป็นแบบเดิม
 */
@media (max-width: 767px) {
	:root {
		/* ตัวแปรนี้คุมทั้งความสูง header, scroll-padding, ตำแหน่งเมนูที่เปิด และระยะบนของ hero
		   เปลี่ยนที่เดียวจึงขยับตามกันหมด ไม่มีช่องว่าง/ทับกัน */
		--cs-nav-height: 76px;
	}

	.cs-header__inner {
		padding-inline: 30px 33px;
	}

	.cs-header__logo {
		/* โลโก้เป็น flex item ถูกทำให้เป็น block อยู่แล้ว line-height ของตัวเองจึงมีผลกับระยะบรรทัดตรง ๆ */
		line-height: 1;
		letter-spacing: normal;
		font-weight: 600;
	}

	/* คงพื้นที่กด 44x44 ไว้ตามเกณฑ์ขนาดปุ่มบนจอสัมผัส — ย่อแค่ตัวเส้นที่ตาเห็น */
	.cs-nav-toggle {
		align-items: center;
		gap: 3px;
	}

	.cs-nav-toggle span {
		width: 20px;
		height: 3px;
		border-radius: 2px;
	}

	/* ระยะจากเส้นบนถึงเส้นกลาง = หนา 3 + ช่อง 3 = 6px (เดิม 2 + 5 = 7px) */
	.cs-nav-toggle[aria-expanded="true"] span:nth-child(1) {
		transform: translateY(6px) rotate(45deg);
	}

	.cs-nav-toggle[aria-expanded="true"] span:nth-child(3) {
		transform: translateY(-6px) rotate(-45deg);
	}

	/*
	 * เมนูที่เปิดบนมือถือ — ให้เหมือน SG (วัดที่ 390px ตอนกดเปิด)
	 *   กล่องเมนู  เริ่ม y=65 กว้างเต็มจอ ไม่มี padding ไม่มีเส้นขอบบน
	 *   แต่ละรายการ  ชิดซ้าย เต็มแถว สูง 50px padding 15px 30px ตัวอักษร 24px ขาว
	 *   ปุ่ม Join Us  เต็มความกว้าง 390x40 ขอบเหลือง 2px มน 40px ข้อความชิดซ้าย padding 6px 35px 10px
	 * เดิมของเราจัดกึ่งกลาง ตัวอักษร 15px ห่างกัน 24px และปุ่มเป็นเม็ดยาเล็ก ๆ ตรงกลาง
	 */
	.cs-nav {
		align-items: stretch;
		/*
		 * เว้นซ้าย-ขวา-ล่าง 6px — ไม่งั้นขอบเหลืองของปุ่มร่วมเป็นอาสาสมัครชิดขอบกล่องเมนูพอดี
		 * พอเมนูเปิดทับ section พื้นขาว ขอบล่างของปุ่มจะติดกับเนื้อหาข้างหลังจนดูเหมือนถูกตัด
		 * ด้านบนไม่เว้น เพราะเมนูต่อจาก header เป็นผืนเดียวกัน
		 */
		padding: 0 6px 6px;
		border-block-start: 0;
	}

	/*
	 * SG ให้เมนูทับขอบล่างของ header 11px (header สูง 76 เมนูเริ่มที่ 65)
	 * ใช้ calc จาก --cs-nav-height ไม่ใส่ 65px ตรง ๆ เผื่อ header เปลี่ยนความสูงอีก
	 */
	.cs-nav.is-open {
		top: calc(var(--cs-nav-height) - 11px);
	}

	.cs-nav ul {
		align-items: stretch;
		gap: 0;
	}

	.cs-nav a {
		display: block;
		/* 24 + padding ของกล่องเมนู 6 = ตัวอักษรเริ่มที่ x=30 ตรงกับโลโก้ */
		padding: 15px 24px;
		/*
		 * SG ใช้ 24px แต่เป็นฟอนต์ตัวบีบ — Prompt 24px ภาษาไทยใหญ่เกิน และสระล่าง (เช่น ู ใน "ถูก")
		 * ยื่นลงไปชนขอบเหลืองของปุ่มร่วมเป็นอาสาสมัครข้างล่าง WWF ขอลดลง
		 */
		font-size: 18px;
		/* SG ใช้ 20px ทำให้แต่ละแถวสูง 50 พอดี — สระบน-ล่างภาษาไทยล้นออกนอกบรรทัดได้โดยไม่ถูกตัด
		   เพราะมี padding บน-ล่าง 15px รองรับ */
		line-height: 20px;
		/* SG ใช้ w500 แต่ Prompt โหลดมาแค่ 300;400;600 เบราว์เซอร์จะปัด 500 ลงเป็น 400 อยู่แล้ว ใส่ให้ชัด */
		font-weight: 400;
		text-transform: uppercase;
	}

	.cs-nav .cs-nav-cta a {
		/* 29 + 2 (ขอบ) + 6 (padding กล่องเมนู) = ตัวอักษรเริ่มที่ x=37 เท่า SG */
		padding: 6px 29px 10px;
		border-radius: 40px;
		font-weight: 400;
	}
}

/* ============================================================
   5. BUTTON
   ============================================================ */
.cs-btn {
	display: inline-block;
	padding: 0.7em 2.2em;
	border: 2px solid var(--cs-yellow);
	border-radius: 999px;
	background: var(--cs-yellow);
	color: var(--cs-black);
	font: inherit;
	font-weight: 600;
	text-align: center;
	cursor: pointer;
	transition: background 0.2s, color 0.2s;
}

.cs-btn:hover {
	background: transparent;
	color: var(--cs-yellow);
	text-decoration: none;
}

.cs-btn--outline {
	background: transparent;
	color: var(--cs-yellow);
}

.cs-btn--outline:hover {
	background: var(--cs-yellow);
	color: var(--cs-black);
}

/*
 * ปุ่มบน section พื้นขาว
 *
 * ⚠️ ต้องมีกฎนี้ 2 เหตุผล:
 *   1. .cs-section--light a ตั้ง color เป็นสีแดงไว้ และ specificity สูงกว่า .cs-btn
 *      ตัวอักษรในปุ่มจะกลายเป็นแดงบนพื้นเหลือง
 *   2. hover เดิมเป็นพื้นโปร่ง + อักษรเหลือง ซึ่งบนพื้นขาวอ่านไม่ออกเลย
 *      สลับเป็นพื้นดำอักษรขาวแทน
 */
/*
 * ปุ่มวงแหวน — แบบเดียวกับปุ่ม JOIN US NOW ของต้นฉบับ SG
 *
 * ของ SG: พื้นดำ ตัวอักษรขาว ขอบเหลืองหนา 8px มนเต็มใบ (วัดได้ 254x68)
 * ไม่ใช่ปุ่มพื้นเหลืองแบบ .cs-btn ปกติของเรา
 *
 * เขียนเป็น .cs-btn.cs-btn--ring (2 คลาส) ไม่ใช่คลาสเดียว เผื่อมีกฎ
 * ที่เจาะจงระดับ 2 คลาสมาทับทีหลัง เช่นกฎที่ผูกกับ section
 */
.cs-btn.cs-btn--ring {
	border-width: 8px;
	border-color: var(--cs-yellow);
	background: var(--cs-black);
	color: var(--cs-white);
	/* เงารอบปุ่ม — SG มีตลอดเวลา ไม่ใช่เฉพาะตอนชี้เมาส์ (วัดได้ rgba(0,0,0,0.5) 0 0 10px) */
	box-shadow: 0 0 10px rgb(0 0 0 / 50%);
	transition: background 0.3s, color 0.3s, box-shadow 0.3s;
	font-size: 24px;
	/*
	 * ⚠️ ต้องตั้ง padding เป็น px และ line-height คู่กับขนาดตัวอักษรเสมอ
	 *    .cs-btn ใช้ padding หน่วย em ซึ่งโตตามตัวอักษร + line-height 1.75 ของ body
	 *    ที่ 24px ปุ่มจะสูงราว 92px เกือบเท่าครึ่งของ SG (วัดได้ 254x68)
	 *    ตั้งไว้ให้สูงใกล้ 68px และขอบซ้าย-ขวา 40px เท่า SG
	 */
	padding: 12px 40px;
	line-height: 1.2;
}

/*
 * มือถือ: ปุ่มวงแหวนเล็กลง — ที่ 24px ข้อความไทยยาวกว่า SG มาก ปุ่มกว้าง 329px (84% ของจอ) ดูใหญ่เกิน
 * SG มือถือวัดได้ 181x60 ขอบ 7px — ตั้งให้สูง 60 และขอบ 7px เท่ากัน
 * ความสูง = 18 x 1.2 (บรรทัด) + 12 x 2 (padding) + 7 x 2 (ขอบ) ≈ 60px
 */
@media (max-width: 767px) {
	.cs-btn.cs-btn--ring {
		border-width: 7px;
		padding: 12px 24px;
		font-size: 18px;
	}
}

/*
 * ⚠️ ต้องเขียนกฎนี้แยก เพราะ [data-cs-reveal].is-reveal ตั้ง transition ไว้ด้วย
 *    transition เป็น shorthand — กฎที่ชนะจะทับรายการทั้งหมด ไม่ได้รวมกัน
 *    ก่อนหน้านี้ปุ่มเหลือแต่ transition ของ opacity สีตอนชี้เมาส์เลยเปลี่ยนแบบกระโดด
 *    selector นี้เจาะจงกว่า (4 คลาส) จึงชนะไม่ว่าจะวางไว้ตรงไหนในไฟล์
 */
/* ตอนยังไม่ปรากฏ: ไม่มี transition ของ opacity (ซ่อนทันที) แต่ยังไล่สีตอนชี้เมาส์ได้ */
.cs-btn.cs-btn--ring[data-cs-reveal].is-reveal {
	transition:
		background 0.3s,
		color 0.3s,
		box-shadow 0.3s;
}

.cs-btn.cs-btn--ring[data-cs-reveal].is-revealed {
	transition:
		opacity 2s ease var(--cs-reveal-delay, 0s),
		transform 2s cubic-bezier(0.22, 1, 0.36, 1) var(--cs-reveal-delay, 0s),
		background 0.3s,
		color 0.3s,
		box-shadow 0.3s;
}

.cs-btn.cs-btn--ring:hover,
.cs-btn.cs-btn--ring:focus-visible {
	background: var(--cs-yellow);
	color: var(--cs-black);
}

/*
 * ปุ่มของ SG เป็นสีขาวล้วนทั้งข้อความ ไม่มีคำเน้นสีแดง
 * ที่นี่ยังใช้ cs_highlight() ในเทมเพลตอยู่ เลยสั่งให้คำเน้นใช้สีเดียวกับปุ่ม
 * (สีแดงบนพื้นดำอ่านยากด้วย)
 */
.cs-btn.cs-btn--ring .cs-text-accent {
	color: inherit;
}

/*
 * ค่อย ๆ จางเข้ามาตอนเลื่อนถึง เทียบคลาส animated + fadeIn ของต้นฉบับ SG
 *
 * คลาส is-reveal / is-revealed ถูกใส่โดย reveal.js
 * ส่วนระยะหน่วง (SG ใช้ 400ms) มาจาก data-cs-reveal ในเทมเพลต
 *
 * ⚠️ ต้องให้ JS เป็นคนใส่ is-reveal ห้ามตั้ง opacity: 0 ที่ [data-cs-reveal] ตรง ๆ
 *    ไม่งั้นถ้า JS โหลดไม่สำเร็จ เนื้อหาจะหายไปเลย
 */
/*
 * ⚠️ ระยะหน่วงมาจากตัวแปร --cs-reveal-delay ที่ reveal.js ตั้งให้
 *    ห้ามให้ JS ตั้ง transition-delay ตรง ๆ เพราะ inline style จะหน่วง
 *    "ทุก property" รวมถึงสีตอนชี้เมาส์ด้วย (ปุ่มจะเปลี่ยนสีช้าไป 400ms)
 */
/*
 * ⚠️ ขาซ่อนต้องไม่มี transition — ต้องกลายเป็น opacity 0 ทันที
 *    ของที่อยู่ในจอตั้งแต่โหลดหน้าจะได้ is-revealed ตามมาภายใน ~60ms
 *    ถ้าขาซ่อนค่อย ๆ จาง มันจะจางไปได้แค่นิดเดียวแล้วถูกสั่งให้กลับมา 1
 *    ผลคือแทบไม่ขยับ = มองไม่เห็นอนิเมชันเลย (เคยพลาดมาแล้ว 2 รอบ)
 */
[data-cs-reveal].is-reveal {
	opacity: -2;
	/* เริ่มจากต่ำกว่าตำแหน่งจริง 24px แล้วค่อยเลื่อนขึ้น = เอฟเฟกต์ Rise ของ Canva */
	transform: translateY(24px);
}

/*
 * transition อยู่ที่ขาปรากฏเท่านั้น — เบราว์เซอร์ใช้ค่า transition ของ
 * "สถานะปลายทาง" ในการไล่ ตอนใส่ is-revealed จึงได้ไล่ 0 → 1 ตามนี้
 */
[data-cs-reveal].is-revealed {
	opacity: 1;
	transform: none;
	/*
	 * เส้นโค้งนี้ออกตัวเร็วแล้วค่อย ๆ เบาลงจนหยุดนิ่ง (ease-out แรง ๆ)
	 * ให้ความรู้สึกเหมือน Rise ของ Canva มากกว่า ease ธรรมดาที่ดูเนือย
	 */
	transition:
		opacity 2s ease var(--cs-reveal-delay, 0s),
		transform 2s cubic-bezier(0.22, 1, 0.36, 1) var(--cs-reveal-delay, 0s);
}

/* ปุ่มเล็ก — สำหรับปุ่ม "JOIN US" ในกรอบ hero (ต้นฉบับใช้ปุ่มเล็กกว่าปุ่ม CTA หลัก) */
.cs-btn--sm {
	padding: 0.4em 1.4em;
	font-size: 0.85rem;
}

/* ============================================================
   6. HERO
   ============================================================ */
.cs-hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: min(88vh, 800px);
	padding-block: calc(var(--cs-nav-height) + 3rem) 4rem;
	text-align: left;
	background: var(--cs-dark);
}

/*
 * มือถือ — จอแคบเกินกว่าจะให้กล่องข้อความอยู่ซ้าย + สัตว์โผล่ขวาแบบ desktop ได้
 * (กล่องข้อความจะเกือบเต็มความกว้างจอ ไม่มีที่เหลือให้เห็นสัตว์อยู่ดี)
 * ย้ายทั้งกล่องไปกึ่งกลางจอแทน — ตรงกับที่ต้นฉบับ SG ทำบนมือถือเช่นกัน
 *
 * ส่วนการจัดข้อความภายในกล่อง (badge/พาดหัว/ปุ่ม center ทั้งหมด) เหมือนกันทุกขนาดจอ
 * อยู่แล้ว ไม่ต้อง override ซ้ำตรงนี้ — จุดต่างมีแค่ "ตำแหน่งกล่อง" (ซ้าย vs กลางจอ)
 */
@media (max-width: 767px) {
	.cs-hero {
		justify-content: center;
	}
}

/*
 * จัดข้อความชิดซ้าย เหมือนต้นฉบับ SG — ปล่อยฝั่งขวาให้เห็นวิดีโอเต็ม ๆ
 * ไม่ทับหน้าสัตว์ซึ่งเป็นจุดเด่นของภาพ
 */
/*
 * เทียบกับต้นฉบับ SG พบว่า: ป้าย, เส้นตกแต่ง, และปุ่ม ทั้งหมด "กึ่งกลาง" ของกล่องเดียวกัน
 * ส่วนพาดหัว (h1) กว้างกว่าป้าย/ปุ่มมาก จึงล้นออกทางซ้ายของจุดกึ่งกลางนั้น
 * ดูเผิน ๆ เหมือนพาดหัวชิดซ้ายเดี่ยว ๆ แต่จริง ๆ คือ text-align:center ของกล่อง
 * แล้ว h1/ข้อความรอง override เป็น left เฉพาะ 2 ตัวนี้
 */
.cs-hero__content {
	position: relative;
	z-index: 3;
	/* แคบกว่าเดิม (560px) — กล่องกว้างเกินทำให้ตัวอักษรขยายจนคำไทยตัดกลางคำ */
	max-width: 400px;
	text-align: center;
}

/*
 * เส้นตกแต่งเหนือป้าย พร้อมจุดปลายเส้น — กึ่งกลางกล่อง .cs-hero__content
 * ใช้ display:block + margin-inline:auto (ไม่ใช่ text-align) เพราะเป็น block-level
 * ที่มีความกว้างคงที่ — ต้อง margin auto ถึงจะจัดกึ่งกลางได้ ไม่งั้นจะติดขอบซ้าย
 */
.cs-hero__content::before {
	content: "";
	display: block;
	width: 1px;
	height: 2.25rem;
	margin-inline: auto;
	margin-block-end: 0.5rem;
	background: rgb(255 255 255 / 55%);
}

/* วิดีโอ/ภาพพื้นหลัง — ซ้อนอยู่หลังข้อความ */
.cs-video-bg {
	position: absolute;
	inset: 0;
	overflow: hidden;
	background: var(--cs-dark);
}

/*
 * ชั้นมืดทับวิดีโอ เพื่อให้ข้อความอ่านออกเสมอ (contrast ตาม WCAG)
 * ⚠️ เดิมทึบเกินไป (45%/70%) ทำให้สีวิดีโอหม่นกว่าต้นฉบับ SG มาก
 *    (ต้นฉบับแทบไม่ทับเลย อาศัย text-shadow ช่วยอ่านออกแทน)
 *    ลดลงมากแล้วเพิ่ม text-shadow ชดเชยแทนที่ .cs-hero__lead/badge
 */
.cs-video-bg::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	background: linear-gradient(rgb(0 0 0 / 10%), rgb(0 0 0 / 40%));
}

.cs-video-bg__poster {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* 50% = กึ่งกลาง, 0% = ชิดบน, 100% = ชิดล่าง (ตั้งได้รายตัวสัตว์จาก wp-admin) */
	object-position: 50% var(--cs-video-pos, 50%);
	transition: opacity 0.8s;
}

/* วิดีโอเริ่มเล่นแล้ว — จางภาพนิ่งออก */
.cs-video-bg.is-playing .cs-video-bg__poster {
	opacity: 0;
}

.cs-video-bg__frame {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/*
 * YouTube บังคับอัตราส่วน 16:9 เสมอ
 * ขยาย iframe ให้ใหญ่เกินกรอบแล้วจัดกึ่งกลาง เพื่อให้เต็มพื้นที่โดยไม่มีขอบดำ
 * (เทียบเท่า object-fit: cover ซึ่งใช้กับ iframe ไม่ได้)
 */
/*
 * iframe ไม่มี object-fit ให้ใช้ จึงเลียนแบบด้วย top + translate
 * ตั้ง top เท่ากับเปอร์เซ็นต์ที่ต้องการ แล้วเลื่อนกลับด้วย translateY เท่ากัน
 *   50% → top 50% + เลื่อนขึ้น 50% = กึ่งกลาง (ค่าเดิม)
 *    0% → top 0 + ไม่เลื่อน       = ชิดขอบบนของวิดีโอ
 *  100% → top 100% + เลื่อนขึ้น 100% = ชิดขอบล่าง
 * ได้พฤติกรรมเหมือน object-position ของภาพนิ่งเป๊ะ ๆ
 */
/*
 * ⚠️ ในกรอบ popup ต้องคิดขนาดจาก "กล่อง" ไม่ใช่ "ขนาดจอ"
 *    ค่าเริ่มต้นด้านล่าง (100vw / 56.25vw) ทำมาเพื่อ hero ที่เต็มจอ
 *    ถ้าปล่อยให้ popup ใช้ด้วย ช่วงที่ถูกครอบตัดจะเปลี่ยนไปตามขนาดจอผู้ชม
 *    พรีวิวในหน้า admin (ซึ่งอิงกล่อง) จึงไม่มีทางตรงกับของจริง
 *
 * เดิมตั้งกว้าง 100% ของกล่องเฉย ๆ ใช้ได้เพราะกล่องเป็น 3:1 ซึ่งแบนกว่า 16:9 เสมอ
 * ตอนนี้กล่องยืดสูงตามเนื้อหาได้แล้ว บางจอจึงสูงกว่า 16:9 แล้วจะเหลือแถบดำบน-ล่าง
 *
 * cqw/cqh = ขนาดของกล่อง .cs-video-bg (ไม่ใช่ขนาดจอ) — สูตรนี้เท่ากับ object-fit: cover
 *   กล่องแบนกว่า 16:9 → กว้าง 100% ของกล่อง ส่วนเกินถูกตัดบน-ล่าง
 *   กล่องสูงกว่า 16:9 → สูง 100% ของกล่อง ส่วนเกินถูกตัดซ้าย-ขวา
 * ใช้แทนเลข 222.3% ที่เคยคำนวณมือไว้สำหรับกล่อง 5:4 บนมือถือ (ลบออกแล้ว)
 */
.cs-animal-popup .cs-video-bg {
	container-type: size;
}

.cs-animal-popup .cs-video-bg__frame iframe {
	width: max(100cqw, calc(100cqh * 16 / 9));
	height: max(100cqh, calc(100cqw * 9 / 16));
	aspect-ratio: auto;
	min-width: 0;
	min-height: 0;
}

.cs-video-bg__frame iframe {
	position: absolute;
	top: var(--cs-video-pos, 50%);
	left: 50%;
	width: 100vw;
	height: 56.25vw;
	/* 100 / 16 * 9 */
	min-height: 100%;
	min-width: 177.78vh;
	/* 100 / 9 * 16 */
	transform: translate(-50%, calc(var(--cs-video-pos, 50%) * -1));
	border: 0;
}

/* ข้อความต้องอยู่เหนือชั้นวิดีโอ */
.cs-hero>.cs-container {
	position: relative;
	z-index: 3;
}

.cs-hero__badge {
	display: inline-block;
	max-width: 12em;
	margin-block-end: 1.25rem;
	padding: 0.4em 0.9em;
	background: var(--cs-yellow);
	color: var(--cs-black);
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.03em;
	text-align: center;
	border-radius: 6px;
}

.cs-hero__title {
	/* ยืนยันแล้วว่าต้องการ center ทั้งหมด (desktop เหมือน mobile) — ไม่ override text-align */
	margin: 0 0 1.25rem;
	/* เพดานลดลงจากเดิม (4.5rem) — กล่องแคบลงแล้ว ฟอนต์ใหญ่เกินจะดันคำไทยตัดกลางคำ */
	font-size: clamp(1.75rem, 5vw, 2.75rem);
	line-height: 1.25;
	text-shadow: 0 2px 20px rgb(0 0 0 / 50%);
}

.cs-hero__title em {
	display: block;
	color: var(--cs-yellow);
	font-style: normal;
}

.cs-hero__lead {
	/* ยืนยันแล้วว่าต้องการ center ทั้งหมด (desktop เหมือน mobile) — ไม่ override text-align */
	max-width: 38ch;
	margin-inline: auto;
	margin-block: 0 1.5rem;
	font-size: clamp(0.9rem, 2vw, 1rem);
	color: rgb(255 255 255 / 85%);
	text-shadow: 0 1px 12px rgb(0 0 0 / 60%);
}

/* ปุ่ม — ไม่ override text-align จึงกึ่งกลางตาม .cs-hero__content เหมือนป้าย */

/* เส้นตกแต่งใต้ปุ่ม พร้อมจุดปลายเส้น — กึ่งกลางกล่อง .cs-hero__content เหมือนเส้นบนป้าย */
.cs-hero__content::after {
	content: "";
	display: block;
	width: 1px;
	height: 1.75rem;
	margin-inline: auto;
	margin-block-start: 0.5rem;
	background: rgb(255 255 255 / 55%);
}

/* ============================================================
   7. CTA BAR
   ============================================================ */
/* ไม่มีพื้นหลังของตัวเอง — อยู่ใน .cs-bg-texture-group ให้พื้นผิวโปร่งใสทะลุลอดขึ้นมา */
.cs-cta-bar {
	padding-block: 2.5rem;
	text-align: center;
}

/* ============================================================
   8. SECTION HEADING
   ============================================================ */
.cs-heading {
	margin-block-end: 3rem;
	text-align: center;
}

.cs-heading__title {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
	margin: 0;
	/* ตัวหนาบีบแบบต้นฉบับ (Disket Mono) — ตัวอักษรไทยไม่มีใน glyph set นี้
	   เบราว์เซอร์จะ fallback ไปฟอนต์หลักให้เองอัตโนมัติทีละตัวอักษร ไม่ต้องกังวล */
	font-family: "Disket Mono", var(--cs-font);
	font-size: clamp(1.5rem, 4vw, 2.5rem);
	text-transform: uppercase;
}

/*
 * เส้นคั่นซ้าย-ขวาของหัวข้อ
 *
 * ⚠️ ต้องมี min-width
 *    flex: 1 คือ flex-basis 0 + ยืดได้ + "หดได้" ด้วย พอหัวข้อภาษาไทยยาว
 *    จนต้องตัดบรรทัด ข้อความจะกินความกว้างไปหมดแล้วบีบเส้นคั่นเหลือ 0px
 *    หายไปทั้งสองข้าง (เจอที่หัวข้อ "กรมอุทยานฯ รณรงค์หยุดค้าสัตว์ป่า..."
 *    บนมือถือ) ตั้งพื้นล่างไว้ 32px เท่าต้นฉบับ SG ที่มือถือใช้ขีดกว้าง
 *    คงที่ 32x1px ทั้งสองข้าง
 */
/*
 * มือถือ: หัวข้อ section เล็กลงจาก 24px เหลือ 20px
 * หัวข้อ "กรมอุทยานฯ รณรงค์หยุดค้าสัตว์ป่าและซากสัตว์" ที่ 24px ตก 3 บรรทัด วัดแล้ว:
 *   360px: 21px → 3 บรรทัด  20px → 2 บรรทัด
 *   390px: 23px → 3 บรรทัด  22px → 2 บรรทัด
 * ใช้กับทุกหัวข้อบนมือถือ ไม่ใช่เฉพาะหัวข้อนี้ — ขนาดหัวข้อ section จะได้เท่ากันทั้งหน้า
 * ⚠️ หัวข้อนี้ WWF แก้เองได้จาก ACF ถ้าข้อความยาวขึ้นอาจกลับไป 3 บรรทัด
 */
@media (max-width: 767px) {
	.cs-heading__title {
		font-size: 20px;
	}
}

.cs-heading__title::before,
.cs-heading__title::after {
	content: "";
	flex: 1;
	min-width: 32px;
	/*
	 * ⚠️ ห้ามใส่ max-width
	 *    ต้นฉบับ SG ปล่อยให้ขีดยืดจนเต็มพื้นที่ที่เหลือ หัวข้อทุกอันจึงเริ่ม-จบ
	 *    ที่ขอบกล่องเนื้อหาตำแหน่งเดียวกันเสมอ (ขีดยาวไม่เท่ากันในแต่ละหัวข้อ
	 *    แต่แถวหัวข้อกว้างเท่ากัน) เคยจำกัดไว้ 120px แล้วแถวหัวข้อกว้างไม่เท่ากัน
	 */
	height: 1px;
	background: currentColor;
	opacity: 0.4;
}

.cs-heading__sub {
	margin-block-start: 0.5rem;
	font-family: "Disket Mono", var(--cs-font);
	font-size: 0.9rem;
	letter-spacing: 0.1em;
	color: var(--cs-yellow);
	text-transform: uppercase;
}

/*
 * บรรทัดรองที่บอก "ปี" — สีขาว ไม่ใช่เหลือง
 *
 * ต้นฉบับ SG แยกบรรทัดรองเป็น 2 แบบชัดเจน (วัดจากเว็บจริง):
 *   บอกปี      "Since 2020"                     ขาว rgb(255,255,255)
 *   บอกวิธีใช้ "CLICK ON OUR TIMELINE TO..."    เหลือง rgb(254,241,0)
 * สีเหลืองของเขาสงวนไว้ให้บรรทัดที่ชวนให้ผู้ใช้ลงมือทำอะไรบางอย่าง
 */
.cs-heading__sub--plain {
	color: var(--cs-white);
}

/* ============================================================
   8ก. TIMELINE
   ============================================================ */

/*
 * กล่องเลื่อนแนวนอน — ตัวนี้คือ viewport ที่ overflow-x:auto จริง
 * ห้ามวาดเส้นตรงนี้ เพราะกล่องนี้กว้างแค่เท่าที่มองเห็น (viewport)
 * ไม่ได้กว้างเท่าเนื้อหาทั้งหมดที่ scroll ได้
 */
.cs-timeline__scroll {
	overflow-x: auto;
	overflow-y: hidden;
	cursor: grab;
	/* ซ่อน scrollbar แต่ยัง scroll ได้ปกติ (ทั้งลาก, wheel, swipe, คีย์บอร์ด) */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.cs-timeline__scroll::-webkit-scrollbar {
	display: none;
}

.cs-timeline__scroll:active {
	cursor: grabbing;
}

/*
 * ใช้ inline-flex ให้กล่องนี้กว้างเท่าผลรวมเนื้อหาจริง (ไม่ใช่เท่า viewport)
 * เพื่อให้เส้น ::before ด้านล่างลากยาวพอดีตั้งแต่จุดแรกถึงจุดสุดท้าย
 */
.cs-timeline__track {
	position: relative;
	display: inline-flex;
	align-items: center;
	/*
	 * แต่ละช่องกว้างเท่ากันหมดและกว้างเท่าการ์ดพอดี (flex: 1 0 ... ที่ .cs-timeline__item)
	 * ได้กริดสม่ำเสมอเหมือนต้นฉบับ SG ที่การ์ดกว้าง 102px เรียงชิดกันทุกใบ
	 * และถ้ารายงานเยอะจนรวมกันกว้างเกินจอ จะล้นออกไปให้ลากได้ตามปกติ
	 * (ของเดิมช่องกว้างแค่ 12px เท่าจุด การ์ดลอย absolute — พอรายงานเยอะการ์ดจะทับกันเอง
	 *  และ track ไม่มีวันล้น เลยเลื่อนไม่ได้ด้วย)
	 */
	/* ชิดกันสนิทเหมือนต้นฉบับ — การ์ดที่ติดกันอยู่คนละแถวบน-ล่างอยู่แล้ว ไม่ชนกัน */
	gap: 0;
	min-width: 100%;
	padding: 5.5rem clamp(1.5rem, 5vw, 3rem);
}

/* เส้นเชื่อมแนวนอน */
.cs-timeline__track::before {
	content: "";
	position: absolute;
	inset-inline: clamp(1.5rem, 5vw, 3rem);
	top: 50%;
	/* 2px ขาวทึบ — ค่าเดียวกับต้นฉบับ SG (วัดได้ w=1040 h=2 bg=#fff) */
	height: 2px;
	background: var(--cs-white);
}

.cs-timeline__item {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	/* โตเต็มพื้นที่ที่มี แต่ไม่ยอมหด — เยอะเกินเมื่อไหร่ค่อยล้นให้ลาก */
	flex: 1 0 6rem;
}

.cs-timeline__dot {
	display: block;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--cs-white);
}

.cs-timeline__card {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	/* เท่าความกว้างช่อง = ทุกใบเท่ากันหมด ไม่แกว่งตามความยาวชื่อเดือน */
	width: 100%;
	/*
	 * ค่าทั้งชุดตรงกับต้นฉบับ SG (อ่านจาก computed style ของหน้าเว็บจริง)
	 * แนวนอนใช้ 10px แทน 20px เพราะชื่อเดือนไทยยาวกว่าอังกฤษมาก
	 * ("พฤศจิกายน" ยาวกว่า "November") ถ้าใช้ 20px ตามเขาข้อความจะตกบรรทัด
	 */
	padding: 20px 10px;
	border: 1px solid #ccc;
	border-radius: 10px;
	background: transparent;
	color: var(--cs-white);
	font-family: "Disket Mono", var(--cs-font);
	font-size: 12px;
	font-weight: 700;
	line-height: 1.2;
	text-transform: uppercase;
	text-align: center;
	text-decoration: none;
	transition: background 0.2s, border-color 0.2s, transform 0.2s;
}

.cs-timeline__card__month,
.cs-timeline__card__year {
	display: block;
}

a.cs-timeline__card:hover,
a.cs-timeline__card:focus-visible {
	background: var(--cs-yellow);
	border-color: var(--cs-yellow);
	color: var(--cs-black);
	transform: translateX(-50%) translateY(-2px);
	text-decoration: none;
}

/*
 * ลูกศรชี้จากการ์ดไปยังเส้นไทม์ไลน์ — สามเหลี่ยมทึบสีขาว ฐาน 20px สูง 10px
 * ค่าตรงกับต้นฉบับ SG (.timeline__content::after) ที่วัดจาก computed style จริง
 *
 * ใช้เทคนิค border triangle: กล่องขนาด 0x0 แล้วให้ขอบด้านเดียวมีสี
 * ที่เหลือโปร่งใส เบราว์เซอร์จะตัดมุมขอบเป็นเส้นทแยงให้เอง กลายเป็นสามเหลี่ยม
 *
 * ⚠️ ห้ามใช้สี่เหลี่ยมหมุน 45 องศาแบบเดิม เพราะการ์ดพื้นโปร่งใส
 *    จะเหลือแค่เส้นขอบ 2 ด้านเป็นขีดเล็ก ๆ ไม่ใช่สามเหลี่ยมทึบอย่างต้นฉบับ
 */
.cs-timeline__card::after {
	content: "";
	position: absolute;
	left: 50%;
	width: 0;
	height: 0;
	background: none;
	border-style: solid;
	transform: translateX(-10px);
}

.cs-timeline__item--up .cs-timeline__card {
	bottom: calc(100% + 14px);
}

/* การ์ดอยู่บน — ลูกศรชี้ลง */
.cs-timeline__item--up .cs-timeline__card::after {
	top: 100%;
	border-width: 10px 10px 9px;
	border-color: var(--cs-white) transparent transparent;
}

.cs-timeline__item--down .cs-timeline__card {
	top: calc(100% + 14px);
}

/* การ์ดอยู่ล่าง — ลูกศรชี้ขึ้น */
.cs-timeline__item--down .cs-timeline__card::after {
	bottom: 100%;
	border-width: 9px 10px 10px;
	border-color: transparent transparent var(--cs-white);
}

.cs-timeline__hint {
	margin-block-start: 1rem;
	font-size: 0.8rem;
	text-align: center;
	color: rgb(255 255 255 / 55%);
}

/*
 * มือถือ: การ์ดซิกแซกบน-ล่างแบบเลื่อนแนวนอนอ่านยากบนจอแคบ (การ์ดทับกันเอง)
 * เปลี่ยนเป็นรายการแนวตั้งเรียงจากบนลงล่างแทน เหมือนต้นฉบับ SG บนมือถือ
 */
@media (max-width: 767px) {
	.cs-timeline__scroll {
		overflow: visible;
		cursor: auto;
	}

	/*
	 * เว้นที่ทางซ้าย (padding-left) ไว้เป็น "ช่องเดิน" ของเส้น+จุด โดยเฉพาะ
	 * แล้วดึงจุดกลับเข้าไปในช่องนั้นด้วย position:absolute แทนการเรียงแบบ flex
	 * ให้ตำแหน่งจุดคงที่แน่นอนทุกแถว ไม่ขยับตามความยาวข้อความในการ์ดอีกต่อไป
	 */
	/*
	 * ตำแหน่งทั้งหมดวัดจาก SG ที่ 390px (กล่องเนื้อหาเริ่ม x=16):
	 *   เส้นกึ่งกลาง x≈42 | จุด 15px | ปลายลูกศร x=60 เว้นจากจุด 12px | การ์ด x=70 ถึง x=360
	 * เดิมช่องเดินแคบ 32px ลูกศรชนจุดพอดี (ปลายลูกศรกับขอบจุดอยู่ที่ x เดียวกัน)
	 */
	.cs-timeline__track {
		display: block;
		min-width: 0;
		/* ซ้าย 54 = 70 (ขอบซ้ายการ์ด SG) - 16 (gutter) | ขวา 14 = 374 (ขอบขวากล่อง) - 360 (ขอบขวาการ์ด SG) */
		padding: 0.5rem 14px 0.5rem 54px;
	}

	/* เส้นเชื่อมแนวตั้ง หนา 2px — วัดพิกเซลจาก SG ได้เส้นอยู่ที่ x=40-41 บนจอ (กล่องเริ่ม x=16 → left 24px) */
	.cs-timeline__track::before {
		inset-inline: auto;
		left: 24px;
		top: 0;
		bottom: 0;
		width: 2px;
		height: auto;
	}

	.cs-timeline__item {
		position: relative;
		display: block;
		/* SG เว้นระหว่างการ์ด 20px (เดิม 28px) */
		margin-block-end: 20px;
	}

	/*
	 * การ์ดค่อย ๆ ปรากฏตอนเลื่อนเข้ามาในจอ เหมือนคลาส animated + fadeIn
	 * + timeline__item--left ของต้นฉบับ SG บนมือถือ
	 *
	 * คลาส is-reveal ถูกใส่โดย timeline-reveal.js ตอนเริ่มทำงาน
	 * และ is-revealed ถูกใส่ทีละใบเมื่อใบนั้นเข้ามาในจอ
	 *
	 * ⚠️ ต้องให้ JS เป็นคนใส่ is-reveal ห้ามตั้ง opacity: 0 ไว้ใน CSS ตรง ๆ
	 *    ไม่งั้นถ้า JS โหลดไม่สำเร็จ การ์ดจะจางหายไปทั้งหมดและอ่านไม่ได้เลย
	 */
	/*
	 * ⚠️ ขาซ่อนต้องไม่มี transition (เหตุผลเดียวกับ [data-cs-reveal] ด้านบน)
	 *    การ์ดที่อยู่ในจอตั้งแต่โหลดหน้าจะได้ is-revealed ตามมาทันที
	 *    ถ้าขาซ่อนค่อย ๆ จาง มันจะจางไปนิดเดียวแล้วกลับมา = แทบมองไม่เห็นอนิเมชัน
	 */
	.cs-timeline__item.is-reveal {
		opacity: 0;
		transform: translateX(-16px);
	}

	/* transition อยู่ที่ขาปรากฏ — เบราว์เซอร์ใช้ค่าของสถานะปลายทางในการไล่ */
	.cs-timeline__item.is-revealed {
		opacity: 1;
		transform: none;
		transition: opacity 0.5s ease, transform 0.5s ease;
	}

	.cs-timeline__item:last-child {
		margin-block-end: 0;
	}

	.cs-timeline__dot {
		position: absolute;
		top: 50%;
		/* SG จุดอยู่ที่ x=34-48 บนจอ → 34 - 16 (gutter) - 54 (padding-left ของ track) = -36px */
		left: -36px;
		width: 15px;
		height: 15px;
		transform: translateY(-50%);
	}

	/*
	 * การ์ดกลับไปอยู่ใน flow ปกติ เต็มความกว้างช่องที่เหลือ แทนที่จะลอย absolute ขึ้น/ลง
	 * ⚠️ .cs-timeline__card เป็น <a>/<span> (inline โดย default) — width:100% เฉย ๆ
	 *    ไม่มีผลกับ inline element ต้องตั้ง display:block ด้วยถึงจะกางเต็มและครอบ
	 *    ข้อความ 2 บรรทัด (เดือน/ปี) ให้อยู่ในกรอบเดียวกันจริง ๆ
	 */
	.cs-timeline__card {
		position: static;
		display: block;
		transform: none;
		max-width: none;
		width: 100%;
		/* SG มือถือ padding 20px รอบด้าน (เดสก์ท็อปใช้ 20px 10px เพราะการ์ดแคบ) */
		padding: 20px;
	}

	a.cs-timeline__card:hover,
	a.cs-timeline__card:focus-visible {
		transform: none;
	}

	/*
	 * layout แนวตั้ง — ลูกศรหันไปชี้เส้นทางซ้ายแทนการชี้ขึ้น/ลง
	 *
	 * ⚠️ ต้องเขียน selector ให้ลึกเท่ากฎของ --up/--down ด้านบน
	 *    ถ้าใช้แค่ .cs-timeline__card::after จะแพ้ specificity แล้วไม่มีผล
	 *    (media query ไม่ได้เพิ่มน้ำหนัก selector)
	 */
	.cs-timeline__item--up .cs-timeline__card::after,
	.cs-timeline__item--down .cs-timeline__card::after {
		top: 50%;
		bottom: auto;
		left: 0;
		/* ระบายเฉพาะขอบขวา = สามเหลี่ยมชี้ซ้าย ฐาน 20px สูง 10px */
		border-width: 10px 10px 10px 0;
		border-color: transparent var(--cs-white) transparent transparent;
		transform: translate(-100%, -50%);
	}
}

/* ============================================================
   8ก¼. ANIMAL MAP (แผนที่สัตว์ป่าที่ถูกลักลอบค้า)
   ============================================================ */

.cs-animal-map {
	position: relative;
}

/*
 * ⚠️ ภาพแผนที่ dot-matrix นี้ดึงมาจาก cyberspotter.wwf.sg (asset ของ WWF
 * Singapore) ใช้ชั่วคราวสำหรับ local dev/demo เท่านั้น เหมือนพื้นผิวกระดาษยับ
 * ของ navbar — ต้องเปลี่ยนเป็นภาพที่ WWF Thailand เป็นเจ้าของเองก่อนขึ้น production
 * (บีบอัดจาก 633 KB เหลือ 113 KB ด้วยการลดจำนวนสี — ภาพมีแค่จุดสีเหลืองบนพื้นโปร่งใส
 *  ไม่ต้องใช้สีเยอะ)
 */
.cs-animal-map__canvas {
	/*
	 * ขนาดหมุดสัตว์ — คิดเป็น % ของ "ความกว้างแผนที่" ไม่ใช่ความกว้างจอ
	 *
	 * ภาพ world-map-dots.png คือ 1536x1024 (อัตราส่วน 1.5) ตรงกับ aspect-ratio
	 * ของ canvas พอดี background-size: contain จึงเต็มกรอบทุกด้าน
	 * => ความกว้าง canvas = ความกว้างแผนที่ที่ตาเห็นเป๊ะ ใช้อ้างอิงได้เลย
	 *
	 * ค่า 11% วัดจากสัดส่วนหมุดต่อแผนที่ในเว็บต้นฉบับ SG
	 * ปรับตัวเลขตรงนี้ที่เดียวได้ถ้าอยากให้หมุดใหญ่/เล็กกว่านี้
	 */
	--cs-marker: 11%;

	position: relative;
	aspect-ratio: 1536 / 1024;
	border-radius: 8px;
	background-image: url("assets/img/world-map-dots.png");
	background-position: center;
	background-size: contain;
	background-repeat: no-repeat;
}

.cs-animal-map__hotspot {
	position: absolute;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	transform: translate(-50%, -50%);
	background: none;
	border: 0;
	cursor: pointer;
}

.cs-animal-map__dot {
	position: relative;
	z-index: 1;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--cs-yellow);
	box-shadow: 0 0 0 3px rgb(0 0 0 / 55%);
	transition: transform 0.2s;
}

.cs-animal-map__hotspot:hover .cs-animal-map__dot,
.cs-animal-map__hotspot:focus-visible .cs-animal-map__dot {
	transform: scale(1.25);
}

/*
 * ต้นฉบับ SG ใช้รูปเดียวจบ (วงกลม + เส้นปักหมุด + ป้ายชื่อ ทำมาในไฟล์เดียวเลย)
 * แทนจุดเฉย ๆ — รองรับผ่านฟิลด์ ACF "ไอคอนบนแผนที่" (map_icon) ทีมทำเนื้อหา
 * เตรียมกราฟิกครบชุดต่อ 1 ตัวสัตว์แล้วอัปโหลด + ปรับพิกัด x/y เองได้เลย
 * จากหน้าแก้ไข CPT สัตว์ป่า — ธีมแค่วางรูปตามพิกัด ไม่ต้องประกอบชิ้นส่วนเอง
 *
 * ⚠️ เช็คไฟล์ตัวอย่างจริงจากต้นฉบับ SG แล้วพบว่า "ตำแหน่งปลายหมุดในรูป"
 *    ไม่คงที่ — บางตัวป้ายอยู่บน หมุดชี้ลง (เช่น Ball Python) บางตัวป้ายอยู่ล่าง
 *    หมุดชี้ขึ้น (เช่น African Elephant, Leopard Gecko) เขาออกแบบเป็นภาพเฉพาะ
 *    ตัวต่อ 1 ตำแหน่งบนแผนที่ ไม่ใช่ template เดียวที่ยึดจุดเดิมได้ทุกใบ
 *    เพราะงั้นยึดที่ "กึ่งกลางรูป" แบบเป็นกลางไปเลย แม่นยำสัมบูรณ์ไม่ได้ 100%
 *    แต่ใช้ได้กับทุกทิศทางเท่า ๆ กัน — ทีม content ควรออกแบบให้จุดหมุด
 *    อยู่ใกล้กึ่งกลางภาพเพื่อให้ตำแหน่งตรงที่สุด
 */
/*
 * ⚠️ ความกว้างต้องอยู่ที่ hotspot ไม่ใช่ photo-wrap — เพราะ % ของลูกจะวัดเทียบ
 *    กับพ่อ ถ้าพ่อเป็น width:auto (หดตามลูก) ค่าจะวนเป็นงูกินหาง
 *    hotspot เป็น position:absolute ใน canvas อยู่แล้ว % จึงวัดกับ canvas ตรง ๆ
 *
 * min-width กันไว้ไม่ให้หมุดเล็กจนกดยากบนจอมือถือ (เกณฑ์ WCAG 2.5.8 target size)
 */
.cs-animal-map__hotspot--photo {
	width: var(--cs-marker);
	min-width: 44px;
	height: auto;
}

.cs-animal-map__photo-wrap {
	position: relative;
	display: block;
	width: 100%;
}

.cs-animal-map__photo {
	position: relative;
	z-index: 1;
	display: block;
	width: 100%;
	height: auto;
	transition: transform 0.2s;
}

/*
 * pulse ของแบบรูปภาพ — วางกึ่งกลาง wrap (สมมติว่าวงกลมตัวสัตว์อยู่ตรงกลาง
 * ภาพพอดี ตามค่าเฉลี่ยของไฟล์ตัวอย่างจริงจาก SG)
 *
 * ⚠️ z-index: 0 ให้ชัดเจน — ไม่งั้น .cs-animal-map__pulse (position:absolute)
 *    จะไปวาดทับหน้ารูป (static) เสมอ ต่อให้ตำแหน่งใน HTML มาก่อนก็ตาม
 *    เพราะ element ที่ positioned (แม้ z-index:auto) วาดทีหลัง static เสมอ
 *
 * ⚠️ ขนาดต้อง "ใหญ่กว่า" วงกลมตัวสัตว์จริง ๆ (ไม่ใช่เท่ากัน) เพราะ pulse
 *    ต้องขยายเลยขอบวงกลมออกมาให้เห็นเป็นคลื่นกระเพื่อม — ถ้าตั้งเท่าวงกลม
 *    พอดี (55% เดิม) ขนาดสูงสุดของ pulse ก็แค่พอดีหรือเล็กกว่าวงกลมทึบ
 *    ที่บังอยู่ด้านหน้า เลยไม่โผล่ออกมาให้เห็นเลย
 */
.cs-animal-map__photo-wrap .cs-animal-map__pulse {
	--cs-pulse-base: translate(-50%, -50%);
	z-index: 0;
	inset: auto;
	/* ตำแหน่งจุดเต้นบนรูป — WWF ลากกำหนดเองได้จาก wp-admin (ฟิลด์ pulse_x / pulse_y) */
	top: var(--cs-pulse-y, 50%);
	left: var(--cs-pulse-x, 50%);
	width: 100%;
	aspect-ratio: 1;
}

.cs-animal-map__hotspot--photo:hover .cs-animal-map__photo,
.cs-animal-map__hotspot--photo:focus-visible .cs-animal-map__photo {
	transform: scale(1.05);
}

/*
 * วงคลื่นเต้น (pulse) รอบจุด — ดึงดูดสายตาให้รู้ว่าคลิกได้
 * ⚠️ --cs-pulse-base ไว้ใส่ transform เพิ่มจาก selector อื่น (เช่น
 *    translateX(-50%) ของ hotspot--photo) เพราะ @keyframes กำหนดค่า
 *    transform เต็ม ๆ ทุก step ถ้าใช้ transform ตรง ๆ นอก keyframes
 *    ระหว่างเล่น animation ค่าที่ตั้งไว้จะโดนทับหายไปทันที
 */
/*
 * 3 ค่าด้านล่างตั้งได้รายตัวสัตว์จาก wp-admin (ฟิลด์ pulse_speed / pulse_size / pulse_color)
 * map.php เขียนทับเป็น inline style เฉพาะตัวที่ WWF ตั้งค่าไว้
 * ค่าที่เขียนตรงนี้คือค่าเริ่มต้น — ต้องตรงกับ cs_core_pulse_defaults() ในปลั๊กอิน
 */
.cs-animal-map__pulse {
	--cs-pulse-base: ;
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--cs-pulse-color, var(--cs-yellow));
	opacity: 0.6;
	/*
	 * ⚠️ ห้ามประกาศ --cs-pulse-duration / --cs-pulse-scale ไว้ในกฎนี้
	 *    ค่าที่ WWF ตั้งถูกใส่เป็น inline style ที่ปุ่ม (element แม่) แล้วสืบทอดลงมา
	 *    ถ้าประกาศไว้ตรงนี้ด้วย ค่าของตัวเองจะชนะค่าที่สืบทอดมาเสมอ
	 *    (เคยเป็นแบบนั้นมาแล้ว: ตั้ง 0.6 วินาที แต่หน้าเว็บยังเต้น 2 วินาทีเหมือนเดิม)
	 *    ใช้ค่าเริ่มต้นเป็น fallback ใน var() แทน
	 */
	animation: cs-map-pulse var(--cs-pulse-duration, 2s) ease-out infinite;
}

@keyframes cs-map-pulse {
	0% {
		transform: var(--cs-pulse-base) scale(0.4);
		opacity: 0.6;
	}

	100% {
		transform: var(--cs-pulse-base) scale(var(--cs-pulse-scale, 1));
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.cs-animal-map__pulse {
		animation: none;
		opacity: 0;
	}
}

/*
 * <dialog> ของเบราว์เซอร์มี UA stylesheet ของตัวเอง (border/padding/พื้นหลัง)
 * ล้างทิ้งให้หมดแล้วจัดสไตล์เอง
 */
.cs-animal-popup {
	/* เว้นขอบจอข้างละ 3% ไม่ให้วิดีโอชนขอบ (เดิม 98vw เหลือข้างละ 1% ดูเหมือนติดขอบ) */
	width: 94vw;
	/* UA ตั้ง max-width: calc(100% - 6px - 2em) ให้ dialog ทับค่าเราไว้ ต้องเขียนทับ */
	max-width: 94vw;
	/*
	 * แนวนอนแบนกว่า 16:9 — เกือบเต็มความกว้างจอ
	 *
	 * ⚠️ ต้องเป็น min-height ไม่ใช่ aspect-ratio ตายตัว
	 *    เดิมใช้ aspect-ratio: 3/1 ความสูงจึงถูกล็อกจากความกว้าง พอข้อความไทย
	 *    ยาวจนการ์ดสูงเกินกล่อง (เจอที่ 768-1100px การ์ดสูง 443px แต่กล่องแค่ 420px)
	 *    overflow: hidden ด้านล่างจะตัดหัว-ท้ายการ์ดทิ้งข้างละ 11px
	 *    ต้นฉบับ SG ไม่ล็อกสัดส่วน — ป๊อปอัพเขายืดสูงตามเนื้อหา (วัดที่ 768px ได้ 730x865)
	 *
	 * 31.333vw = 94vw ÷ 3 คือความสูงเดิมที่ 3:1 ให้ — ตอนนี้เป็นแค่ "อย่างน้อยเท่านี้"
	 * ถ้าการ์ดสูงกว่านั้น กล่องยืดตาม ไม่ตัดข้อความ
	 */
	min-height: max(420px, 31.333vw);
	max-height: 85vh;
	padding: 0;
	border: 0;
	border-radius: 12px;
	/*
	 * แนวนอนซ่อน (ไว้ครอบวิดีโอที่กว้างเกินกรอบ) แนวตั้งเลื่อนได้
	 * กล่องยืดตามการ์ดได้ก็จริง แต่ยืดได้ไม่เกิน 85vh — ถ้า WWF เขียนคำอธิบาย
	 * ยาวมากจนชนเพดาน ต้องเลื่อนอ่านได้ ไม่ใช่ถูกตัดหาย (จอมือถือทำแบบนี้อยู่แล้ว)
	 */
	overflow: hidden auto;
	background: var(--cs-dark);
	color: var(--cs-white);
}

/*
 * UA ตั้ง dialog[open] { display: block } ไว้ — เขียนทับเป็น flex
 * เพื่อให้ __inner ยืดเต็มความสูงกล่องเสมอ (ก่อนหน้านี้พึ่ง height: 100%
 * ซึ่งใช้ไม่ได้แล้วเมื่อความสูงกล่องมาจาก min-height + เนื้อหา)
 */
.cs-animal-popup[open] {
	display: flex;
}

.cs-animal-popup::backdrop {
	background: rgb(0 0 0 / 75%);
}

.cs-animal-popup__inner {
	position: relative;
	flex: 1;
	width: 100%;
	display: flex;
	/*
	 * safe = ถ้าการ์ดสูงเกินกล่อง ให้เริ่มจากขอบบนแทนการจัดกึ่งกลาง
	 * ไม่งั้นการ์ดจะล้นออกทั้งบนและล่างเท่า ๆ กัน ส่วนที่ล้นด้านบนเลื่อนตามไปอ่านไม่ได้
	 */
	align-items: safe center;
	justify-content: flex-start;
	/* 5.7% ของความกว้างป๊อปอัพ — ระยะขอบซ้ายเท่าต้นฉบับ SG ทุกขนาดจอ */
	padding-inline: 5.7%;
	padding-block: clamp(1rem, 3vw, 2rem);
}

/* ต้นฉบับ SG เป็นกากบาทบาง ๆ ลอยบนวิดีโอ ไม่มีพื้นหลังวงกลม
   ใช้ text-shadow ช่วยให้อ่านออกเมื่อวิดีโอฉากสว่าง */
.cs-animal-popup__close {
	position: absolute;
	top: 0.5rem;
	right: 0.9rem;
	z-index: 6;
	width: 36px;
	height: 36px;
	border: 0;
	background: none;
	color: rgb(255 255 255 / 85%);
	font-size: 1.75rem;
	line-height: 1;
	text-shadow: 0 1px 4px rgb(0 0 0 / 70%);
	cursor: pointer;
}

.cs-animal-popup__close:hover,
.cs-animal-popup__close:focus-visible {
	color: var(--cs-yellow);
}

.cs-animal-popup__window-wrap {
	position: relative;
	z-index: 5;
	/*
	 * 33.8% ของ content box = ≈30% ของความกว้างป๊อปอัพ เท่าสัดส่วนต้นฉบับ SG
	 * (ต้องหารด้วย 88.6% เพราะ % ของลูกคิดจากกล่องที่หัก padding แล้ว)
	 */
	width: 33.8%;
	min-width: 300px;
	max-width: 620px;
}

.cs-animal-popup__window {
	position: relative;
	z-index: 5;
}

/* ครอบเฉพาะแถบหน้าต่าง เพื่อเป็น containing block ให้เส้นชี้
   (ถ้าอิงกับ __window ทั้งก้อน ตำแหน่งเส้นจะขยับตามความยาวข้อความ) */
.cs-animal-popup__bar {
	position: relative;
	line-height: 0;
}

.cs-animal-popup__windowbar {
	display: block;
	width: 100%;
	height: auto;
}

/*
 * เส้นชี้ + จุดกลม ยื่นออกจากขอบขวาของหน้าต่าง
 * ระดับความสูง = แถวปุ่มควบคุมของแถบหน้าต่าง ≈30% ของความสูงแถบ
 * ความยาว ≈15.5% ของความกว้างหน้าต่าง — ทั้งคู่วัดจากหน้าต้นฉบับ SG
 */
.cs-animal-popup__pointer {
	position: absolute;
	left: 100%;
	top: 30%;
	z-index: 4;
	width: 15.5%;
	height: auto;
	transform: translateY(-50%);
}

.cs-animal-popup__content {
	position: relative;
	z-index: 1;
	width: 100%;
	background: var(--cs-black);
	border: 3px solid #E28805;
	border-top: 0;
	border-radius: 0 0 12px 12px;
	padding: 6% 6.4% 8.6%;
	text-align: center;
	margin-top: -2px;
}

.cs-animal-popup__sci {
	margin: 0.15rem 0 0;
	font-style: italic;
	font-size: clamp(0.85rem, 0.8vw, 1rem);
	color: var(--cs-yellow);
}

.cs-animal-popup__name-en {
	margin: 0;
	font-family: "Disket Mono", var(--cs-font);
	font-size: clamp(1.3rem, 1.55vw, 1.85rem);
	text-transform: uppercase;
	color: var(--cs-yellow);
}

.cs-animal-popup__desc {
	margin: 1.25rem 0 0;
	font-size: clamp(0.9rem, 0.85vw, 1.05rem);
	line-height: 1.5;
	color: var(--cs-white);
}

/*
 * ฟิลด์นี้เป็น editor แล้ว เนื้อหาจึงมาเป็นย่อหน้า <p> ได้หลายย่อหน้า
 * ย่อหน้าแรกไม่ต้องเว้นบน เพราะกล่องเว้นให้แล้ว ย่อหน้าถัดไปเว้นห่างกันพอให้อ่านง่าย
 */
.cs-animal-popup__desc p {
	margin: 0.75em 0 0;
}

.cs-animal-popup__desc p:first-child {
	margin-block-start: 0;
}

/* ตัวหนาที่ WWF กดจากปุ่ม B — Prompt โหลดมาหนาสุด 600 (เหตุผลเดียวกับบล็อกเกี่ยวกับโครงการ) */
.cs-animal-popup__desc strong,
.cs-animal-popup__desc b {
	font-weight: 600;
}

/* ลิงก์ในคำอธิบาย — พื้นหลังการ์ดเป็นสีเข้ม ใช้เหลืองของแบรนด์ให้อ่านออก */
.cs-animal-popup__desc a {
	color: var(--cs-yellow);
}

/*
 * มือถือ: ต้นฉบับ SG ไม่ให้การ์ดทับวิดีโอ แต่วางซ้อนกันเป็นชั้น —
 * วิดีโออยู่บน การ์ดเต็มความกว้างอยู่ล่าง ความสูงป๊อปอัพไหลตามเนื้อหา
 * (จอแคบถ้าเอาการ์ดทับวิดีโอ จะเหลือวิดีโอให้เห็นแค่ขอบบาง ๆ)
 */
@media (max-width: 767px) {
	.cs-animal-popup {
		/* dialog:modal ของ UA ตั้ง inset:0 ไว้ ถ้า height:auto กล่องจะยืดเต็ม 85vh
		   fit-content ทำให้สูงตามเนื้อหาจริง */
		min-height: 0;
		height: fit-content;
		max-height: 90vh;
		/* วิดีโออยู่ใน flow แล้ว เลื่อนดูได้ทั้งก้อนถ้าข้อความไทยยาวเกินจอ */
		overflow-y: auto;
	}

	/* เลิกเป็น flex ที่วางการ์ดทับวิดีโอ — ให้ไหลเป็นบล็อกซ้อนกันแทน */
	.cs-animal-popup__inner {
		display: block;
		padding: 0;
	}

	/*
	 * ดึงวิดีโอออกจาก position:absolute กลับเข้า flow
	 * 5:4 = สัดส่วนที่วัดได้จากหน้ามือถือต้นฉบับ SG (373x297)
	 */
	.cs-animal-popup .cs-video-bg {
		position: relative;
		inset: auto;
		width: 100%;
		aspect-ratio: 5 / 4;
	}


	.cs-animal-popup__window-wrap {
		width: 100%;
		min-width: 0;
		max-width: 100%;
	}

	.cs-animal-popup__pointer {
		display: none;
	}

	.cs-animal-popup__content {
		padding: 1.5rem 1.25rem 2rem;
	}

	/* จอแคบมีที่ให้ตัวอักษรใหญ่ขึ้นได้ — ต้นฉบับ SG ก็ขยายตรงนี้ */
	.cs-animal-popup__name-en {
		font-size: 1.75rem;
	}

	.cs-animal-popup__sci {
		margin-top: 0.35rem;
		font-size: 1rem;
	}

	.cs-animal-popup__desc {
		font-size: 1rem;
	}
}

/* ============================================================
   8ก½. WILDLIFE PRODUCTS (carousel เลื่อนแนวนอน)
   ============================================================ */

/*
 * กล่อง carousel — marquee.js สั่งเลื่อนเองด้วย scrollLeft เท่านั้น
 * ผู้ใช้เลื่อน/ลากเองไม่ได้ (overflow: hidden ยังสั่งเลื่อนด้วย JS ได้ตามปกติ)
 * scroll-behavior: auto กัน smooth ของ html มาแทรกตอนดีดตำแหน่งเวลาวนลูป
 */
.cs-products__scroll {
	overflow: hidden;
	scroll-behavior: auto;
	/* กันข้อความ/รูปถูกไฮไลต์ระหว่างลาก — ต้นฉบับ SG ไม่ได้ตั้ง cursor เป็นรูปมือ */
	user-select: none;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.cs-products__scroll::-webkit-scrollbar {
	display: none;
}

/*
 * display: flex (ไม่ใช่ inline-flex) เพื่อให้ track กว้างเท่ากล่องแบบชัดเจน
 * การ์ดจึงคิดความกว้างเป็น % ของกล่องได้ = โชว์ครบ 4 ใบพอดีทุกขนาดจอ
 * ไม่ใส่ padding ซ้าย-ขวา เพราะ 4 ใบต้องพอดีขอบกล่อง (มือถือใส่คืนด้านล่าง)
 */
.cs-products__track {
	display: flex;
	/* marquee.js ขยับด้วย transform — บอกเบราว์เซอร์ล่วงหน้าให้เตรียม layer ไว้ */
	will-change: transform;
	/* 20px — ตรงกับ spaceBetween ของ Swiper ต้นฉบับ */
	gap: 1.25rem;
	padding: 0.5rem 0 1.5rem;
}

/* การ์ด = รูปล้วน ๆ ไม่มีขอบ/มุมโค้ง/พื้นหลัง เพราะรูปมีกรอบมาในไฟล์อยู่แล้ว */
.cs-product-card {
	flex-grow: 0;
	flex-shrink: 0;
	/* 4 ใบ + ช่องไฟ 3 ช่อง (1.25rem × 3 = 3.75rem) — ย่อได้ถึง 220px แล้วหยุด */
	flex-basis: max(220px, calc((100% - 3.75rem) / 4));
}

.cs-product-card__thumb {
	display: block;
	/* สัดส่วนรูปตามที่กำหนด 260 x 162 px (≈16:10) — วัดจากการ์ดต้นฉบับ SG */
	aspect-ratio: 260 / 162;
	background: var(--cs-dark);
}

.cs-product-card__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/*
	 * กันลากรูปออกไปวางที่อื่น/แท็บอื่น
	 * pointer-events: none ทำให้เมาส์ทะลุไปโดนการ์ดแทน เมนูคลิกขวาเลยไม่ขึ้น
	 * "บันทึกรูปภาพเป็น..." ให้ด้วย
	 * ⚠️ กันได้แค่การลาก/คลิกขวาแบบง่าย ๆ ไฟล์รูปยังเปิดตรง URL ได้อยู่เสมอ
	 */
	-webkit-user-drag: none;
	user-select: none;
	pointer-events: none;
}

/* ยังไม่มีรูป — แสดงพื้นผิวเรียบแทนกรอบว่างเปล่า */
.cs-product-card__thumb--empty {
	background: linear-gradient(135deg, rgb(255 255 255 / 6%), rgb(255 255 255 / 0%));
}

/*
 * จำนวนการ์ดต่อหน้าจอ — ไล่ตามต้นฉบับ SG
 *   จอใหญ่ 4 ใบ (สูตรหลักด้านบน) / iPad แนวตั้ง 2 ใบ / มือถือ 1 ใบ
 * ตัวหารคือจำนวนใบ ส่วนที่ลบออกคือช่องไฟรวม (1.25rem = 20px ต่อช่อง)
 */

/* iPad แนวตั้ง (768-1024) — 2 ใบ */
@media (max-width: 1024px) {
	.cs-product-card {
		flex-basis: calc((100% - 1.25rem) / 2);
	}
}

/*
 * มือถือ — 1 ใบเต็มกรอบ ไม่ให้ใบถัดไปโผล่
 *
 * วัดจาก Swiper ของต้นฉบับ SG ที่ 390px: slidesPerView = 1 และสไลด์กว้าง 311px
 * เท่ากับกรอบ 311px พอดี = เต็มกรอบ ไม่มีขอบโผล่
 *
 * ⚠️ ต้อง 100% เท่านั้น แคบกว่านี้ไม่ได้ เพราะการ์ดเรียงติดกันใน flex
 *    พอการ์ดแคบกว่ากรอบ ใบถัดไปจะโผล่เข้ามาทันที
 * และต้องตัด padding-inline ของ track ทิ้ง ไม่งั้นช่องไฟ 20px จะน้อยกว่า padding 24px
 *    ใบถัดไปจะเบียดเข้ามาให้เห็นอีก 4px
 *    (ระยะห่างจากขอบจอยังมี เพราะ .cs-container มี gutter ของตัวเองอยู่แล้ว)
 */
@media (max-width: 767px) {

	/*
	 * เว้นขอบซ้าย-ขวาให้เท่าต้นฉบับ SG (กรอบเริ่มที่ x=40 ในจอ 390 = ข้างละ 40px)
	 * .cs-container ให้มาแล้ว 16px จึงเติมอีกข้างละ 24px
	 *
	 * ⚠️ ต้องใส่ที่กรอบ (scroller) ไม่ใช่ที่ track — track อยู่ข้างในกรอบ
	 *    ถ้าใส่ padding ที่ track ขอบใบถัดไปจะโผล่กลับมาอีก
	 */
	.cs-products__scroll {
		margin-inline: 1.5rem;
	}

	.cs-products__track {
		padding-inline: 0;
	}

	.cs-product-card {
		flex-basis: 100%;
	}
}

/* ============================================================
   8ข. YOUTUBE EMBED (คลิกเล่นเอง — ต่างจาก video-bg ที่ autoplay)
   ============================================================ */
.cs-video-embed-wrap {
	max-width: 900px;
	margin-inline: auto;
}

.cs-video-embed {
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	border-radius: 8px;
	background: var(--cs-dark);
}

.cs-video-embed__poster {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cs-video-embed__play {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
	padding: 0;
	background: rgb(0 0 0 / 15%);
	border: 0;
	cursor: pointer;
	transition: background 0.2s;
}

/*
 * ปกติดึง thumbnail จริงได้ผ่าน Open Graph (cs_get_facebook_thumbnail)
 * พื้นหลังเข้มนี้เป็นแค่สีรองพื้นตอนรูปกำลังโหลด หรือ fallback ตอนดึง thumbnail ไม่สำเร็จ
 * (เช่น URL ผิด, Facebook เปลี่ยนโครงสร้างหน้า, หรือ network error)
 * — ตอน fallback จะไม่มี <img>, เห็นแค่ไอคอน Facebook ลอยอยู่กลางกล่องแทน
 */
.cs-video-embed--facebook {
	background: var(--cs-dark);
}

.cs-video-embed--facebook .cs-video-embed__play {
	/*
	 * ⚠️ เดิมตั้ง position:static ไว้ ทำให้หลุดจากกฎ position:absolute;inset:0
	 * ของ .cs-video-embed__play ฐาน (ที่ทำให้กึ่งกลางเต็มกล่องผ่าน place-items:center)
	 * ปุ่มเลยไปเกาะมุมบนซ้ายแทนที่จะอยู่กลางกล่อง — คง position:absolute;inset:0 ไว้
	 * แค่เปลี่ยน display เป็น flex column เพื่อวางไอคอน Facebook ซ้อนเหนือปุ่ม play
	 * ตอน fallback (ไม่มี poster) — ถ้ามี poster จริงจะมีแค่ปุ่ม play ตัวเดียว
	 * ใช้ layout เดียวกันได้เลยเพราะ flex column กับ child เดียวก็ยังกึ่งกลางถูกต้อง
	 */
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1rem;
}

.cs-video-embed--facebook .cs-video-embed__play:hover .cs-video-embed__fb-icon,
.cs-video-embed--facebook .cs-video-embed__play:focus-visible .cs-video-embed__fb-icon {
	transform: scale(1.08);
}

.cs-video-embed__fb-icon {
	transition: transform 0.2s;
}

.cs-video-embed__play:hover,
.cs-video-embed__play:focus-visible {
	background: rgb(0 0 0 / 35%);
}

.cs-video-embed__play svg {
	width: clamp(48px, 8vw, 68px);
	height: auto;
	filter: drop-shadow(0 2px 8px rgb(0 0 0 / 40%));
}

.cs-video-embed iframe {
	width: 100%;
	height: 100%;
	border: 0;
}

/* ============================================================
   8ค. MEDIA GRID
   ============================================================ */
/* บล็อกที่ซ้อนอยู่ใต้ Video ในกล่องเดียวกัน — เว้นระยะห่างจากด้านบนเอง */
.cs-media-section {
	margin-block-start: var(--cs-section-y);
}

.cs-media-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.5rem;
}

.cs-media-card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid rgb(255 255 255 / 15%);
	border-radius: 8px;
	background: rgb(0 0 0 / 35%);
	color: var(--cs-white);
	text-decoration: none;
	transition: border-color 0.2s, transform 0.2s;
}

.cs-media-card:hover,
.cs-media-card:focus-visible {
	border-color: var(--cs-yellow);
	transform: translateY(-3px);
	text-decoration: none;
}

/*
 * บล็อก Media Features อยู่บน section พื้นขาว (cs-section--light)
 * การ์ดแบบพื้นดำโปร่งแสงเดิมออกแบบไว้สำหรับพื้นเข้ม ใช้บนพื้นขาวไม่ได้
 * override เฉพาะตอนอยู่ในบริบทนี้ ให้เหลือแค่รูป + ข้อความเปล่า ๆ ตามต้นฉบับ
 * (ไม่แก้ .cs-media-card ตรง ๆ เผื่ออนาคตเอาไปใช้ในที่ที่พื้นเข้มอีก)
 */
.cs-section--light .cs-media-card {
	border-color: transparent;
	background: transparent;
	color: var(--cs-dark);
}

.cs-section--light .cs-media-card:hover,
.cs-section--light .cs-media-card:focus-visible {
	border-color: transparent;
}

.cs-media-card__thumb {
	display: block;
	aspect-ratio: 16 / 10;
	border-radius: 20px;
	/* ตัดพื้นหลังให้โค้งตามรูป ไม่งั้นสีพื้นจะโผล่เป็นขอบดำที่มุม */
	overflow: hidden;
	background: var(--cs-dark);
}

/*
 * ขอบมนของรูปข่าว — 20px เท่าต้นฉบับ SG (วัดจาก computed style ของรูปข่าวเขา)
 *
 * ⚠️ ต้องใส่ที่ตัว img เอง ไม่ใช่แค่ที่กล่องครอบ
 *    กล่องครอบเป็น overflow: visible รูปข้างในจึงไม่ถูกตัดมุมตาม
 *    (ก่อนหน้านี้ตั้ง radius ไว้ที่กล่องอย่างเดียว รูปเลยออกมามุมเหลี่ยม)
 */
.cs-media-card__thumb img {
	width: 100%;
	height: 100%;
	border-radius: 20px;
	object-fit: cover;
}

/* ยังไม่มีรูป — แสดงพื้นผิวเรียบแทนกรอบว่างเปล่า */
.cs-media-card__thumb--empty {
	background: linear-gradient(135deg, rgb(255 255 255 / 6%), rgb(255 255 255 / 0%));
}

.cs-media-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1rem 1.1rem 1.25rem;
}

.cs-media-card__title {
	font-size: 0.95rem;
	font-weight: 600;
	line-height: 1.5;
}

/* ============================================================
   9. STAT GRID
   ============================================================ */
.cs-stats {
	display: grid;
	/*
	 * ความกว้างขั้นต่ำต่อคอลัมน์ — คุมว่าจะเรียงได้กี่ใบต่อแถว
	 *
	 * ⚠️ 200px และ 170px เคยทำให้ใบที่ 4 ตกลงไปอยู่แถวล่าง
	 *    วัดจริง: iPad mini แนวตั้ง 768px พื้นที่ในกริดเหลือ 707px
	 *    4 ใบที่ 170px ต้องใช้ 170x4 + ช่องไฟ 20x3 = 740px → ไม่พอ เหลือ 3 คอลัมน์
	 *    160px ใช้ 160x4 + 60 = 700px → พอดีกับ 707px
	 *    (ที่จอกว้างขึ้นการ์ดยืดเต็มพื้นที่เองเพราะ 1fr ไม่ได้ติดอยู่ที่ 160px)
	 */
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 2rem;
	text-align: center;
}

/*
 * ไอคอนเหนือข้อความ — ใช้เฉพาะบล็อก "สรุปผลการดำเนินงาน" (ไม่บังคับ ถ้าไม่ใส่ก็ไม่แสดง)
 *
 * กล่องรูป 170x113 เท่า SG — แต่ไฟล์ไอคอน (ทั้งของ SG และของเรา) มีพื้นที่โปร่งใสรอบลายเส้น
 * ลายเส้นกินแค่ราว 52% ของความกว้าง วัดพิกเซลจริงที่ 390px:
 *   SG  กล่อง 170x113 → ลายเส้นที่ตาเห็น 88x87
 *   เรา กล่อง 170x113 → ลายเส้นที่ตาเห็น 88x87  (เท่ากัน)
 *   เรา กล่อง  86x57  → ลายเส้นที่ตาเห็น 44x45  (ครึ่งเดียวของ SG)
 * ⚠️ ถ้าอยากให้ไอคอนที่ตาเห็นเล็ก/ใหญ่ขึ้น ต้องคิดจากลายเส้น ไม่ใช่จากกล่อง
 */
.cs-stat__icon {
	width: 170px;
	height: auto;
	margin: 0 auto 1.25rem;
}

/*
 * คลิปประกอบเหนือตัวเลขในบล็อก "ผลงานที่ผ่านมา"
 *
 * ต้นฉบับ SG: วิดีโอ 265x149 (16:9) object-fit: cover
 * มุมมน 20px อยู่ที่กล่องครอบ + overflow: hidden ไม่ได้อยู่ที่ <video> เอง
 * เว้นใต้คลิปถึงตัวเลข 20px
 *
 * ⚠️ ต้องใส่มุมมนที่กล่องครอบ ไม่ใช่ที่ <video>
 *    Safari ไม่ยอมตัดมุมของ <video> ให้ ถึงจะตั้ง border-radius ไว้ก็ตาม
 */
.cs-stat__video {
	/* กดได้ — ของ SG ก็เป็นเมาส์รูปมือเหมือนกัน เพราะต้องกดเองถึงจะเล่น */
	cursor: pointer;
	margin-block-end: 20px;
	border-radius: 20px;
	overflow: hidden;
	aspect-ratio: 16 / 9;
	/* กันหน้ากระตุกตอนคลิปยังโหลดไม่เสร็จ — จองที่ไว้เป็นสีจาง ๆ ก่อน */
	background: rgb(255 255 255 / 6%);
}

.cs-stat__video video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* กล่องแม่รับคลิกแทน ไม่ให้วิดีโอขโมยโฟกัสไป */
	pointer-events: none;
}

/* เห็นชัดว่าโฟกัสอยู่ใบไหนตอนใช้คีย์บอร์ด — ต้นฉบับ SG กดด้วยคีย์บอร์ดไม่ได้เลย */
.cs-stat__video:focus-visible {
	outline: 2px solid var(--cs-yellow);
	outline-offset: 3px;
}

.cs-stat__value {
	margin: 0;
	font-size: clamp(2.25rem, 6vw, 3.5rem);
	font-weight: 600;
	line-height: 1.1;
	color: var(--cs-yellow);
}

.cs-stat__label {
	margin-block-start: 0.5rem;
	font-size: 0.95rem;
}

/*
 * ประโยคสถิติของบล็อก "สรุปผลรายปี" — ตัวเลขรวมอยู่ในประโยคเดียวกับข้อความ
 * ตามต้นฉบับ SG (วัดได้ 32px/400/ขาว/uppercase/line-height 1)
 * ⚠️ ห้ามไปแก้ .cs-stat__value แทน เพราะคลาสนั้นใช้ร่วมกับบล็อก "ผลงานที่ผ่านมา"
 *    ซึ่งต้นฉบับ SG ก็ใช้ตัวเลขใหญ่จริง ๆ (22 / 650+ / 33,400+ / 465)
 */
.cs-stat__line {
	margin: 0;
	font-size: clamp(1.25rem, 2.3vw, 2rem);
	font-weight: 600;
	line-height: 1.15;
	color: var(--cs-white);
}

/* หมายเหตุใต้ประโยค — เดิมไม่มี CSS เลยทั้งที่ template เรียกใช้มาตลอด */
.cs-stat__note {
	margin-block-start: 0.75rem;
	font-size: 0.9rem;
	line-height: 1.5;
	color: rgb(255 255 255 / 80%);
}


/* มือถือ: ตัวเลขสถิติแถวละ 1 อัน เหมือนต้นฉบับ SG (จอแคบ 2 คอลัมน์อ่านอึดอัด) */
@media (max-width: 767px) {
	.cs-stats {
		grid-template-columns: 1fr;
	}
}

/*
 * บล็อก "ผลงานที่ผ่านมา" ให้เหมือนต้นฉบับ SG — ขอบเขตเฉพาะบล็อกนี้
 * บล็อก "สรุปผลการดำเนินงาน" ใช้ .cs-stats เหมือนกันแต่หน้าตาคนละแบบ ไม่ให้โดนไปด้วย
 *
 * ค่าที่วัดจาก SG ที่ 1400px:
 *   ช่องไฟระหว่างใบ 20px | คลิป→ตัวเลข 20px | ตัวเลข→ป้าย 20px
 *   ตัวเลข 50px w600 line-height 1 (เท่ากันทุกขนาดจอ รวมมือถือ)
 *   ป้าย   32px w400 สีขาว
 */
.cs-stats--highlights {
	column-gap: 20px;
}

.cs-stats--highlights .cs-stat__value {
	font-size: 50px;
	/* ตัวเลขไม่มีสระบน-ล่าง ใช้ 1 เท่า SG ได้โดยไม่ชน */
	line-height: 1;
}

.cs-stats--highlights .cs-stat__label {
	margin-block-start: 20px;
	/* SG ใช้ 32px — WWF ขอลดเหลือ 28px เพราะ Prompt ตัวใหญ่กว่าฟอนต์บีบของ SG */
	font-size: 28px;
	font-weight: 400;
	/*
	 * SG ใช้ line-height 1 แต่ป้ายภาษาไทยมีสระบน-ล่าง ถ้าบีบเท่านั้นบรรทัดที่ 2 จะชน
	 * ใช้ 1.3 แทน
	 */
	line-height: 1.3;
	/*
	 * แบ่งบรรทัดให้ยาวใกล้เคียงกัน — ไม่งั้นเบราว์เซอร์ยัดบรรทัดแรกจนเต็มแล้วเหลือคำเดียว
	 * ตกบรรทัดสอง เช่น "คำค้นหาใหม่ที่ค้น / พบ" ตัดคำว่า ค้นพบ ขาดกลางคำ
	 * เบราว์เซอร์ที่ยังไม่รองรับจะตัดบรรทัดแบบปกติ ไม่พัง
	 */
	text-wrap: balance;
}

/*
 * แท็บเล็ต (768-960): เรียง 4 ใบต่อแถวเหมือน SG แต่การ์ดแคบกว่าเดสก์ท็อปมาก (162-200px)
 * ป้ายกำกับ 28px ตก 3 บรรทัด ส่วน SG อยู่ 2 บรรทัด — วัดจำนวนบรรทัดของป้ายที่ยาวที่สุด:
 *   768px การ์ด 162: 24px → 3 บรรทัด  22px → 2 บรรทัด
 *   800px การ์ด 169: 24px → 3 บรรทัด  22px → 2 บรรทัด
 *   900px การ์ด 192: 26px → 2 บรรทัด
 *  1000px การ์ด 215: 28px → 2 บรรทัด (ไม่ต้องลด)
 * ใช้ 22px ทั้งช่วง เพื่อให้ขนาดไม่กระโดดตอนหมุนจอ
 *
 * ⚠️ ต้องอยู่ "หลัง" กฎ .cs-stats--highlights .cs-stat__label ของเดสก์ท็อป
 *    น้ำหนัก selector เท่ากัน (media query ไม่เพิ่มน้ำหนัก) อันที่อยู่หลังเท่านั้นถึงจะชนะ
 */
@media (min-width: 768px) and (max-width: 960px) {
	.cs-stats--highlights .cs-stat__label {
		font-size: 22px;
	}
}

/*
 * วัดจำนวนบรรทัดของป้ายที่ยาวที่สุด (ช่องไฟ 20px แล้ว):
 *   1400px ใบกว้าง 261: 28px → 2 บรรทัด
 *   1024px ใบกว้าง 221: 28px → 2 บรรทัด  (ไม่ต้องมี media query แยก)
 *    390px ใบกว้าง 358: 28px → 2 บรรทัด  26px → 1 บรรทัด (SG มือถือ 1 บรรทัด)
 * ⚠️ ถ้า WWF แก้ป้ายให้ยาวขึ้น ให้วัดใหม่
 */
@media (max-width: 767px) {

	/*
	 * มือถือให้เหมือน SG (วัดที่ 390px):
	 *   คลิปกว้าง 370 เว้นขอบจอ 10px — กล่องเนื้อหาของเราเว้น 16px จึงดึงออกข้างละ 6px
	 *   ป้ายของใบบน → คลิปใบถัดไป 20px (เดิม 58px = ช่องแถว 32px + ขอบล่างของ <p> 26px)
	 */
	.cs-stats--highlights {
		margin-inline: -6px;
		row-gap: 20px;
	}

	/*
	 * WWF ขอลดขนาดบนมือถือ — ป้าย 26px ใหญ่กว่าหัวข้อ section (20px) ดูเกินไป
	 * ตัวเลข 50px → 40px และป้าย 26px → 20px (ไม่เกินขนาดหัวข้อ)
	 */
	.cs-stats--highlights .cs-stat__value {
		font-size: 40px;
	}

	.cs-stats--highlights .cs-stat__label {
		font-size: 20px;
		margin-block-end: 0;
	}
}

/* ============================================================
   10. PROSE (บล็อกข้อความยาว)
   ============================================================ */
.cs-prose {
	max-width: 68ch;
	margin-inline: auto;
}

.cs-prose h2 {
	font-size: clamp(1.4rem, 3.5vw, 2rem);
	margin-block-start: 2.5rem;
}

.cs-prose h2:first-child {
	margin-block-start: 0;
}

/*
 * บล็อก "เกี่ยวกับโครงการ" — 2 คอลัมน์ รูปซ้อนกันทางซ้าย ข้อความทางขวา
 * สัดส่วน 550 : 509 และช่องไฟ 57px วัดจากหน้าเว็บจริงของ SG
 *
 * ใส่คลาสนี้เฉพาะตอนมีรูปอย่างน้อย 1 ใบ (ดู about.php)
 * ถ้ายังไม่ได้อัปรูป จะกลับไปเป็นคอลัมน์เดียวแบบ .cs-prose ปกติ ไม่เหลือช่องโหว่
 */
.cs-about {
	display: grid;
	grid-template-columns: 550fr 509fr;
	gap: 3.5rem;
	align-items: start;
}

.cs-about__media {
	display: grid;
	gap: 1.5rem;
}

/*
 * รูปค้างอยู่กับที่ตอนเลื่อนอ่านข้อความ แล้วหยุดค้างเองเมื่อจบ section
 * ตรงกับต้นฉบับ SG ที่ตั้ง Elementor sticky: {"sticky":"top","sticky_offset":60,
 * "sticky_parent":"yes","sticky_on":["desktop"]}
 *
 * position: sticky ทำได้ครบทั้ง 3 อย่างโดยไม่ต้องใช้ JS:
 *   - ค้างที่ top ที่กำหนด
 *   - หยุดค้างเองเมื่อถึงขอบล่างของ grid ที่ครอบอยู่ (= sticky_parent)
 *   - เปิดเฉพาะ desktop ด้วย media query (= sticky_on)
 *
 * ⚠️ ถ้ามี ancestor ตัวไหนตั้ง overflow: hidden sticky จะใช้ไม่ได้ทันที
 */
@media (min-width: 768px) {
	.cs-about__media {
		position: sticky;
		/* ต้นฉบับใช้ 60px — ของเราเผื่อความสูง navbar ที่ค้างบนจอด้วย */
		top: calc(var(--cs-nav-height) + 1rem);
	}
}

/* ต้นฉบับ SG ใช้รูปมุมเหลี่ยม (radius 0) ต่างจากรูปข่าวที่มน 20px */
.cs-about__figure {
	width: 100%;
	height: auto;
}

/* ยกเลิก max-width 68ch ของ .cs-prose เพราะคอลัมน์คุมความกว้างให้แล้ว */
.cs-about__body {
	max-width: none;
	margin-inline: 0;
}

/* ต้นฉบับ 30px น้ำหนัก 100 แต่เราโหลด Prompt มาแค่ 300;400;600 จึงใช้ 300 ซึ่งบางสุดที่มีจริง */
.cs-about__body h2 {
	font-size: clamp(1.5rem, 2.2vw, 1.875rem);
	font-weight: 300;
	line-height: 1.15;
}

.cs-about__body p {
	font-size: 1rem;
}

/*
 * ตัวหนาที่ WWF กดปุ่ม B ในหน้าแก้ไข ต้องหนาจริงบนหน้าเว็บ
 *
 * ⚠️ ห้ามลบ — ปัญหาที่เคยเจอ:
 *    หัวข้อตั้งไว้บาง (300) ตามต้นฉบับ SG ส่วน <strong> ของเบราว์เซอร์ใช้ font-weight: bolder
 *    ซึ่งแปลว่า "หนากว่าแม่หนึ่งขั้น" จาก 300 ขึ้นไปได้แค่ 400 ตาเปล่าแทบไม่ต่าง
 *    WWF กดตัวหนาในแอดมินแล้วหน้าเว็บยังบางเหมือนเดิม
 *    ใช้ 600 เพราะเป็นน้ำหนักที่หนาที่สุดที่โหลด Prompt มาจริง (300;400;600)
 */
.cs-about__body strong,
.cs-about__body b {
	font-weight: 600;
}

/* มือถือ: รูปกับข้อความเรียงลงมาเป็นคอลัมน์เดียว */
@media (max-width: 767px) {
	.cs-about {
		grid-template-columns: 1fr;
	}
}

/* ============================================================
   11. PLACEHOLDER BANNER
   เตือนว่าเนื้อหาปัจจุบันยังเป็นข้อมูลของสิงคโปร์
   ลบทิ้งเมื่อได้เนื้อหาจริงจาก WWF แล้ว
   ============================================================ */
.cs-placeholder-notice {
	padding: 0.75rem var(--cs-gutter);
	background: var(--cs-red);
	color: var(--cs-white);
	font-size: 0.85rem;
	text-align: center;
}

/* ============================================================
   12. FOOTER
   ============================================================ */
.cs-footer {
	padding-block: 3rem;
	background: var(--cs-footer);
}

/*
 * เลย์เอาต์แนวนอน โลโก้ซ้าย ข้อความขวา ชิดซ้ายทั้งหมด
 * วัดจากต้นฉบับ SG: โลโก้ 120x144 ที่ x=199 และข้อความเริ่มที่ x=399
 */
.cs-footer__inner {
	display: flex;
	align-items: flex-start;
	gap: clamp(1.5rem, 4vw, 3rem);
}

.cs-footer__logo {
	flex: 0 0 auto;
	width: 120px;
	height: auto;
	background-color: #fff;
}

.cs-footer__text {
	flex: 1;
}

/*
 * ⚠️ ต้นฉบับใช้ font-weight 100 แต่เราโหลด Prompt มาแค่ 300;400;600
 *    ถ้าใส่ 100 เบราว์เซอร์จะไปสังเคราะห์เองแล้วตัวหนังสือจะเพี้ยน ใช้ 300 ซึ่งบางสุดที่มีจริง
 * text-transform: uppercase ไม่มีผลกับภาษาไทย ใส่ไว้เผื่อข้อความอังกฤษ
 */
.cs-footer__tagline {
	margin: 0 0 0.75rem;
	/*
	 * 36px เท่าต้นฉบับ SG (วัดได้ทั้งที่ 390 และ 1400)
	 * บนมือถือลดเหลือ 28px — ดูใน media query ท้ายส่วน footer
	 */
	font-size: 2.25rem;
	font-weight: 300;
	/*
	 * ต้นฉบับใช้ line-height 1.0 พอดีเป๊ะกับความสูงตัวอักษร
	 * แต่ภาษาไทยมีสระบน-ล่างซ้อนออกมานอกตัวอักษร ถ้าบีบเท่านั้นสระจะชนกันเอง
	 * ระหว่างบรรทัด — ใช้ 1.15 ซึ่งยังแน่นแต่ไม่ชน
	 */
	line-height: 1.15;
	text-transform: uppercase;
}

.cs-footer__legal {
	margin: 0 0 0.5rem;
	font-size: 1rem;
	line-height: 1.5;
	/* SG ใช้สีเทาทึบ rgb(122,122,122) ไม่ใช่ขาวโปร่งแสง — บนพื้น #333 สองแบบนี้ออกมาไม่เท่ากัน */
	color: var(--cs-grey);
}

.cs-footer__pdpa {
	margin: 0;
}

/*
 * ต้นฉบับใช้ลิงก์สีแดงอมชมพู ไม่ใช่เหลืองเหมือนลิงก์อื่นในเว็บ
 * และไม่ใช่ --cs-red (#ff0000) ที่เป็นสีเน้นคำของแบรนด์
 *
 * ⚠️ สีนี้บนพื้น #222 ได้ contrast ราว 2.5:1 ต่ำกว่าเกณฑ์ WCAG AA (4.5:1)
 *    ของ SG เองก็ต่ำเท่ากัน — เลือกตามต้นฉบับ ไม่ได้เลือกตามเกณฑ์
 */
.cs-footer__pdpa a {
	color: var(--cs-link);
}

/* มือถือ: เรียงลงมาเป็นแนวตั้ง โลโก้อยู่กึ่งกลาง ข้อความยังชิดซ้าย
   (ต้นฉบับ SG ที่ 390px: โลโก้ 120x144 อยู่ที่ x=135 ในกล่องกว้าง 331 = กึ่งกลาง) */
@media (max-width: 767px) {
	.cs-footer__inner {
		flex-direction: column;
	}

	.cs-footer__logo {
		align-self: center;
	}

	/*
	 * ต่างจาก SG โดยตั้งใจ — ของเขาใช้ 36px บนมือถือด้วย
	 * แต่ข้อความไทยยาวกว่า ที่ 36px ตัดเป็น 3 บรรทัดและเหลือที่ว่างขวามือเยอะ
	 * วัดแล้ว 28px คือขนาดใหญ่สุดที่ยังลงได้ 2 บรรทัดครบทุกจอ
	 *   360px: 30px→3 บรรทัด  28px→2 บรรทัด
	 *   390px: 34px→3 บรรทัด  32px→2 บรรทัด
	 *   430px: 36px→3 บรรทัด  34px→2 บรรทัด
	 * ⚠️ ถ้าแก้ข้อความ tagline ให้วัดใหม่ ข้อความยาวขึ้นอาจกลับไป 3 บรรทัด
	 */
	.cs-footer__tagline {
		font-size: 1.75rem;
	}
}