/* ============================================================
   HỮU TÍN — common.css
   Shared shell: design tokens, reset, header, footer, buttons.
   Loaded before home.css. Keep this WordPress-convertible.
   Tokens are taken verbatim from spec/06_design_tokens.md.
   ============================================================ */

/* ---- FONT (đổi 2026-09-22) ----
   · TIÊU ĐỀ: Playfair Display — Google Fonts (link trong <head>), h1 700,
     h2–h4 --fw-heading.
   · CHỮ CHẠY/UI: SVN-Georgia — bản Việt hoá của Georgia, khách cấp file .otf
     (SVN-Georgia.zip), chuyển woff2 bằng fontTools, TỰ HOST ở ../fonts/.
     Bốn nét: Regular 400 · Bold 700 · Italic 400 · Bold Italic 700 — có
     nghiêng THẬT nên placeholder/chú thích italic không còn nghiêng giả.
     Nét 300/500 rơi về 400 theo quy tắc so khớp (không có file).
   · ĐÃ KIỂM cmap (fontTools): cả 4 file đủ 114/114 ký tự tiếng Việt.
   · Metric (upm 2048): x-height 0.48, cap 0.69, hhea = win = 2115/449 nên
     macOS và Windows đặt chữ giống nhau (khác Philosopher trước đó).
   · GIẤY PHÉP: font thương mại (SVN) — nhúng web cần licence webfont, khách tự
     chịu trách nhiệm; ghi ở đây để không ai tưởng là font OFL.
   Lịch sử: Beautique+AlmarenaVN (09-07) → Playfair+Philosopher (09-08) → đây. */
@font-face{font-family:"SVN-Georgia";src:url("../fonts/svn-georgia-400.woff2?v=95418e4e") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"SVN-Georgia";src:url("../fonts/svn-georgia-700.woff2?v=21409a70") format("woff2");font-weight:700;font-style:normal;font-display:swap;}
@font-face{font-family:"SVN-Georgia";src:url("../fonts/svn-georgia-400i.woff2?v=7a01e218") format("woff2");font-weight:400;font-style:italic;font-display:swap;}
@font-face{font-family:"SVN-Georgia";src:url("../fonts/svn-georgia-700i.woff2?v=7f81eadf") format("woff2");font-weight:700;font-style:italic;font-display:swap;}

