จานสีสองระดับกับธีม
styles/tokens.css เก็บทุกสีที่สไตล์ชีตและคอมโพเนนต์ใช้ — ข้อยกเว้นเดียวคือคู่โทนสีของ domain ซึ่งทะเบียนของไซต์ส่งเข้ามาเป็นข้อมูล ไฟล์นี้เขียนเป็นสองระดับ — จานสีดิบ ของเม็ดสีแบบกระดาษกับหมึก และ โทเคนเชิงความหมาย ที่สร้างทับบนมัน — และระดับเชิงความหมายยังแบ่งเป็นสองบริบท เพราะวิกิมีหน้าอยู่สองชนิด: คอลัมน์ที่คุณนั่งอ่าน กับชั้นหนังสือที่คุณกวาดตาเลือก
§1.1ระดับที่หนึ่ง: เม็ดสี
จานสีดิบคือกล่องสีของจิตรกร ไม่ขึ้นกับธีม ตั้งชื่อว่า --p-* กระดาษ: พื้นฝั่งเลือกดู 纸 กับหน้าการ์ดของมัน 页, พื้นฝั่งอ่าน 素 (เย็นกว่าหนึ่งขั้น อ่านนาน ๆ แล้วสบายตากว่า) กับผิวนุ่มของมัน 帛, การ์ดขาว, พื้นโค้ดและพื้นสูตรคณิตศาสตร์ หมึก: ชุดโทนอุ่นสำหรับชั้นหนังสือ กับชุดโทนกลางสำหรับคอลัมน์อ่าน อย่างละสามระดับความเข้ม เส้นเข้าเล่ม: เส้นหนาของชั้นหนังสือ ขอบเม็ดยา และเส้นผมสองเส้น แล้วก็ เม็ดสี — สีที่แบกความหมาย:
--p-zhu: #7d3a3a; /* 朱 · แดงไวน์ — สีเน้นฝั่งเลือกดู ตราของไซต์ */
--p-shi: #b6552e; /* 石 · ส้มไหม้ — สีเน้นฝั่งอ่าน: ลิงก์ ตัวเลข kicker */
--p-shi-text: #8f3f1f; /* 石 · ขั้นสำหรับตัวอักษรเล็ก (ผ่าน AA บนสีจาง ๆ ของตัวมันเอง) */
--p-zhe: #c08a2c; /* 赭 · เหลืองดิน — เส้นและเส้นขอบ */
--p-dai: #2a6f6b; /* 黛 · เขียวหัวเป็ด — สีเน้นรองของเนื้อหา */
--p-zi: #6b4ec4; /* 紫 · ม่วง — ความหมายเชิง "ระบบ" */บวกด้วยชุด กลางคืน สำหรับฉบับมืด: พื้นสีโพล้เพล้ หมึกขาวจันทร์ และคู่แฝดที่ปรับสว่างขึ้นของเม็ดสีทุกเม็ด
§1.2สองบริบท จานสีเดียว
ระดับที่สองคือสิ่งที่ชั้นคอมโพเนนต์นำไปใช้ และมันมีสองหน้า:
| บริบท | โทเคน | พื้น | หมึก | สีเน้น | อยู่ที่ไหน |
|---|---|---|---|---|---|
| คอลัมน์อ่าน | --color-* | 素 #fbf9f4 | โทนกลาง #1f2024 | 石 ส้มไหม้ | หน้าบันทึก คอมโพเนนต์เนื้อหาทุกตัว base.css |
| ชั้นหนังสือ | --wb-* | 纸 #faf6ec | โทนอุ่น #2b2622 | 朱 แดงไวน์ | หน้าแรกและหน้าหมวดหมู่ คอมโพเนนต์วิกิ browse.css |
คอลัมน์อ่านคือฝั่งที่เงียบกว่า — คุณอยู่กับมันเป็นชั่วโมง ส่วนชั้นหนังสืออุ่นกว่าและเรียงด้วยเซอริฟแบบ display — คุณกวาดตาแล้วเลือกหยิบ หน้าหนึ่ง ๆ เข้าสู่บริบทชั้นหนังสือด้วยคลาสเดียวคือ wb-root บน body ของมัน ข้างในนั้นโทเคนของ chrome (--color-bg, --color-accent, …) ถูกจับคู่ใหม่ให้ชี้ไปยังค่าของชั้นหนังสือ แถบนำทางที่เขียนครั้งเดียวจึงวางบนพื้นทั้งสองแบบได้อย่างถูกต้อง — และอะตอมหมวดหมู่ (ตราประเภท จุดสถานะ ชิป domain) ซึ่งเขียนไว้กับ --color-* ก็กลมกลืนเป็นส่วนหนึ่งของคอลัมน์บนหน้าบันทึก และเป็นส่วนหนึ่งของชั้นหนังสือบนหน้าเลือกดู ชั้นคอมโพเนนต์ใช้ได้เฉพาะระดับที่สองเท่านั้น — ทั้ง base.css, browse.css และคอมโพเนนต์ทุกตัว ไม่มีกฎข้อไหนบรรจุค่าสีดิบ และไม่มีอะไร fallback ไปหาค่าสีดิบด้วย นี่คือวินัยเหล็กของแพ็กเกจ
§2.1ไซต์ปรับเอกลักษณ์อย่างไร
โอเวอร์ไรด์ระดับที่หนึ่ง เปลี่ยนเม็ดสีเป็นของคุณเอง แล้วทั้งสองบริบทกับชั้นคอมโพเนนต์ทั้งชั้นจะตามไปเอง เม็ดสีแต่ละเม็ดเป็น คู่กลางวัน/กลางคืน: ธีมสว่างอ่าน --p-shi กับ --p-zhu ส่วนธีมมืดอ่านคู่แฝดยามค่ำ --p-shi-n กับ --p-zhu-n — การโอเวอร์ไรด์เอกลักษณ์จึงตั้งทั้งคู่ หรือจะปล่อยให้ฝั่งมืดใช้เม็ดสีเดิมของแพ็กเกจก็ได้:
:root {
--p-shi: #b03a48; /* สีเน้นฝั่งอ่านของคุณ */
--p-shi-text: #93303c; /* ขั้นตัวอักษรเล็กปรับให้เข้มแยกต่างหาก ดูหัวข้อถัดไป */
--p-zhu: #3b4a7a; /* สีเน้นฝั่งชั้นหนังสือ และตราของไซต์ */
--p-shi-n: #e0919b; /* คู่แฝดยามค่ำ ปรับสว่างขึ้นสำหรับพื้นโพล้เพล้ */
--p-zhu-n: #9fb0e4;
}หากระบบออกแบบของคุณมีจานสีของตัวเองอยู่แล้ว การจับคู่ระดับที่สองใหม่ให้ชี้ไปยังจานสีนั้นก็รองรับเท่า ๆ กัน — ชี้ --color-* กับ --wb-* ไปที่ตัวแปรของคุณ สวนแห่งนี้จงใจไม่โอเวอร์ไรด์อะไรเลย: สิ่งที่คุณกำลังอ่านคือหน้าตาเปล่า ๆ ของแพ็กเกจ หน้าเดียวกับที่ กระดาษกับหมึก อธิบายเหตุผลไว้
§2.2คอนทราสต์ผ่านการวัดจริง
ค่าสีระดับตัวอักษรทุกค่าถูกตรวจกับ WCAG AA บนทุกพื้นผิวที่มันไปวางอยู่: ตัวอักษรเล็กเริ่มที่ 4.5:1 สีเน้นที่ใช้เป็นตัวอักษรเล็กจะได้ ขั้นตัวอักษร ที่ปรับเข้มแยกต่างหาก (--p-shi-text, --p-zhe-text) เพราะป้ายขนาด 12px สีเน้นมักไปนั่งอยู่บนพื้นจาง ๆ ของสีเน้นตัวเดียวกันนั้นเอง หมึกจางตั้งไว้ที่เฉดเข้มที่สุดที่ยังอ่านออกว่าจาง — #6a6d74 บนพื้นฝั่งอ่านได้ 4.9:1 และยังคง 4.5:1 บนผิวนุ่ม พื้นโค้ดสว่างกว่ากระดาษหนึ่งขั้นเพื่อให้โทเคนที่จางที่สุดของธีมไฮไลต์ (คอมเมนต์) ผ่าน 4.5:1 ส่วนฉบับมืดมีชุดสีปรับสว่างของตัวเอง วัดเทียบกับพื้นกลางคืนโดยตรง แพ็กเกจส่งการวัดนี้มาให้เป็นเครื่องมือด้วย: scripts/contrast_probe.mjs เรนเดอร์เดโมในเบราว์เซอร์จริง ทั้งสองธีมและสองความกว้าง เก็บตัวอย่างพื้นใต้ตัวอักษรทุกช่วงจากพิกเซลจริง แล้วรายงานทุกช่วงที่ต่ำกว่าเกณฑ์ (ตัววัดคอนทราสต์) ก่อนจะแก้ค่าไหน ให้รู้ก่อนว่ามันไปวางอยู่บนพื้นผิวใดบ้าง
§2.3ธีมสว่างคือเอกลักษณ์
ธีมของแพ็กเกจจงใจ ไม่ อ่าน prefers-color-scheme: หน้าเว็บต้องไม่พลิกธีมของตัวเองใต้สายตาผู้อ่านเด็ดขาด ธีมมืดทำงานผ่าน [data-theme='dark'] เท่านั้น สลับโดยสวิตช์ของไซต์เอง (ปุ่มพระอาทิตย์/พระจันทร์ทางขวาของแถบนำทางไซต์นี้ ตัวเลือกถูกเก็บใต้คีย์ inkstone-theme ใน localStorage และถูกสคริปต์อินไลน์ ThemeInit เล่นซ้ำก่อนการวาดหน้าจอครั้งแรก ผู้อ่านธีมมืดจึงไม่มีวันเห็นแฟลชสีครีม) ธีมมืดไม่ใช่การกลับสี แต่เป็นฉบับพิมพ์ที่สองซึ่งตั้งค่าด้วยมือทั้งชุด: พื้นโพล้เพล้ หมึกขาวจันทร์ เม็ดสีที่ปรับสว่างขึ้นใหม่ — ธีมมืดคือฉบับพิมพ์ที่สอง ไม่ใช่การกลับสี
§2.4ฟอนต์ก็อยู่ที่นี่ด้วย
สี่สแตก --font-display คือหน้าตาของชั้นหนังสือ — เซอริฟแบบ optical size (Source Serif 4 คู่กับ Noto Serif SC สำหรับอักษรจีน) ใช้กับแถบหัวเรื่องและชื่อบนชั้น เดโมนี้โฮสต์เองผ่าน @fontsource ไซต์ที่ไม่โฮสต์จะถอยไปใช้ฟอนต์ฝั่งอ่านแทน --font-body เป็นของคอลัมน์อ่าน — สแตกเซอริฟของระบบนำโดย Charter และ Iowan Old Style โดยมีฟอนต์ display เข้ามาแทนเมื่อสองตัวนั้นไม่มีในเครื่อง --font-ui คือ Inter (Noto Sans SC สำหรับอักษรจีน) ใช้กับหัวข้อ chrome และตัวพิมพ์เล็ก ๆ ส่วน --font-mono คือซับเซ็ตชุดอักขระตายตัวของ Maple Mono CN (ASCII + อักขระวาดกล่อง + อักษรจีนสามัญ 3500 ตัว + อักขระทั้งหมดที่เนื้อหามีอยู่จริง): อักษรละตินกว้าง 0.6em อักษรจีนกว้าง 1.2em — อักษรจีนหนึ่งตัวกว้างเท่ากับสองช่องอักขระพอดี ไดอะแกรมวาดกล่องจึงเรียงตรงแม้ในข้อความจีนปนละติน สูตรตัดซับเซ็ตและสคริปต์สร้างใหม่มากับแพ็กเกจ (fonts/build_font_subset.py) เมื่อเนื้อหาต้องใช้อักขระนอกชุด ให้รันใหม่แล้วคอมมิตไฟล์ woff2 กรอบโค้ด ทั้งหมดเรียงด้วยซับเซ็ตชุดนี้ล้วน ๆ