/* ============================================================
   墨讀 · Mặc Độc — landing
   Nền tối là mặt bàn. Vật SÁNG duy nhất trên trang là chính sản
   phẩm: tờ giấy demo và ảnh chụp app. Không thẻ trang trí nào
   sáng. Nhờ vậy tương phản mang thông tin — sáng là sản phẩm,
   tối là mọi thứ còn lại — chứ không phải để cho đẹp.
   ============================================================ */

/* ---------- chữ: TỰ HOST, đã cắt ----------
   Trước đây nạp từ Google Fonts và đo được ~810KB: tám tệp con Noto Serif SC
   để vẽ đúng 42 chữ Hán, cộng Newsreader đầy đủ. Nay ~149KB, và quan trọng
   không kém — mất luôn một tệp CSS bên thứ ba đang CHẶN VẼ TRANG cùng hai
   lượt preconnect. Tái tạo bằng `scripts/cat-font.sh`; giấy phép OFL của cả
   hai bộ chữ nằm ở `/font/OFL.txt`.
   `font-display: swap` giữ nguyên: chữ phải đọc được ngay, kể cả khi font
   chưa về. Đó cũng là lý do stack dự phòng phải là serif thật (Georgia),
   không phải `serif` chung chung. */
@font-face {
  font-family: "Newsreader";
  /* Còn nguyên trục opsz — mặt chữ này vẽ cả tiêu đề 83px lẫn thân bài 17px,
     nên `font-optical-sizing: auto` ở body có thứ để làm việc. */
  src: url("/font/newsreader-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  /* opsz ghim ở 16: mặt này chỉ dùng cho vài cụm in đậm cỡ ~17px. */
  src: url("/font/newsreader-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  /* Cắt hẹp về ASCII + nguyên âm có dấu thanh pinyin: bản nghiêng dùng ở ĐÚNG
     .kn-pinyin. Có test khoá điều đó — dùng nghiêng cho chữ tiếng Việt sẽ rơi
     về Georgia nghiêng ngay giữa câu. */
  src: url("/font/newsreader-italic-400.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Noto Serif SC";
  /* 42 chữ, giữ trục wght: 400 thân bài · 600 con dấu · 700 chữ hiệu. */
  src: url("/font/noto-serif-sc.woff2") format("woff2");
  font-weight: 200 900; font-style: normal; font-display: swap;
}

:root {
  /* mực & giấy — sắc ấm, lấy từ chính token của app rồi đảo vai */
  --muc:        #14120d;   /* nền: mực loãng trên mặt bàn tối */
  --muc-cao:    #1f1b14;   /* mặt nổi hiếm khi dùng */
  --giay:       #efe9dc;   /* CHÍNH LÀ màu nền của app, nay là màu chữ */
  --giay-mo:    #c9c1ae;
  --giay-nhat:  #948b77;
  --chi:        #35301f;   /* kẻ chỉ mảnh */

  /* son — dùng ở ĐÚNG ba chỗ: con dấu, từ đang chạm, nút gửi */
  --son:        #e0654f;   /* trên nền tối */
  --son-dam:    #b23529;   /* ruột con dấu, y hệt app */
  --ngoc:       #86a890;
  --vang:       #c9a86a;

  --serif:    "Newsreader", Georgia, "Times New Roman", serif;
  --serif-cn: "Noto Serif SC", "Songti SC", serif;

  /* Thang chữ theo Elements of Typographic Style — tỉ lệ quãng năm (1.5)
     ở đầu thang, thu dần về 1.25 ở thân bài. */
  --t-display: clamp(2.6rem, 8.5vw, 5.2rem);
  --t-lon:     clamp(1.9rem, 4.6vw, 2.9rem);
  --t-vua:     clamp(1.25rem, 2.4vw, 1.5rem);
  --t-than:    clamp(1.0rem, 1.6vw, 1.125rem);
  --t-nho:     0.875rem;

  --long:      clamp(20px, 5.5vw, 32px);   /* lề trong khung */
  --khoang:    clamp(64px, 12vw, 128px);   /* khoảng giữa các mục */
  --rong:      680px;                       /* dưới 80 ký tự mỗi dòng */
  --khung-max: 1080px;                      /* bề rộng khung ngoài cùng */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scrollbar-gutter: stable; -webkit-text-size-adjust: 100%; }

body {
  background: var(--muc);
  color: var(--giay);
  font-family: var(--serif);
  font-size: var(--t-than);
  line-height: 1.65;          /* serif cần thoáng hơn sans */
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Vân giấy rất mờ + hai vệt sáng lệch tâm, để nền không phẳng lì như một
     khối màu. Cùng thủ pháp với app, đảo sang tông tối. */
  background-image:
    radial-gradient(ellipse 80% 50% at 15% 0%, rgba(224, 101, 79, 0.07), transparent 60%),
    radial-gradient(ellipse 70% 40% at 90% 30%, rgba(134, 168, 144, 0.05), transparent 60%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
  background-attachment: fixed;
}

/* MÀU LINK GỐC. Trước đây KHÔNG có luật `a` nào ở mức gốc — chỉ có `.chan a`,
   `.dong-y a`, `.quay-lai`. Nên một liên kết nằm trong <p class="than"> rơi về
   màu mặc định của trình duyệt: xanh dương đậm trên nền #14120d, tương phản
   khoảng 1,3:1. Chỗ nó xảy ra là địa chỉ thư liên hệ trong mục "Ai làm cái
   này" — tức là đúng dòng người ta cần đọc được nhất để quyết định có tin hay
   không. Đặt ở gốc chứ không vá riêng `.than a`: lỗi này không thuộc về một
   lớp nào, nó thuộc về việc thiếu một mặc định. */
a { color: var(--son); text-underline-offset: 3px; }

/* Một glyph Hán đứng cạnh chữ Latin thổi phồng hộp dòng nó nằm trong (~1.45x ở
   cùng font-size), và font dự phòng còn đổi hộp dòng mà không đổi nét — nên
   cùng một trang lệch một kiểu lúc font chưa nạp, lệch kiểu khác sau khi nạp.
   `line-height: 1` chốt hộp dòng, ô vuông cố định ở nơi gọi mới là thứ căn với
   hàng xóm. Lý do đầy đủ nằm trong frontend/src/styles.css của app.
   CỐ Ý KHÔNG có font-size ở đây và CỐ Ý KHÔNG nudge bằng transform. */
.cjk-mark {
  display: inline-grid;
  place-items: center;
  align-self: center;
  font-family: var(--serif-cn);
  line-height: 1;
}

/* LỀ NGANG CỦA CẢ TRANG NẰM Ở ĐÂY, và chỉ ở đây.
   Mọi lớp dùng CHUNG phần tử với .khung (.hero, .muc, .form-khoi, .chan…) PHẢI
   dùng `margin-block` / `padding-block`, KHÔNG BAO GIỜ dùng shorthand `margin`
   hay `padding`: shorthand đặt lại cả bốn cạnh, nên nó xoá sạch trục ngang mà
   .khung vừa đặt — cùng độ đặc hiệu, đứng sau nên thắng, không có cảnh báo nào.
   Đã xảy ra HAI lần: `padding` làm cả trang dính mép trái ở điện thoại, rồi
   `margin` trong .form-khoi và .chan xoá mất `margin-inline: auto` nên biểu mẫu
   và chân trang văng sang sát mép trái ở màn rộng — mà ở điện thoại thì không
   thấy, vì ở đó `auto` vốn đã bằng 0.
   Có test tĩnh khoá điều này: xem `noi-dung.test.js`. */
.khung { width: 100%; max-width: var(--khung-max); margin-inline: auto; padding-inline: var(--long); }

/* KHÔNG có lớp "cột chữ hẹp" nào ở đây, và đó là điểm chính.
   Bản đầu dựng trang theo mô hình một cột 680px — bố cục của BÀI BÁO. Trên màn
   1194px nó để trống 464px bên phải suốt cả trang; ở 1440 và 1920 còn tệ hơn.
   Kéo cột đó sang trái cho thẳng hàng chỉ làm chỗ trống lộ ra rõ hơn, không
   chữa được gì — đó là vá triệu chứng.
   Thay bằng: mỗi mục có bố cục riêng dùng hết bề ngang, xếp chồng thành một
   cột ở điện thoại. Bề rộng đọc được vẫn giữ, nhưng giữ Ở TỪNG CỘT
   (`.than { max-width: 62ch }`) chứ không bằng cách bóp cả mục. */
.doi { display: grid; gap: clamp(30px, 4.5vw, 60px); }
@media (min-width: 900px) {
  .doi { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  /* Cột trái nhỉnh hơn khi nó mang lập luận còn cột phải mang bằng chứng. */
  .doi.lech { grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr); }
}

/* ---------- masthead ---------- */
.dau-trang {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding-block: 26px 18px;
  border-bottom: 1px solid var(--chi);
}
.hieu { display: flex; align-items: center; gap: 14px; }
.hieu .glyph {
  font-family: var(--serif-cn); font-weight: 700; font-size: 30px;
  line-height: 1; letter-spacing: 3px; color: var(--giay);
}
.hieu .ten { font-size: var(--t-nho); color: var(--giay-nhat); letter-spacing: 0.06em; }

/* Con dấu thật: ô vuông son ĐẶC, chữ màu giấy khoét ngược ra — đúng cách một
   con dấu 阳文 hoạt động. Viền rỗng ruột là cách vẽ của giao diện, không phải
   của con dấu. */
.dau {
  width: 34px; height: 34px; border-radius: 5px;
  background: var(--son-dam); color: var(--giay);
  font-size: 19px; font-weight: 600;
  transform: rotate(-5deg);
  box-shadow: 0 1px 0 rgba(0,0,0,0.35);
}

/* ---------- hero ---------- */
/* Ở điện thoại: một cột, lời hứa rồi tới sản phẩm.
   Từ 1000px: HAI CỘT — lời hứa trái, tờ giấy demo phải. Không phải để lấp chỗ
   trống: nó đặt lời hứa và bằng chứng cạnh nhau trong cùng một tầm mắt, và nó
   bó dòng chữ Hán về bề rộng đọc được. Một cột ở 1440px cho dòng chữ Hán dài
   gần 1000px — quá dài để đọc, mà nửa phải màn hình thì bỏ không. */
.hero { padding-block: clamp(48px, 11vw, 104px) 0; }

@media (min-width: 1000px) {
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
    gap: clamp(40px, 5vw, 72px);
    align-items: center;
  }
  .hero .to-giay { margin-top: 0; }
  /* Bỏ trần 15ch: cột lưới đã bó bề rộng đọc được rồi, nên giữ thêm trần chỉ
     làm tiêu đề vỡ thành năm dòng ngắn trong một cột rộng gấp rưỡi nó. */
  /* --t-display neo theo `vw`, đúng khi h1 chiếm cả bề ngang. Từ 1000px nó chỉ
     còn nằm trong một cột rộng ~500px, nên tính theo cả màn hình là tính sai
     vật chứa: đo ở 1194px được h1 cao 529px trong khung 834px, đẩy câu phụ đề
     xuống y=770–882 — BỊ CẮT bởi mép dưới màn hình, cùng với chỗ đăng ký.
     Cỡ chữ ở đây neo theo cột, không theo màn hình. */
  .hero .dinh-vi { max-width: none; font-size: clamp(2.9rem, 4.6vw, 4.1rem); }
}

.dinh-vi {
  font-size: var(--t-display);
  line-height: 1.06;
  letter-spacing: -0.022em;
  font-weight: 400;
  text-wrap: balance;
  max-width: 15ch;
}

/* Nét bút loang dưới câu định vị. Đây là MỘT khoảnh khắc chuyển động duy nhất
   không do người dùng kích hoạt trên cả trang — mọi mục khác hiện thẳng, không
   trượt-mờ. Hiệu ứng trượt-mờ rải đều từng mục là dấu hiệu trang máy sinh, và
   nó cũng làm người đọc phải đợi nội dung. */
.net-but { display: block; width: min(420px, 78%); height: 14px; margin: 18px 0 0; overflow: visible; }
.net-but path {
  fill: none; stroke: var(--son); stroke-width: 3.5; stroke-linecap: round;
  stroke-dasharray: 300; stroke-dashoffset: 300;
  animation: ve-net 1.1s cubic-bezier(0.25, 0.6, 0.3, 1) 0.35s forwards;
}
@keyframes ve-net { to { stroke-dashoffset: 0; } }

.phu-de {
  margin: 26px 0 0; max-width: 46ch;
  font-size: var(--t-vua); line-height: 1.55; color: var(--giay-mo);
}

.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; margin: 30px 0 0; }
.hero-cta .nut { margin: 0; }
.hero-cta-phu { font-size: var(--t-nho); color: var(--giay-nhat); max-width: 30ch; }

/* Điểm dừng thứ hai, ngay sau loạt ảnh sản phẩm. */
.giua-cta { margin: 40px 0 0; }
.giua-cta .nut { margin: 0; }

/* ---------- tờ giấy demo: vật sáng đầu tiên trên trang ---------- */
.to-giay {
  position: relative;
  margin: clamp(34px, 7vw, 56px) 0 0;
  background: var(--giay);
  color: #211e18;
  border-radius: 3px;
  padding: clamp(26px, 5vw, 40px);
  /* Bóng nhiều lớp: một lớp sát để tách khỏi nền, một lớp xa và mềm để tờ giấy
     có vẻ NẰM TRÊN mặt bàn chứ không dán vào nền. */
  box-shadow:
    0 1px 2px rgba(0,0,0,0.4),
    0 12px 28px rgba(0,0,0,0.45),
    0 40px 80px rgba(0,0,0,0.35);
}
/* CỐ Ý KHÔNG có lớp gradient giả "mép giấy vênh" ở đây. Đã thử: một
   ::before `position:absolute; inset:0` vẽ ĐÈ LÊN chữ, vì con của .to-giay
   không được định vị. Lớp trắng 50% ở góc trên làm dòng chữ Hán đầu tiên nhạt
   hẳn so với dòng cuối — tụt tương phản đúng chỗ quan trọng nhất của cả trang,
   để đổi lấy một hiệu ứng không ai nhận ra. Muốn thêm lại thì phải đặt nó
   dưới chữ (z-index âm) và đo tương phản sau khi đặt, chứ không đặt bằng mắt.
*/

.doan-demo {
  font-family: var(--serif-cn);
  font-size: clamp(1.25rem, 4.6vw, 1.6rem);
  line-height: 2.15;
  letter-spacing: 0.01em;
  color: #211e18;
}
/* Chữ Hán cấm bắt đầu một dòng bằng dấu đóng câu. Mỗi token ở đây là một
   <button> (inline-block) nên trình duyệt coi ranh giới giữa nút và dấu câu
   là chỗ ngắt dòng hợp lệ và bỏ qua luật đó — kết quả là dấu 。 rơi xuống một
   dòng riêng. demo.js gói mỗi nút cùng dấu câu theo sau vào .cum. */
.cum { white-space: nowrap; }

/* "Hán-Việt" KHÔNG được ngắt dòng ở dấu gạch nối. Nó là thuật ngữ trung tâm của
   cả luận điểm bán hàng, và trình duyệt coi gạch nối là chỗ ngắt hợp lệ nên nó
   vỡ thành "Hán-" / "Việt" ngay ở tiêu đề — đã xảy ra hai lần trên cùng một
   màn hình 1440px. */
.lien { white-space: nowrap; }

.hz {
  cursor: pointer; border: 0; background: none; padding: 0 1px;
  font: inherit; color: inherit; border-radius: 3px;
  transition: color 0.15s, background 0.15s;
}
.hz:hover { color: var(--son-dam); background: rgba(178,53,41,0.08); }
.hz.dang-chon { color: var(--son-dam); background: rgba(178,53,41,0.14); }
.hz:focus-visible { outline: 2px solid var(--son-dam); outline-offset: 2px; }

.goi-y {
  display: flex; align-items: center; gap: 9px;
  margin: 20px 0 0; font-size: var(--t-nho); color: #8b8270;
}
.goi-y .cham { width: 7px; height: 7px; border-radius: 50%; background: var(--son-dam); flex: none; }

/* Khung nghĩa — cùng thứ tự tầng với WordSheet của app: chữ, pinyin,
   Hán-Việt, nghĩa Việt, nghĩa Anh. */
.khung-nghia {
  margin: 22px 0 0; padding: 22px 0 0;
  border-top: 1px solid #d8cfba;
}
.khung-nghia[hidden] { display: none; }
.kn-tu {
  font-family: var(--serif-cn); font-size: clamp(2rem, 7vw, 2.6rem);
  line-height: 1.1; color: #211e18;
}
.kn-pinyin { margin-top: 6px; font-size: 1.05rem; color: #4c473c; font-style: italic; }
.kn-hv { margin-top: 12px; font-size: 1.15rem; color: var(--son-dam); }
.kn-hv .nhan {
  display: inline-block; margin-right: 9px; font-size: 0.72rem;
  color: #8b8270; font-style: normal; letter-spacing: 0.02em;
}
.kn-vi { margin-top: 12px; font-size: 1.1rem; line-height: 1.5; color: #211e18; }
.kn-en { margin-top: 8px; font-size: 0.95rem; color: #4c473c; }
.kn-en .nhan { margin-right: 9px; font-size: 0.72rem; color: #8b8270; }

/* ---------- mục chung ---------- */
.muc { padding-block: var(--khoang) 0; }
.tieu-de {
  font-size: var(--t-lon); font-weight: 400; line-height: 1.15;
  letter-spacing: -0.015em; text-wrap: balance; max-width: 20ch;
}
/* Tiêu đề cỡ nhỏ, dùng cho mục nằm trong một cột của lưới đôi — cỡ lớn ở đó
   sẽ vỡ thành bốn dòng và nuốt mất cột. */
.tieu-de.nho { font-size: clamp(1.5rem, 2.6vw, 1.9rem); max-width: 24ch; }

.than { margin: 20px 0 0; max-width: 62ch; color: var(--giay-mo); }
.than + .than { margin-top: 14px; }
.than strong { color: var(--giay); font-weight: 500; }

/* ---------- ba cặp từ: luận điểm Hán-Việt ---------- */
/* margin-top chỉ cần khi bảng nằm DƯỚI đoạn văn (điện thoại, một cột). Trong
   lưới đôi nó là cột riêng, nên phải bằng 0 để mép trên thẳng hàng với tiêu đề
   cột bên cạnh. */
.cap-tu { margin-block: 34px 0; border-top: 1px solid var(--chi); }
@media (min-width: 900px) { .doi > .cap-tu { margin-block: 0; } }
.cap {
  display: flex; align-items: baseline; gap: clamp(16px, 4vw, 32px);
  padding: 18px 2px; border-bottom: 1px solid var(--chi);
}
.cap .han {
  font-family: var(--serif-cn); font-size: clamp(1.9rem, 6vw, 2.4rem);
  line-height: 1.15; color: var(--giay); flex: none; min-width: 2.6em;
}
.cap .viet { font-size: var(--t-vua); color: var(--son); }
.cap .nghia { margin-left: auto; font-size: var(--t-nho); color: var(--giay-nhat); text-align: right; }

/* ---------- vòng lặp + ảnh chụp ---------- */
.anh-loat {
  display: grid; gap: clamp(20px, 4vw, 30px);
  grid-template-columns: 1fr;
  margin: 38px 0 0;
}
@media (min-width: 760px) { .anh-loat { grid-template-columns: repeat(3, 1fr); } }

.anh figure { margin: 0; height: 100%; display: flex; flex-direction: column; }
.anh img {
  display: block; width: 100%; height: auto; border-radius: 4px;
  background: var(--giay);
  box-shadow: 0 2px 6px rgba(0,0,0,0.4), 0 18px 44px rgba(0,0,0,0.42);
}
.anh figcaption { margin: 14px 0 0; font-size: var(--t-nho); color: var(--giay-nhat); }
@media (min-width: 760px) { .anh figcaption { margin-top: auto; padding-top: 14px; } }
.anh figcaption b { display: block; color: var(--giay); font-weight: 500; margin-bottom: 2px; }

/* ---------- ai làm cái này: mốc thời gian ---------- */
/* Cố ý KHÔNG có border-top ở .nguoi-lam: .form-khoi ngay sau đó đã mở bằng một
   vạch, hai vạch cách nhau một dải trống lớn thì dải đó đọc ra là thiếu nội
   dung — cùng lý do đã bỏ vạch dưới của .form-khoi. */
.moc { margin-block: 34px 0; padding-block: 24px 0; border-top: 1px solid var(--chi); }
@media (min-width: 900px) { .doi > .moc { margin-block: 0; } }
.moc-nhan { font-size: var(--t-nho); color: var(--giay-nhat); letter-spacing: 0.04em; }
.moc-gia { margin-top: 4px; font-size: var(--t-lon); line-height: 1.1; color: var(--son); }
.moc-phu { margin-top: 16px; font-size: var(--t-nho); line-height: 1.55; color: var(--giay-mo); max-width: 40ch; }

/* ---------- biểu mẫu ---------- */
.form-khoi {
  margin-block: var(--khoang) 0; padding-block: clamp(30px, 6vw, 46px) 0;
  /* CHỈ có vạch trên. Vạch dưới đã bị bỏ: .chan ngay sau đó cũng mở bằng một
     vạch, nên hai vạch nằm cách nhau một dải trống lớn và dải đó đọc ra là
     thiếu nội dung. Một khối cần một vạch mở, không cần cả vạch đóng khi khối
     kế tiếp đã tự mở. */
  border-top: 1px solid var(--chi);
}
/* Ba câu trấn an đứng cạnh ô nhập, không phải dưới nó — đây là lúc người ta
   phân vân có nên đưa email không, nên câu trả lời phải nằm trong tầm mắt.
   Cả ba đều là sự thật kiểm được ở /rieng-tu; có test buộc chúng khớp nhau. */
.yen-tam { margin: 26px 0 0; padding-block: 18px 0; border-top: 1px solid var(--chi); list-style: none; }

/* Ở lưới đôi, cột trái (lời mời + ba câu trấn an) ngắn hơn cột phải (cả biểu
   mẫu) khoảng 630px, để lại một mảng trống lớn dưới đáy. Đẩy ba câu trấn an
   xuống cuối cột vừa lấp mảng đó, vừa đưa chúng về ngang tầm ô ĐỒNG Ý — chỗ
   người ta phân vân nhất, và cũng là ô mà bấm trượt thì mất luôn một email. */
@media (min-width: 900px) {
  .form-khoi .doi { align-items: stretch; }
  .form-khoi .doi > div:first-child { display: flex; flex-direction: column; }
  .form-khoi .yen-tam { margin-top: auto; }
}
.yen-tam li { font-size: var(--t-nho); color: var(--giay-nhat); line-height: 1.5; padding-left: 20px; position: relative; }
.yen-tam li + li { margin-top: 9px; }
.yen-tam li::before { content: "·"; position: absolute; left: 6px; color: var(--son); font-size: 1.3em; line-height: 1.05; }

.o { display: block; margin: 22px 0 0; }
.o > .nhan { display: block; margin-bottom: 8px; font-size: var(--t-nho); color: var(--giay-mo); }

input[type="email"] {
  width: 100%; max-width: 420px; padding: 13px 15px;
  font-family: var(--serif); font-size: 1.0625rem;
  color: var(--giay); background: rgba(239,233,220,0.05);
  border: 1px solid var(--chi); border-radius: 4px;
}
input[type="email"]::placeholder { color: var(--giay-nhat); }
input[type="email"]:focus-visible { outline: 2px solid var(--son); outline-offset: 1px; border-color: transparent; }

fieldset { border: 0; margin: 26px 0 0; }
legend { font-size: var(--t-nho); color: var(--giay-mo); margin-bottom: 4px; }
.tuy-chon { color: var(--giay-nhat); }
.ghi-chu { font-size: var(--t-nho); color: var(--giay-nhat); margin-bottom: 12px; max-width: 52ch; }

/* padding-block 11px cho ra 45px ở bề rộng điện thoại (16px × 1.45 + 22).
   Với 9px nó ra 41px — dưới chuẩn chạm 44px của iOS ở MỌI bề rộng điện thoại,
   và chỉ vừa đủ 44px ở đúng màn ~1194px, nên đo ở một bề rộng là không phát
   hiện ra. Đây là năm ô bấm chính của cả trang. */
.chon {
  display: flex; align-items: flex-start; gap: 11px;
  padding-block: 11px; cursor: pointer;
}
.chon input { margin-top: 6px; accent-color: var(--son-dam); flex: none; width: 17px; height: 17px; }
.chon span { line-height: 1.45; }

/* padding-block 10px đẩy vùng bấm lên 48px. Đo được 43px khi chưa có nó —
   dưới chuẩn chạm 44px của iOS, mà đây lại là ô BẮT BUỘC về pháp lý: bấm trượt
   ô này là người dùng gửi hỏng rồi bỏ đi, và ta mất một email vì một pixel. */
.dong-y {
  display: flex; align-items: flex-start; gap: 11px;
  margin-block: 26px 0; padding-block: 10px; cursor: pointer;
}
.dong-y input { margin-top: 5px; accent-color: var(--son-dam); flex: none; width: 17px; height: 17px; }
.dong-y span { font-size: var(--t-nho); line-height: 1.55; color: var(--giay-mo); max-width: 56ch; }
.dong-y a { color: var(--giay); text-underline-offset: 3px; }

.nut {
  display: inline-block; text-decoration: none; text-align: center;
  margin: 28px 0 0; padding: 14px 30px;
  font-family: var(--serif); font-size: 1.0625rem; letter-spacing: 0.01em;
  color: var(--giay); background: var(--son-dam);
  border: 1px solid var(--son-dam); border-radius: 999px;
  cursor: pointer; transition: transform 0.16s, filter 0.16s;
}
.nut:hover { filter: brightness(1.1); }
.nut:active { transform: scale(0.98); }
.nut:focus-visible { outline: 2px solid var(--son); outline-offset: 3px; }

/* Ở bước cuối của một biểu mẫu dài, nút phải là thứ khó bấm trượt nhất trên
   màn hình. Đo được 249px = 64% bề ngang ở 390px — đủ rộng để bấm, nhưng
   không phải thứ ngón cái tìm thấy mà không cần nhìn. */
@media (max-width: 759px) {
  .nut { width: 100%; }
}

/* Honeypot: ẩn khỏi mắt VÀ khỏi trình đọc màn hình, nhưng vẫn nằm trong form.
   `display:none` bị một số bot bỏ qua có chủ ý, nên dùng cách đẩy ra ngoài. */
.bay { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Ẩn mặc định, hiện khi fragment của URL trỏ đúng vào id. Function chuyển
   hướng về `/#loi-<mã>` sau một lượt gửi hỏng, nên câu lỗi hiện ra mà không
   cần một dòng JS nào — và trình duyệt tự cuộn tới đúng chỗ. */
.loi {
  display: none;
  margin: 20px 0 0; padding: 12px 15px;
  border-left: 3px solid var(--son); background: rgba(224,101,79,0.09);
  color: var(--giay); font-size: var(--t-nho); line-height: 1.5;
  scroll-margin-top: 24px;
}
.loi:target { display: block; }

/* ---------- chân trang ---------- */
.chan {
  margin-block: clamp(40px, 8vw, 72px) 0; padding-block: 30px 44px;
  border-top: 1px solid var(--chi);
  font-size: var(--t-nho); color: var(--giay-nhat);
}
.chan a { color: var(--giay-mo); text-underline-offset: 3px; }
.chan p + p { margin-top: 10px; }
.chan-luoi { display: grid; gap: 18px; }
@media (min-width: 760px) {
  .chan-luoi { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 48px; }
}

/* ---------- trang phụ ---------- */
.trang-phu { padding-block: clamp(40px, 9vw, 76px) 0; }
.trang-phu h1 { font-size: var(--t-lon); font-weight: 400; line-height: 1.2; letter-spacing: -0.015em; }
.trang-phu h2 { margin: 34px 0 10px; font-size: var(--t-vua); font-weight: 500; }
.trang-phu p, .trang-phu li { color: var(--giay-mo); max-width: 62ch; }
.trang-phu p + p { margin-top: 12px; }
.trang-phu ul { margin: 10px 0 0 1.1em; }
.trang-phu li { margin-bottom: 7px; }
.quay-lai {
  display: inline-block; margin-top: 34px; padding-block: 9px;
  color: var(--giay); text-underline-offset: 4px;
}

/* ---------- thanh neo đáy (điện thoại) ---------- */
/* Mặc định KHÔNG có thanh. Nó chỉ bật ở trình duyệt vừa hiện được vừa GIẤU
   được nó khi biểu mẫu đã vào tầm mắt — vì một thanh cố định không giấu được
   sẽ nằm đè lên đúng cái nút gửi ở cuối trang, tức là tự bắn vào chân.
   Nơi không hỗ trợ thì không có thanh, và hai CTA tĩnh (màn đầu + giữa trang)
   vẫn làm xong việc. Đây là nâng cấp, không phải điều kiện. */
.thanh-neo { display: none; }

@supports (timeline-scope: --form-hien) {
  @media (max-width: 899px) and (prefers-reduced-motion: no-preference) {
    /* CẢ HAI tên mốc phải nằm trong scope. Thiếu một cái thì mốc đó không
       phân giải được, hoạt ảnh gắn với nó im lặng không chạy, và thanh neo
       hiện ngay từ đầu trang — không có cảnh báo nào. Đã xảy ra. */
    body { timeline-scope: --form-hien, --hero-roi; }
    #dangky { view-timeline-name: --form-hien; }

    .hero-cta { view-timeline-name: --hero-roi; }

    .thanh-neo {
      display: block; position: fixed; inset: auto 0 0 0; z-index: 20;
      padding: 10px var(--long) calc(10px + env(safe-area-inset-bottom));
      background: rgba(20, 18, 13, 0.92);
      backdrop-filter: blur(8px);
      border-top: 1px solid var(--chi);

      /* Nằm ngoài màn hình cho tới khi được gọi. Vị trí mặc định phải là ẨN:
         nếu một trong hai hoạt ảnh dưới đây không chạy, thứ còn lại là một
         thanh không bao giờ hiện — phiền, nhưng vô hại. Mặc định HIỆN thì
         hỏng ngược lại: một thanh không bao giờ tắt, đè lên nút gửi. */
      transform: translateY(110%);

      /* HAI mốc, không phải một, vì thanh này có hai câu hỏi khác nhau:
           lên  — khi CTA ở màn đầu đã trôi khỏi màn hình (trước đó nó chỉ là
                  bản sao của một nút đang nhìn thấy, hai nút đỏ y hệt nhau
                  trong cùng một màn);
           xuống — khi biểu mẫu chớm vào tầm mắt (từ đó trở đi nó chỉ còn là
                  vật cản nằm trên chính nút gửi).
         Cả hai cùng lái `transform`, nên khung hình khuyết của hoạt ảnh sau
         lấy giá trị từ hoạt ảnh trước — chúng nối nhau chứ không giành nhau. */
      animation: neo-len linear both, neo-xuong linear both;
      animation-timeline: --hero-roi, --form-hien;
      animation-range: exit 0% exit 100%, cover 0% cover 20%;
    }
    .thanh-neo .nut { margin: 0; width: 100%; }
  }
}
@keyframes neo-len   { to { transform: translateY(0); } }
@keyframes neo-xuong { to { transform: translateY(110%); } }

/* ---------- tôn trọng người tắt hiệu ứng ---------- */
@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;
  }
  /* Nét bút phải HIỆN SẴN, không phải ẩn mãi mãi — không hiệu ứng nào được là
     điều kiện để nhìn thấy nội dung. */
  .net-but path { stroke-dashoffset: 0; }
}