:root{
  /* ===== Bộ màu thương hiệu — ĐƠN SẮC: Xám · Đen · Trắng · Kem =====
     Đã loại bỏ HOÀN TOÀN nâu socola và vàng amber. Không còn màu ấm nào
     ngoài sắc kem trung tính dùng cho card/section xen kẽ.
     Xám ở đây là xám TRUNG TÍNH (R≈G≈B), cố ý không ám xanh/ám vàng. */
  /* Nhạt lại một bậc cùng đợt với --ink/--heading (2026-08-04). Bộ này gần
     như không còn call-site trực tiếp (mọi nơi đã đọc --ink/--heading/
     --gray-*), giữ để không vỡ chỗ nào còn sót. */
  --primary:      #33363A;   /* Đen → than — nút chính/nhấn, icon nổi */
  --primary-dark: #26292C;   /* Đen sâu → than đậm — border đậm, hover */
  --text:         #33363A;   /* = --heading */
  --secondary:    #6E7276;   /* Xám trung — chữ phụ, icon phụ, divider */
  --accent:       #55585C;   /* = --ink — badge, tag, trạng thái */
  --background:var(--bg);   /* Trắng — nền website */
  --surface:      #F4F2ED;   /* Kem — card, input, box nền, hover nhẹ */

  /* Nền */
  --white:      #FFFFFF;   /* CHỈ còn là màu CHỮ/ICON trên nền tối — nền dùng --bg */
  /* 2026-09-07: tách vai NỀN khỏi MỰC. --bg là mặt nền (trang, header, section
     sáng, card, ô nhập, nút sáng) — mọi `background:var(--white)` / `#fff`
     trong 10 file CSS đọc token này; --white chỉ còn là mực trắng trên nền tối
     (.on-dark h2, chữ hover CTA). Khách từng thử --bg = #F5F4EF (kem) rồi rút
     lại trong cùng ngày: "không ổn, đổi lại màu trắng" — sắc kem chuyển sang
     --gray-100 (nền section/panel xám) thay thế. Giữ token để lần sau đổi nền
     là một dòng. */
  --bg:         #FFFFFF;
  --cream:      #F4F2ED;   /* nền section xen kẽ / card — sắc kem duy nhất */
  --paper:      var(--bg);   /* = --background */

  /* ===== Khối màu ấm-trung tính — lấy từ ref manubens.es =====
     Hai sắc này là NỀN CỦA Ô ẢNH trong lưới mosaic, không phải nền trang.
     Nền trang vẫn trắng; sand/greige chỉ đóng vai khối đặc xen giữa. */
  --sand:       #B0B1B2;   /* ô thị trường — nền lộ ra lúc ảnh chưa tải.
                              XÁM TRUNG TÍNH từ 2026-08-19: bản cũ #B5A68A là cát
                              ấm, tức nâu nhạt — khách chốt bỏ hẳn sắc nâu. */
  --greige:     #B4B5B7;   /* ô sản phẩm / nền ảnh — xám trung tính (bản cũ
                              #B3ADA4 ngả be, bỏ cùng đợt với --sand) */

  /* Mực / xám trung tính. NHẠT LẠI 2026-08-04 theo yêu cầu khách
     ("giảm sắc độ màu xám, nhạt lại"): #3B3D40 → #55585C, tức 10.89:1 xuống
     7.15:1 trên nền trắng. Vẫn dư xa ngưỡng AA 4.5:1 cho chữ thường. */
  --ink:        #55585C;   /* heading = --text — 7.15:1 trên trắng */
  --gray-700:   #55585C;   /* body — 7.15:1 trên trắng, 6.27:1 trên --gray-100 */
  /* #666D70 GIỮ NGUYÊN, KHÔNG nhạt theo đợt trên — đây là ngoại lệ có số đo:
     token này dùng cho chữ nhỏ 12.5-13px (.contact-form__note, .pd-note,
     .m-nlist__note, .footer__cert-txt), và một phần trong số đó nằm trên nền
     --gray-100 chứ không phải nền trắng. Đo tại đó:
        #666D70 trên #EFF0F1 → 4.62:1  ✓ vừa qua sàn AA 4.5
        #6E7276 trên #EFF0F1 → 4.25:1  ✗ rớt chuẩn
     Nhạt thêm đúng MỘT nấc là chữ chú thích rớt chuẩn đọc. Chênh lệch với
     --gray-700 mới (7.15) vẫn đủ để phân biệt chữ chính / chữ phụ. */
  --gray-500:   #666D70;   /* muted = --secondary — 5.27:1 trên trắng */
  /* Bậc 400 — 3.56:1 trên trắng: dưới sàn chữ thường 4.5 nhưng ĐẠT sàn 3:1 của
     CHỮ CỠ LỚN. Đừng mượn cho chữ nhỏ; nhạt hơn nữa là rớt hẳn (#949698 còn
     2.97:1).
     HIỆN KHÔNG CÓ CALL-SITE: thêm vào cho số cỡ lớn ở trang giới thiệu, rồi
     cùng ngày khách đổi ý sang màu vàng (xem .m-story__stat-num trong
     about.css). GIỮ LẠI vì đây là lối quay về đã đo sẵn nếu khách thấy số vàng
     mờ quá — không phải token chết bỏ quên. */
  --gray-400:   #86888A;   /* số cỡ lớn / chữ phụ CỠ LỚN — 3.56:1 trên trắng */
  --gray-200:   #E3E1DC;   /* border — ám kem rất nhẹ để hoà với --surface */
  /* Nấc nhạt nhất của thang xám — nền cho dải xám (hiện chỉ .m-news).
     TRUNG TÍNH THẬT (R≈G≈B, lệch 2 điểm): đây chính là điểm khác --cream
     (#F4F2ED, ám vàng 7 điểm). Hai token này KHÔNG thay thế nhau được —
     --cream dành cho card/khối kem, --gray-100 dành cho dải nền xám.
     Đừng làm đậm thêm mà không đo lại: --gray-500 (chữ nhỏ 12.5-13px) đặt
     trên nền này chỉ còn 4.62:1, sát ngưỡng WCAG AA 4.5:1. */
  /* 2026-09-07: #EFF0F1 (xám lạnh) → #F5F4EF (kem ấm) theo khách. Có thử #FFFDF4
     một lượt nhưng khách thấy "sáng quá" và quay về #F5F4EF — đây là bản chốt.
     Đây là nền section xen kẽ và panel form. Cách trắng 1.10:1, đủ để
     đọc ra khối. Tương phản chữ trên nền:
        #666D70 → 4.78:1 (cũ 4.62) · --gray-500 #6E7276 → 4.40:1 (cũ 4.25 ✗, nay ✓)
     nên các ghi chú AA phía dưới về #EFF0F1 vẫn đúng chiều, chỉ dư an toàn hơn. */
  --gray-100:   #F5F4EF;   /* nền section / panel — kem ấm */

  /* ===== NHẤN — VÀNG METALLIC, TRÊN NỀN XÁM/TRẮNG/ĐEN =====
     Khách chốt 2026-08-19 (hai lượt trong ngày):
       1. đổi tone navy → vàng metallic #D3AF37;
       2. **KHÔNG DÙNG MÀU NÂU**. Xám/trắng/đen là màu chính, vàng chỉ dành cho
          MỘT ÍT hành động nhỏ; được phép thêm sắc vàng nhạt #E9D491.
     Yêu cầu 2 là thứ định hình cả bảng dưới đây, nên phải hiểu vì sao:

     ⚠️ "VÀNG ĐẬM" LÀ NÂU. Vàng metallic trên nền trắng chỉ 2.11:1 nên không
     làm chữ được; phản xạ tự nhiên là hạ độ sáng cho đủ tương phản, nhưng vàng
     hạ sáng thì ra ĐỒNG THAU/NÂU (#8A6A16 — đúng thứ khách vừa bác bỏ). Không
     có lối thoát nào trong sắc vàng: muốn đọc được trên trắng thì phải nâu.
     KẾT LUẬN, và đây là quy tắc của cả site:
       · CHỮ, LIÊN KẾT, VÒNG FOCUS, VIỀN trên nền sáng → XÁM ĐEN trung tính.
         Vàng KHÔNG bao giờ làm chữ trên nền sáng.
       · VÀNG chỉ xuất hiện ở ba chỗ: (a) nền nút hành động, chữ trên đó là ĐEN;
         (b) dấu/chấm/thanh trang trí nhỏ; (c) mọi thứ nằm trên NỀN TỐI.
     Số đo thật: #D3AF37 ↔ #141516 8.67:1 ✓ · #E9D491 ↔ #141516 12.44:1 ✓ ·
     #33363A ↔ trắng 12.14:1 ✓ · #D3AF37 ↔ trắng 2.11:1 ✗.

     CỐ Ý GIỮ TÊN --gold* dù --gold-deep nay KHÔNG còn là màu vàng: ~60
     call-site trong 12 file đọc các token này. Đổi tên là 60 điểm có thể sót,
     đổi GIÁ TRỊ ở đây là một điểm duy nhất. (Tên này đã sống qua vàng → đen →
     navy → vàng; nó là VAI TRÒ, không phải màu.) */
  /* 2026-09-07: khách đổi màu hành động từ #D3AF37 (đặc) sang GRADIENT vàng.
     Trong ngày đổi qua lại: #F2D469 → #DBA026, #E0C982 → #D5A11D, quay về
     #F2D469 → #DBA026, #FFF1BD → #F5C753, rồi CHỐT #FFEEB6 → #E3B23E (lần 5; chiều
     vẫn 180deg: sáng trên, tối dưới). Gradient là ẢNH NỀN, không phải màu, nên
     chỉ đặt được vào `background` — chữ, icon, viền, chấm, thanh 2px và JS
     (effects.js đọc --gold để tô số bước) vẫn cần MỘT màu đặc: --gold nay là
     ĐẦU TỐI của gradient (#E3B23E — xem ghi chú ngay tại token), để dấu nhỏ đứng cạnh nút gradient
     không lệch tông.
     Quy tắc call-site:
       · Mặt NGHỈ của CTA, tag, ô "đang chọn"  → var(--gold-grad)
       · Mặt HOVER của ô trung tính (pager, social, mũi tên tin tức) → var(--gold)
         đặc, vì background-image KHÔNG animate được — đổi gradient ở hover là
         nhảy màu cụt, mất transition .25s đã có.
       · Hai CTA chính (.btn-primary, .m-about__more) hover bằng lớp ::after mờ
         dần (opacity) đè lên gradient — cùng lý do.
     Tương phản đo lại với mực --btn-ink #141516: đầu sáng #FFEEB6 15.81:1 ·
     đầu tối #E3B23E 9.32:1 (cũng là --gold) · hover đậm
     #D1A439 7.91:1 — đều ✓ AA. Trắng trên đầu tối chỉ 1.96:1 ✗, nên
     chữ trên gradient VẪN LÀ ĐEN, y như trước. */
  /* --gold lấy ĐẦU TỐI của gradient chứ không phải điểm giữa: đầu sáng của các
     cặp khách chọn đều rất nhạt, điểm giữa trên nền trắng chỉ ~1.3–1.5:1 nên
     chấm, thanh gạch chân, số bước gần như tàng hình. Đầu tối cũng là phần đáy
     nút mà mắt nhận là "màu nút". Với #E3B23E: 1.96:1 trên trắng. Vẫn chỉ
     dùng cho dấu trang trí, không bao giờ cho chữ chạy trên nền sáng. */
  --gold:       #E3B23E;   /* đầu tối gradient — dấu nhỏ, icon, viền, hover ô trung tính */
  --gold-deep:  #33363A;   /* VAI "chữ/nét nhấn trên nền sáng" — nay là XÁM ĐEN
                              trung tính, KHÔNG phải vàng đậm (vàng đậm = nâu) */
  --gold-light: #E9D491;   /* vàng nhạt khách đưa — CHỈ dùng trên NỀN TỐI */
  /* 180deg = sáng TRÊN, tối DƯỚI (khách chốt 2026-09-07 "đổi chiều từ trên xuống";
     bản đầu 135deg chéo). */
  --gold-grad:  linear-gradient(180deg,#FFEEB6 0%,#E3B23E 100%);   /* mặt nghỉ CTA/tag */

  /* ===== MÀU HÀNH ĐỘNG — VÀNG ĐẶC + CHỮ ĐEN =====
     Nút primary (Liên hệ báo giá, Gửi yêu cầu), cụm nút nổi, nút điều hướng.
     Nền/chữ/khối trung tính vẫn là thang xám đơn sắc — vàng là điểm nhấn, KHÔNG
     phải màu nền của site.

     CHỮ TRÊN NÚT LÀ ĐEN, KHÔNG PHẢI TRẮNG: trắng trên #D3AF37 chỉ 2.11:1 —
     rớt chuẩn, không phải chuyện thẩm mỹ. #141516 trên #D3AF37 8.67:1 ✓, trên
     hover #BE9A2A 6.83:1 ✓. Mực ĐEN TRUNG TÍNH (#141516 = --dark) chứ không
     phải đen ngả nâu: cùng lý do "không dùng màu nâu" ở trên. */
  /* ===== VÒNG FOCUS CỦA Ô NHẬP — MỘT TOKEN CHO MỌI Ô (khách 2026-09-07) =====
     Trước có 4 kiểu: form liên hệ viền TRONG 1.5px xám đen (khách: "border màu
     đen → không ok"), tìm kiếm header viền ngoài vàng 3px, tìm kiếm trang 4px,
     menu mobile chỉ đổi viền. Nay tất cả CHỈ CÒN quầng ngoài 3px vàng 40% (khách
     bỏ luôn viền trong 1.5px: "chỉ để quầng vàng phía ngoài thôi"); viền nghỉ
     của ô giữ nguyên màu. color-mix lấy thẳng từ --gold nên đổi gradient là vòng
     đổi theo (trước là rgba(211,175,55) gõ cứng của mã vàng cũ). */
  --ring:        0 0 0 3px color-mix(in srgb, var(--gold) 40%, transparent);
  --btn-grad:   var(--gold-grad);
  /* HOVER CTA chính = GRADIENT XÁM ĐEN (khách 2026-09-07: "màu của button khi
     hover đổi thành gradient xám đen giống kiểu vàng khi default"): cùng chiều
     180deg, sáng trên tối dưới, hai đầu là --gray-700 → --dark. Chữ chuyển trắng
     (trắng trên #2B2D30 > 12:1). --btn-grad-h (vàng đậm) không còn call-site,
     giữ token phòng khách đổi ý. TÊN --btn-grad-dark chứ không --dark-grad:
     token --dark-grad đã có sẵn ở dưới (ba nấc gần đen cho khối nền tối) và
     khai sau sẽ ghi đè — đã dẫm phải một lần. */
  --btn-grad-dark: linear-gradient(180deg,#55585C 0%,#2B2D30 100%);
  /* hover: cả hai đầu đậm hơn một bậc, KHÔNG phải sáng lên. Áp qua ::after
     mờ dần (xem .btn-primary), vì gradient không transition được. */
  --btn-grad-h: linear-gradient(180deg,#EBDBA7 0%,#D1A439 100%);
  --btn-ink:    #141516;   /* chữ/icon TRÊN mảng vàng — xem dẫn giải ngay trên */

  /* Nút CTA cụm nổi (gọi hotline + lên đầu trang): cùng một màu đặc. */
  --cta-grad:   var(--gold-grad);
  --cta-ink:    #141516;   /* icon ĐEN trên vàng — 8.67:1 ✓ */
  /* Không viền (yêu cầu khách 2026-07-27) → bóng là thứ tách nút khỏi nền. */
  --cta-shadow: 0 10px 26px rgba(0,0,0,.35);

  /* Nền tối */
  --dark:       #141516;   /* footer / section tối (đen trung tính) */
  /* Gradient nền tối: than → gần đen */
  --dark-grad:  linear-gradient(180deg,#2A2C2E 0%,#141516 52%,#08090A 100%);

  /* ===== FOOTER — thang riêng trên nền tối (spec §1.1) =====
     Bốn giá trị này trước đây gõ thẳng ~12 chỗ trong khối footer (#D8D5CC 4×,
     #9A9CA0 5×, rgba(255,255,255,.06) 2×, rgba(255,255,255,.1) 1×). Gom về đây
     vì footer sắp được dựng lại theo Manubens ở đợt sau: khi đó chỉnh sắc chữ
     là chỉnh một dòng, không phải rà 12 chỗ và bỏ sót vài chỗ.
     TƯƠNG PHẢN đo trên nền --dark #141516: chữ chính 12.5:1 ✓ · chữ phụ 6.7:1 ✓
     — cả hai dư chuẩn AA cho chữ thường. Hạ --footer-muted nhạt thêm là rớt. */
  --footer-bg:     var(--dark);
  /* 2026-09-07: chữ footer về MỘT SẮC TRẮNG, chỉ khác opacity (khách: "text body
     đổi thành màu trắng opacity giống nhau"). Trước là ba màu xám pha khác nhau
     (#D8D5CC nhãn · #9A9CA0 mô tả · #fff link menu) nên cùng một vai mà ba sắc.
     .92 cho nhãn/tagline, .72 cho mọi chữ chạy — kể cả link menu. */
  --footer-text:   rgba(255,255,255,.92); /* nhãn cột, tagline, <strong> */
  --footer-muted:  rgba(255,255,255,.72); /* chữ chạy: địa chỉ, mô tả, tên chứng nhận, link menu */
  --footer-border: rgba(255,255,255,.1); /* đường kẻ chia */
  --footer-tile:   rgba(255,255,255,.06);/* nền ô chứng nhận / khối nổi nhẹ */

  /* ===== Ba nấc trung tính spec §1.1 yêu cầu mà thang cũ chưa có =====
     Không đặt tên --color-* như spec: site đã có sẵn một thang tên khác
     (--gray-*, --surface, --heading) đang được ~40 call-site dùng, thêm bộ tên
     thứ hai cho cùng những màu đó là mời gọi hai nguồn sự thật. Ba token dưới
     đây là những nấc THẬT SỰ CÒN THIẾU, đặt theo lối tên sẵn có của site. */
  --surface-2:     #EFEFF1;   /* nền card/hover nhẹ — spec --color-surface-2 */
  --border-strong: #C9C9CE;   /* viền đậm hơn --gray-200 khi cần tách rõ */
  /* CẢNH BÁO TƯƠNG PHẢN — token này KHÔNG thay được --gray-500.
     Đo thật: 3.43:1 trên nền trắng → chỉ đạt ngưỡng "chữ lớn" (3:1), tức từ
     24px thường hoặc 18.66px đậm trở lên. Chữ nhỏ 13px (ngày tháng, meta) mà
     dùng token này là RỚT chuẩn AA — vẫn phải dùng --gray-500 (5.27:1).
     Trên --surface-2 nó chỉ còn 2.98:1, tức hỏng ở MỌI cỡ chữ. */
  --text-subtle:   #8A8A92;
  /* PLACEHOLDER (khách 2026-09-22: "placeholder nhạt rõ hơn so với khi điền"):
     tách hẳn khỏi --text-subtle. #B4B6BA ≈ 2.3:1 trên trắng — cố ý dưới AA vì
     placeholder là GỢI Ý, không phải nội dung; chữ đã điền là --ink. */
  --placeholder:   #B4B6BA;

  /* ===== Typography — HAI font (chốt 2026-09-07): serif tiêu đề · sans chữ chạy =====
     · --font-heading = Playfair Display (Google Fonts): h1–h4, .footer__since b, banner h1
       (qua --font-accent). h1 nét --fw-h1 700, h2–h4 nét --fw-heading 500.
     · --font-body = SVN-Georgia (tự host): chữ chạy, nav, nút, nhãn, số liệu — mọi chỗ gọi
       --font-display cũng về đây.
     Lịch sử trong ngày: EB Garamond (sáng) → Playfair (trưa) → bộ này (chiều).
     ⚠️ SỐ ĐO ĐÃ LÀM LẠI cho bộ này (canvas, 100px, bộ ký tự xấu nhất):
          sàn line-height  Beautique 700 = 1.250 · 500 = 1.221 · AlmarenaVN 400 = 1.151
          (SVN-Gotham cũ: 500 = 1.281 · 400 = 1.263)
       → mọi token --lh-* hiện có đều CAO HƠN sàn, giữ nguyên.
       cap-height Beautique 0.78 (Gotham 0.70, +11%), x-height 0.58 (Gotham 0.53);
       AlmarenaVN x-height 0.516 ≈ Gotham. Vì thế thang --fs-* QUAY VỀ các giá
       trị khách đã duyệt với Gotham (đợt +22% cho Playfair đã bỏ) — tiêu đề nay
       trông nhỉnh hơn Gotham ~11% ở cùng cỡ, đúng hướng "nâng cỡ" khách muốn.
       Bề rộng "Hữu Tín": Beautique 700 = 398 (Gotham 500 = 391) → tracking 0
       vẫn đúng; AlmarenaVN 400 = 322 (Gotham 388, −17%) → body tracking 0.
     --font-accent chỉ còn là alias của --font-heading. */
  --font-heading: "Playfair Display",Georgia,"Times New Roman",serif;
  --font-body:    "SVN-Georgia",Georgia,"Times New Roman",serif;
  --font-accent:  var(--font-heading);
  /* Alias lịch sử: nút, nav, nhãn, số liệu, eyebrow… — đi cùng chữ chạy. */
  --font-display: var(--font-body);

  /* ===== THANG NÉT CHỮ — ĐÚNG 4 MỐC, KHÔNG HƠN =====
     Bốn con số này là bốn FILE CÓ THẬT trong assets/fonts/. Không có mốc nào
     khác được phép xuất hiện trong CSS.
     Trước 2026-08-04 có 11 chỗ khai font-weight:600 — nét KHÔNG CÓ FILE, nên
     trình duyệt phải tự tổng hợp; Chrome, Safari và Firefox tổng hợp khác nhau
     nên cùng một nhãn ra ba độ đậm tuỳ máy. Đó là một trong hai nguồn chính
     của cảm giác "chữ toàn site không thống nhất" mà khách nêu.
     Muốn đậm hơn 500 thì nhảy thẳng lên 700, đừng ghé 600.
     2026-09-07: quy tắc vẫn đúng với bộ chốt cuối — Beautique Display không có
     file 600 (khai 600 là lấy Bold, h2 sẽ bằng h1), AlmarenaVN càng không. */
  --fw-light:    300;   /* SVN-Georgia không có 300 → rơi về 400 */
  --fw-body:     400;   /* SVN-Georgia Regular 400          */
  --fw-medium:   500;   /* KHÔNG có file → rơi về Light 400 */
  --fw-bold:     700;   /* SVN-Georgia Bold 700             */
  /* ===== NÉT TIÊU ĐỀ — 500, ĐỪNG ĐỔI VỀ 600 =====
     Giá trị này đã bị lật qua lật lại trong CÙNG ngày 2026-08-04, nên ghi đủ
     cả hai vế ở đây để không ai phải đoán lại:

     · Vòng trước đặt 600 theo yêu cầu "tiêu đề semibold". Phép đo kèm theo lúc
       đó ĐÚNG và vẫn còn giá trị: SVN-Gotham không có file 600, mà quy tắc so
       khớp nét của CSS quy định nét yêu cầu > 500 thì tìm LÊN trước, gặp 700 là
       lấy. Bề rộng một chuỗi thật ở 100px:
          nét 400 → 2050,8px
          nét 500 → 2058,8px
          nét 600 → 2064,6px
          nét 700 → 2064,6px   ← TRÙNG KHÍT 600
       Tức 600 không phải nét trung gian mà chính là face Bold (chọn file có
       thật, không tổng hợp — nên nó ổn định giữa các trình duyệt).

     · NHƯNG chính điều đó phá hỏng spec §1.3, thứ khách cũng chốt cùng ngày:
       tiêu đề phải TRỘN hai nét trong một dòng (phần dẫn Regular + cụm nhấn
       <span class="h-hl"> Bold). Nền 600 và nhấn 700 vẽ bằng ĐÚNG MỘT FILE nên
       cụm nhấn tàng hình — bảng đo ở trên chính là bằng chứng.

     Chốt 2026-08-04 (sau khi trình bày số đo): nền 500, nhấn 700. Đây là nấc
     nặng nhất còn giữ được tương phản, vì giữa 500 và 700 không có file nào.
     Muốn tiêu đề nặng hơn nữa thì phải BỎ hẳn yêu cầu trộn nét ở §1.3 — hai
     điều đó loại trừ nhau, không thể có cả hai.

     CHỐT LẠI 2026-08-05: khách bỏ hẳn yêu cầu trộn nét ("không dùng 2
     font-weight khác nhau nữa, chuyển về cùng loại khoảng 500"). Đúng cái vế
     mà đoạn trên nói là bắt buộc phải bỏ nếu muốn thoát thế loại trừ. Nay
     tiêu đề MỘT nét 500 từ đầu đến cuối; .h-hl không còn đổi nét nữa, chỉ còn
     là móc ngữ nghĩa cho i18n (xem rule h1 .h-hl … bên dưới).
     Số đo ở trên vẫn giữ nguyên giá trị tham chiếu: đừng khai 600 ở bất cứ
     đâu, nó vẽ ra đúng file Bold. */
  --fw-heading:  500;   /* h2–h4: Playfair Display 500 (Playfair có cả 600 nếu khách muốn semibold thật) */
  /* 2026-09-07: khách tách nét theo cấp — TIÊU ĐỀ TRANG (h1, kể cả banner) Bold,
     tiêu đề nhỏ hơn "semibold". Token riêng cho h1 để không phá chốt "một nét
     trong một dòng" ở trên: trong MỘT tiêu đề vẫn chỉ có một nét, chỉ khác nhau
     GIỮA các cấp. */
  --fw-h1:       700;   /* h1: Playfair Display Bold */

  /* ===== THANG CỠ CHỮ — 10 NẤC, MỌI CALL-SITE ĐỌC TỪ ĐÂY =====
     Nguồn thứ hai của "chữ không thống nhất": trước 2026-08-04 có ~70 khai báo
     font-size rời rạc trong 10 file CSS, gồm những cụm gần trùng đến mức không
     phân biệt nổi bằng mắt — riêng "đoạn văn thường" đã có 9 biến thể
     (16px · 15px · 17px · clamp(14.5,1.15,16.5) · clamp(15,1.25,17.5) ...),
     "tiêu đề section" 9 biến thể, "chữ nhỏ" 9 biến thể. Không ai cố ý làm vậy;
     nó tích tụ do mỗi section được dựng ở một thời điểm khác nhau.
     ĐỪNG viết số rời tại call-site nữa. Cần một cỡ chưa có ở đây thì hoặc dùng
     nấc gần nhất, hoặc thêm nấc mới VÀO ĐÂY kèm lý do.
     Ngoại lệ có chủ ý (chữ do JS điều khiển, số cỡ lớn vai trò đồ hoạ) được
     ghi chú tường minh ngay tại chỗ — xem .banner h1, .pwheel__item, .seal__num. */
  /* Giá trị trong ngoặc là cỡ THỰC TẾ ở khổ 1440px — dùng để soi thứ bậc.
     Thang chia làm HAI VÙNG, cố ý bước khác nhau:
       tiêu đề  bước ~1.4×       (46 · 32 · 20 · 18)
       chữ chạy bước ~1.12×      (18 · 16,5 · 14,5 · 13 · 12)
     Nhờ vậy nhìn vào là biết đâu là tiêu đề đâu là chữ thường, không phải đoán.

     CHỈNH 2026-08-04 vòng 3 (khách: "trang con vẫn còn chữ to nhỏ bất thường"):
       · --fs-h4 17,2 → 20px. Cũ chỉ hơn --fs-body 4% — một TIÊU ĐỀ mà to hơn
         đoạn văn có 0,7px thì đọc ra như lỗi chứ không ra thứ bậc.
       · --fs-h3 21 → 25px. Lấp bớt hố 38→21 giữa tiêu đề section và tiêu đề
         thẻ, đồng thời tách rõ khỏi --fs-h4 mới.
       · --fs-sm 15,08 → 14,5px. Cũ trùng gần khít --fs-ui (15px): hai token
         cách nhau 0,5% là hai token không phân biệt được, chỉ tạo cảm giác
         "cỡ chữ lộn xộn" đúng như khách nêu.
       · --fs-lead 20 → 18px, để không giẫm lên --fs-h4 mới.

     CHỈNH 2026-08-05 vòng 5 (khách: "giảm nhẹ font-size tiêu đề khoảng 4-8px"):
     giảm theo BẬC THANG chứ không trừ phẳng một con số — 8 · 6 · 6 · 4 · 2 từ
     trên xuống. Lý do h3/h4 không trừ đủ 4-8px: --fs-body giữ nguyên (16,5px ở
     1440), trừ h4 đủ 8px là đưa nó xuống 12px, tức NHỎ HƠN đoạn văn — chính là
     lỗi vòng 3 vừa sửa. Sàn clamp gần như giữ nguyên nên bản mobile không đổi;
     toàn bộ phần giảm dồn vào khổ desktop, nơi khách nhìn thấy chữ to. */
  /* 2026-09-07: từng NÂNG +22% cho Playfair (cap-height thấp), rồi BỎ khi khách
     chốt Beautique Display — font này cap-height 0.78, CAO hơn Gotham 0.70, nên
     thang gốc khách đã duyệt tự cho tiêu đề nhỉnh hơn ~11%, không cần bù nữa. */
  /* CHỈNH 2026-09-22 (khách: "text body trên web bị nhỏ quá, tăng đồng bộ 2px",
     rồi "to hơn 2px nữa", rồi "hơi to, giảm 1px", rồi "giảm thêm 1px" → tổng
     +2px so với thang 08-05; TIÊU ĐỀ h1–h4 +2px và --btn-fs +2px giữ nguyên).
     ĐỔI FONT 2026-09-22 (Philosopher → SVN-Georgia): đo canvas cùng cỡ, Georgia
     rộng hơn 5,4%, chữ hoa cao hơn 5%, x-height cao hơn 2% → CẢ VÙNG CHỮ CHẠY
     trừ lại 1px (nay +1px so với 08-05), --btn-fs 15.5 → 14.5, và --lh-* nới
     +.05 vì serif x-height cao cần thoáng dòng hơn sans hẹp.
     (Trước đó: CẢ VÙNG CHỮ CHẠY cộng phẳng +2px ở sàn lẫn trần clamp (lead · body · sm ·
     meta · micro · ui, và body 640px). Tiêu đề GIỮ NGUYÊN — khoảng cách
     h4 (18) ↔ body (18,5) nay gần bằng nhau, nếu khách kêu "tiêu đề nhỏ hơn
     chữ" thì nâng h3/h4 theo, đừng hạ body lại. */
  --fs-display:  clamp(40px,4.9vw,78px);    /* 78 · số cỡ lớn: con dấu "20 NĂM" */
  /* h1 +6px (khách 2026-09-07 tối, đợt 2: "những tiêu đề chỗ này to hơn 4-8px" —
     hero trang con, bài viết, banner). Đi cùng h2 38 → bậc thang 52 · 38 · 20. */
  --fs-h1:       clamp(31px,3.85vw,54px);   /* 54 · tiêu đề trang               */
  /* h2 +6px (khách 2026-09-07 tối: "tiêu đề cho to hơn khoảng 4-8px", ví dụ đưa
     ra đều là tiêu đề section). Chỉ h2; h1 46 và h3 20 giữ nguyên nên bậc thang
     thành 46 · 38 · 20 — h2 sát h1 hơn nhưng vẫn tách được nhờ h1 nét Bold. */
  --fs-h2:       clamp(27px,2.85vw,40px);   /* 40 · tiêu đề section             */
  /* SÀN của h3/h4 giữ cao hơn --fs-lead (sàn 16px): ở khổ 390px mọi nấc đều
     kịch sàn, mà --fs-lead sàn 16px — để h4 cũng 16px thì một TIÊU ĐỀ bằng
     chằn chặn đoạn văn ngay dưới nó. Sàn khác nhau giữ được thứ bậc ở khổ hẹp,
     nơi thang bị nén mạnh nhất. h4 chạm sàn 16px là chấp nhận được vì ở 390px
     --fs-body cũng kịch sàn 15px — vẫn còn chênh 6,7%. */
  /* Trần 20px (khách chốt 2026-08-05, trước 24px). Tên sản phẩm trên vòng xoay
     KHÔNG còn đọc token này nữa — khách yêu cầu tăng riêng nó lên, xem
     .pwheel__item.is-active trong home.css. */
  --fs-h3:       clamp(20px,1.5vw,22px);    /* 22 · tiêu đề thẻ / khối con      */
  --fs-h4:       clamp(18px,1.3vw,20px);    /* 20 · tiêu đề nhỏ, nhãn khối      */
  --fs-lead:     clamp(17px,1.25vw,19px);   /* 19 · đoạn mở đầu section         */
  --fs-body:     clamp(16px,1.15vw,18px);   /* 17,5 · đoạn văn chuẩn            */
  --fs-sm:       clamp(14.5px,1.01vw,15.5px); /* 15,5 · mô tả thẻ, chú thích    */
  --fs-meta:     14px;                      /* ngày, nhãn ô nhập, ghi chú     */
  --fs-micro:    13px;                      /* nhãn IN HOA giãn chữ, tag      */
  /* Chrome giao diện: menu, ô nhập, nút ngôn ngữ, link cột footer.
     CỐ ĐỊNH, KHÔNG co giãn theo vw — khác hẳn --fs-body dù cùng xuất phát từ
     15px. Lý do: đám này nằm trong khung có chiều cao/bề ngang cố định
     (header cao 64px, ô tìm kiếm rộng 230px, cụm nav+actions đã sát nhau ở
     khoảng 1360-1560px). Cho nó nở tới 17px ở màn rộng là đẩy cụm bên phải
     chen vào nav giữa. Nội dung thì nên co giãn, chrome thì không. */
  --fs-ui:       16px;

  /* Heading colours — tiêu đề nay MỘT màu, một nét, không tách chữ nhấn nữa
     (trước: nửa câu đen + nửa câu xám qua .h-hl). */
  /* PHẢI đậm hơn --gray-700 (chữ thường). Trước để bằng nhau y hệt #3B3D40 nên
     tiêu đề không tách khỏi đoạn văn — đọc ra là "tiêu đề bị nhạt". Chênh lệch
     này là tầng phân cấp RẺ NHẤT: không tốn thêm cỡ chữ hay nét nào. */
  /* NHẠT LẠI cùng đợt với --ink (2026-08-04): #1C1F22 → #33363A, tức
     16.56:1 xuống 12.14:1. Vẫn phải ĐẬM HƠN --gray-700 (7.15:1) — chênh lệch
     đó là tầng phân cấp rẻ nhất, không tốn thêm cỡ chữ hay nét nào. */
  --heading:      #33363A;   /* tiêu đề trên nền sáng — 12.14:1 */
  /* Không còn --hl: tiêu đề nay MỘT màu, .h-hl đã tàng hình. --hl-dark còn lại
     vì footer vẫn dùng cho tagline + dòng "since", không phải cho tiêu đề. */
  --hl-dark:      #D8D5CC;   /* accent tone on dark bg (footer only) */

  /* ===== THANG LINE-HEIGHT — SỐ ĐO, KHÔNG PHẢI THẨM MỸ =====
     Khách thấy khoảng dòng hơi lỏng (2026-08-04) nên cả thang đã siết ~12%.
     Nhưng có một SÀN CỨNG không được vượt qua, đo lại trực tiếp trên file font
     bằng canvas.measureText với bộ ký tự xấu nhất
     (ẾỀỄỆẤẦẪẬỐỒỖỘỚỜỠỢỨỪỮỰ + ẠẸỊỌỤỴ + gjpqy):

       nét 400 (body)     ascent 1.10 · descent .20 · ink 1.050 / .188
       nét 500 (tiêu đề)  ascent 1.15 · descent .20 · ink 1.087 / .192

     Có HAI ràng buộc, và trước đây chúng bị gộp làm một nên sàn bị đẩy lên cao
     hơn thực tế:

     1. CẮT CHỮ trong hộp dòng — chỉ áp dụng khi có overflow:hidden, tức mặt nạ
        reveal. Cần L >= 2·inkAsc − asc + desc và L >= 2·inkDesc + asc − desc
        → nét 500 ra 1.334. NHƯNG .reveal-word-wrap đã tự chừa .14em mỗi bên
        (padding-block/margin-block bù nhau), nên hộp cắt thật là L + .28em →
        ràng buộc này chỉ còn L >= 1.054. KHÔNG còn là ràng buộc quyết định.

     2. HAI DÒNG CHẠM NHAU — áp dụng cho MỌI tiêu đề/đoạn văn xuống dòng, không
        liên quan overflow. Hai baseline cách nhau đúng L, nên điều kiện là
        L > inkAscent + inkDescent:
            tiêu đề nét 500 → 1.087 + .192 = 1.279
            body    nét 400 → 1.050 + .188 = 1.238
        ĐÂY mới là sàn thật.

     Kiểm chứng lại bằng cách RASTER HOÁ hai dòng thật rồi dò pixel có mực
     (không chỉ tin công thức) — cặp "HẠNH PHÚC TRỌN VẸN MỤC TIÊU" trên
     "ĐỀ CAO UY TÍN VỚI HỮU TÍN", nét 500:
        lh 1.28 → khe .060em  ✓
        lh 1.20 → ĐÈ  .020em  ✗
        lh 1.12 → ĐÈ  .100em  ✗
        lh 1.05 → ĐÈ  .170em  ✗
     Tức sàn thực dụng ≈ 1.22, sàn tuyệt đối (ghép glyph xấu nhất) 1.279.

     CẬP NHẬT 2026-08-04: nâng 1.28 → 1.30 theo spec §1.3 ("heading in hoa phải
     để line-height 1.3"). Bảng đo ở trên thực hiện ở NÉT 500; từ nay nét nền
     của tiêu đề là 400 và cụm nhấn là 700, tức cơ sở đo đã đổi — 1.30 cho thêm
     .02em đệm so với sàn tuyệt đối 1.279 đo được, đủ che phần chênh do nét 700
     có dấu nhỉnh cao hơn. Muốn hạ lại thì phải RASTER HOÁ LẠI ở nét 700 trước.

     1.28 từng là con số THẤP NHẤT còn an toàn ở CẢ HAI mức. Khách hỏi
     hạ 20-30% (tức 1.12-0.98) nhưng ở đó hai dòng đè nhau 10-17% em — dấu nặng
     Ạ/Ọ/Ụ dòng trên chồng lên dấu Ế/Ữ dòng dưới. Tiếng Việt có cả hai rất dày
     nên đây không phải trường hợp hiếm.
     ĐỔI FONT thì phải đo lại cả bảng này, đừng hạ bừa. */
  /* ĐÃ ĐO LẠI 2026-09-07 cho Beautique Display (canvas, ẾỮẦỔ trên / ẠỘỤ dưới):
     sàn 700 = 1.250 · 500 = 1.221 — sát Gotham 500 (1.281) vì cap-height 0.78
     cao, dấu chồng tầng vươn gần hết em-box. 1.30 còn dư .05em ở h1 Bold: ĐỦ
     nhưng không dư nhiều — đừng hạ. (Trong ngày còn đo Playfair 1.052, Garamond
     1.096, đều đã bỏ.) */
  --lh-heading:  1.30;
  /* Ba nấc cho chữ chạy — trước là 7 giá trị rời (1.4 1.45 1.5 1.55 1.6 1.65
     1.7 1.75 1.8) rải khắp 10 file cho cùng vài vai trò.
     LỊCH SỬ 2026-08-04: siết một lượt xuống 1.3 / 1.45 / 1.58, khách xem thấy
     "gần quá" nên nới lại một nấc thành 1.38 / 1.55 / 1.65. Vẫn thấp hơn bản
     gốc (1.45 / 1.65 / 1.78) khoảng 5-7%, tức vẫn đặc hơn trước, chỉ không còn
     sát sàn nữa. Khoảng dòng TIÊU ĐỀ không đụng tới, xem --lh-heading ở trên. */
  --lh-tight:    1.40;   /* body gốc, dòng ngắn 1-2 dòng, chú thích  (gốc 1.4-1.5)  */
  --lh-body:     1.60;   /* mô tả thẻ, đoạn văn trong section        (gốc 1.55-1.7) */
  --lh-relaxed:  1.70;   /* văn bản dài đọc liền: pháp lý, câu chuyện (gốc 1.75-1.8) */

  /* Tracking TIÊU ĐỀ — âm nhẹ (khách chốt 2026-08-04). Trước để normal (0).
     -.02em chứ không hơn: gần như MỌI tiêu đề trên site đều text-transform
     uppercase, mà chữ IN HOA vốn cần tracking RỘNG hơn chữ thường để đọc được
     (không có hình dáng lên/xuống của chữ thường để mắt bám). Siết tới -.03em
     như bản rất cũ là các dấu phụ tiếng Việt (Ư, Ơ, Ằ) chạm chữ bên cạnh.
     Chữ chạy có tracking riêng ở body (-.015em); nhãn IN HOA giãn chữ
     (.eyebrow, tag, .legal__map h2...) giữ tracking DƯƠNG của chúng — đó là
     vai trò khác, đừng gom vào đây. */
  /* 2026-09-07: về 0 — hai vế trên đo cho SVN-Gotham. Beautique Display 700 rộng
     tương đương ("Hữu Tín": 398 so với 391 của Gotham) nhưng là serif có chân,
     siết âm là chân chữ chạm nhau; 0 là đúng cho font này. */
  --ls-heading:  0;

  /* Layout */
  --maxw:        1280px;
  /* Nhịp RỘNG — header, giới thiệu, tin tức, liên hệ dùng CHUNG bề ngang này.
     Trước là 1600px/80px chép tay ở 2 nơi, còn tin tức + liên hệ thì kẹt ở
     --maxw 1280 nên đọc ra như bị thụt vào so với phần trên. Gom thành token
     để 4 chỗ không trôi khỏi nhau nữa. */
  --maxw-wide:   1600px;
  --pad-wide:    clamp(20px,5.5vw,80px);
  /* ===== HAI NHỊP KHOẢNG CÁCH DÙNG CHUNG (đo lại toàn site 2026-09-07) =====
     Khách: "có những chỗ cùng chức năng, cùng style nhưng khoảng cách lại khác".
     · --hero-gap: đệm TRÊN của section đầu tiên ngay sau .page-hero. Cộng với
       padding-bottom 20px của hero ra khe ~40px — chính con số khách đã duyệt
       cho trang Về Hữu Tín 2026-08-05 ("khối chữ đầu trang hở quá rộng").
       Trước khi gom: 38px (ve-huu-tin) · 46px (san-pham) · 20px (lien-he) ·
       61px (tin-tuc) · 76px (tim-kiem) · 90px (3 trang pháp lý).
     · --cta-col: bề ngang cột chữ của khối CTA cuối trang. .pd-sample từng khai
       760px nhưng bị `.pd-sample .container` (product.css, đặc hiệu hơn) kéo ra
       1600px — đoạn văn co về 1 dòng nên section thấp hơn .cta-band 29px dù hai
       khối cùng đệm 96px. */
  --hero-gap:    clamp(12px,1.4vw,20px);
  /* 720 → 860px (khách 2026-09-07: "tăng width cụm này" — khối CTA đóng trang). */
  --cta-col:     860px;
  --gutter:      24px;
  /* Ngôn ngữ hình khối: BO GÓC NHẸ (khách chốt 4-8px, 2026-08-04). Trước đó
     site chốt góc vuông nhọn tuyệt đối — mọi `border-radius:0` chép tay đã
     đổi sang đọc 3 token này, nên chỉnh ở đây là chỉnh cả site.
     Ba bậc chứ không một: bo cùng một số cho ô nhãn 24px và thẻ 400px thì ô
     nhỏ đọc ra như viên thuốc còn thẻ to gần như vẫn vuông.
     NGOẠI LỆ CÓ CHỦ Ý — ảnh TRÀN VIỀN vẫn để vuông (.fb--*, .pd-hero,
     .footer-hero, marquee, banner): chúng chạm mép màn hình, bo góc sẽ hở ra
     bốn khe trắng ở rìa; lưới sát nhau khe 3px thì bo góc còn sinh ra hình
     thoi trắng tại mỗi mối nối. */
  /* 2026-09-07: khách "giảm thêm bo góc của button" — 6 → 3px, nấc nhỏ 4 → 2px
     để giữ thứ bậc (chip luôn bo ít hơn nút). Gần vuông nhưng chưa vuông hẳn:
     ảnh/thẻ đã là 0 (--radius-lg), nút còn 3px để vẫn tách được khỏi khối ảnh. */
  --radius-sm:   2px;    /* nhãn, chip, ô icon nhỏ */
  --radius:      3px;    /* nút, ô nhập, ô icon vừa */
  /* 0 — KHÁCH CHỐT 2026-08-05: "bỏ bo góc toàn bộ hình và card, button để bo
     góc nhẹ (4-6px)". Nên bo góc nay tách làm hai vai rõ rệt:
       · KHỐI NỘI DUNG (ảnh, thẻ, panel) → vuông, đọc token này
       · ĐIỀU KHIỂN (nút, ô nhập, chip, tile icon) → 4-6px, đọc --radius-sm/--radius
     Việc giữ --radius-lg là một token riêng thay vì đi xoá 9 call-site chính là
     để đổi được một dòng như lần này. Đừng thay `var(--radius-lg)` bằng `0`
     chép tay ở call-site — làm thế là vứt mất cái công tắc. */
  --radius-lg:   0;      /* thẻ, ảnh trong khung, khối lớn — VUÔNG */
  /* HIỆN KHÔNG CÒN CALL-SITE NÀO. Khách chốt 2026-08-05 (vòng 6) cho mũi tên
     carousel bo nhẹ 6px như mọi nút khác, nên hai chỗ duy nhất đọc token này
     (.pwheel__btn và .m-news__nav button trong home.css) đã chuyển sang
     --radius. Giữ token lại làm chỗ dựng sẵn, đừng dùng cho khối chữ nhật —
     ngôn ngữ hình khối của site là bo NHẸ và ĐỀU.
     Lưu ý: .group-contact vẫn tròn nhưng nó hard-code 50% chứ không đọc token
     này, và đó là ngoại lệ khách yêu cầu trực tiếp (logo FB/Zalo vốn tròn). */
  --radius-full: 999px;
  --header-h:    64px;

  /* ẢNH KHÔNG CÓ LỚP PHỦ MÀU. Từng có --img-grade (saturate/sepia) kéo mọi ảnh
     về một tông, đã gỡ theo yêu cầu: ảnh giữ nguyên màu gốc. Đừng thêm filter
     màu lên ảnh nội dung nữa — với nhà sản xuất dây dệt thì MÀU CHÍNH LÀ SẢN
     PHẨM, hạ bão hoà là bóp méo thứ khách cần xem. */

  /* ===== NÚT — MỘT THANG DUY NHẤT =====
     Chuẩn lấy từ nút liên hệ (.btn.btn-primary — "Gửi yêu cầu" / "Liên hệ báo
     giá"), là nút đã được duyệt. Trước đó mỗi nơi một kiểu:
       nút chữ  : .btn 13.5px/700/.06em ‖ .m-about__more 16px/400/không hoa
                  ‖ .link-arrow 13px/600/.14em
       nút icon : 30 ‖ 32 ‖ 37 ‖ 39 ‖ 44 ‖ 48 px — bảy cỡ cho cùng một vai trò
     Mọi nút PHẢI lấy số từ đây, đừng viết số rời tại chỗ. */
  /* 44px (khách yêu cầu hạ chiều cao, 2026-08-04 — trước 50px).
     KHÔNG hạ tiếp: 44px là vùng chạm tối thiểu khuyến nghị trên cảm ứng, và
     cũng đúng bằng --btn-icon-sm bên dưới — tức từ nay MỌI nút trên site cao
     bằng nhau. Phân tầng "nút cấp section to hơn nút chrome" ghi trong chú
     thích --btn-icon/--btn-icon-sm coi như hết hiệu lực; giữ hai token riêng
     vì chúng vẫn có thể tách ra sau này, nhưng đừng tưởng chúng đang khác nhau. */
  --btn-h:       44px;    /* chiều cao nút chữ */
  /* Đệm ngang rộng hẳn + --btn-min-w bên dưới: khách muốn nút DÀI ra, chữ
     nằm giữa một khoảng thoáng chứ không bó sát mép (mẫu 2026-08-04). */
  --btn-pad-x:   40px;
  /* Bố cục lấy từ nút "Đọc thêm" ở section giới thiệu — bản đã được duyệt:
     chữ sát trái, mũi tên dạt hẳn sang phải, bề ngang tối thiểu cố định để các
     nút không so le nhau khi độ dài chữ khác nhau.
     MÀU thì KHÔNG đồng bộ theo nút đó: nút chính giữ nền tối. Nút xám nhạt
     #D8D9DB đặt trên panel form #EFF0F1 chỉ đạt 1.24:1 — dưới xa ngưỡng WCAG
     3:1 cho ranh giới thành phần, tức nút submit gần như tàng hình. */
  /* CHỈ dùng cho biến thể .btn--wide / nút "Đọc thêm" ở section giới thiệu —
     KHÔNG phải mặc định. Xem ghi chú tại .btn--wide. */
  --btn-min-w:   205px;   /* dùng cho .btn--wide; bề ngang TỐI THIỂU của
                             mọi nút nằm ở --btn-min-w-base ngay dưới */
  --btn-min-w-base: 180px;
  /* (--btn-gap đã gỡ 2026-08-04 cùng lúc với việc bỏ icon khỏi mọi CTA: trong
     nút không còn hai phần tử nào để mà cách nhau nữa.)
     --btn-icon-fs đổi tên thành --icon-arrow: nó không còn phục vụ nút chữ,
     nhưng vẫn là cỡ của MŨI TÊN VẼ BẰNG NÉT ở cỡ cố định — hiện chỉ còn nút
     "lên đầu trang" trong cụm nổi dùng. arrow-right.svg vẽ stroke 1.6 trong
     khung 24, nên cỡ icon CHÍNH LÀ độ dày nét: để 20px thì nét ra 1.33px,
     đậm hơn 33% so với mọi mũi tên khác. Mũi tên trong nút điều hướng cấp
     section co giãn theo --icon-nav bên dưới — hai vai trò khác nhau. */
  --icon-arrow:  16px;
  /* ===== BÙ LỆCH QUANG HỌC CỦA SVN-GOTHAM =====
     Đo trực tiếp trên font: tại 13.5px em box = ascent 16px + descent 3px,
     tức ascent gấp hơn 5 lần descent. Với line-height:1, flex align-items
     canh giữa HỘP DÒNG — nhưng khối chữ HOA nằm lệch trong hộp đó, rơi
     .132em thấp hơn tâm thật (1.78px ở cỡ nút). Đó chính là "chữ bị lệch dọc".
     padding-block-end = 2 × .132em kéo tâm hộp NỘI DUNG lên đúng bằng độ lệch,
     vì align-items canh theo hộp nội dung chứ không theo hộp viền.
     Đã đo lại sau khi áp: sai số còn 0.06px.
     Theo em nên đúng ở mọi cỡ nút. ĐỔI FONT thì phải đo lại con số này. */
  /* ĐÃ ĐO LẠI 2026-09-07: với Alegreya Sans (em box 12/4 gần cân) nudge .26em
     đẩy chữ HOA lên cao hơn tâm 2,1px → về 0. Với AlmarenaVN Display Bold (chốt
     sau đó, hhea ascent .769 / descent .184, cap .70): tính từ metric, hộp chữ
     hoa nằm cao hơn tâm .058em = 0,8px ở 13.5px — dưới 1px, giữ 0. Nếu khách
     thấy lệch thì nudge phải ÂM (padding-top), không phải padding-bottom như
     thời Gotham. Giữ token để chỉ sửa một chỗ.

     ĐO LẠI BẰNG RASTER 2026-09-07 (khách: "canh giữa text với khung button cho
     toàn bộ button"). Phép tính theo metric ở trên cho ra .11em và canvas báo
     lệch 0,01px — NHƯNG ảnh chụp thật của nút cho thấy thân chữ hoa vẫn cao hơn
     tâm nút 1,0px. Bài học: với font có dấu tiếng Việt, số của canvas
     (fontBoundingBox) KHÔNG khớp thứ trình duyệt vẽ ra; phải đếm hàng pixel.
     Cách đo: chụp riêng nút ở tỉ lệ thiết bị, ngưỡng sáng 45%, lấy hàng đầu và
     hàng cuối có mực rồi so tâm với tâm ảnh.
     Đệm trên nằm trong hộp nội dung mà flex canh giữa, nên thêm 2px đệm chỉ dời
     chữ xuống 1px — vì thế .11em → .26em (1,485 → 3,51px ở cỡ 13,5px). */
  --cap-nudge:   0;
  /* ĐO 2026-09-07 tối trên nút thật (AlmarenaVN Display Bold 13.5px, canvas):
     em-box ascent 10 / descent 2 → hộp chữ HOA nằm CAO hơn tâm nút 0,72px, đúng
     chiều NGƯỢC với Gotham. Bù bằng đệm TRÊN = 2 × 0,72 = 1,44px ≈ .11em (theo
     em để đúng ở mọi cỡ nút). Hai token: --cap-nudge (đệm dưới, cho font có
     descent lớn) và --cap-nudge-top (đệm trên, cho font có ascent lớn) — chỉ
     một trong hai khác 0 tại một thời điểm. Đổi font là đo lại cả hai. */
  /* ĐO LẠI 2026-09-22 cho Philosopher Bold 15.5px, Chrome macOS — bằng điểm dò
     baseline đặt ĐÚNG trong inline box của chữ (lần đo đầu trong ngày gắn điểm
     dò thẳng vào nút flex nên "baseline" đo ra là tâm nút, kết luận sai .66em
     và đẩy chữ thấp 5px — khách báo hai lần). Kết quả đúng: với đệm 0, thân
     chữ HOA chỉ thấp hơn tâm 0,13px ⇒ cả hai đệm về 0. Đây chỉ là DỰ PHÒNG
     khi không có JS: main.js (calibrateButtonText) đo trên máy người xem và
     ghi đè bằng px, vì Windows dùng bộ metric khác macOS. */
  --cap-nudge-top: 0;
  --btn-fs:      14.5px;   /* 13.5 → 15.5 (khách 2026-09-22: +2px) → 14.5 khi đổi sang SVN-Georgia (chữ hoa cao hơn Philosopher 5%) */
  --btn-fw:      var(--fw-bold);
  --btn-ls:      .06em;
  /* Nút icon vuông. Hai cấp, KHÁC NHAU CÓ CHỦ ĐÍCH:
       --btn-icon    điều khiển cấp section (chuyển slide, xoay vòng sản phẩm)
                     — ngang hàng nút chữ nên dùng đúng --btn-h.
       --btn-icon-sm chrome (header, nút nổi, đóng menu) — nhỏ hơn một bậc để
                     không tranh chấp thị giác với nội dung. */
  --btn-icon:    var(--btn-h);
  /* 44px chứ không nhỏ hơn: cụm nút nổi (Facebook/Zalo/gọi/lên đầu trang) và
     nút đóng menu VỐN ĐÃ cùng 44px — đó là mốc đồng thuận sẵn có, hạ xuống 40
     sẽ phá vỡ nó để đổi lấy một con số tròn hơn mà không ai thấy.
     44px cũng đúng vùng chạm tối thiểu khuyến nghị trên cảm ứng. */
  --btn-icon-sm: 44px;
  /* Cỡ MŨI TÊN nằm trong nút điều khiển. Phải là MỘT con số dùng chung, vì
     arrow-right.svg vẽ bằng nét (stroke 1.6 trong khung 24): cỡ icon đổi thì
     ĐỘ DÀY NÉT đổi theo. Trước đây nút tin tức để 20px còn nút vòng xoay 15px —
     cùng khung 48px, cùng file, nhưng nét ra 1.33px so với 1.00px, đậm hơn 33%,
     nên đọc ra như hai kiểu mũi tên khác nhau. Đừng đặt cỡ lẻ tại call-site. */
  --icon-nav:    clamp(12px,1.05vw,15px);

  /* ===== CHUYỂN ĐỘNG — MỘT NGÔN NGỮ DUY NHẤT CHO TOÀN SITE =====
     Lấy từ hiệu ứng "rèm quét" của section tin tức và nâng lên thành chuẩn
     chung, vì trước đó site có tới BA ngôn ngữ rời rạc:
       · tin tức : cubic-bezier(.77,0,.18,1) / 1.2s   (rèm quét)
       · effects.js: power4.out, power3.out / .5-1s   (GSAP)
       · CSS chung: cubic-bezier(.16,1,.3,1) / .5s

     BA NHÓM (2026-08-19 tách thêm nhóm VẬN CHUYỂN, trước đây chỉ có hai):

     1 · VẬN CHUYỂN — --ease-glide
        Thứ ĐI MỘT QUÃNG ĐƯỜNG rồi đỗ: băng tin trượt một nấc, dải ảnh sản
        phẩm, vòng xoay danh mục. Đây là nhóm mới, đẻ ra từ đúng một câu
        feedback: "không phải trượt qua mà là giật lên".
        VÌ SAO KHÔNG DÙNG --ease CHO NHÓM NÀY: --ease là expo-out
        (.16,1,.3,1) — nó đi hết NỬA quãng đường trong ~10% đầu của thời gian.
        Với một cú đổi trạng thái nhỏ (hover) thì đó là "phản hồi tức thì", rất
        đúng. Nhưng với một khối ảnh đi ngang cả trăm px thì mắt đọc ra một cú
        BẮN rồi bò — chính là chữ "giật" của khách. Kéo dài thời lượng KHÔNG
        chữa được, chỉ làm phần bò dài thêm; phải đổi HÌNH DẠNG đường cong.
        cubic-bezier(.65,0,.35,1) = easeInOutCubic: khởi hành nhẹ, nhanh nhất ở
        giữa quãng, hãm dần khi tới nơi — đúng cảm giác một vật có khối lượng
        đang trượt.
        ⚠️ product-wheel.js CHÉP LẠI đường cong này bằng JS (nó cố ý không phụ
        thuộc GSAP). Đổi số ở đây thì đổi cả ở đó, không thì dải ảnh (CSS) và
        vòng chữ (JS) lệch pha nhau ngay.
     2 · HIỆN LÊN (reveal) — --reveal-*  : rèm quét, chữ trồi lên khi cuộn tới.
     3 · TƯƠNG TÁC NHỎ — --ease/--dur   : hover, focus, đổi màu. GIỮ expo-out,
        vì ở đây "phản hồi ngay khi chạm" mới là đúng. */
  --ease-glide:  cubic-bezier(.65,0,.35,1);

  /* 1.3s và stagger .13 (đường đi 1.2 → 1.45 → 1.3; khách chê nấc 1.45 chậm) — 2026-08-19
     "cho cảm nhận trượt rõ hơn". Đây là nguồn của cả ba tầng thời lượng trong
     effects.js (D_BLOCK = DUR, D_LINE = .75·DUR, D_TEXT = .5·DUR) nên chỉ cần
     đổi một chỗ. */
  --reveal-ease: cubic-bezier(.77,0,.18,1);  /* ease-in-out mạnh: chậm→nhanh→chậm */
  --reveal-dur:  1.3s;                      /* nhịp của một lần quét rèm */
  --reveal-stagger: .13s;                    /* lệch pha giữa các phần tử cùng nhóm */

  /* Tương tác nhỏ (hover/focus) — nhanh và nhẹ, KHÁC với hai nhóm trên. */
  --ease:        cubic-bezier(.16,1,.3,1);
  --dur:         .5s;
}

/* ---------- Reset ---------- */
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
/* Khi Lenis điều khiển cuộn (effects.js gắn class .lenis lên <html>):
   PHẢI tắt smooth-behavior của trình duyệt, nếu không hai bên đánh nhau
   từng frame → cuộn giật/kẹt. */
html.lenis{scroll-behavior:auto !important;}
html.lenis,html.lenis body{height:auto;}
body{
  margin:0;
  font-family:var(--font-body);
  font-size:16px;
  /* Đây chỉ là giá trị KẾ THỪA cho phần tử không tự khai; đoạn văn thật đọc
     --lh-body/--lh-relaxed. Siết từ 1.45 xuống 1.3 (−10%) theo yêu cầu khách
     2026-08-04; sàn đo được của nét 400 là 1.238, xem thang ở :root. */
  line-height:var(--lh-tight);
  color:var(--gray-700);
  background:var(--bg);
  /* Siết nhẹ 1.5% (khách thấy chữ hơi thưa, 2026-08-04). Cố ý dừng ở -.015em:
     SVN-Gotham vốn đã là face hình học bề ngang rộng, siết quá -.03em là các
     dấu phụ tiếng Việt (ư, ơ, ằ) bắt đầu dính vào chữ bên cạnh.
     CHỈ áp cho chữ chạy — h1-h4 đọc --ls-heading, còn nav và nút tự khai
     letter-spacing riêng, nên không cái nào ăn theo dòng này. */
  /* 2026-09-07: về 0 — −.015em ở trên là bù cho bề ngang rộng của Gotham;
     AlmarenaVN hẹp hơn 17% ("Hữu Tín" 400: 322 so với 388) nên không bù nữa. */
  letter-spacing:0;
  /* SVN-Georgia mặc định là SỐ KIỂU CŨ (2, 0 thấp hơn dòng) — ngày tháng, số
     liệu "20+ NĂM", "1.000+" đọc lệch. Bật số thẳng hàng (lnum) cho toàn site. */
  font-variant-numeric:lining-nums;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:clip;   /* clip (not hidden) so <body> stays out of the scroll context and .header sticky keeps working */
}
img{max-width:100%;height:auto;display:block;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;cursor:pointer;border:0;background:none;}
input,textarea,select{font-family:inherit;font-size:inherit;color:inherit;}
/* Headings — theo ref manubens.es: MỘT nét 400 cho mọi cấp, giãn chữ tự nhiên,
   KHÔNG ép in hoa bằng CSS.
   · nét 400 = svn-gotham-book.otf, face CÓ THẬT (300/400/500/700, không có 600).
   · letter-spacing normal: ref để normal; -.03em cũ bó chữ lại làm tiêu đề
     "nặng" hơn con số nét gợi ý.
   · line-height: xem --lh-heading ở :root (số ĐO ĐƯỢC). Ref để 1.2 nhưng đó là
     web tiếng Tây Ban Nha — KHÔNG chép được, tiếng Việt có dấu chồng tầng nên
     nét 400 cần tối thiểu 1.276. Giữ 1.4 cho dư. */
/* Nét tiêu đề là 500 (Regular) cho MỌI cấp và MỌI phần của dòng — khách chốt
   2026-08-05. Đoạn comment cũ ở đây từng ghi "nét nền 400"; đó là mô tả sai kể
   cả với trạng thái trước, --fw-heading đã là 500 từ vòng 3. */
h1,h2,h3,h4{margin:0;font-family:var(--font-heading);color:var(--heading);font-weight:var(--fw-heading);letter-spacing:var(--ls-heading);line-height:var(--lh-heading);}
/* h1 = tiêu đề trang: nét Bold riêng (khách chốt 2026-09-07), h2–h4 giữ --fw-heading. */
h1{font-weight:var(--fw-h1);}
/* CỐ Ý KHÔNG có text-transform: ref gõ hoa thẳng trong nội dung khi cần, nhờ đó
   tiêu đề trên ô ảnh giữ được chữ thường và đọc mềm hơn. Muốn hoa thì sửa chuỗi
   trong index.html / i18n.js, đừng ép lại ở đây. */

/* .h-hl — MẶC ĐỊNH TÀNG HÌNH, chỉ "sống dậy" bên trong tiêu đề (rule ngay dưới).
   Kế thừa trọn vẹn — kể cả letter-spacing, nếu không chỗ nối hai nửa câu sẽ lộ
   ra một khe rộng hơn các chữ còn lại.
   Vì sao vẫn cần mặc định này: 12/29 chỗ dùng .h-hl nằm trong <p> (tagline
   footer, chú thích ảnh) chứ không phải tiêu đề. Ở đó span phải hoàn toàn vô
   hình — bold một nửa câu chú thích là ra lỗi chính tả thị giác. */
.h-hl{font:inherit;color:inherit;letter-spacing:inherit;}

/* ===== TIÊU ĐỀ MỘT NÉT (khách chốt 2026-08-05) =====
   Rule này TRƯỚC ĐÂY đặt .h-hl thành nét 700 để trộn hai nét trong một dòng
   (spec §1.3):
       CÔNG TY TNHH SX-TM HỮU TÍN   →   CÔNG TY TNHH SX-TM <b>HỮU TÍN</b>
   Khách đã bỏ yêu cầu đó: "không dùng 2 font-weight khác nhau nữa, chuyển về
   cùng loại khoảng 500". Giữ rule (thay vì xoá) và trỏ về --fw-heading vì
   .h-hl vẫn phải THẮNG mọi khai báo nét lẻ mà một call-site có thể đặt cho
   phần chữ bao quanh — có nó thì hai nửa dòng chắc chắn bằng nhau.
   Tiêu đề nay chỉ còn MỘT tầng phân cấp thị giác: cỡ chữ. Không nét, không màu
   (.h-hl vẫn color:inherit từ vòng trước). Muốn nhấn thì đổi cỡ hoặc tách dòng,
   đừng lén thêm nét thứ hai vào đây. */
h2 .h-hl,h3 .h-hl,h4 .h-hl{font-weight:var(--fw-heading);}
h1 .h-hl{font-weight:var(--fw-h1);}
/* Nền tối: cả tiêu đề trắng */
.on-dark h1,.on-dark h2,.on-dark h3,.banner h1{color:var(--white);}
p{margin:0;}
ul{margin:0;padding:0;list-style:none;}
/* --gold-deep chứ KHÔNG --gold: vòng focus là NÉT trên nền sáng, sàn 3:1.
   Vàng metallic chỉ được 2.11:1 — xem dẫn giải ở khối token. */
:focus-visible{outline:2px solid var(--gold-deep);outline-offset:3px;}

/* ---------- Layout helpers ---------- */
.container{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:clamp(20px,5vw,48px);}
/* Nhãn chỉ dành cho screen reader (vd. label của ô tìm kiếm trên header) */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.container-sec{width:100%;max-width:1440px;margin-inline:auto;padding-inline:clamp(20px,5vw,48px);}
.eyebrow{
  font-family:var(--font-display);
  font-size:var(--fs-micro);letter-spacing:.22em;text-transform:uppercase;
  color:var(--gold-deep);font-weight:var(--fw-medium);
}
.section-pad{padding-block:clamp(72px,11vw,140px);}

/* ---------- Page hero (trang con: ve-huu-tin, san-pham) ----------
   Heading + kicker canh giữa theo nhịp manubens.es — dùng chung nên nằm ở
   common.css thay vì lặp trong từng file CSS trang. */
.page-hero{
  background:var(--bg);text-align:center;
  /* Đáy siết 36px → 20px (khách 2026-08-05: khối chữ đầu trang hở quá rộng).
     Khoảng hở h1 → đoạn văn là TỔNG của padding-bottom ở đây và padding-top của
     khối ngay dưới (.m-story--intro trong about.css) — đo được 73px, siết cả
     hai đầu còn ~40px. Sửa một mình chỗ này chỉ đi được nửa đường.
     Ảnh hưởng CẢ san-pham.html vì .page-hero dùng chung — có chủ ý, hai trang
     đang hở như nhau. Đỉnh giữ nguyên 96px: đó là khoảng thở dưới header. */
  padding:clamp(48px,7vw,96px) 0 clamp(12px,1.6vw,20px);
}
/* Section ĐẦU TIÊN sau hero: đệm trên đọc từ --hero-gap để khe tiêu đề → nội
   dung bằng nhau ở MỌI trang con. Đặc hiệu (0,1,1) và (0,2,1) là cố ý — phải
   thắng .legal/.search-results/.m-nlead/.m-story--intro (0,1,0) và
   .m-plist.section-pad (0,2,0) mà không cần !important. */
.page-hero + section:not(.fb),
.page-hero + div:not(.fb),
.page-hero + article{
  padding-top:var(--hero-gap);
}
/* KHỐI ẢNH TRÀN VIỀN dùng MARGIN, không padding. Hai lý do, cả hai đều làm đệm
   thành vô hình:
   · <img> trong .fb--band/.fb--tall là position:absolute inset:0 — containing
     block của nó là HỘP PADDING, nên ảnh phủ luôn phần đệm.
   · .fb--band/.fb--tall có height cố định + box-sizing:border-box, đệm chỉ ăn
     vào chiều cao ảnh chứ không đẩy khối xuống.
   Đây đúng là chỗ khách báo 2026-09-07: "khoảng cách ở trang liên hệ quá nhỏ" —
   .fb--band ở lien-he là thẻ <figure> nên cũng không khớp ba selector trên. */
.page-hero + .fb{
  margin-top:var(--hero-gap);
}
.page-hero__kicker{
  display:inline-block;font-family:var(--font-display);
  font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:.14em;
  /* VÀNG THẬT --gold (khách 2026-09-07 tối, chốt sau khi bác bản hạ sáng
     #917228: "sai màu" — nó ngả nâu, không còn ra vàng).
     ĐÃ BÁO KHÁCH phần đánh đổi: #E3B23E trên nền trắng chỉ 1.96:1, dưới sàn AA
     4.5:1 cho chữ 12px. Đây là nhãn phụ, nội dung lặp lại tiêu đề ngay bên dưới
     nên không phải thông tin duy nhất — khách chấp nhận. ĐỪNG tự hạ sáng lại. */
  text-transform:uppercase;color:var(--gold);
  margin-bottom:clamp(12px,1.4vw,20px);
}
.page-hero h1{
  font-size:var(--fs-h1);line-height:var(--lh-heading);
  letter-spacing:var(--ls-heading);color:var(--heading);
/* +18% (khách 2026-09-07: "tăng width những cụm text khoảng 15-20%") */
  margin:0 auto;max-width:28ch;
}
.page-hero__intro{
  margin:clamp(14px,1.6vw,22px) auto 0;max-width:73ch;   /* +18% cùng đợt 2026-09-07 */
  font-size:var(--fs-lead);line-height:var(--lh-body);color:var(--gray-700);
}

/* ---------- Ảnh TRÀN VIỀN (.fb) — vốn từ dùng chung của trang con ----------
   DỜI TỪ about.css SANG (2026-08-05) khi trang Liên hệ cần đúng bộ này: nó chỉ
   nạp common.css + contact-page.css nên nằm ở about.css là với không tới. Cùng
   lý do .page-hero và .cta-band ở đây thay vì lặp trong từng file CSS trang.
   Đang dùng: ve-huu-tin.html (trio/tall/grid4/band/overlay), lien-he.html
   (band/overlay).

   KHÔNG bọc .container: các khối này nằm thẳng trong <main> nên tự tràn hết
   bề ngang, đúng cách ref cho ảnh phá khung. */
.fb{margin:0;}
/* Hai khối tràn viền ĐỨNG LIỀN NHAU cách nhau đúng 3px — cùng khe với gap bên
   trong .fb--trio/--grid4/--grid2 và .m-markets__grid, nên cả mảng ảnh đọc ra
   một lưới liền mạch. Chỗ duy nhất đang dính nhau là .fb--tall + .fb--grid4 ở
   ve-huu-tin (khách 2026-09-07: "từ hình to tới 4 hình dưới thiếu 1 khoảng nhỏ
   giống những chỗ còn lại"). Chú thích HTML giữa hai khối không phá selector
   này — `+` xét phần tử, không xét node văn bản. */
.fb + .fb{margin-top:3px;}
.fb img{display:block;width:100%;height:100%;object-fit:cover;background:var(--gray-100);}

/* Dải BA ẢNH NGANG (khách chốt 2026-08-05, thay dải đôi 2fr/1fr trước đó).
   Ba ô bằng nhau: khác dải đôi, ở đây không có ảnh nào đóng vai chính — bộ ba
   kể một mạch xưởng → sợi → thành phẩm nên chia đều mới đọc ra là một chuỗi. */
.fb--trio{display:grid;grid-template-columns:repeat(3,1fr);gap:3px;}
.fb--trio img{height:clamp(240px,30vw,440px);}

/* ---- Ảnh tràn viền CÓ THỊ SAI (effects.js mục 12) -------------------
   Chiều cao chuyển từ thẻ ảnh LÊN KHUNG, ảnh cao hơn khung 12% và thò đều hai
   đầu 6%: phần thừa đó là quỹ đạo cho cú trôi khi cuộn. Không có nó thì tween
   yPercent kéo lộ mép trắng. Cùng cặp số với .plist-card__media — sửa 6% ở đây
   mà quên sửa 4.5 trong effects.js là hở khung.

   height:112% khai TƯỜNG MINH, KHÔNG dùng cặp top:-6%/bottom:-6%: với phần tử
   thay thế được định vị tuyệt đối, CSS §10.6.5 lấy chiều cao NỘI TẠI của ảnh
   rồi bỏ `bottom` đi. Ảnh ở đây loading="lazy" nên trước lúc giải mã chiều cao
   nội tại là 0 → cả dải sập thành vạch trắng. */
.fb--tall,.fb--band{position:relative;overflow:hidden;}
.fb--tall{height:clamp(320px,52vw,720px);}
.fb--band{height:clamp(260px,34vw,480px);}
.fb--tall img,.fb--band img,.fb--overlay img{
  position:absolute;left:0;top:-6%;width:100%;height:112%;
}

/* Lưới ảnh sát nhau: 4 cột × 2 hàng (ref) và 2×2. Khe 3px giữ đúng nhịp
   .m-markets__grid / .pband__grid của trang chủ — ref để 0 nhưng cả site
   này đã chốt 3px, đổi riêng ở đây là lệch hệ. */
.fb--grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:3px;}
.fb--grid4 img{aspect-ratio:1/1;height:auto;}
.fb--grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:3px;}
.fb--grid2 img{aspect-ratio:3/2;height:auto;}

/* Ảnh tràn viền CÓ CHỮ ĐÈ — khối đóng trang, đúng cách ref kết thúc
   /business/ và /contact/ bằng một tấm ảnh rất lớn có câu tuyên ngôn nằm trên.
   overflow:hidden là BẮT BUỘC từ khi có thị sai — chiều cao đã dời lên khung
   (rule chung ở trên cho ảnh 112%), thiếu nó thì phần thừa của ảnh tràn ra
   ngoài section và đè lên footer. */
.fb--overlay{position:relative;isolation:isolate;overflow:hidden;height:clamp(420px,56vw,760px);}
/* Scrim navy (không phải đen) để chữ trắng đạt tương phản trên mọi tấm ảnh
   mà vẫn nằm trong hệ màu hành động của site.

   NẶNG Ở GIỮA, đối xứng — đi kèm việc cụm chữ chuyển sang canh giữa ngay bên
   dưới. Trọng tâm scrim phải nằm ĐÚNG chỗ chữ nằm; bản trước dốc .24→.66 xuống
   đáy vì hồi đó chữ neo đáy. Đo lại trên m-factory-01 (khung 1440×760) bằng
   đúng phép đo của hero — composite scrim lên ảnh đã cover, lấy phân vị 95 của
   luminance dải chữ, tính contrast với trắng:
     chữ đáy  + scrim dốc cũ   4.34   ← mốc trước khi canh giữa
     chữ giữa + scrim dốc cũ   3.11   ← dời chữ mà quên scrim thì rơi xuống đây,
                                         dưới cả sàn ~3.2 của tiêu chí ảnh hero
     chữ giữa + scrim này      4.08
   Nếu sau này chữ neo lại về đáy thì phải trả scrim về dạng dốc. */
.fb--overlay::after{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(34,44,96,.30) 0%,rgba(34,44,96,.62) 50%,rgba(34,44,96,.30) 100%);
}
/* Cụm chữ CANH GIỮA theo chiều dọc (khách chốt 2026-08-05; trước đó neo đáy
   bằng inset:auto 0 0 0).
   Canh bằng GRID + align-content, KHÔNG bằng top:50%/translateY(-50%): quy tắc
   nhà là không canh giữa bằng translate cho khối có reveal, vì GSAP/[data-aos]
   ghi đè transform và phần tử nhảy vị trí không báo gì
   (xem ghi chú data-aos-eats-transform). Ở đây chính .fb__caption chưa có
   reveal, nhưng con của nó có — đặt tiền lệ translate ở đây là mời người sau
   dẫm bẫy.
   Grid chứ không Flex: grid item vẫn giãn hết bề ngang cột nên h2/p giữ nguyên
   `margin:0 auto` + max-width như cũ; flex với align-items:center sẽ bóp chúng
   về bề rộng nội dung và phá cách canh giữa hiện có.
   Đệm dọc nay ĐỐI XỨNG — canh giữa mà đáy còn đệm riêng thì cụm chữ lệch lên. */
.fb__caption{
  position:absolute;inset:0;z-index:2;
  display:grid;align-content:center;
  padding:clamp(36px,5.5vw,80px) var(--pad-wide);
  text-align:center;color:var(--white);
}
.fb__caption h2{
  font-size:var(--fs-h2);
  line-height:var(--lh-heading);margin:0 auto clamp(12px,1.4vw,20px);
  max-width:20ch;color:var(--white);
}
.fb__caption p{
  margin:0 auto;max-width:60ch;
  font-size:var(--fs-body);line-height:var(--lh-body);color:rgba(255,255,255,.9);
}
.fb__caption .btn{margin-top:clamp(20px,2.6vw,34px);}
/* .h-hl trên nền tối: sắc navy của nền sáng sẽ chìm hẳn. */
.fb__caption .h-hl{color:var(--white);}

@media (max-width:900px){
  /* 4 cột co còn 2: ở khổ này mỗi ô của lưới 4 chỉ còn ~180px, ảnh nhà
     máy mất hết chi tiết và đọc ra như hoa văn chứ không phải ảnh. */
  .fb--grid4{grid-template-columns:repeat(2,1fr);}
  /* Bộ ba rớt xuống 2 cột: ở 900px mỗi ô của lưới 3 chỉ còn ~298px, ảnh ngang
     bị bóp thành dải hẹp không đọc ra nội dung. Ô thứ ba xuống hàng một mình
     và chiếm trọn bề ngang — chấp nhận có chủ ý, nó thành ảnh kết đoạn. */
  .fb--trio{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:640px){
  /* Xếp dọc hẳn — chia đôi ở khổ này mỗi ô chỉ còn ~318px. */
  .fb--trio{grid-template-columns:1fr;}
  .fb--trio img{height:clamp(200px,52vw,280px);}
  .fb--grid2{grid-template-columns:1fr;}
}

/* ---------- Dải CTA đóng trang (trang con: san-pham, tin-tuc, chi tiết) ----
   Ba trang con đều kết bằng đúng một khối này nên nó nằm ở common.css thay vì
   chép ba lần: sửa một chỗ là cả ba trang theo. */
.cta-band{background:var(--gray-100);padding-block:clamp(56px,7.5vw,112px);}
.cta-band__inner{max-width:var(--cta-col);margin-inline:auto;text-align:center;}
.cta-band h2{
  font-size:var(--fs-h2);
  line-height:var(--lh-heading);color:var(--heading);margin-bottom:clamp(12px,1.4vw,20px);
}
.cta-band p{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--gray-700);margin:0 0 6px;}
/* `p.` là BẮT BUỘC, không phải thừa. Nút này là một thẻ <p>, nên nó cũng khớp
   `.cta-band p` ngay trên — mà selector đó có độ đặc hiệu (0,1,1) còn
   `.cta-band__btn` trần chỉ (0,1,0). Nó thắng, và vì `margin` là thuộc tính
   RÚT GỌN nên nó đặt lại margin-top về 0 dù tác giả chỉ định bụng khai lề
   dưới. Kết quả: nút dính sát đoạn văn 6px trên cả ba trang con dùng khối này
   (san-pham · tin-tuc · san-pham-chi-tiet), và quy tắc dưới đây là code chết
   suốt từ lúc viết. Khách báo 2026-08-05: "cta dị dính text". */
.cta-band p.cta-band__btn{margin-top:clamp(24px,3vw,40px);}

/* ---------- Khối liên hệ dùng chung (trang chủ + lien-he + chi tiết SP) -----
   Chuyển từ home.css sang đây khi dựng trang Liên hệ riêng: các trang dùng
   ĐÚNG một thẻ form và một danh sách thông tin, để lại ở home.css thì trang
   kia không nạp được.

   2026-08-05 chuyển nốt phần BỐ CỤC SECTION xuống đây (nền + .m-contact__grid
   + cỡ chữ .m-contact__intro). Trước đó phần này ở lại home.css với lý do "là
   chuyện riêng của trang chủ" — không còn đúng từ khi san-pham-chi-tiet.html
   kết trang bằng chính khối này. Cách hỏng nếu để nguyên rất khó truy: trang
   kia có đủ markup và đủ kiểu dáng cho form, chỉ riêng cái lưới hai cột là
   không có, nên nó sập thành một cột mà không báo lỗi gì.
   home.css nay chỉ còn hai override .m-contact.section-pad của riêng trang chủ
   và quy tắc .m-contact .container trong phần nhịp rộng. */
/* Nền trắng: thẻ form tự là một khối xám nên đã tách khỏi nền, section không
   cần tự nhuộm màu. */
.m-contact{background:var(--bg);}
/* 1fr 1fr (trước .85fr 1.15fr) — khách 2026-09-22: "tăng width cụm" tiêu đề +
   đoạn dẫn bên trái. Cùng lượt nới trần chữ của h2/p ngay dưới. */
.m-contact__grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(36px,6vw,80px);align-items:start;}
/* Về MỘT cột ở 1024px — chuyển từ home.css sang cùng đợt với quy tắc gốc ngay
   trên. Tách hai nơi thì trang chi tiết có lưới hai cột nhưng không bao giờ
   gộp lại, tức là hỏng đúng ở khổ tablet. */
