/* =============================================================
   THIỆP CƯỚI NINH & TRANG — DESIGN TOKENS
   Concept "HAI CHƯƠNG": Chương I phông trắng Hàn Quốc
                       → Chương II sân vườn
   -------------------------------------------------------------
   Bảng màu KHÔNG chọn cảm tính: quantize trực tiếp từ hai bảng
   concept ảnh cưới sẽ chụp. Điều đổi so với bản cũ không phải MÀU
   mà là TỈ LỆ dùng màu — trước đây rêu đậm phủ nguyên khối, trong
   ảnh thật rêu chỉ là hậu cảnh ở xa, còn trắng/kem mới là trường
   màu chính.
   ============================================================= */

:root {
  /* ---------- Trường màu chính: "phông trắng Hàn Quốc" ---------- */
  --paper:      #FBFAF7;   /* nền mặc định toàn trang */
  --paper-2:    #F2F0E9;   /* nền so le, đậm hơn một nấc */

  /* ---------- Kem: xe cổ mui trần + tháp bánh kem ---------- */
  --cream:      #EFE7D6;
  --cream-d:    #E1DACB;

  /* ---------- Mực: vest chú rể. Đây là MÀU CHỮ, không phải nền ----------
     Bản trước ghi "vest chú rể" rồi đặt một màu NAVY. Đo lại chính hai
     tấm concept mới biết là đặt sai: lượng tử hoá k-means k=7 trên tấm
     phông trắng cho mảng tối nhất là #222227 với chroma OKLCH đúng
     .009 — tức THAN CHÌ trung tính, ở mức bão hoà đó thì góc hue chỉ
     là nhiễu. Token cũ có chroma .0155 ở hue 269°: xanh gấp gần hai
     lần ảnh, và lệch 133° khỏi mọi màu còn lại của trang.

     Đây mới là vết nứt thật của bảng màu, đo được chứ không phải cảm
     tính: cả trang nằm gọn trong cung ấm 77–136°, riêng họ ink — màu
     chữ trên 94% diện tích — văng sang 269°, gần như đối đỉnh.

     Sửa theo đúng số đo được: xoay về 138° và HẠ chroma xuống .013
     cho gần với .009 của ảnh. Giữ nguyên L* nên tương phản gần như
     không đổi (ink trên paper 14,49 -> 14,39). Kết quả không ai chỉ ra
     được "đã đổi màu gì", chỉ thấy chữ nằm TRONG nền kem chứ không
     còn đè lên nó. */
  --ink:        #232822;
  --ink-2:      #4B5149;
  --ink-3:      #8B9189;

  /* ---------- Rêu: hàng bách hậu cảnh trong ảnh sân vườn ----------
     Cũng lấy thẳng từ tấm sân vườn: #324627 (L*36.8 C.057 h135) và
     #12220F (L*23.2 C.041 h141). Hai token dưới giữ nguyên L* cũ,
     chỉ khớp lại hue/chroma theo hai mảng đó. */
  --moss:       #475E3E;
  --moss-d:     #25361E;

  /* ---------- Đồng thau: chữ ký, nhãn nhỏ, nét trang trí ----------
     GIỮ NGUYÊN, có chủ đích. Sau khi ink về 138°, đồng thau ở 80° là
     điểm nhấn ẤM DUY NHẤT còn lại — cả trang trở thành một hue neo
     (132–138°) xếp ba tầng chữ → rêu → chân trang, cộng đúng một
     giọng thứ hai. Thêm màu nhấn nữa là hỏng thế cân bằng đó. */
  --gold:       #A38B63;
  --gold-lt:    #C6B392;

  --line:       rgba(35, 40, 34, .13);
  --line-lt:    rgba(251, 250, 247, .18);

  /* ---------- CHẤT LIỆU ----------
     Lỗi lớn nhất của bản trước không phải thiếu hoạ tiết mà là mọi nền
     đều là màu PHẲNG TUYỆT ĐỐI — thứ chỉ có trên màn hình, không có
     trên giấy. Thiệp in tối giản vẫn sang vì nó có thớ giấy, có nhũ,
     có vết dập. Hai token dưới đây là "chất liệu" của trang.

     --noise: một ô nhiễu 160px lát kín. Cố ý để XÁM TRUNG TÍNH chứ
     không phải đen: cùng một ảnh dùng được cho cả nền giấy (làm sạm
     đi) lẫn nền mực (làm sáng lên), khỏi phải nuôi hai file. Vẽ bằng
     feTurbulence nên nặng đúng 0 request. */
  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.085'/%3E%3C/svg%3E");

  /* --foil: đồng thau ÉP NHŨ. Nhũ thật không phải một màu — nó bắt
     sáng lệch một trục, tối ở hai đầu và loé ở giữa. Chỉ dùng cho chữ
     ký cỡ lớn; đổ gradient lên nhãn 11px thì chỉ ra một vệt bùn. */
  --foil: linear-gradient(102deg,
            #8A7245  0%, #A38B63 20%, #D8C298 40%,
            #F2E7CD 50%, #D8C298 60%, #A38B63 80%, #856F44 100%);

  /* ---------- CHỮ ----------
     Cả ba font đều CÓ bộ ký tự tiếng Việt trên Google Fonts. Cách
     kiểm tra: gọi fonts.googleapis.com/css2 bằng User-Agent Chrome
     MỚI rồi tìm khối unicode-range tên "vietnamese"; UA cũ không trả
     về khối đó nên rất dễ tưởng nhầm là font thiếu dấu.
     Bodoni Moda / Instrument Serif dáng đẹp hơn nhưng KHÔNG có subset
     Việt -> dấu rơi về font dự phòng, chữ loang lổ. Đừng đổi lại.

     --f-disp là "Playfair", KHÔNG phải "Playfair Display". Hai họ
     khác nhau, không phải tên gọi tắt. Chọn họ này vì đúng một lý do
     kỹ thuật: trang gọi --f-disp từ .8rem (số ô ảnh) tới 11rem (tên
     cô dâu chú rể) — chênh 14 lần. Một dáng chữ tương phản cao vẽ cho
     khổ lớn thì nét mảnh của nó ở 12.8px rụng mất, chữ đọc ra lỗ chỗ;
     vẽ cho khổ nhỏ thì ở 176px nó béo và thô. Playfair có trục quang
     học opsz 5..1200 nên nó tự vẽ lại nét theo cỡ. Playfair Display
     chỉ có trục wght, không giải được việc này.

     Không cần khai gì thêm để opsz chạy: giá trị khởi tạo của
     font-optical-sizing đã là auto, trình duyệt tự gán opsz = cỡ chữ
     đang render. Chỉ cần TUYỆT ĐỐI không đặt font-optical-sizing:none
     ở đâu cả.

     --f-sign là Carattere chứ không phải Allura nữa. Chữ ký chỉ hiện
     ở ba chỗ và cả ba đều nằm dưới --foil hoặc màu đồng. Nét Allura
     mảnh như sợi tóc: dải nhũ 7 chặng phủ lên một nét 1-2px thì không
     đủ chỗ để chuyển màu, ra một vệt bùn. Carattere dày nét hơn hẳn,
     đủ thân cho nhũ ăn. */
  --f-disp:     "Playfair", "Playfair Display", Georgia, serif;
  --f-body:     "Be Vietnam Pro", system-ui, -apple-system, sans-serif;
  --f-sign:     "Carattere", cursive;

  /* ---------- Thang chữ TRÔI, không breakpoint rời rạc ---------- */
  --t-mega:     clamp(3.4rem, 12vw, 11rem);        /* tên cô dâu chú rể */
  --t-disp:     clamp(2.6rem, 6.4vw, 5.6rem);
  --t-h2:       clamp(2rem, 4.4vw, 3.6rem);
  --t-h3:       clamp(1.25rem, 2.2vw, 1.7rem);
  --t-body:     clamp(1rem, .55vw + .88rem, 1.12rem);
  --t-small:    .88rem;
  /* NHÃN IN HOA — hai token, không phải một.
     Trên máy tính, .69rem giãn .34em đọc được vì có chỗ để giãn. Đo
     lại ở 390px thì cùng nhãn đó ra 11,04px kèm 3,75px tracking:
     "Save the Date · 20.12.2026" chiếm gần trọn bề ngang rồi gãy hai
     dòng, và mấy nhãn viết cứng .58rem tụt xuống 9,28px — dưới ngưỡng
     đọc trên điện thoại cầm xa tay.

     Nên cỡ chữ đi NGƯỢC chiều bề rộng: sàn cao hơn ở máy nhỏ, và
     tracking co lại theo (--track-cap ở khối media bên dưới). Chữ nhỏ
     mà giãn rộng là kiểu chỉ đúng trên bản in khổ lớn. */
  --t-cap:      clamp(.72rem, .1vw + .69rem, .78rem);
  --t-micro:    clamp(.66rem, .08vw + .64rem, .7rem);
  --track-cap:  .34em;
  --track-mic:  .24em;

  /* ---------- Nhịp ---------- */
  --sec:        clamp(5.5rem, 12vw, 10rem);        /* padding dọc mỗi khối */
  --gut:        clamp(1.1rem, 2vw, 1.75rem);       /* rãnh lưới 12 cột */
  --wrap:       min(100% - 2.6rem, 78rem);
  --edge:       clamp(1.3rem, 4vw, 4.5rem);        /* lề khi tràn mép */

  /* ---------- SỐNG LƯNG — ba nhịp cột, và CHỈ ba ----------
     Lưới 12 cột đã có từ đầu, cái thiếu là luật dùng nó. Kiểm kê từng
     `grid-column` của bản trước:

       hero        1/span 6  ·  8/span 5   -> mép phải 12
       lời mời     1/span 5  ·  7/span 6   -> mép phải 12
       câu chuyện  1/span 5  ·  7/span 5   -> mép phải 11   ✕
       hồi âm      1/span 4  ·  6/span 7   -> mép phải 12
       quà         căn giữa  ·  3/span 8   -> mép phải 10   ✕

     Hai lỗi đo được: mép phải trôi (12,12,11,12,10) và cột thứ hai
     bắt đầu ở năm chỗ khác nhau (8,7,7,6,3) cho cùng một quan hệ
     "chữ đứng cạnh ảnh". Mắt không đọc ra lý do, chỉ đọc ra sự lỏng.

     Từ đây mọi khối chỉ được chọn trong ba nhịp dưới. Tỉ lệ 7:5 —
     lệch đủ để một vế thắng rõ ràng, mà không chừa cột chết: 7+5=12
     nên mép trái luôn ở 1 và mép phải luôn đóng ở 12, cả trang đọc
     theo đúng MỘT đường dọc duy nhất (vạch giữa cột 7 và 8).

     (Đã thử 7:4 chừa một cột trống ở giữa cho "thoáng": hỏng ngay ở
     hero, vì vế nhẹ 4 cột thì ảnh cưới teo thành một dải đứng.)

     Bản soi gương (-r/-l) dành cho khối so le, không phải nhịp thứ
     tư: vẫn 7:5, chỉ lật bên, nên vạch chia dời sang giữa cột 5 và 6. */
  --sp-full:    1 / span 12;
  --sp-major:   1 / span 7;    /* vế nặng: ảnh, biểu mẫu, tên           */
  --sp-minor:   8 / span 5;    /* vế nhẹ: nhãn, chú thích, khối phụ     */
  --sp-major-r: 6 / span 7;
  --sp-minor-l: 1 / span 5;

  /* ---------- CHUYỂN ĐỘNG ----------
     Ba bậc thời lượng, không hơn.
       · fast  phản hồi chạm/rê chuột, phải dưới ngưỡng "thấy độ trễ"
       · mid   hiện dần khi cuộn
       · slow  chỉ dành cho hai khoảnh khắc dàn dựng: mở trang và
               vạch chuyển chương ở album

     Bản trước để --dur .62s mà vẫn bị chê vừa nhanh vừa không mượt —
     nghe mâu thuẫn nhưng cả hai đều đúng, và cả hai đều do ĐƯỜNG CONG
     chứ không do con số: expo-out đi hết 90% quãng đường trong 20%
     thời lượng đầu, nên mắt đọc ra một cú BẮN rồi một cái đuôi dài
     không có gì nhúc nhích. Kéo dài thêm chỉ làm cái đuôi dài ra.

     Cách sửa là đổi đường cong trước, rồi mới nới thời lượng.

     STAGGER = 120ms. Đủ để mắt đọc ra thứ tự, chưa đủ để thành máy
     đánh bạc quay từng ô. */
  --dur-fast:   .3s;
  --dur:        .95s;
  --dur-slow:   1.6s;
  --stag:       120ms;

  /* Một đường cong duy nhất cho mọi chuyển cảnh. Thêm đường cong thứ
     hai là trang bắt đầu nói hai giọng — và nếu hai đường cong đó lại
     nằm trên hai thuộc tính của CÙNG một cử chỉ (opacity một kiểu,
     transform một kiểu) thì chữ đáp xuống xong mới hiện lên: đó đúng
     là cảm giác nhoè của bản trước.

     Chọn bằng SỐ, không bằng cảm tính. Quãng đường đi được sau mỗi
     mốc thời lượng, đo thật bằng Web Animations API:

                        10%   25%   50%   75%   90%
       expo-out (cũ)    40%   76%   96%  100%  100%   <- bắn rồi chết
       material         3%    24%   78%   96%   99%   <- khựng rồi vọt
       ease-out-sine    16%   38%   70%   92%   99%   <- đi đều

     Đường cũ xong sạch quãng đường ở 3/4 thời lượng: một phần tư cuối
     KHÔNG có gì nhúc nhích, mắt đọc ra một cú giật rồi đứng hình. Kéo
     dài thời lượng chỉ làm khoảng chết đó dài thêm — đó là lý do bản
     trước vừa bị chê nhanh vừa bị chê không mượt.

     Các đường kiểu material thì ngược lại: 10% thời lượng đầu gần như
     đứng yên rồi mới vọt, đọc ra máy bị lag chứ không ra thong thả.

     ease-out-sine trải chuyển động gần như đều suốt thời lượng, vẫn
     giảm tốc thật ở đoạn cuối để đỗ êm. Chậm hơn hẳn mà mượt hơn. */
  --ease:       cubic-bezier(.61, 1, .88, 1);
  --radius:     2px;                               /* vintage = gần vuông góc */
}

/* Máy nào bật "giảm chuyển động" thì tắt sạch hiệu ứng */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: .01s; --dur: .01s; --dur-slow: .01s; --stag: 0ms; }
}

/* ---------- ĐIỆN THOẠI: co tracking, nới rãnh ----------
   Tracking là thứ KHÔNG được giữ nguyên khi khổ hẹp lại. .34em trên
   một nhãn 11px ở màn 390px ăn hết 3,75px mỗi ký tự — nhãn dài gãy
   đôi dòng, mà nhãn IN HOA gãy dòng thì đọc ra như lỗi chứ không ra
   nhịp. Ba mức co dần, đo tại 390 / 480 / 768px.

   --wrap cũng nới: 2,6rem lề hai bên là tỉ lệ của màn hình rộng; ở
   390px nó lấy mất 10,6% bề ngang trong khi --edge đã lo phần lề rồi. */
@media (max-width: 48rem) {
  :root {
    --track-cap: .26em;
    --track-mic: .2em;
    --wrap:      min(100% - 2rem, 78rem);
  }
}
@media (max-width: 30rem) {
  :root {
    --track-cap: .2em;
    --track-mic: .16em;
  }
}