@media (max-width:1024px){
  .m-contact__grid{grid-template-columns:1fr;gap:40px;}
  /* TABLET: cụm mở đầu tách làm HAI CỘT — trái là tiêu đề + đoạn dẫn, phải là
     ba mục liên hệ XẾP DỌC (khách chốt 2026-09-08).
     ⚠️ Ba mục thì chỉ được "cả ba một hàng" hoặc "cả ba một cột" — y như lưới
     thị trường ở home.css. Bản trước dùng auto-fit minmax nên ở khổ này ra 2
     cột, tức Hotline | Email rồi Trụ sở trơ trọi hàng dưới; đã gỡ.
     Phải đặt vị trí TƯỜNG MINH: h2 và p là hai phần tử riêng, để lưới tự xếp
     thì p nhảy sang cột 2 chứ không nằm dưới h2. */
  /* Cột phải phải đủ 300px cho hàng hotline hai số; hết chỗ thì cột trái co
     lại trước, và khi cả hai không còn vừa thì media query 720 bên dưới gộp
     dọc hẳn. minmax(0,1fr) cho cột trái để chữ dài không đẩy lưới tràn. */
  .m-contact__intro{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,auto);
    /* ⚠️ grid-template-rows PHẢI KHAI. Cột phải (3 mục liên hệ) trải qua CẢ HAI
       hàng, nên nếu để hàng tự co theo nội dung thì chiều cao của nó bị chia
       cho hai hàng — hàng 1 phình ra và đoạn dẫn tụt xuống, cách tiêu đề một
       quãng trống lớn (khách báo 2026-09-08 "ipad dọc bị thưa quá").
       min-content khoá hàng 1 đúng bằng tiêu đề; 1fr cho hàng 2 nuốt phần dư. */
    grid-template-rows:min-content 1fr;
    column-gap:clamp(24px,3vw,48px);align-items:start;
  }
  .m-contact__intro > h2{grid-column:1;grid-row:1;}
  .m-contact__intro > p{grid-column:1;grid-row:2;}
  /* ⚠️ BÓ TRONG .m-contact__grid. Lớp .m-contact__info còn được TRANG LIÊN HỆ
     dùng lại cho hàng Hotline/Email/Kết nối (.lh-info__grid), mà ở đó nó là
     lưới 3 CỘT NGANG — rule một cột dưới đây từng đè lên và bẻ hàng đó xuống
     dọc (khách báo 2026-09-08). */
  .m-contact__grid .m-contact__info{
    grid-column:2;grid-row:1 / 3;
    /* Khe SIẾT LẠI (khách 2026-09-08 "tablet dọc cho 3 phần này gần lại"): ba
       mục nay xếp dọc trong một cột hẹp nên chúng đọc ra là MỘT cụm, không cần
       khe rộng như hồi còn nằm ngang cả bề ngang trang. */
    display:grid;grid-template-columns:1fr;gap:clamp(10px,1.3vw,15px);
  }
  /* ⚠️ Phải mượn thêm .m-contact__grid cho đủ đặc hiệu. Rule gốc
     `.m-contact__info li{margin-bottom:22px}` cũng là 0-1-1 và nằm SAU khối
     media này trong file — media query không cộng đặc hiệu, nên viết ngang
     nhau là rule gốc thắng và khe vẫn cộng thêm 22px (đo được 32-35px thay vì
     10-13px như đã khai). */
  .m-contact__grid .m-contact__info li{margin-bottom:0;}
}/* ⚠️ PHẢI ĐỨNG SAU khối 1024 ngay trên. Bản trước đặt nhầm lên phía trước và
   hai khối cùng đặc hiệu (0-1-0) — khối 1024 nạp sau nên nó thắng, và ở điện
   thoại cụm mở đầu vẫn kẹt ở dạng hai cột.
   Điện thoại: hết chỗ cho hai cột, trả cụm mở đầu về một dòng chảy dọc. */
@media (max-width:720px){
  /* Khe giữa cụm liên hệ và form: 40px là nhịp của khổ tablet, xuống điện thoại
     thì hai khối đã xếp dọc nên 40px đọc ra như một quãng đứt (khách báo
     2026-09-08 "thưa quá"). */
  .m-contact__grid{gap:clamp(20px,4vw,28px);}
  .m-contact__intro{display:block;}
  .m-contact__grid .m-contact__info{display:block;}
  /* ⚠️ Phải mượn .m-contact__grid cho ĐỦ ĐẶC HIỆU (0-2-1). Khối 1024 ở trên đã
     dùng đúng selector đó để đưa margin về 0 cho bố cục lưới; viết ngang bằng
     0-1-1 ở đây thì thua, và ba mục dính sát nhau trên điện thoại (khách báo
     2026-09-08 "ở mobile quá gần"). */
  .m-contact__grid .m-contact__info li{margin-bottom:22px;}
}

/* Bó cả CỤM (tiêu đề + đoạn văn) vào một bề ngang thay vì chỉ giới hạn đoạn
   văn 40ch: khách 2026-09-07 "giảm width của cụm text". Một số cho cả hai thì
   mép phải của tiêu đề và đoạn văn thẳng nhau, trước đây tiêu đề chạy hết cột
   còn đoạn văn dừng sớm. */
/* Bó cụm chữ bằng HAI số riêng, KHÔNG bó ở khối cha: max-width trên cha chặn
   trần của mọi con, nên đặt 40ch ở .m-contact__intro thì tiêu đề không thể rộng
   hơn 361px dù tự khai 27ch (đã thử và hỏng đúng như vậy).
   · h2 27ch — tính theo cỡ CHỮ CỦA CHÍNH NÓ, ở 1280 ra ~437px. Cần bấy nhiêu vì
     tiêu đề có <br /> ngắt tay trước "từ Hữu Tín" (khách 2026-09-07) mà dòng 1
     "Liên hệ để nhận báo giá" đo được 418px — hẹp hơn là gãy thành 3 dòng.
   · p 40ch (~361px) — giữ nguyên bề ngang vốn có.
   Đổi --fs-h2 hoặc sửa chuỗi tiêu đề thì ĐO LẠI dòng 1. */
.m-contact__intro h2{font-size:var(--fs-h2);margin-bottom:20px;max-width:34ch;}   /* 27ch → 34ch (2026-09-22) */
.m-contact__intro p{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--gray-700);margin-bottom:32px;max-width:52ch;}   /* 40ch → 52ch (2026-09-22) */
.m-contact__info li{display:flex;gap:14px;margin-bottom:22px;align-items:flex-start;}
/* Hàng hotline: cả cụm icon+nhãn+số chính là MỘT link (gọi số đầu tiên);
   số thứ hai là link riêng đứng NGANG cùng hàng số chính (feedback
   2026-08-03). align-self:flex-end neo nó xuống dòng số (dòng cuối của
   .info-call — phía trên là nhãn "Hotline"); dấu · ngăn cách do ::before vẽ
   nên KHÔNG lọt vào vùng bấm của link nào. */
.m-contact__info .info-call{display:flex;gap:14px;align-items:flex-start;}
/* KHÔNG cho rớt dòng: hai số hotline nằm cùng một hàng, ngăn bằng dấu ·. Khi
   cột thông tin hẹp lại (khổ tablet, xem .m-contact__intro hai cột) mà để chữ
   tự ngắt thì mỗi số vỡ làm ba dòng "0985 / 868 / 881" — đọc ra như ba số khác
   nhau (khách báo 2026-09-08). Cột nào hẹp quá thì tự xuống một dòng ở dấu ·,
   nhưng bản thân từng số luôn nguyên khối. */
.m-contact__info .info-call__num{font-size:var(--fs-body);color:var(--gray-700);line-height:var(--lh-tight);white-space:nowrap;}
.m-contact__info .info-call:hover .info-call__num{color:var(--gold-deep);}
.m-contact__info .info-call__alt{
  white-space:nowrap;
  align-self:flex-end;margin-left:2px;
  font-size:var(--fs-body);color:var(--gray-700);line-height:var(--lh-tight);
}
.m-contact__info .info-call__alt::before{content:"·";margin-right:10px;color:var(--gray-500);}
.m-contact__info .info-call__alt:hover{color:var(--gold-deep);}
/* Ô icon cùng tone xám với thẻ form, không để lẻ một mảng kem trong section */
.m-contact__info .ic{width:46px;height:46px;flex:0 0 auto;border-radius:var(--radius);background:var(--gray-100);display:flex;align-items:center;justify-content:center;color:var(--gold-deep);}
.m-contact__info .ic .icon{width:20px;height:20px;}
.m-contact__info .t b{display:block;font-family:var(--font-display);color:var(--ink);font-size:var(--fs-body);margin-bottom:3px;letter-spacing:.01em;}
.m-contact__info .t span,.m-contact__info .t a{font-size:var(--fs-body);color:var(--gray-700);line-height:var(--lh-tight);}
.m-contact__info .t a:hover{color:var(--gold-deep);}

/* Tone XÁM, không đổ bóng. --gray-100 là xám trung tính thật (R≈G≈B) chứ không
   ám vàng như --cream — xem chú thích token ở common.css.
   Bỏ shadow rồi thì thứ duy nhất tách thẻ khỏi nền trắng là chênh 5% độ sáng
   của chính nền thẻ. Đủ thấy, nhưng ĐỪNG làm nền thẻ nhạt thêm nữa.
   Ô nhập vẫn trắng nên nó tự nổi lên trên nền xám, không cần viền đậm. */
.contact-form{
  background:var(--gray-100);border-radius:var(--radius-lg);padding:clamp(24px,3vw,40px);
}
.contact-form__row{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
.field{display:flex;flex-direction:column;gap:8px;margin-bottom:18px;}
/* Nhãn ô nhập IN ĐẬM (khách 2026-09-07) — áp cho MỌI form của site vì cả ba
   form (trang chủ, lien-he, san-pham-chi-tiet) dùng chung .field. */
.field label{font-size:var(--fs-meta);font-weight:var(--fw-bold);font-family:var(--font-display);color:var(--ink);letter-spacing:.02em;}
.field label .req{color:var(--gold-deep);}
.field input,.field textarea{
  width:100%;background:var(--bg);
  padding-block:14px;padding-inline:16px;
  /* VIỀN THẬT 1px (khách 2026-09-07: "border của form 1px, không shadow").
     Trước là border:0 + inset box-shadow 1.5px giả làm viền — dày hơn 0.5px so
     với mọi viền khác trên site và không nằm trong hộp bố cục. Quầng vàng lúc
     focus VẪN là box-shadow (khách chốt riêng ở trên), đó là vòng NGOÀI. */
  border:1px solid var(--gray-200);border-radius:var(--radius);
  transition:border-color .25s var(--ease),box-shadow .25s var(--ease),background .25s var(--ease);
  color:var(--ink);font-size:var(--fs-body);
}
/* line-height:1 để hộp chữ đúng bằng một em-box, nhờ vậy đệm 14/14 cân bằng cho
   ra khối chữ CANH GIỮA THẬT. Trước đây ô nhập kế thừa line-height 1.38 của
   body: phần leading dư 0,38em phân bổ đều trên/dưới nhưng khối chữ hoa lại
   nằm lệch trong đó, nên đệm cân bằng vẫn ra kết quả lệch. Xem phép đo raster
   ghi tại .header__search input — và ĐỪNG thêm --cap-nudge ở đây, lý do cũng
   nằm trong chú thích đó. */
.field input{line-height:1;}
/* Cùng kiểu với placeholder của 3 ô tìm kiếm (--gray-500 + nghiêng). Trước đây
   chỗ này để hex cứng #9A9CA0 và KHÔNG nghiêng, nên trong cùng một trang có hai
   kiểu placeholder khác nhau mà không vì lý do gì. */
.field input::placeholder,.field textarea::placeholder{color:var(--placeholder);opacity:1;}
.field input:focus,.field textarea:focus{outline:none;background:var(--bg);box-shadow:var(--ring);}
/* textarea KHÔNG lấy line-height:1 của ô một dòng: nó là chữ chạy nhiều dòng,
   dòng dính nhau ở 1.0 thì dấu tiếng Việt của dòng dưới đội lên dấu dòng trên. */
.field textarea{resize:vertical;min-height:110px;line-height:var(--lh-body);}
/* #E9EAEB thay #F1EFEA: nền lỗi cũ ám vàng, lạc tone giữa thẻ xám */
.field.is-error input,.field.is-error textarea{background:#E9EAEB;border-color:var(--accent);}
.field__err{display:none;font-size:var(--fs-meta);color:var(--accent);}
.field.is-error .field__err{display:block;}
.contact-form__submit{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:6px;}
/* Nút "Gửi yêu cầu" bỏ 2 hiệu ứng của .btn dùng chung: vệt sáng quét ngang
   (.btn::before) và cú nhấc 1px khi hover.
   Nền đổi màu khi hover là tín hiệu DUY NHẤT còn lại — từ 2026-08-04 nút không
   còn icon để trượt nữa. Đừng gỡ nốt nó. */
.contact-form__submit .btn::before{display:none;}
.contact-form__submit .btn:hover,
.contact-form__submit .btn:active{transform:none;}
.contact-form__note{font-size:var(--fs-meta);color:var(--gray-500);}
.form-status{display:none;margin-top:16px;padding:14px 16px;border-radius:var(--radius);font-size:var(--fs-sm);}
.form-status.is-ok{display:block;background:#EDF3EC;color:#2F6B37;}

/* Ô icon tô VÀNG + nhấc nhẹ khi rê chuột; nhãn ô nhập đổi màu khi đang gõ. */
.m-contact__info .ic{transition:background .3s var(--ease),color .3s var(--ease),transform .3s var(--ease);}
.m-contact__info li:hover .ic{
  /* Icon ĐEN trên mảng vàng — trắng chỉ được 2.11:1, xem khối token. */
  background:var(--gold-grad);color:var(--btn-ink);
  transform:translateY(-2px) scale(1.06);
}
.field label{transition:color .2s var(--ease);}
.field:focus-within label{color:var(--gold-deep);}

/* Hai cột ô nhập gộp thành một ở khổ hẹp. (Ngưỡng 768 ở đây KHÁC ngưỡng 1024
   của .m-contact__grid — cố ý: lưới section gộp sớm hơn vì cột chữ bên trái
   cần bề ngang, còn cặp ô nhập vẫn vừa đôi tới tận 768. Chú thích cũ ghi "cùng
   ngưỡng" là sai, đã sửa.) */
@media (max-width:768px){
  /* (đã dời xuống mốc 560 — xem cuối file: khách chốt 2026-09-08 "form dàn 2
     field 1 hàng" ở tầng giữa.) */
}

/* ---------- Icons (local SVG, recolored via CSS mask = currentColor) ---------- */
.icon{
  display:inline-block;width:1em;height:1em;flex:0 0 auto;vertical-align:-.14em;
  background-color:currentColor;
  -webkit-mask:var(--ic) center/contain no-repeat;
  mask:var(--ic) center/contain no-repeat;
}
.icon--180{transform:rotate(180deg);}
.icon--flip{transform:scaleX(-1);}
/* Mọi mũi tên trên site đều là arrow-right.svg xoay đi — một file, một nét, một
   hình dạng. Xoay chứ không thêm file .svg cho từng hướng. */
.icon--up{transform:rotate(-90deg);}

/* ---------- Buttons (PILL · màu ĐẶC · chữ CANH GIỮA · UPPERCASE · no border) ----------
   KHÔNG CÒN ICON TRONG NÚT (khách chốt 2026-08-04): mọi CTA nay chỉ có chữ,
   nằm giữa khung. Các thẻ <i class="icon"> đã gỡ khỏi HTML ở cả 12 trang, và
   những rule .btn .icon / :hover .icon đi kèm cũng gỡ theo — đừng thêm lại một
   nửa (rule CSS không có thẻ, hoặc thẻ không có rule). */
.btn{
  /* MẶC ĐỊNH LÀ GỌN: hộp co theo nội dung. Dạng rộng là NGOẠI LỆ, phải gọi tên
     bằng .btn--wide — xem bên dưới. */
  display:inline-flex;align-items:center;justify-content:center;
  height:var(--btn-h);
  /* padding-bottom = --cap-nudge để bù lệch quang học của SVN-Gotham; xem chú
     thích đầy đủ tại token trong :root. KHÔNG gộp về `padding:0 X` được. */
  padding:var(--cap-nudge-top) var(--btn-pad-x) var(--cap-nudge);
  /* HẾT dạng viên thuốc (999px). Khách chốt 2026-08-05: nút chỉ "bo góc nhẹ
     4-6px". Nay nút là chỗ DUY NHẤT còn bo góc đáng kể trên site — ảnh và thẻ
     đã vuông (--radius-lg:0) — nên chính bán kính này là tín hiệu "bấm được".
     Nút icon TRÒN (mũi tên carousel, nút liên hệ nổi) vẫn giữ tròn, đó là quy
     ước điều hướng riêng và khách đã chốt giữ. */
  border-radius:var(--radius);
  min-width:var(--btn-min-w-base);
  font-family:var(--font-display);font-weight:var(--btn-fw);line-height:1;
  font-size:var(--btn-fs);letter-spacing:var(--btn-ls);text-transform:uppercase;
  transition:transform .25s var(--ease),box-shadow .3s var(--ease),background .3s var(--ease),color .3s var(--ease),opacity .3s var(--ease);
  white-space:nowrap;
}
.btn:active{transform:translateY(1px);}
/* Primary: màu ĐẶC (--btn-grad), hover đậm hơn một bậc */
/* color: --btn-ink (ĐEN), không phải #fff — chữ trắng trên vàng 2.11:1, rớt
   chuẩn. Xem khối MÀU HÀNH ĐỘNG trong bảng token. */
.btn-primary{background:var(--btn-grad);color:var(--btn-ink);}
/* Hover = lớp ::after mang gradient đậm hơn, mờ dần bằng opacity. z-index:-2
   nằm DƯỚI vệt sáng ::before (-1) và TRÊN nền của chính nút — .btn đã là
   stacking context (isolation:isolate) nên con z-index âm vẫn vẽ đè lên nền. */
.btn-primary::after{content:"";position:absolute;inset:0;z-index:-2;background:var(--btn-grad-dark);opacity:0;transition:opacity .3s var(--ease);pointer-events:none;}
.btn-primary:hover{color:var(--white);}
.btn-primary:hover::after{opacity:1;}
/* Light: solid on dark imagery */
.btn-light{background:var(--bg);color:var(--text);}
.btn-light:hover{background:var(--gold-light);color:var(--text);}
/* Glass: borderless translucent (secondary on dark) */
.btn-glass{background:rgba(255,255,255,.14);color:#fff;backdrop-filter:blur(6px);}
.btn-glass:hover{background:rgba(255,255,255,.24);}
/* ---- NGOẠI LỆ: biến thể RỘNG ----
   Chỉ dùng khi nút đứng MỘT MÌNH và canh trái trong cột của nó, đúng như nút
   "Đọc thêm" ở section giới thiệu — ở đó bề ngang lớn hơn giúp nút giữ được
   sức nặng khi không có gì đứng cạnh.

   ĐỪNG dùng làm mặc định. Khi nút nằm trong một hàng cùng phần tử khác (nút
   submit cạnh dòng ghi chú, CTA trong menu), bề ngang tối thiểu 205px làm nó
   trương ra vô cớ — đó chính là lý do dạng gọn mới là mặc định.

   .m-about__more nằm chung selector này: nó KHÔNG phải .btn (có nền + kiểu chữ
   riêng trong home.css) nhưng dùng ĐÚNG bố cục rộng, nên hai thuộc tính dưới
   đây chỉ được khai MỘT nơi. Trước đó chúng bị chép lại trong home.css — hai
   bản sao của cùng một quyết định, sửa một bên là lệch ngay. */
.btn--wide,
.m-about__more{min-width:var(--btn-min-w);justify-content:center;}

/* Ghost: bỏ hộp nút, GIỮ NGUYÊN kiểu chữ chuẩn — trước để 13px/.14em nên
   đứng cạnh .btn là đọc ra hai hệ khác nhau.
   padding:0 gỡ luôn --cap-nudge kế thừa từ .btn: đây là chữ TRẦN, không có
   khung để canh giữa trong đó, nên khoảng đệm dưới chỉ tạo lệch với dòng chữ
   đứng cạnh. Cũng phải gỡ min-width — bề ngang tối thiểu 205px trên một nhãn
   chữ trần là một khoảng trống vô cớ. */
.btn-ghost{
  height:auto;padding:0;background:none;color:var(--ink);
  font-size:var(--btn-fs);letter-spacing:var(--btn-ls);
  min-width:0;justify-content:flex-start;
}

/* Link hành động (trước là "link mũi tên" — mũi tên đã gỡ 2026-08-04).
   KHÔNG phải nút (không hộp, không nền) nhưng cùng vai trò "nhãn hành động",
   nên dùng CHUNG kiểu chữ với .btn. Trước để 13px/600/.14em — ba thông số đều
   lệch chuẩn cùng lúc.
   Đổi màu khi hover là tín hiệu DUY NHẤT còn lại sau khi bỏ mũi tên trượt. */
.link-arrow{
  display:inline-flex;align-items:center;
  font-family:var(--font-display);font-weight:var(--btn-fw);font-size:var(--btn-fs);
  letter-spacing:var(--btn-ls);text-transform:uppercase;color:var(--ink);
}
.link-arrow:hover{color:var(--gold-deep);}

/* =========================================================
   OVERLAY (mobile menu backdrop)
   ========================================================= */
/* MÀN TỐI CỦA MENU MOBILE (đổi 2026-09-22): phủ phần màn DƯỚI header (không
   đè header — X vẫn bấm được), đen 70% + làm mờ nội dung phía sau. Bước 1 của
   cú mở menu: màn này tối xuống trước (~0.5s), rồi tấm menu mới trượt từ trái
   sang (xem .header-mobile). z-index 60 < header 70. */
.overlay{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  top:calc(var(--header-h) + 1px);
  background:rgba(0,0,0,.35);   /* tối NHẸ thôi (khách 2026-09-22) — tấm menu sẽ tối thêm khi trượt vào */
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  opacity:0;visibility:hidden;
  transition:opacity .45s var(--ease),visibility 0s linear .45s;
}
.overlay.is-open{opacity:1;visibility:visible;transition:opacity .45s var(--ease),visibility 0s;}

/* =========================================================
   HEADER (desktop)
   ========================================================= */
.header{
  position:sticky;top:0;z-index:70;
  background:var(--bg);
  border-bottom:1px solid rgba(0,0,0,.08);
  transition:transform .4s var(--ease);
}
.header.is-hidden{transform:translateY(-100%);}
/* KHÔNG đổ bóng khi cuộn (khách chốt 2026-08-04). Thứ tách header khỏi nội
   dung nay chỉ còn viền dưới 1px khai ở trên — đủ, vì header nền trắng đặc.
   Class .is-scrolled đã hết chỗ dùng nên phần gắn class trong main.js cũng gỡ
   luôn; đừng thêm lại rule ở đây mà không bật lại bên đó. */
/* Header chạy rộng hơn .container mặc định (1280) để khớp mockup: ~80px lề ở 1440. */
.header .container{max-width:var(--maxw-wide);padding-inline:var(--pad-wide);}
.header__inner{
  display:flex;align-items:center;
  height:var(--header-h);
}

/* Brand lockup: biểu tượng | các dấu chứng nhận, ngăn bằng divider dọc mảnh.
   Divider chỉ vẽ ở dấu ĐẦU TIÊN — hai dấu liền nhau thì đứng chung một cụm,
   thêm vạch giữa chúng sẽ đọc ra như ba thương hiệu rời rạc. */
.header__brand{display:flex;align-items:center;gap:14px;flex:0 0 auto;}
.header__logo{display:flex;align-items:center;}
.header__logo img{height:48px;width:auto;}
.header__certs{display:flex;align-items:center;gap:12px;}
.header__cert{height:46px;width:auto;}
.header__certs{padding-left:14px;border-left:1px solid var(--gray-200);}

/* Nav + actions DỒN VỀ PHẢI, khoảng trống co giãn nằm ngay sau brand — bố cục
   gốc, khách yêu cầu quay lại (2026-08-04). Bản canh giữa tuyệt đối (kèm
   media-query 1360px và position:relative trên .header__inner) đã gỡ. */
/* Khe giữa các mục menu siết lại (khách chốt 2026-08-04, trước 20-38px): cụm
   menu đọc ra thành MỘT khối thay vì bốn chữ rời. Sàn 14px là mức thấp nhất
   còn phân tách được hai mục khi cả hai đều là chữ thường không viền. */
.header__nav{display:flex;align-items:center;gap:clamp(14px,1.3vw,26px);margin-inline-start:auto;}
.header__nav a{
  font-family:var(--font-body);
  font-size:var(--fs-ui);font-weight:var(--fw-medium);color:var(--gray-700);position:relative;
  padding-block:6px;letter-spacing:normal;
  transition:color .25s var(--ease);
}
/* Hover/trang đang xem: ĐỔI MÀU + gạch chân vàng. Lịch sử: 2026-08-04 khách
   chốt bỏ gạch chân, chỉ đổi màu; 2026-09-07 khách yêu cầu lại "gạch chân màu
   vàng" — xem rule ::after ngay dưới. Phần đổi màu vẫn giữ vì:
   PHẢI là --gold-deep chứ không phải --ink: --gray-700 (màu nghỉ) và --ink là CÙNG
   một giá trị #3B3D40, nên bản cũ thực chất không đổi màu gì cả — gạch chân là
   tín hiệu hover DUY NHẤT. Gỡ gạch chân mà vẫn để --ink thì hover thành vô
   hình, mất luôn dấu hiệu cho bàn phím. */
/* Gạch chân VÀNG khi hover (khách 2026-09-07). Vẽ bằng ::after 2px kéo từ trái
   sang (scaleX 0→1) thay vì text-decoration: gạch của trình duyệt bám baseline,
   cắt ngang dấu dưới của ư/ợ/ệ và không animate được. Nằm sát mép dưới
   padding-block 6px nên không đụng dấu. Màu --gold (đầu tối gradient) chứ không
   --gold-deep: đây là "action nhỏ" được phép mang accent, còn chữ vẫn đổi sang
   --gold-deep để giữ tương phản (vàng làm chữ 15px trên trắng chỉ ~2:1). Trang
   đang mở (.is-active) giữ gạch cố định để biết mình ở đâu. */
.header__nav a::after{
  /* GẠCH SÁT MÉP DƯỚI HEADER (khách 2026-09-22: "nằm thấp xuống sát dưới
     luôn"): link được align-items:center canh giữa khung 64px, nên mép dưới
     header = tâm link + --header-h/2. top = tâm + 32px − 2px (bề dày gạch) ⇒
     gạch nằm ngay trên viền 1px dưới header, như tab đang chọn. */
  content:"";position:absolute;left:0;right:0;height:2px;
  top:calc(50% + var(--header-h) / 2 - 2px);
  background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .25s var(--ease);
}
.header__nav a:hover,.header__nav a.is-active{color:var(--gold-deep);}
/* Trang ĐANG XEM in đậm (khách 2026-09-07) — nét 700 là file AlmarenaVN Display
   Bold có thật, không phải nét tổng hợp. Chỉ .is-active, KHÔNG áp cho :hover:
   nếu hover cũng đổi nét thì chữ nở ra và các mục bên cạnh nhích theo mỗi lần
   rê chuột. Gạch chân ::after khai left:0;right:0 nên nó tự dài theo chữ đậm. */
.header__nav a.is-active{font-weight:var(--fw-bold);}
.header__nav a:hover::after,.header__nav a.is-active::after{transform:scaleX(1);}
.header__actions{display:flex;align-items:center;gap:20px;flex:0 0 auto;margin-inline-start:32px;}

/* Ô tìm kiếm HIỆN SẴN (khách yêu cầu quay lại bố cục gốc 2026-08-04). Bản
   "thu thành nút icon + popover trượt ra" đã gỡ, kèm cả initHeaderSearch
   trong main.js. */
.header__search{
  display:flex;align-items:center;gap:8px;
  height:38px;width:230px;padding:0 6px 0 16px;
  border:1px solid var(--gray-200);border-radius:var(--radius);
  background:var(--bg);
  transition:border-color .25s var(--ease),box-shadow .25s var(--ease);
}
.header__search:focus-within{box-shadow:var(--ring);}
/* ===== CANH GIỮA DỌC TRONG Ô NHẬP — GIẢI THÍCH GỐC, 3 Ô CÒN LẠI TRỎ VỀ ĐÂY =====
   Khách 2026-08-05: "canh text vào giữa khung (chiều dọc)". Nguyên nhân KHÔNG
   phải flexbox sai — .header__search đã align-items:center, và trình duyệt cũng
   tự canh giữa nội dung input. Nguyên nhân là lệch QUANG HỌC của SVN-Gotham:
   ascent gấp ~5 lần descent, nên khối chữ hoa nằm thấp hơn tâm hình học .132em.
   Ô nhập chỉ có chữ hoa/chữ thường không đuôi xuống (placeholder "Tìm kiếm sản
   phẩm", tên, email) nên phần descent bỏ trống đó lộ hẳn ra thành khoảng hở
   dưới. .btn đã bù chuyện này từ vòng trước bằng --cap-nudge; KHÔNG ô nhập nào
   được bù, nên chữ trong ô đọc ra là "chìm xuống đáy".
   Cách bù: bỏ height:100% và line-height kế thừa, cho hộp co đúng bằng MỘT
   em-box (height:auto + line-height:1) rồi để flex cha canh giữa hộp đó.

   ĐÃ ĐO BẰNG RASTER, VÀ KẾT QUẢ NGƯỢC VỚI DỰ ĐOÁN BAN ĐẦU — đừng "sửa lại"
   theo trực giác: chỉ hai dòng trên là ĐỦ, KHÔNG được thêm
   `padding-bottom:var(--cap-nudge)` như .btn. Phép đo (khung 38px phóng 7 lần,
   kẻ vạch đỏ đúng tâm khung, chuỗi "HTM" thuần chữ hoa):
       height:auto + line-height:1                → khối chữ hoa lệch 0,3px
       height:auto + line-height:1 + --cap-nudge  → lệch 2,8px LÊN TRÊN
   Lý do .btn cần bù mà ô nhập thì không, dù cùng font: .btn cao CỐ ĐỊNH 44px và
   canh giữa cả HỘP DÒNG, mà hộp dòng gánh trọn ascent+descent lệch nhau 5:1 của
   SVN-Gotham. Ô nhập ở đây cao đúng một em-box, tức đã cắt bỏ phần descent thừa
   đó trước khi flex canh giữa — bù thêm lần nữa là bù hai lần.
   Muốn kiểm lại thì dựng lại đúng phép đo trên, đừng suy từ công thức: mô hình
   tính baseline bằng getComputedStyle cho <input> ra sai gần 8px vì trình duyệt
   tự canh giữa phần soạn thảo bên trong, không theo hộp CSS. */
.header__search input{
  flex:1 1 auto;min-width:0;
  height:auto;line-height:1;
  border:0;background:none;outline:none;
  /* --fs-ui − 2px (khách 2026-09-22: ô tìm kiếm header "giảm font size 2px"). */
  font-size:calc(var(--fs-ui) - 2px);color:var(--ink);
}
.header__search button{
  display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;flex:0 0 auto;border-radius:var(--radius-sm);
  color:var(--gray-500);transition:color .25s var(--ease),background .25s var(--ease);
}
.header__search button:hover{color:var(--ink);background:var(--surface);}
.header__search button .icon{width:17px;height:17px;}
.header__search input::placeholder{color:var(--placeholder);opacity:1;}
/* Chrome vẽ sẵn nút X cho input[type=search] — bỏ đi để giữ đúng mockup */
.header__search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;}

/* social */
.header__social{display:flex;align-items:center;gap:12px;}
.header__social a{
  display:flex;align-items:center;justify-content:center;
  transition:color .25s var(--ease),transform .25s var(--ease);
}
.header__social a:hover{transform:translateY(-2px);}
.header__social .icon{width:21px;height:21px;}

/* MÀU GỐC CỦA TỪNG NỀN TẢNG (khách chốt 2026-08-04) — cùng quy ước với cụm
   nút nổi góc phải, nơi Facebook/Zalo đã dùng logo màu thật.
   .icon vẽ bằng CSS mask + background-color:currentColor, nên chỉ cần đặt
   `color` trên thẻ <a> là icon đổi màu theo.
   CHỌN THEO href chứ không theo :nth-child hay aria-label: thứ tự hai link có
   thể đảo khi sửa markup, còn aria-label thì i18n có thể dịch — href là thứ
   ổn định nhất trong ba.
   Hover đậm xuống một nấc TRONG CHÍNH sắc của nền tảng; đừng đưa về --gold,
   làm vậy là kéo cả hai icon về chung một xanh navy, mất luôn ý nghĩa của
   việc dùng màu gốc. */
.header__social a[href*="linkedin"],
.header-mobile__social a[href*="linkedin"]{color:#0A66C2;}
.header__social a[href*="linkedin"]:hover,
.header-mobile__social a[href*="linkedin"]:hover{color:#004182;}
.header__social a[href*="facebook"],
.header-mobile__social a[href*="facebook"]{color:#1877F2;}
.header__social a[href*="facebook"]:hover,
.header-mobile__social a[href*="facebook"]:hover{color:#0C63D4;}

/* (Các rule thu search / ẩn social theo bậc 1560/1280 đã bỏ 2026-08-03:
   search nay là nút icon 40px nên cụm actions chỉ còn ~350px — social đứng
   được ở mọi khổ desktop mà không chen nav giữa. Ô nhập khi mở là popover
   absolute, không chiếm layout.) */

/* language switch (custom select hook) */
.re-select-main{position:relative;}
.re-select-main .re-select__btn{
  display:inline-flex;align-items:center;gap:6px;
  /* Cùng kiểu chữ với .btn. Trước đây BA bộ chuyển ngôn ngữ dùng ba kiểu khác
     nhau: 15px/500/normal (đây), 13px/600/.06em (mobile), 13px/500/normal
     (mục trong dropdown) — cùng một chức năng mà ba mặt chữ. */
  font-family:var(--font-display);font-size:var(--btn-fs);font-weight:var(--btn-fw);
  /* line-height:1 (không phải --cap-nudge): hộp chữ co đúng một em-box rồi để
     flex canh giữa — cùng hình học đã ĐO ĐƯỢC là chuẩn ở các ô nhập, xem
     .header__search input. Nút này cao theo ĐỆM chứ không cao cố định như .btn
     nên nó thuộc nhóm ô nhập, không thuộc nhóm .btn. */
  letter-spacing:var(--btn-ls);color:var(--gray-700);line-height:1;
  /* Cùng hình học với khung tìm kiếm bên cạnh (.header__search): cao 38px, viền
     1px, bo --radius. Viền ở trạng thái nghỉ TRONG SUỐT để không thành ô thứ
     hai; margin âm bù đúng phần đệm + viền để chữ "VI" không xê dịch. */
  height:38px;padding:0 10px;border:1px solid transparent;border-radius:var(--radius);
  margin-inline:-11px;
  transition:color .25s var(--ease),border-color .25s var(--ease);
}
/* Hover/mở = VIỀN ĐEN NHẠT như khung tìm kiếm (khách 2026-09-07, đổi lại từ nền
   vàng nhạt): cùng --gray-200, cùng chiều cao, cùng bo góc — hai khối cạnh nhau
   đọc ra một họ. Không nền, không quầng. */
.re-select-main .re-select__btn:hover,
.re-select-main.is-open .re-select__btn{color:var(--ink);border-color:var(--gray-200);}
/* CANH GIỮA THẬT SỰ trong khung (khách 2026-09-08). align-items:center chỉ căn
   giữa HỘP CHỮ; với "VI" viết hoa, phần mực chỉ chiếm nửa trên của hộp em nên
   chữ trông cao hơn tâm khung. Đo raster ở 1440 (khung trong viền 1→36, tâm
   18.5): mực chữ nằm 12→21, tâm 16.5 — cao hơn tâm khung ĐÚNG 2px; còn mũi tên
   17→21, tâm 19.0, gần đúng tâm rồi.
   ⚠️ Vì thế chỉ đẩy RIÊNG CHỮ xuống, KHÔNG đẩy cả nút: đẩy cả nút thì mũi tên
   tụt xuống 2.5px dưới tâm.
   ⚠️ Và phải dùng position/top chứ KHÔNG padding-top: đệm trên một flex item
   đang bị align-items:center căn lại, nên nó chỉ ăn có một nửa. Đệm chỉ dùng
   được khi đặt trên chính hộp flex (đó là cách .btn dùng --cap-nudge-top).
   2px / 13.5px = .15em, khai theo em để còn co giãn cùng cỡ chữ.
   2026-09-22 (Philosopher, khách báo chưa canh giữa): đo lại bằng probe
   baseline — top:.15em cho tâm chữ THẤP hơn tâm nút 2,45px, top:0 còn 0,13px
   ⇒ về 0. Giữ position:relative để sau này đổi font chỉ cần sửa con số. */
.re-select-main .re-select__current{position:relative;top:var(--lang-nudge,0);}   /* main.js đo và đặt --lang-nudge */
.re-select-main .re-select__btn .icon{width:13px;height:13px;color:currentColor;transition:transform .25s var(--ease);}
.re-select-main.is-open .re-select__btn .icon{transform:rotate(180deg);}
.re-select-main .re-select__list{
  /* 140 → 190px (khách 2026-09-22: "tăng width popup"): chữ 15.5px làm "Tiếng
     Việt" gãy hai dòng ở 140. right:0 = mép phải popup trùng mép phải nút VI
     (.re-select-main co đúng bằng nút). */
  position:absolute;right:0;top:calc(100% + 6px);min-width:190px;
  background:var(--bg);border-radius:var(--radius);
  /* Header giờ nền trắng: cần viền + đổ bóng thì dropdown mới tách khỏi nền. */
  border:1px solid var(--gray-200);box-shadow:0 12px 28px rgba(0,0,0,.12);
  padding:6px;
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .25s var(--ease),transform .25s var(--ease),visibility .25s;
  z-index:5;
}
.re-select-main.is-open .re-select__list{opacity:1;visibility:visible;transform:translateY(0);}
.re-select-main .re-select__list button{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  width:100%;text-align:left;padding:8px 10px;border-radius:var(--radius-sm);white-space:nowrap;
  /* Khách 2026-09-07: mục ĐANG CHỌN in đậm, mục còn lại in NHẠT — và giữ nhạt
     kể cả khi hover (hover chỉ đổi nền để biết đang trỏ vào đâu). Nét 400 là
     file AlmarenaVN Light, 700 là Display Bold — hai file thật, không faux. */
  font-size:var(--btn-fs);font-weight:var(--fw-body);letter-spacing:var(--btn-ls);color:var(--gray-500);
  transition:background .2s var(--ease);
}
.re-select-main .re-select__list button:hover{background:var(--cream);}
.re-select-main .re-select__list button.is-active{background:var(--cream);color:var(--ink);font-weight:var(--fw-bold);}
/* Mã ngôn ngữ (VI/EN) đứng sau nhãn, đẩy sát mép phải, nhỏ và giãn chữ như
   nhãn IN HOA khác trên site. Kế thừa màu/nét của mục để đậm–nhạt đi cùng. */
.re-select-main .re-select__code{font-size:var(--fs-micro);letter-spacing:.12em;opacity:.8;}

/* BURGER → X (tham chiếu oppein-home.com.vn, khách 2026-09-22): ba vạch là ba
   <span> chứ không còn icon mask menu.svg — icon mask không hoạt hình được
   từng vạch. Giữ nhịp so le của menu.svg (vạch trên/dưới ngắn, dồn mép phải).
   Số 7.25px = (16 − 1.5)/2: khoảng từ tâm vạch ngoài tới tâm hộp 16px.

   BIẾN HÌNH HAI PHA (khách 2026-09-22 lần 2: "chưa thấy rõ" khi mọi thứ chạy
   cùng lúc trong 0.4s). Dùng các thuộc tính rời translate / rotate / width
   thay cho một transform gộp — nhờ vậy mỗi thành phần có thể có delay riêng:
     PHA 1 (0 → .35s): cả hộp quay trọn 360°, đồng thời vạch trên và vạch dưới
            kéo dài hết cỡ rồi TỤT/ĐỘI VỀ TÂM đè lên vạch giữa, vạch dưới mờ đi.
            Kết thúc pha 1 chỉ còn thấy MỘT gạch ngang ở tâm.
     PHA 2 (.35s → .75s): gạch giữa xoay 45° và vạch trên (đang chồng lên nó)
            xoay −45° → tách ra thành chữ X. Đây chính là "gạch giữa chuyển
            thành một thanh của nút đóng" mà khách muốn thấy.
   Lúc ĐÓNG chạy ngược thứ tự: X gập về một gạch trước (rotate không delay),
   rồi ba gạch mới tách ra (translate/width có delay). */
.header__burger{display:none;width:var(--btn-icon-sm);height:var(--btn-icon-sm);align-items:center;justify-content:center;color:var(--ink);-webkit-tap-highlight-color:transparent;}
.header__burger-box{position:relative;display:block;width:22px;height:16px;transition:rotate .45s var(--ease);}
.header__burger[aria-expanded="true"] .header__burger-box{rotate:360deg;}
.header__burger-box span{
  position:absolute;right:0;height:1.5px;border-radius:1px;background:currentColor;
  /* thứ tự lúc ĐÓNG: rotate trước (0s), translate/width/opacity sau (.3s) */
  transition:rotate .3s var(--ease),translate .3s var(--ease) .3s,width .3s var(--ease) .3s,opacity .2s var(--ease) .35s;
}
.header__burger-box span:nth-child(1){top:0;width:14px;}
.header__burger-box span:nth-child(2){top:50%;width:22px;translate:0 -50%;}
.header__burger-box span:nth-child(3){bottom:0;width:10px;}
.header__burger[aria-expanded="true"] .header__burger-box span{
  /* thứ tự lúc MỞ: translate/width/opacity trước (0s), rotate sau (.35s) */
  transition:translate .3s var(--ease),width .3s var(--ease),opacity .2s var(--ease) .1s,rotate .4s var(--ease) .35s;
}
.header__burger[aria-expanded="true"] .header__burger-box span:nth-child(1){width:22px;translate:0 7.25px;rotate:-45deg;}
.header__burger[aria-expanded="true"] .header__burger-box span:nth-child(2){rotate:45deg;}
.header__burger[aria-expanded="true"] .header__burger-box span:nth-child(3){width:22px;translate:0 -7.25px;opacity:0;}

/* =========================================================
   HEADER — MOBILE (tấm menu trượt từ TRÁI, dưới header)
   ========================================================= */
/* ĐỔI 2026-09-22 theo tham chiếu oppein-home.com.vn, hai bước như khách mô tả:
   (1) bấm burger → .overlay tối xuống ~0.5s (khai ở .overlay);
   (2) tấm menu này trượt từ trái sang (translateX(-100%) → 0), bắt đầu sau
       0.5s (khách 2026-09-22: 1s → 0.5s) = transition-delay chỉ khai ở trạng thái mở; lúc đóng delay về 0
       nên đóng tức thì.
   Tấm nằm trên .overlay (z 61 > 60) và dưới header (70). Nền tấm trong suốt
   nhẹ — màn tối đã do .overlay lo, tấm chỉ cần mang chữ trượt vào. */
.header-mobile{
  position:fixed;left:0;right:0;z-index:61;
  top:calc(var(--header-h) + 1px);
  height:calc(100dvh - var(--header-h) - 1px);
  background:rgba(0,0,0,.7);   /* tối thêm khi menu đã ra (khách 2026-09-22); cộng với .overlay .35 ≈ 80% */
  color:#fff;
  display:flex;flex-direction:column;
  padding:12px 20px 32px;overflow-y:auto;
  transform:translateX(-100%);visibility:hidden;
  transition:transform .4s var(--ease),visibility 0s linear .4s;
}
.header-mobile.is-open{
  transform:translateX(0);visibility:visible;
  transition:transform .45s var(--ease) .5s,visibility 0s linear .5s;
}
/* Header không được tự trốn (.is-hidden) khi menu đang mở — tấm bám dưới nó. */
body.is-menu-open .header{transform:none;}
@media (min-width:1025px){.header-mobile,.overlay{display:none;}}
/* (Ô TÌM KIẾM TRONG DRAWER ĐÃ GỠ 2026-09-08 theo yêu cầu của khách — markup
   gỡ khỏi cả 13 trang. CSS giữ lại vì nó là khuôn ô nhập trong drawer, sẽ cần
   nếu gắn lại; hiện không phần tử nào dùng.)
.header-mobile__search{
  display:flex;align-items:center;gap:8px;
  height:44px;margin-bottom:20px;padding:0 6px 0 16px;
  border:1px solid var(--gray-200);border-radius:var(--radius);background:var(--bg);
}
.header-mobile__search:focus-within{box-shadow:var(--ring);}
/* Bù lệch quang học — xem chú thích đầy đủ tại .header__search input. */
.header-mobile__search input{
  flex:1 1 auto;min-width:0;border:0;background:none;outline:none;
  height:auto;line-height:1;
  font-size:var(--fs-ui);color:var(--ink);
}
.header-mobile__search input::placeholder{color:var(--text-subtle);opacity:1;}
.header-mobile__search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;}
.header-mobile__search button{
  display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;flex:0 0 auto;border-radius:var(--radius-sm);color:var(--gray-500);
}
.header-mobile__search button .icon{width:18px;height:18px;}
/* MỤC MENU (2026-09-22, theo ảnh mẫu oppein-home.com.vn khách gửi): chữ chạy
   cỡ vừa, nét thường, trắng, không kẻ ngăn, không mũi tên hover — thay cho
   bản chữ tiêu đề clamp(31px…) kẻ vàng của 2026-09-07. Mục có menu con
   (.header-mobile__group) gồm MỘT HÀNG = link cha + nút mũi tên: bấm chữ thì
   đi tới trang, bấm mũi tên thì xổ danh sách con (accordion) — đúng cách web
   mẫu tách hai việc, không bắt người dùng đoán bấm chữ sẽ xổ hay sẽ đi. */
.header-mobile__nav{display:flex;flex-direction:column;gap:0;}
/* KẺ NGĂN giữa các mục cấp 1 (khách 2026-09-22) — trắng 15% trên nền tối, đủ
   thấy mà không cắt menu thành từng ô. Chỉ giữa các mục (* + *), không kẻ
   trên mục đầu và dưới mục cuối. */
.header-mobile__nav > * + *{border-top:1px solid rgba(255,255,255,.15);}
.header-mobile__nav a{
  color:#fff;font-family:var(--font-body);font-size:18px;line-height:1.4;
  transition:color .25s var(--ease);
}
.header-mobile__nav a:hover,
.header-mobile__nav a:focus-visible{color:var(--gold);}
.header-mobile__nav .header-mobile__item:hover,
.header-mobile__nav .header-mobile__item:focus-visible{color:#fff;}
/* Mục cấp 1: 21px (17 + 4, khách 2026-09-22) và VÀNG KIM; mục con vẫn 16px trắng. */
/* Selector đủ nặng (.nav .item = 0,2,0) để thắng .header-mobile__nav a (0,1,1) ở trên. */
.header-mobile__nav .header-mobile__item{display:flex;align-items:center;flex:1 1 auto;min-height:58px;padding:12px 0;font-size:22px;color:var(--gold);}   /* 21 → 20 (SVN-Georgia) → 22 (khách 2026-09-22: "tăng thêm 2px") */
.header-mobile__more{color:var(--gold);}
.header-mobile__row{display:flex;align-items:center;width:100%;}
/* Nút mũi tên: vùng chạm 44px, dùng down.svg xoay −90° (chỉ sang phải) khi
   đóng và về 0° (chỉ xuống) khi mở — cùng icon với select ngôn ngữ. */
.header-mobile__more{
  flex:0 0 44px;height:44px;margin-right:-12px;
  display:flex;align-items:center;justify-content:center;color:#fff;
  -webkit-tap-highlight-color:transparent;
}
.header-mobile__more .icon{width:20px;height:20px;transform:rotate(-90deg);transition:transform .3s var(--ease);}
.header-mobile__more[aria-expanded="true"] .icon{transform:rotate(0);}
/* ACCORDION bằng grid 0fr → 1fr: hoạt hình chiều cao mà không cần đo px trong
   JS. Lớp trong bắt buộc overflow:hidden + min-height:0, nếu không ô lưới
   vẫn bị nội dung chống lên và không co về 0. */
.header-mobile__sub{display:grid;grid-template-rows:0fr;transition:grid-template-rows .35s var(--ease);}
.header-mobile__sub-in{overflow:hidden;min-height:0;}
.header-mobile__group.is-open .header-mobile__sub{grid-template-rows:1fr;}
.header-mobile__sub a{display:block;padding:10px 0 10px 16px;font-size:17px;color:rgba(255,255,255,.85);}   /* 16 → 15 (SVN-Georgia) → 17 (khách 2026-09-22: +2px) */
.header-mobile__sub-in{padding-bottom:0;transition:padding .35s var(--ease);}
.header-mobile__group.is-open .header-mobile__sub-in{padding-bottom:10px;}
.header-mobile__foot{margin-top:auto;padding-top:24px;display:flex;flex-direction:column;gap:16px;}
/* Màu hai icon lấy từ khối .header__social phía trên — cùng một cặp selector
   theo href nên không khai lại ở đây. */
.header-mobile__social{display:flex;align-items:center;gap:16px;}
.header-mobile__social a{display:flex;transition:color .25s var(--ease);}
.header-mobile__social .icon{width:24px;height:24px;}
.header-mobile__lang{display:flex;gap:8px;}
.header-mobile__lang button{
  font-family:var(--font-display);font-size:var(--btn-fs);font-weight:var(--btn-fw);letter-spacing:var(--btn-ls);
  /* line-height:1 chứ không --cap-nudge — cùng lý do đã ghi ở .re-select__btn:
     nút cao theo đệm thì chỉ cần co hộp chữ về một em-box. */
  padding:9px 16px;line-height:1;border-radius:var(--radius);
  background:rgba(255,255,255,.12);color:#fff;   /* trên nền tấm đen (2026-09-22) */
}
.header-mobile__lang button.is-active{background:var(--btn-grad);color:var(--btn-ink);}
.header-mobile__call{
  display:flex;align-items:center;gap:8px;font-family:var(--font-display);
  font-weight:var(--fw-medium);color:var(--ink);font-size:var(--fs-ui);
}
.header-mobile__call .icon{color:var(--gold-deep);width:18px;height:18px;}

/* =========================================================
   FOOTER
   ========================================================= */
/* Dải ảnh dẫn vào footer. Nền của tấm ảnh là đen tuyền, trùng đúng nền footer
   nên hai khối dính liền, không cần đường phân cách. Ảnh co theo CHIỀU RỘNG
   (height:auto) — cố định chiều cao rồi cover sẽ cắt mất phần dây rủ xuống. */
.footer-hero{background:#000;line-height:0;}
.footer-hero__img{display:block;margin-inline:auto;width:min(100%,1180px);height:auto;}

/* Footer đen tuyền để nối liền mạch với ảnh phía trên */
footer.footer{background:#000;color:var(--footer-text);padding-block:clamp(56px,7vw,88px) clamp(40px,5vw,48px);}
/* Cùng nhịp rộng với header, giới thiệu, tin tức, liên hệ — xem --maxw-wide */
.footer .container{max-width:var(--maxw-wide);padding-inline:var(--pad-wide);}
/* Hai khối: TRÁI là dấu hiệu thương hiệu, PHẢI là toàn bộ chữ — đúng cách web
   mẫu chia footer. Cột trái rộng theo nội dung (auto) chứ không theo fr, để
   khoảng thở giữa hai khối luôn đúng bằng column-gap dù logo to nhỏ thế nào. */
.footer__grid{
  display:grid;gap:48px clamp(48px,7vw,112px);
  grid-template-columns:minmax(200px,auto) minmax(0,1fr);
  align-items:start;
}

/* Cột trái · logo + huy hiệu, canh giữa theo nhau như web mẫu.
   Cột tự co theo bề ngang logo (auto), nên align-items:center chính là canh
   huy hiệu vào giữa trục logo — không phải canh giữa cả footer. */
/* --footer-logo-w khai ở ĐÂY chứ không gõ thẳng vào .footer__logo: hình chìm
   bên dưới phải giữ đúng TỈ LỆ với logo ở mọi khổ màn (xem .footer__watermark),
   nên hai phần tử buộc phải đọc chung một con số. */
.footer__brand{
  --footer-logo-w:clamp(186px,17vw,258px);
  display:flex;flex-direction:column;align-items:center;
}
/* LOGO VÀNG (khách chốt 2026-08-05). Không cần asset mới: file
   footer-logo-stack-01.png VỐN ĐÃ là bản vàng — trước đây nó bị
   `filter:brightness(0) invert(1)` ép về trắng đặc để thoả spec §3.10 ("logo
   footer phải một màu"), vì khi đó không có file trắng dùng được
   (assets/images/logo/huutin_logo_white.png thực chất là một ô trắng đặc,
   không phải logo). Nay khách bỏ yêu cầu đó → chỉ việc gỡ filter.
   ĐỪNG thêm filter nào khác vào đây: logo vàng có gradient, mọi phép lọc màu
   sẽ dập gradient thành một sắc phẳng. */
/* Thẻ <a> bọc ngoài logo (thêm 2026-09-08): phải là block và co đúng bề rộng
   logo, nếu không vùng bấm trải hết cột và người dùng bấm trúng chỗ trống cũng
   nhảy về trang chủ. flex:0 0 auto vì .footer__brand là hàng ngang ở khổ
   tablet trở xuống. */
.footer__logo-link{display:block;width:var(--footer-logo-w);flex:0 0 auto;}
.footer__logo{width:100%;height:auto;display:block;}
/* Huy hiệu tạm cắt từ PDF mockup (ảnh gốc tối tới max 38/255 nên đã kéo sáng).
   Ảnh nền đen tuyền, trùng nền footer nên không cần khử nền. Thay ảnh khác chỉ
   cần đổi src — khung này tự canh theo bề ngang cột. */
/* ---- HÌNH CHÌM DƯỚI LOGO (dựng lại 2026-08-19) ---------------------------
   Ô này từng bị GỠ 2026-08-04 vì ảnh của nó là huy hiệu Agnus Dei của
   MANUBENS, cắt từ mockup — mà mockup chính là ảnh chụp manubens.es. Bằng
   chứng nằm trong CÙNG KHUNG HÌNH của Web HuuTin.pdf: info@manubens.es ·
   "Ramon Farguell 26-28, Manresa (Barcelona)" · "Name of the beneficiary:
   PRODUCCIONES JOSÉ MANUBENS, S.A.U".
   2026-08-19 khách ĐƯỢC BÁO RÕ điều trên và vẫn chốt "dùng hình này trong
   pdf". Đây là quyết định của khách, không phải sót — ghi lại để người sau
   đừng gỡ lần nữa mà không hỏi. Muốn thay thì cần huy hiệu/con dấu riêng của
   Hữu Tín, đổi đúng file assets/images/footer-emblem-01.png là xong.

   ẢNH LÀ BẢN CẮT NGUYÊN ĐỘ SÁNG TỪ PDF, KHÔNG kéo sáng (bản cũ trước đây kéo
   ×5.3). Nhờ vậy opacity để 1: độ "chìm" nằm sẵn trong chính tấm ảnh, đúng
   như mockup. Nền ảnh là đen tuyệt đối (0-1/255), trùng khít nền footer #000
   nên không thấy mép hộp — ĐỪNG đổi nền footer sang màu khác mà quên tấm này.

   HÌNH HỌC ĐO TỪ MOCKUP (dò biên bằng ngưỡng sáng trên ảnh phẳng 2481px):
     logo     x 93→565  = 473px
     huy hiệu x 171→485 = 315px  → 315/473 = .666
     khe hở   88px               → 88/473  = .186
     lệch tâm 1px (coi như canh giữa)
   Hai số đó là BỘI SỐ CỦA --footer-logo-w chứ không phải px cố định: logo co
   theo vw, hình chìm phải co cùng nhịp, nếu không tỉ lệ vỡ ở khổ hẹp. */
.footer__watermark{
  display:block;
  width:calc(var(--footer-logo-w) * .666);
  height:auto;
  margin-top:calc(var(--footer-logo-w) * .186);
  /* pointer-events:none — đây là hoạ tiết, không phải thứ để bấm hay bôi đen. */
  pointer-events:none;user-select:none;
}

/* Cụm bên phải · hàng trên = các cột thông tin, hàng dưới = đoạn mô tả.
   Gap CHIA ĐÔI so với trước (36–60 → 18–30) vì .footer__intro nay tự đắp lại
   nửa còn lại bằng padding-top: đường kẻ giữa hai cụm phải nằm GIỮA khoảng
   trắng, để nguyên gap cũ rồi thêm padding là khoảng thở phình gấp đôi. */
.footer__main{display:grid;gap:clamp(18px,2.25vw,30px);}
/* BỐN cột (khách chốt 2026-08-05 vòng 6: "chứng nhận đem lên thành 1 cột kế
   sản phẩm"). Liên hệ rộng nhất vì chứa hai địa chỉ dài; hai cột link hẹp hơn
   vì chỉ là danh sách chữ ngắn; cột chứng nhận hẹp nhất vì nay chỉ còn tiêu đề
   + 2 badge xếp dọc. */
.footer__cols{display:grid;gap:40px clamp(28px,3vw,48px);grid-template-columns:1.4fr 1fr 1fr .9fr;}
/* Mô tả: chữ bên trái, badge "Từ 2002" đẩy sang phải cho kín hàng.
   Tagline + blurb bọc trong .footer__intro-txt chứ không để làm 2 grid item
   riêng: badge cao hơn tagline, nếu để rời nó sẽ kéo giãn hàng của tagline và
   hở một khoảng trống ngay dưới dòng chữ. */
/* Đường kẻ tách cụm cột thông tin khỏi cụm mô tả (khách chốt 2026-08-05, vòng
   8: "thêm line giữa 2 cụm này"). Dùng border-top của chính khối mô tả chứ
   không chèn <hr>: footer nằm trong CẢ 12 trang, thêm thẻ là phải sửa 12 file
   và bản /en/ sinh ra từ script cũng phải dựng lại.
   --footer-border là đúng token của mọi đường kẻ trong footer (dải bản quyền ở
   cuối đã dùng), nên hai đường kẻ cùng một sắc độ. */
.footer__intro{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:24px clamp(32px,4vw,56px);align-items:start;
  border-top:1px solid var(--footer-border);
  padding-top:clamp(18px,2.25vw,30px);
}
.footer__intro-txt{min-width:0;}
/* Colour spelled out here rather than inherited from .h-hl: that class is now
   fully transparent, and this tagline is the one place the accent tone still
   earns its keep — it sits alone, not inside a heading.
   Nét 700 (khách chốt 2026-08-05 vòng 8: "in đậm TỪ TÂM ĐẾN TẦM"). 700 có file
   thật (svn-gotham-bold) nên không bị trình duyệt tổng hợp giả — xem khối
   --fw-* ở đầu file. Khai trên thẻ <p> nên <span class="h-hl"> bên trong kế
   thừa; rule h1-h4 .h-hl không với tới đây được vì đây không phải tiêu đề. */
.footer__tagline{
  margin-bottom:16px;font-size:var(--fs-h4);font-weight:var(--fw-bold);
  /* VÀNG (khách 2026-09-07), trước là --hl-dark (kem xám). */
  line-height:var(--lh-heading);text-transform:uppercase;color:var(--gold);
}
/* max-width theo ch chứ không theo cột: khối mô tả nay trải hết bề ngang cụm
   phải, không giới hạn thì dòng dài ~110 ký tự, đọc mỏi mắt.
   --fs-sm (14,5px) thay cho --fs-body (khách chốt vòng 8: "giảm font-size text
   mô tả ở dưới"). Đây là chữ phụ nằm dưới một tagline nay đã in đậm — để cùng
   cỡ body thì hai dòng đọc ra ngang hàng nhau. 14,5px trên --footer-muted vẫn
   dư chuẩn AA (xem ghi chú tương phản ở khối --footer-*). */
.footer__blurb{font-size:var(--fs-sm);line-height:var(--lh-body);color:var(--footer-muted);max-width:64ch;}
.footer__since{
  /* 2 → 8px (khách 2026-09-07: "tăng khoảng cách 2 text này") — hai dòng khác
     vai (con số mốc / chú thích) nên cần khe rõ hơn khe dòng thường. */
  display:inline-flex;flex-direction:column;gap:8px;
  padding:14px 16px;background:var(--footer-tile);border-radius:var(--radius);
}
.footer__since b{font-family:var(--font-heading);font-size:var(--fs-h4);font-weight:var(--fw-medium);color:var(--hl-dark);letter-spacing:-.01em;line-height:1;}
.footer__since span{font-size:var(--fs-meta);color:var(--footer-muted);}

/* Col headings + link columns */
/* Nhãn cột footer: 13px IN HOA giãn rộng — cần nét 500 để không mảnh quá mức
   trên nền đen (nét 400 ở cỡ nhỏ + giãn chữ .16em đọc ra rất yếu). */
/* VÀNG + BOLD (khách 2026-09-07): nhãn cột là thứ duy nhất mang accent trong
   footer đen; --gold trên nền #000 dư tương phản. */
.footer__col h2{color:var(--gold);font-size:var(--fs-meta);font-weight:var(--fw-bold);letter-spacing:.16em;text-transform:uppercase;margin-bottom:20px;font-family:var(--font-display);}
.footer__col nav{display:flex;flex-direction:column;gap:8px;}
.footer__col nav a{font-size:var(--fs-ui);color:var(--footer-muted);transition:color .25s var(--ease);width:fit-content;}
.footer__col nav a:hover{color:var(--gold-light);}

/* Liên hệ */
.footer__contact li{display:flex;gap:12px;font-size:var(--fs-sm);line-height:var(--lh-body);color:var(--footer-muted);margin-bottom:18px;}
/* --gold hiện là #1A1B1D (thang xám) → vô hình trên footer đen tuyền.
   Dùng --gold-light, token được định nghĩa riêng cho NỀN TỐI. */
.footer__contact .icon{width:18px;height:18px;color:var(--gold-light);flex:0 0 auto;margin-top:3px;}
.footer__contact a:hover{color:var(--gold-light);}
.footer__contact strong{color:var(--footer-text);font-weight:var(--fw-bold);display:block;font-family:var(--font-display);letter-spacing:.02em;margin-bottom:2px;}

/* ===== DẢI CHỨNG NHẬN — MỘT HÀNG NGANG GỌN (khách chốt 2026-08-05) =========
   "chứng nhận làm gọn lại như kiểu footer web ref manubens.es". Ref đặt chứng
   nhận thành một hàng logo nhỏ nằm ngang, KHÔNG kèm chữ giải thích — chúng là
   tín hiệu tin cậy liếc qua là nhận ra, không phải nội dung để đọc.
   Bản trước là lưới 2 cột, mỗi cột có tên + badge 64px + đoạn 45-60 chữ. Hai
   đoạn đó chiếm gần bằng cả khối liên hệ + 2 cột link cộng lại, tức phần NẶNG
   nhất của footer lại là phần ít người đọc nhất.
   .footer__cert-body đã gỡ khỏi markup; khoá footer.isoBody/sedexBody vẫn nằm
   trong i18n.js (không còn tham chiếu, để lại cũng vô hại) — cần dựng lại trang
   giới thiệu chứng nhận thì đã có sẵn chữ.

   VÒNG 6 (cùng ngày 2026-08-05) — khách chuyển tiếp: "chứng nhận đem lên thành
   1 cột kế sản phẩm". Nay nó là CỘT THỨ 4 của .footer__cols, không còn là dải
   riêng. Vì sao lần này ở được trong lưới còn lần trước thì không: bản bị tách
   ra hồi đó mang theo hai đoạn ~55 chữ, ở cột ~223px sẽ rớt 12-14 dòng chữ nhỏ
   dựng đứng. Đoạn chữ đã gỡ, chỉ còn tiêu đề + 2 badge — vừa đúng một cột.
   Không còn quy tắc bố cục riêng: .footer__certs nay chỉ là .footer__col, ăn
   trọn h2/khoảng cách của cột. Phần còn lại dưới đây chỉ lo dải badge. */
.footer__certs-row{
  /* Xếp DỌC trong cột hẹp (trước là hàng ngang khi nó còn là dải riêng). */
  display:flex;flex-direction:column;align-items:flex-start;gap:16px;
}
.footer__cert{display:flex;align-items:center;gap:12px;}
/* Tên chỉ còn là chú thích cạnh badge, không phải tiêu đề khối nữa: --fs-meta
   thay cho --fs-h4, và màu lùi về --footer-muted để badge là thứ bắt mắt trước. */
.footer__cert-name{
  font-family:var(--font-display);font-size:var(--fs-meta);font-weight:var(--fw-heading);
  letter-spacing:.04em;color:var(--footer-muted);margin:0;white-space:nowrap;
}
/* CAO cố định, RỘNG tự do — hai badge lệch tỉ lệ nhau khá xa (ISO 115×158 dọc,
   Sedex 180×184 gần vuông). Khoá cả hai chiều vào ô 64px như bản cũ thì logo
   dọc bị thu nhỏ hơn hẳn logo vuông dù cùng ô; khoá chiều cao thì hai logo có
   cùng "trọng lượng" thị giác trên hàng. */
.footer__cert-media{flex:0 0 auto;height:46px;display:flex;}
.footer__cert-media img{height:100%;width:auto;object-fit:contain;display:block;}
/* Nền trắng là bắt buộc chứ không phải thẩm mỹ: header-cert-sedex-01.png không
   có kênh alpha (nền trắng đặc). Đặt thẳng lên footer đen sẽ ra một ô trắng
   vuông lởm chởm; cho nó nền trắng + bo nhẹ + đệm thì ô trắng đó trở thành khối
   chủ ý. Khi nào khách gửi bản PNG có alpha hoặc SVG thì đổi về transparent. */
/* Ô badge KHOÁ CẢ HAI CHIỀU (khách 2026-09-07: "width của 2 cụm này giống
   nhau"): trước chỉ khoá cao 46px, rộng chạy theo tỉ lệ logo nên ISO (dọc) hẹp
   hơn Sedex (vuông) 24px. Ảnh vẫn object-fit:contain nên không méo. */
.footer__cert-media--badge{background:var(--bg);width:56px;box-sizing:border-box;justify-content:center;padding:6px 9px;border-radius:var(--radius-sm);}

/* Divider */
.footer__divider{margin:clamp(40px,6vw,56px) 0 0;border:0;height:1px;background:var(--footer-border);}

/* Bottom · 3 vùng */
.footer__bottom{
  padding-top:24px;display:grid;gap:16px 32px;align-items:center;
  grid-template-columns:1fr auto;
  font-size:var(--fs-meta);color:var(--footer-muted);
}
.footer__copy{white-space:nowrap;}
.footer__meta{display:flex;flex-direction:column;align-items:flex-end;gap:14px;}
.footer__policy{display:flex;flex-wrap:wrap;gap:8px 18px;justify-content:flex-end;}
.footer__policy a{color:var(--footer-muted);transition:color .25s var(--ease);}
.footer__policy a:hover{color:var(--gold-light);}
.footer__social{display:flex;gap:10px;}
.footer__social a{
  /* .07 trước đây — lệch 1 điểm so với .06 của các ô nổi khác, không phân biệt
     nổi bằng mắt nên gom về cùng token. */
  width:40px;height:40px;border-radius:var(--radius);background:var(--footer-tile);overflow:hidden;
  display:flex;align-items:center;justify-content:center;color:var(--footer-text);
  transition:background .25s var(--ease),color .25s var(--ease),transform .25s var(--ease);
}
/* Chữ TRẮNG chứ không phải --dark: nền hover nay là navy đậm (--gold đã đổi
   giá trị), icon tối trên navy tối là mất hút. */
.footer__social a:hover{background:var(--gold);color:var(--btn-ink);transform:translateY(-2px);}
.footer__social .icon{width:18px;height:18px;}
.footer__social-img{width:22px;height:22px;}

/* =========================================================
   GROUP CONTACT (floating quick contact)
   ========================================================= */
.group-contact{position:fixed;right:18px;bottom:18px;z-index:60;display:flex;flex-direction:column;gap:12px;}
/* NGOẠI LỆ CÓ CHỦ Ý so với thang bo góc chung (--radius-* = 4/6/8px): cụm nút
   nổi phải BO TRÒN HẲN.
   Lý do: logo Facebook và Zalo bản thân đã là hình TRÒN, nên để hộp bo nhẹ thì
   cụm 4 nút thành "2 tròn + 2 gần vuông" — nhìn như lỗi lắp ghép. Vì vậy ở đây
   dùng 50% cứng chứ KHÔNG gọi var(--radius); đổi thang bo góc toàn site thì
   cụm này vẫn phải giữ tròn.
   Yêu cầu trực tiếp của khách 2026-07-27 — đừng "sửa" cho đồng bộ. */
.group-contact a{
  width:44px;height:44px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  /* Nền dự phòng: thực tế không bao giờ lộ ra (2 nút dưới có --cta-grad, 2 nút
     logo có background:none) nhưng vẫn để đúng accent xanh thay vì xám-đen cũ,
     phòng khi thêm nút thứ năm. */
  background:var(--gold-grad);color:var(--btn-ink);
  transition:transform .25s var(--ease),background .25s var(--ease);
}
.group-contact a:hover{transform:translateY(-3px);}

/* Brand colours */
/* Gọi hotline + lên đầu trang: gradient XANH #2947FE (chốt 2026-08-04).
   Khai báo CHUNG một chỗ để hai nút không bao giờ lệch nhau. Xem --cta-grad. */
.group-contact a.is-phone,
.group-contact .gc-top{
  position:relative;
  background:var(--cta-grad);
  color:var(--cta-ink);            /* icon trắng — xem ghi chú ở --cta-grad */
  border:0;
  /* KHÔNG có viền (yêu cầu khách) → bóng là thứ DUY NHẤT tách nút khỏi nền
     trắng, đừng bỏ nốt.
     Đặt ở rule chung chứ không để keyframe gc-pulse lo: trước đây bóng của nút
     gọi CHỈ nằm trong keyframe, nên ở chế độ giảm chuyển động (animation:none)
     nút mất sạch bóng — vừa chìm vào nền vừa lệch hẳn với nút còn lại. */
  box-shadow:var(--cta-shadow);
}
/* Hover: lớp phủ trắng mờ bằng ::after (opacity — thuộc tính compose) thay
   cho filter:brightness cũ: CSS không nội suy được giữa hai gradient, còn
   transition filter thì ép trình duyệt vẽ lại nút mỗi frame — nút này lại
   fixed + đang chạy gc-pulse vô hạn, filter là chi phí trả suốt đời trang. */
.group-contact a.is-phone,
.group-contact .gc-top{transition:transform .25s var(--ease),opacity .3s var(--ease),visibility .3s;}
.group-contact a.is-phone::after,
.group-contact .gc-top::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:rgba(255,255,255,.16);opacity:0;transition:opacity .25s var(--ease);
}
.group-contact a.is-phone:hover::after,
.group-contact .gc-top:hover::after{opacity:1;}
/* FB & Zalo: full-colour brand logos — no wrapper circle, fill full button size */
.group-contact a.is-fb,
.group-contact a.is-zalo{background:none;box-shadow:none;}
.group-contact .gc-logo{width:100%;height:100%;display:block;}

/* "Nháy" — ring pulse + phone shake to signal a live hotline (phone only) */
.group-contact a.is-phone{animation:gc-pulse 2.2s var(--ease) infinite;}
.group-contact a.is-phone .icon{animation:gc-ring 2.2s var(--ease) infinite;transform-origin:50% 60%;}
@keyframes gc-ring{0%,60%,100%{transform:rotate(0);}70%{transform:rotate(-18deg);}80%{transform:rotate(14deg);}90%{transform:rotate(-8deg);}}

/* Scroll-to-top — hidden until JS adds .is-visible */
/* Tròn cùng cỡ với 3 nút trên — xem ghi chú ngoại lệ ở .group-contact a */
.group-contact .gc-top{
  width:var(--btn-icon-sm);height:var(--btn-icon-sm);border-radius:50%;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  /* background/color/border do rule chung ở trên đặt (dùng --cta-grad) */
  opacity:0;visibility:hidden;transform:translateY(12px);
}
.group-contact .gc-top:hover{transform:translateY(-3px);}
.group-contact .gc-top.is-visible{opacity:1;visibility:visible;transform:none;}

@media (prefers-reduced-motion:reduce){
  .group-contact a,
  .group-contact a .icon{animation:none;}
}

.group-contact .icon{width:20px;height:20px;}
/* Riêng nút lên đầu trang: nó là MŨI TÊN, mà mũi tên vẽ bằng nét nên cỡ = độ
   dày nét. Để 20px thì nét ra 1.33px, lệch 33% so với mọi mũi tên khác trên
   site. Hạ về chuẩn chung; các icon còn lại trong cụm (Facebook/Zalo/gọi) là
   glyph ĐẶC, không dính chuyện này nên giữ nguyên 20px. */
.group-contact .gc-top .icon{width:var(--icon-arrow);height:var(--icon-arrow);}
/* Vòng lan toả lấy stop xanh sáng của --cta-grad (#6E80FF) — cùng accent với
   chính nút. Giá trị ghi thẳng vì keyframe không nội suy được var() qua
   rgba(). */
@keyframes gc-pulse{0%,100%{box-shadow:0 10px 26px rgba(0,0,0,.35),0 0 0 0 rgba(211,175,55,.6);}50%{box-shadow:0 10px 26px rgba(0,0,0,.35),0 0 0 14px rgba(211,175,55,0);}}

/* =========================================================
   Reveal masks (GSAP layer — effects.js + hero-title.js)
   Nằm ở common.css vì hai script đó chạy trên MỌI trang (trang con dùng
   data-reveal="mask" cũng cần .reveal-mask). Chuyển từ home.css 2026-08-03.
   ========================================================= */
/* Premium word-by-word mask reveal (hero-title.js splitWords). JS splits the
   text into .reveal-word-wrap > .reveal-word; the wrapper clips the upward
   slide so each word emerges from below rather than merely fading. */
.reveal-word-wrap{
  display:inline-block;overflow:hidden;vertical-align:top;
  /* Headroom on BOTH sides — descenders (g, ý, đ) below, stacked tone marks
     (Ế, Ộ, Ứ) above; the equal negative margins keep the mask from adding any
     vertical layout space. Same pairing as .reveal-mask below. */
  padding-block:.14em;margin-block:-.14em;
}
/* Không will-change: entrance chạy đúng một lần; GSAP tự lo layer lúc tween. */
.reveal-word{display:inline-block;}
/* Hero per-CHAR reveal (ltd-style, hero-title.js splitChars): .reveal-cword
   bọc từng TỪ (inline-block → không bẻ dòng giữa từ), .reveal-char là từng
   grapheme trượt ngang vào. Không mask: chuyển động là x + opacity. */
.reveal-cword{display:inline-block;}
.reveal-char{display:inline-block;}
/* Masked LINE reveal for headings (effects.js wraps the heading content in
   .reveal-line): the line slides up from beneath its own baseline. */
.reveal-mask{display:block;overflow:hidden;padding-block:.14em;margin-block:-.14em;}
.reveal-mask .reveal-line{display:block;}

/* =========================================================
   Reveal-on-scroll (JS toggles .is-inview)
   ========================================================= */
/* Hệ reveal dự phòng cho phần tử GSAP không chiếm (và cho lúc CDN GSAP hỏng).
   Dùng CHUNG --reveal-ease/--reveal-dur với effects.js, nếu không hai hệ chạy
   cạnh nhau trên cùng màn hình bằng hai nhịp khác nhau — đó chính là thứ làm
   trang đọc ra "lộn xộn" dù từng hiệu ứng riêng lẻ đều mượt.
   Thời lượng .6·DUR: đây là chuyển động nhỏ (dịch 10px), không phải khối lớn.
   KHÔNG đặt will-change ở đây: selector này phủ hàng chục phần tử và reveal
   chỉ chạy một lần lúc vào màn — giữ layer thường trực cho tất cả chúng tốn
   bộ nhớ compositor suốt vòng đời trang (một nguồn khựng khi cuộn). */
[data-aos]{opacity:0;transform:translateY(10px);transition:opacity calc(var(--reveal-dur) * .6) var(--reveal-ease),transform calc(var(--reveal-dur) * .6) var(--reveal-ease);}
[data-aos].is-inview{opacity:1;transform:none;}
/* Bậc trễ = bội số của --reveal-stagger, cùng nhịp lệch pha với GSAP stagger. */
[data-aos-delay="1"]{transition-delay:calc(var(--reveal-stagger) * 1);}
[data-aos-delay="2"]{transition-delay:calc(var(--reveal-stagger) * 2);}
[data-aos-delay="3"]{transition-delay:calc(var(--reveal-stagger) * 3);}
[data-aos-delay="4"]{transition-delay:calc(var(--reveal-stagger) * 4);}

/* =========================================================
   RESPONSIVE — shell
   ========================================================= */
@media (max-width:1024px){
  .header__nav{display:none;}
  .header__actions .re-select-main{display:none;}
  .header__burger{display:flex;}
  /* Nav ẩn → actions tự nhận khoảng trống co giãn để vẫn dính lề phải.
     (Search là nút icon nên không cần thu width như bản cũ.) */
  .header__actions{margin-inline-start:auto;}
  /* Tablet: hai khối xếp chồng. Cột thương hiệu nay chỉ còn logo (huy hiệu đã
     gỡ — xem ghi chú .footer__emblem ở trên), nên không cần xếp ngang nữa. */
  .footer__grid{grid-template-columns:1fr;gap:44px;}
  /* HÀNG NGANG: logo dạt trái, hình chìm dạt phải (khách chốt 2026-09-08, áp
     từ TABLET DỌC trở xuống chứ không chỉ điện thoại). Từ mốc này .footer__grid
     đã gộp một cột nên khối thương hiệu có trọn bề ngang — xếp chồng và canh
     giữa thì nó cao gấp đôi mà hai bên vẫn trống.
     ⚠️ .footer__watermark vốn là hình CHÌM đặt DƯỚI logo (có margin-top theo
     tỉ lệ); về hàng ngang thì phải gỡ margin đó, nếu không nó tụt xuống lệch
     hẳn so với logo. */
  .footer__brand{
    flex-direction:row;align-items:center;justify-content:space-between;
    width:100%;margin-inline:0;gap:clamp(16px,4vw,32px);
  }
  .footer__watermark{margin:0;flex:0 0 auto;}
  /* LƯỚI 2×2 (khách chốt 2026-09-08): Liên hệ | Khám phá, rồi Sản phẩm | Chứng
     nhận. Bản trước cho Liên hệ và Chứng nhận trải hết hàng — footer vì thế
     kéo dài ra bốn hàng và thừa một mảng trống lớn bên phải mục Chứng nhận.
     Hai hàng cao lệch nhau (badge 46px so với dòng link) là cái giá đã cân
     nhắc: align-items:start giữ mọi cột thẳng mép trên nên chênh lệch đó rơi
     xuống dưới, không đội tiêu đề cột lên. */
  /* minmax(0,1fr) chứ không 1fr trần: sàn `auto` của một ô lưới lấy theo kích
     thước nội tại của nội dung, mà cột Liên hệ có địa chỉ dài không ngắt được
     — ô phình quá phần chia của nó và ĐÈ lên cột Chứng nhận bên cạnh (khách
     báo 2026-09-08). minmax(0,…) đóng cửa đó lại. */
  .footer__cols{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:start;}
  /* THỨ TỰ Ô (khách chốt 2026-09-08):
         Liên hệ  |  Chứng nhận
         Khám phá |  Sản phẩm
     Trong DOM, Chứng nhận là cột CUỐI (thứ 4). Chỉ cần ghim hai ô đầu hàng 1;
     Khám phá và Sản phẩm không khai gì, lưới tự thả chúng vào hai ô trống còn
     lại của hàng 2 — đúng thứ tự DOM. Không phải đổi markup. */
  .footer__cols > .footer__col:first-child{grid-column:1;grid-row:1;}
  .footer__cols > .footer__certs{grid-column:2;grid-row:1;}
}
/* (Bề rộng drawer 2/3 – 4/5 màn theo khổ máy đã gỡ 2026-09-22: tấm menu nay
   tràn 100% bề ngang dưới header — xem khối HEADER — MOBILE.) */
/* 720 → 560 (khách 2026-09-08: "còn chỗ thì cho nó ngang, đừng xếp dọc").
   Ở 560-720px cả hai cụm vẫn thừa bề ngang: dòng bản quyền ~46 ký tự cộng hai
   link chính sách vừa đúng một hàng, còn huy hiệu "Từ 2002" chỉ rộng ~150px.
   Dưới 560 thì mới thật sự hết chỗ. */
@media (max-width:560px){
  .footer__intro{grid-template-columns:1fr;gap:20px;}
  .footer__intro .footer__since{grid-column:1;grid-row:auto;justify-self:start;}
  /* Bỏ nowrap: dòng bản quyền dài hơn màn hình sẽ đẩy trang trượt ngang */
  .footer__copy{white-space:normal;}
  .footer__blurb{max-width:46ch;}
  .footer__bottom{grid-template-columns:1fr;justify-items:start;text-align:left;}
  .footer__meta{align-items:flex-start;}
  .footer__policy{justify-content:flex-start;}
}
@media (max-width:640px){
  body{font-size:17px;}
  /* Mobile: chỉ giữ brand + burger; tìm kiếm và social chuyển xuống menu
     off-canvas (menu đã có nút gọi riêng) + cụm liên hệ nổi. */
  .header__search,.header__social{display:none;}
  .header__logo img{height:40px;}
  .header__cert{height:38px;}
  .header__certs{padding-left:10px;gap:8px;}
  .header__brand{gap:10px;}
  /* ĐIỆN THOẠI:
         Liên hệ            (trải hết hàng — địa chỉ dài)
         Khám phá | Sản phẩm (hai cột link, chữ ngắn, chung một hàng)
         Chứng nhận         (trải hết hàng — badge cao)
     Khách chốt 2026-09-08: "mobile cho 2 cụm này chung hàng".
     ⚠️ minmax(0,1fr) chứ KHÔNG 1fr: sàn `auto` của ô lưới lấy theo kích thước
     nội tại, mà cột Liên hệ có địa chỉ dài không ngắt được — ô phình quá phần
     chia và ĐÈ sang ô bên cạnh. Đây đúng là lỗi đã xảy ra ở bản trước.
     ⚠️ grid-row:auto để xoá vị trí ghim của khối 1024 (Liên hệ 1/1, Chứng nhận
     2/1); grid-column thì khai lại tường minh ngay dưới. */
  .footer__cols{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:32px 28px;}
  .footer__cols > .footer__col:first-child,
  .footer__cols > .footer__certs{grid-column:1 / -1;grid-row:auto;}
  .footer__certs-row{flex-direction:row;align-items:center;flex-wrap:wrap;gap:16px 28px;}
  /* Hẹp nhất: huy hiệu xuống dòng dưới logo. width:fit-content để khối bám lề
     trái như phần chữ bên dưới, còn huy hiệu vẫn canh giữa theo logo.
     KHÔNG đặt gap ở đây: khe logo ↔ hình chìm do .footer__watermark{margin-top}
     giữ, theo tỉ lệ đo từ mockup. Rule cũ có gap:30px — viết từ hồi huy hiệu là
     phần tử duy nhất bên dưới — nay CỘNG DỒN với margin đó, đo tại 390px ra
     65px thay vì 35px. Một khoảng cách thì chỉ được một nơi quyết. */
  /* (Logo + hình chìm xếp trái/phải đã dời lên khối 1024 — xem ở trên.) */
}

/* =========================================================
   INTRO / PRELOADER — "RUY BĂNG MỞ MÀN" (vòng 6, video)
   Concept: một video 3s cận cảnh ruy băng satin cream-gold — đúng
   sản phẩm dây dệt — từ thế gấp xếp trải phẳng dần thành sóng ngang.
   File: intro-ribbon-02.mp4 = bản LÀM NÉT (hqdn3d + gradfun + cas,
   nén crf18) từ nguồn satin TÔNG SÁNG — khách chốt giữ độ sáng này
   (mean 231 giữ nguyên, chỉ tăng nét; bản grade xám ít cháy hơn đã
   bị loại). Nguồn thô đã dời khỏi site về
   "[MONA] HUU TIN/huutin/assets/video/" (intro-src-*.mp4) — đừng
   thêm lại vào assets/: deploy không bao giờ xóa file trên server.
   CSS chỉ đặt video phủ màn + nền lót ĐÚNG MÀU NỀN VIDEO (#FFFFFF,
   đo từ 4 góc frame — trùng luôn nền trang): object-fit:cover có
   cắt kiểu gì thì mép cũng không lộ vệt khác màu, và trước khi
   frame đầu về thì màn đã đúng sắc đó — không lóe.
   Mở màn: main.js gắn class is-done ở ~0.45s cuối video → fade .5s.
   Bản cũ "quả cầu gold" lưu tại intro-qua-cau-gold.zip gốc dự án.
   ========================================================= */
body.is-loading{ overflow:hidden; height:100vh; }
.intro{
  position:fixed; inset:0; z-index:2000;
  background:var(--bg);
  overflow:hidden;
  transition:opacity .5s ease;
}
.intro.is-done{ opacity:0; pointer-events:none; }
.intro__video{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
}


/* =========================================================
   MICRO-INTERACTIONS — shared components
   Hover/focus polish. Reuses --ease/--dur; the global reduced-motion
   kill switch (below) zeroes these durations automatically.
   ========================================================= */

/* --- Buttons: light "sheen" sweeps across on hover --- */
/* isolation:isolate + z-index:-1 puts the streak ABOVE the button's
   gradient background but BELOW its label/icon (paint order). */
.btn{position:relative;overflow:hidden;isolation:isolate;}
/* VỆT SÁNG CHÉO ĐÃ GỠ 2026-09-07 (khách: "dư hiệu ứng chớp chéo trái qua
   phải"). Trước đây .btn::before là một dải trắng 30% nghiêng 18° quét ngang
   khi hover. Nút nay chỉ còn MỘT tín hiệu hover: nền chuyển sang gradient xám
   đen (.btn-primary::after) — cùng ngôn ngữ với CTA chữ, vốn cũng chỉ đổi một
   thứ. Rule .contact-form__submit .btn::before{display:none} từng phải tắt vệt
   này cho riêng nút gửi form, nay thành thừa nhưng vô hại. */
.btn:hover::before{transform:translateX(230%) skewX(-18deg);}
.btn:hover{transform:translateY(-1px);}
.btn:active{transform:translateY(1px);}   /* keep press feedback over the -1px hover */

/* --- CTA CHỮ DÙNG CHUNG (.link-arrow và .pfall__cta) ---
   Khuôn chốt 2026-09-07: chữ IN HOA + MŨI TÊN bên phải; NGHỈ không gạch chân,
   HOVER mới hiện gạch vàng kéo từ trái sang.

   Lịch sử để khỏi đi vòng lại: bản trước cho gạch hiện SẴN và hover thì rút về
   phải rồi vẽ lại (keyframes cta-line, nay đã gỡ). Khách đổi ý cùng ngày:
   "default bỏ gạch chân, khi hover thì gạch chân vàng".

   ICON vẽ bằng ::before + mask chứ không phải thẻ <i> trong markup: CTA này có
   mặt ở 8 chỗ trên 5 trang, thêm thẻ là 8 chỗ có thể sót. order:1 đẩy nó xuống
   cuối hàng flex (::before mặc định đứng TRƯỚC chữ). Dùng chung arrow-right.svg
   với mọi mũi tên khác của site; --icon-arrow (16px) là token cỡ mũi tên NÉT.
   stamp-assets.mjs có quét url() trong .css nên file này vẫn được đóng dấu ?v=.

   GẠCH 2px, cách đáy 4px. Vì sao 2px chứ không 1.5px: hộp dòng 13.5 × 1.38 =
   18.63px nên đáy link rơi vào toạ độ lẻ khác nhau tuỳ chỗ (đo: news .72, vòng
   xoay .03); 1.5px ở toạ độ lẻ bị chia thành hai hàng mờ, ở toạ độ chẵn thành
   một hàng đậm — đúng lỗi "Xem thêm có border nhỏ hơn" khách từng báo.
   left:0;right:0 nên gạch phủ CẢ chữ lẫn icon. */
.link-arrow,.pfall__cta{
  position:relative;display:inline-flex;align-items:center;gap:8px;
}
.link-arrow::before,.pfall__cta::before{
  content:"";order:1;flex:0 0 auto;
  width:var(--icon-arrow);height:var(--icon-arrow);
  background-color:currentColor;
  -webkit-mask:url("../icons/arrow-right.svg?v=e658a6fd") center/contain no-repeat;
  mask:url("../icons/arrow-right.svg?v=e658a6fd") center/contain no-repeat;
  transition:transform .3s var(--ease);
}
.link-arrow:hover::before,.pfall__cta:hover::before{transform:translateX(3px);}
.link-arrow::after,.pfall__cta::after{
  content:"";position:absolute;left:0;right:0;bottom:-4px;height:2px;
  background:var(--gold);transform:scaleX(0);transform-origin:left;
  transition:transform .3s var(--ease);
}
.link-arrow:hover::after,.pfall__cta:hover::after{transform:scaleX(1);}

/* --- Footer nav links: sliding underline (matches header nav) --- */
.footer__col nav a{position:relative;}
.footer__col nav a::after{
  content:"";position:absolute;left:0;bottom:-1px;height:1px;width:100%;
  background:var(--gold-light);transform:scaleX(0);transform-origin:left;
  transition:transform .3s var(--ease);
}
.footer__col nav a:hover::after{transform:scaleX(1);}

/* --- Floating quick-contact: logo/icon pops on hover --- */
.group-contact .gc-logo,
.group-contact a .icon{transition:transform .25s var(--ease);}
.group-contact a:hover .gc-logo,
.group-contact a:hover .icon{transform:scale(1.12);}

/* =========================================================
   REDUCED MOTION — global kill switch
   ========================================================= */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  [data-aos]{opacity:1 !important;transform:none !important;}
  .group-contact a.is-phone{animation:none;}
}

/* ============================================================
   PHÂN TRANG — dùng chung cho lưới danh mục sản phẩm và lưới bài viết
   ============================================================
   Ở COMMON chứ không ở products-list.css: từ 2026-08-19 tin-tuc.html cũng dùng
   bộ nút này, mà trang đó không nạp products-list.css — để nguyên bên kia thì
   bộ nút bên này hiện ra trần trụi (hai mũi tên xếp dọc, số không có khung).
   Bộ nút do assets/js/plist-page.js dựng, HTML không author sẵn — số trang suy
   ra từ số thẻ. Không có JS thì cả lưới hiện hết và khối này không tồn tại,
   tức mất phân trang chứ không mất nội dung.
   Cùng khuôn nút với .pwheel__btn / .m-news__nav: nghỉ = chỉ viền, hover = tô
   VÀNG + chữ đen (vàng chỉ dành cho hành động nhỏ — xem bảng màu common.css). */
.plist-pager{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(8px,1vw,14px);
  margin-top:clamp(34px,4vw,60px);
}
.plist-pager__nums{display:flex;gap:6px;}
.plist-pager__num,
.plist-pager__arrow{
  display:flex;align-items:center;justify-content:center;
  min-width:44px;height:44px;padding:0 12px;
  border:1px solid var(--gray-200);border-radius:var(--radius);
  background:transparent;color:var(--ink);
  font-family:var(--font-display);font-size:var(--fs-sm);font-weight:var(--fw-medium);
  /* line-height:1 + --cap-nudge: nút cao cố định thì chữ phải được canh giữa
     bằng quang học, xem ghi chú --cap-nudge trong common.css. */
  line-height:1;cursor:pointer;
  transition:background .25s var(--ease),border-color .25s var(--ease),color .25s var(--ease);
}
.plist-pager__arrow .icon{width:var(--icon-nav);height:var(--icon-nav);}
.plist-pager__num:hover,
.plist-pager__arrow:not(:disabled):hover{
  background:var(--gold);border-color:var(--gold);color:var(--btn-ink);
}
/* Trang ĐANG XEM: tô đặc luôn, không chỉ đổi viền — người dùng phải thấy mình
   đang ở đâu mà không cần so sánh hai sắc viền gần nhau. */
.plist-pager__num.is-active{
  /* border trong suốt: nền vẽ cả dưới viền (background-clip mặc định) nên
     gradient chạy liền ra mép, không có khung vàng đặc bao quanh. */
  background:var(--gold-grad);border-color:transparent;color:var(--btn-ink);
  cursor:default;
}
/* Nút vô hiệu vẫn HIỆN (không display:none): bộ nút đổi bề ngang giữa các
   trang thì cả cụm nhảy ngang mỗi lần bấm. */
.plist-pager__arrow:disabled{opacity:.35;cursor:not-allowed;}
@media (max-width:520px){
  .plist-pager__num,
  .plist-pager__arrow{min-width:38px;height:38px;padding:0 9px;}
}

/* ---- Form liên hệ: hai ô mỗi hàng cho tới 560px --------------------------
   Khách chốt 2026-09-08: ở tầng giữa (bài + form xếp dọc) form vẫn phải dàn
   hai trường một hàng. Mốc gộp cũ là 1024 — quá sớm, cả một khoảng tablet chỉ
   có một ô mỗi hàng trong khi thừa hơn 300px trống. */
@media (max-width:560px){
  /* gap:0 chứ không giữ 18px: khi hàng gộp về MỘT cột, khe của lưới CỘNG THÊM
     vào margin-bottom 18px của .field — hai trường cùng một hàng cách nhau
     36px trong khi hai hàng khác nhau chỉ cách 18px, nhìn ra là so le (khách
     báo 2026-09-08 "canh đều field lại"). Bỏ khe lưới thì mọi trường cách nhau
     đúng 18px do .field quyết. */
  .contact-form__row{grid-template-columns:1fr;gap:0;}
}
