﻿/* ============================================================
   MIWANG — TRANG CÔNG KHAI
   Phụ thuộc: tokens.css → components.css → main.css (đúng thứ tự này)
   File này CHỈ chứa bố cục riêng của trang. Mọi primitive dùng chung
   (nút, ô nhập, thẻ, nhãn, bảng…) nằm ở components.css.
   ============================================================ */

/* ============================================================
   NỀN TẢNG
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* Cuộn tới neo phải trừ chiều cao nav cố định, nếu không tiêu đề bị che (§2.4) */
  scroll-padding-top: calc(var(--nav-h-lg) + var(--s-6));
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--f-body);
  font-size: var(--t-base);
  line-height: var(--lh-base);
  /* Chặn cuộn ngang ở MỌI bề rộng — tiêu chí nghiệm thu §15.7 */
  overflow-x: hidden;
  width: 100%;
  min-height: 100dvh;
  transition: background-color var(--d-base) var(--ease), color var(--d-base) var(--ease);
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
}
h3, h4, h5, h6 { line-height: var(--lh-snug); }

p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; }
img, svg, video, iframe { display: block; max-width: 100%; }
img, video { height: auto; }

a { color: inherit; text-decoration: none; transition: color var(--d-fast) var(--ease); }
button { font: inherit; color: inherit; background: none; border: 0; }

/* Viền hiển thị vị trí bàn phím (§12.5). :focus-visible để chuột không kích hoạt. */
:focus-visible {
  outline: var(--focus-ring-w) solid var(--c-accent);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute;
  left: var(--s-4);
  top: calc(var(--s-4) * -8);
  z-index: var(--z-skip);
  display: inline-flex;
  align-items: center;
  height: var(--ctl-md-h);
  padding-inline: var(--ctl-md-px);
  background: var(--c-accent);
  color: var(--c-text-on-accent);
  border-radius: var(--r-pill);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  transition: top var(--d-fast) var(--ease);
}
.skip-link:focus { top: var(--s-4); }

/* ============================================================
   KHUNG & NHỊP
   ============================================================ */
.wrap {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--prose { max-width: calc(var(--w-prose) + var(--gutter) * 2); }

.section { padding-block: var(--section-y); }
.section--sm { padding-block: var(--section-y-sm); }
.section--flush-top { padding-top: 0; }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-6);
  margin-bottom: var(--s-9);
}
.section-head__text { max-width: 46ch; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-accent);
  line-height: 1;
}
.eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: var(--r-circle);
  background: currentColor;
  flex: none;
}

.section-title { font-size: var(--t-d2); }
.lede {
  font-size: var(--t-lg);
  line-height: var(--lh-base);
  color: var(--c-text-muted);
  max-width: var(--w-prose);
}

/* ============================================================
   THANH ĐIỀU HƯỚNG
   ============================================================ */
.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-nav);
  pointer-events: none;   /* chỉ ruột nav nhận sự kiện, không chặn cả dải ngang */
}

/* Ở đầu trang nav TRONG SUỐT hoàn toàn, không khung viền.
   Khi cuộn xuống, nền mờ trải ngang toàn dải mới hiện ra — cần thiết vì
   nav cố định, không có nền thì chữ đè lên nội dung phía dưới.
   Dùng lớp giả + opacity thay vì đổi background trực tiếp: opacity không
   kích hoạt tính lại bố cục, nên chuyển cảnh mượt khi cuộn. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c-overlay);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border-bottom: var(--bw) solid var(--c-border);
  opacity: 0;
  transition: opacity var(--d-base) var(--ease);
  pointer-events: none;
}
.nav[data-scrolled="true"]::before { opacity: 1; }

.nav__inner {
  position: relative;   /* nằm trên lớp nền mờ ::before */
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  height: var(--nav-h-lg);
  padding-block: var(--s-3);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  flex: none;
  /* Logo trong nav là liên kết về trang chủ → phải đạt vùng chạm 44px.
     Đo được 98×24 trước khi thêm dòng này. */
  min-height: var(--tap-min);
  font-family: var(--f-display);
  font-weight: var(--fw-bold);
  font-size: var(--t-d4);
  letter-spacing: var(--ls-tight);
  line-height: 1;
}
.brand__mark { width: var(--icon-lg); height: var(--icon-lg); flex: none; }

.nav__links { display: flex; align-items: center; gap: var(--s-1); list-style: none; }

/* Nhãn VIẾT HOA theo đúng công thức nhãn nhỏ của hệ thiết kế: giãn chữ
   --ls-wide + đậm vừa, vì chữ hoa không có phần nhô lên/thụt xuống nên
   dính sát nhau sẽ khó đọc.
   Bỏ số thứ tự rồi thì mỗi mục hụt đi khoảng 26px, cả hàng ngắn lại hẳn —
   nên cỡ chữ trả về 14px và đệm ngang giãn lại 16px, lấy lại đúng sức nặng
   thị giác mà con số vừa mang đi. */
.nav__link {
  display: inline-flex;
  align-items: center;
  height: var(--ctl-md-h);
  /* Giãn chữ cộng khoảng trắng vào SAU ký tự cuối, nên đệm phải trông dày
     hơn đệm trái. Trừ lại đúng lượng đó để chữ nằm giữa thật. */
  padding-inline-start: var(--s-4);
  padding-inline-end: calc(var(--s-4) - 0.10em);
  border-radius: var(--r-pill);
  font-size: var(--t-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-muted);
  transition: color var(--d-fast) var(--ease), background-color var(--d-fast) var(--ease),
              scale var(--d-fast) var(--ease);
}
/* Trỏ chuột vào thì mục hơi phóng to. Dùng thuộc tính `scale` riêng chứ
   không dùng `transform`, vì `transform` còn dành cho hiệu ứng khác và hai
   bên sẽ ghi đè nhau. Chỉ 6%: đủ để tay cảm nhận được phản hồi, chưa đủ để
   xô lệch các mục bên cạnh. */
.nav__link:hover,
.nav__link:focus-visible { color: var(--c-text); background: var(--c-bg-elev-2); scale: 1.06; }
.nav__link[aria-current="true"] { color: var(--c-text); }

.nav__tools { display: flex; align-items: center; gap: var(--s-2); flex: none; }

/* BỎ khung viền bao ngoài: khung đó buộc chiều cao lên 52px để hai nút
   bên trong đạt 44px, khiến bộ chuyển ngôn ngữ cao hơn mọi thứ cạnh nó.
   Nay hai nút đứng độc lập, mỗi nút TỰ đạt 44×44 mà nhìn vẫn nhẹ vì
   không có viền và nền. */
.lang-switch {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  height: var(--ctl-md-h);
  flex: none;
}
.lang-switch a {
  display: grid;
  place-items: center;
  min-width: var(--tap-min);
  height: var(--ctl-md-h);
  border-radius: var(--r-pill);
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  color: var(--c-text-dim);
  transition: color var(--d-fast) var(--ease), background-color var(--d-fast) var(--ease);
}
/* Ngôn ngữ đang chọn được đánh dấu bằng HAI kênh — nền nhạt VÀ chữ đậm
   hơn — chứ không chỉ bằng màu (§12.5). */
.lang-switch a[aria-current="true"] {
  background: var(--c-accent-soft);
  color: var(--c-accent);
  font-weight: var(--fw-bold);
}
.lang-switch a:not([aria-current="true"]):hover { color: var(--c-text); background: var(--c-bg-elev-2); }

.nav__burger { display: none; }

/* ---------- MENU DI ĐỘNG ---------- */
.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--s-7);
  padding: var(--s-4) var(--gutter) var(--s-9);
  background: var(--c-bg);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform var(--d-slow) var(--ease-out), visibility var(--d-slow);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.drawer[data-open="true"] { transform: none; visibility: visible; }

.drawer__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-h-lg);
  flex: none;
}
.drawer__links { list-style: none; display: grid; gap: 0; align-content: center; }
/* Cùng cách viết với nav trên máy tính: VIẾT HOA, không số thứ tự. Chỉ
   khác cỡ chữ — đây là menu chữ lớn nên giữ font hiển thị và cỡ --t-d2.
   Giãn chữ để --ls-normal chứ không --ls-wide: cỡ chữ này chữ hoa đã tự
   thoáng, giãn thêm sẽ rời rạc. */
.drawer__links a {
  display: flex;
  align-items: center;
  min-height: 60px;
  padding-block: var(--s-3);
  border-bottom: var(--bw) solid var(--c-border);
  font-family: var(--f-display);
  font-size: var(--t-d2);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-normal);
  text-transform: uppercase;
}
.drawer__foot { display: grid; gap: var(--s-3); }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 100svh;   /* svh: không nhảy khi thanh địa chỉ di động ẩn/hiện */
  padding-top: calc(var(--nav-h-lg) + var(--s-10));
  padding-bottom: var(--s-6);
  overflow: hidden;
}

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: var(--grid-gap);
  align-items: start;
  margin-bottom: var(--s-9);
}

.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  height: var(--ctl-sm-h);
  padding-inline: var(--s-4);
  margin-bottom: var(--s-6);
  border-radius: var(--r-pill);
  background: var(--c-bg-elev);
  border: var(--bw) solid var(--c-border);
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-muted);
  line-height: 1;
}
/* Chấm xanh KHÔNG phải phương tiện truyền đạt duy nhất — luôn có chữ
   "Đang nhận dự án" bên cạnh (§12.5). */
.hero__badge .dot { width: 7px; height: 7px; border-radius: var(--r-circle); background: var(--c-success); flex: none; }

.hero__title { font-size: var(--t-d1); max-width: 15ch; }
.hero__title em { font-style: normal; color: var(--c-accent); }

.hero__aside { display: grid; gap: var(--s-6); padding-top: var(--s-2); }
.hero__intro { color: var(--c-text-muted); max-width: 44ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* Ảnh chân dung — CHỈ tỉ lệ khung, KHÔNG kèm min-height (cạm bẫy §12.4) */
.hero__portrait {
  position: relative;
  aspect-ratio: var(--ar-portrait);
  border-radius: var(--r-xl);
  overflow: hidden;
  border: var(--bw) solid var(--c-border);
  background:
    radial-gradient(120% 90% at 50% 0%, var(--c-accent-soft), transparent 62%),
    var(--c-bg-elev);
  display: grid;
  place-items: center;
  padding: var(--s-6);
  text-align: center;
}

/* Lưới cột ĐỀU, TRẢI HẾT bề ngang khung nội dung.
   Hai lần sửa trước đều lệch vì hai lý do khác nhau:
   1. Dùng flex → mỗi cột rộng theo nội dung, các mốc không thẳng hàng.
   2. Có max-width → ba cột dồn về bên trái, chừa khoảng trống lớn bên
      phải trong khi đường kẻ phía trên lại trải hết bề ngang.
   Nay bỏ max-width: ba cột chia đều toàn bộ bề ngang, thẳng hàng với
   đường kẻ và với lưới dự án phía dưới. */
.hero__stats {
  display: grid;
  /* auto-fit + minmax: ba cột trên màn rộng, tự rút còn hai rồi một cột
     khi hẹp — không cần viết lại ở từng điểm ngắt. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-7) var(--s-6);
  padding-top: var(--s-6);
  border-top: var(--bw) solid var(--c-border);
  margin: 0;
}
.hero__stats > div { display: grid; gap: var(--s-2); align-content: start; }
.stat__num {
  margin: 0;
  font-family: var(--f-display);
  font-size: var(--t-d2);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: 1;
}
.stat__label {
  margin: 0;
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
  line-height: var(--lh-snug);
}

/* Chữ "MiWang" cỡ đại ngồi sát đáy màn — đặc trưng mạnh nhất của ảnh tham khảo */
.hero__wordmark {
  /* KHÔNG dùng margin-bottom âm: nó kéo chữ xuống dưới khung, khiến phần
     đuôi chữ "g" bị cắt cụt. Dùng line-height sát và padding-bottom nhỏ
     để chữ vẫn ngồi thấp mà không mất nét nào. */
  margin: var(--s-7) 0 0;
  padding-inline: var(--s-2);
  font-family: var(--f-display);
  font-size: var(--t-hero);
  font-weight: var(--fw-black);
  /* Chữ "g" có đuôi thò xuống dưới đường chân chữ khoảng 0,21em. Với
     line-height 0,90 thì hộp dòng THẤP HƠN chính con chữ, nên đuôi chữ
     nằm ngoài hộp và bị cắt. Đặt 1,0 để hộp đủ chứa cả đuôi. */
  line-height: 1;
  letter-spacing: var(--ls-tighter);
  text-align: center;
  user-select: none;
  /* KHÔNG đặt overflow ở đây. Theo quy tắc CSS, khi một trục khác
     `visible` thì trục còn lại bị ép cắt theo — nên `overflow-x: clip`
     vẫn cắt cụt chiều dọc. Việc chặn tràn ngang do phần tử cha .hero
     đảm nhiệm, nơi không có chữ nào thò ra ngoài hộp. */
}

/* ============================================================
   THANH CHẠY VÔ HẠN
   ============================================================ */
.ticker {
  overflow: hidden;
  border-block: var(--bw) solid var(--c-border);
  padding-block: var(--s-6);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

/* Chạy vòng lặp liên tục, KHÔNG dừng khi trỏ chuột vào.
   (Bản trước có animation-play-state: paused khi hover — đã bỏ theo yêu
   cầu, thanh chạy giờ không bao giờ đứng lại.) */
.ticker__track { display: flex; }

/* Mỗi nhóm là MỘT bản sao đầy đủ và rộng tối thiểu bằng khung nhìn. Hai nhóm
   cùng trượt hết bề rộng của chính mình, nên lúc nhóm 1 vừa ra khỏi màn thì
   nhóm 2 đã nằm đúng chỗ nhóm 1 lúc đầu — khung hình lặp lại y hệt, không có
   điểm nhảy. `min-width` là chỗ mấu chốt: nội dung ngắn hơn màn (màn rộng,
   ít vai trò) vẫn phủ kín, không hở khoảng trống ở mép phải. */
.ticker__group {
  display: flex;
  align-items: center;
  flex: none;
  min-width: 100%;
  justify-content: space-around;
  animation: ticker-scroll 36s linear infinite;
}

/* Khoảng cách nằm ở margin của CHÍNH mỗi phần tử, không dùng `gap` của nhóm.
   `gap` chỉ chèn vào GIỮA các phần tử (n phần tử → n-1 khoảng) nên chỗ nối
   giữa hai nhóm bị hụt mất một khoảng. Margin thì phần tử nào cũng mang theo
   khoảng trống của mình, kể cả phần tử cuối → nối nhóm khít đều. */
.ticker__item {
  display: flex;
  align-items: center;
  margin-inline-end: var(--s-10);
  font-family: var(--f-display);
  font-size: var(--t-d3);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  color: var(--c-text-muted);
  white-space: nowrap;
  line-height: 1;
}

/* Dấu chấm ngăn cách là phần tử NGANG HÀNG với chữ, không phải ::after bên
   trong ô chữ. Có vậy `space-around` mới chia đều khoảng trống ở cả hai bên
   dấu chấm; nếu nằm trong ô chữ thì toàn bộ khoảng dôi ra dồn về một phía và
   dấu chấm bị lệch hẳn về phía từ đứng trước. */
.ticker__sep {
  flex: none;
  width: 7px;
  height: 7px;
  margin-inline-end: var(--s-10);
  border-radius: var(--r-circle);
  background: var(--c-accent);
}

/* Trượt hết bề rộng của CHÍNH nhóm (không phải nửa track) — nhờ vậy quãng
   trượt luôn khớp bản sao dù nhóm bị `min-width` kéo giãn rộng thêm. */
@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}

@media (prefers-reduced-motion: reduce) {
  .ticker { -webkit-mask-image: none; mask-image: none; }
  .ticker__group {
    animation: none;
    min-width: 0;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-5);
  }
  /* Đứng yên thì bản sao thứ hai chỉ gây lặp chữ — ẩn hẳn đi. */
  .ticker__group[aria-hidden] { display: none; }
  .ticker__item { font-size: var(--t-d4); }
  /* Đứng yên thì `gap` lo hết khoảng cách — bỏ margin kẻo cộng dồn. */
  .ticker__item, .ticker__sep { margin-inline-end: 0; }
}

/* ============================================================
   KHỐI CHỮ ĐỐI TÁC — bật từ ngoài màn bay vào
   ------------------------------------------------------------
   TRẠNG THÁI NGHỈ là một KHỐI CHỮ căn giữa: các tên chảy thành dòng, cùng
   cỡ, cùng màu. Không phải chữ tản mát — tản mát chỉ là khoảnh khắc giữa
   chừng lúc các tên còn đang bay.

   BA QUYẾT ĐỊNH QUAN TRỌNG:

   1. Xếp bằng `flex-wrap` chứ KHÔNG định vị tuyệt đối. Chữ tự chảy dòng
      nên thêm bao nhiêu đối tác cũng không vỡ, và không đời nào tràn ngang.

   2. Bay vào từ ĐỦ TÁM HƯỚNG, nhưng quãng bay đo bằng ĐIỂM ẢNH và ngắn
      vừa đủ nằm gọn trong khung đã nới đệm.
      ĐÃ THỬ `overflow: clip` + `overflow-clip-margin: 30vh` để chữ bay
      ngoài khung vẫn thấy — ĐO RA HỎNG: biên nới làm phình vùng cuộn của
      cả trang (tràn ngang 32–648px tuỳ khổ màn). `overflow: hidden` chặn
      sạch, nên giữ nó và bù bằng `padding-block` để có chỗ bay theo dọc.

   3. Nhoè chỉ có TRONG LÚC bay rồi tan hết khi chữ đứng yên. Giữ nhoè
      vĩnh viễn thì tên đối tác vĩnh viễn khó đọc. Góc nghiêng cũng vậy:
      lúc bay thì chữ nghiêng, về chỗ là thẳng lại — chữ nằm nghiêng vĩnh
      viễn vừa khó đọc vừa phá nhịp dòng.
   ============================================================ */
.cloud {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  align-items: baseline;
  gap: var(--s-2) var(--s-5);
  margin-top: var(--s-9);
  /* Khối phải RỘNG VÀ CAO gần bằng màn hình thì bốn góc của nó mới nằm
     đúng chỗ bốn góc màn — chữ mới có cảm giác lao vào từ ngoài rìa màn
     chứ không phải từ mép một dải chữ hẹp. Lằn cắt của khối cũng chính là
     rìa màn, nên chữ biến mất đúng lúc ra khỏi tầm nhìn. */
  min-height: clamp(340px, 52vh, 620px);
  padding-block: clamp(2rem, 5vw, 4.5rem);
  /* Xem quyết định 2 ở trên: `hidden` chứ KHÔNG phải `clip` + biên nới. */
  overflow: hidden;
}

.cloud__item {
  font-family: var(--f-display);
  /* Trần 3vw chứ không sát hơn: khối cắt gọn phần thò ra nên chữ quá khổ
     sẽ bị xén ÂM THẦM, không báo lỗi. Chừa biên để danh sách đối tác dài
     thêm vẫn an toàn. */
  font-size: clamp(1.25rem, 3vw, 3rem);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--c-text);
  white-space: nowrap;
}

/* ---------- Hiệu ứng bay từ ngoài vào ----------
   MỐC QUAN SÁT ĐẶT Ở KHỐI BAO NGOÀI, không phải từng chữ. Đây là điểm
   mấu chốt: chữ khởi đầu nằm tận ngoài màn (±70–95vw) nên nếu quan sát
   từng chữ thì chúng không bao giờ lọt vào tầm nhìn, và hiệu ứng không
   bao giờ được kích hoạt. Khối bao ngoài nằm trong dòng chảy bình thường
   nên luôn được nhìn thấy đúng lúc.

   Khối bao phải tự vô hiệu hiệu ứng mặc định của [data-reveal] (mờ dần +
   dịch theo trục Y) — ở đây chỉ có chữ bên trong chuyển động. */
.js-reveal .cloud[data-reveal] {
  opacity: 1;
  transform: none;
}

/* Trạng thái Ở NGOÀI: chữ đứng tại một góc quanh màn, PHÓNG TO và MỜ —
   như đang ở rất gần ống kính nên vừa lớn vừa mất nét. Từ đây nó lùi về
   đúng cỡ, nét dần và trôi vào chỗ của mình.

   Đây cũng chính là trạng thái mà chữ QUAY LẠI khi cuộn ngược lên: cùng
   một khai báo lo cả hai chiều, chuyển tiếp CSS tự chạy ngược — không cần
   viết thêm dòng nào cho chiều ra. */
.js-reveal .cloud[data-reveal] .cloud__item {
  opacity: 0;
  /* translate / rotate / scale là BA thuộc tính riêng, trình duyệt tự gộp
     lại theo đúng thứ tự. Viết tách bạch thế này để mỗi thành phần của
     chuyển động khai báo và chuyển tiếp độc lập được. */
  translate: var(--fx, -60vw) var(--fy, 0);
  rotate: var(--r, 0deg);
  scale: 2.4;
  filter: blur(18px);
  transition:
    opacity var(--d-slower) var(--ease),
    translate var(--d-slower) var(--ease),
    rotate var(--d-slower) var(--ease),
    scale var(--d-slower) var(--ease),
    filter var(--d-slower) var(--ease);
  /* Mỗi tên lệch nhau một nhịp → thành một luồng, không phải cả đám ập
     vào cùng lúc. */
  transition-delay: var(--d, 0ms);
}

/* Trạng thái Ở CHỖ: đúng cỡ, thẳng, nét căng. */
.js-reveal .cloud[data-reveal="in"] .cloud__item {
  opacity: 1;
  translate: none;
  rotate: none;
  scale: none;
  filter: blur(0);
}

/* ============================================================
   GIỚI THIỆU NGẮN
   ============================================================ */
/* Cả khối nằm trong MỘT thẻ nền để tách hẳn khỏi nhịp trang. */
.about-card {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--grid-gap) var(--s-11);
  padding: clamp(1.75rem, 4vw, 4rem);
  border-radius: var(--r-2xl);
  background: var(--c-bg-elev);
  border: var(--bw) solid var(--c-border);
}

/* Cột trái: tiêu đề trên cùng, cụm chữ + chip DÍNH ĐÁY. `space-between`
   đẩy hai đầu ra hai phía nên chân cột trái thẳng hàng với đáy ảnh bên
   phải, đúng như bố cục mẫu. */
.about-card__left {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-10);
}
.about-card__foot { display: grid; gap: var(--s-5); justify-items: start; }
.about-card__right { display: grid; gap: var(--s-9); align-content: start; }

.about__lead {
  font-size: var(--t-lg);
  line-height: var(--lh-base);
  color: var(--c-text);
  max-width: var(--w-prose);
}

.about__body { display: grid; gap: var(--s-5); justify-items: start; }
.about__body p { color: var(--c-text-muted); max-width: var(--w-prose); }
.about__body strong { color: var(--c-text); font-weight: var(--fw-semibold); }

/* Liên kết sang trang giới thiệu đầy đủ. Mũi tên là trang trí nên gắn
   bằng ::after, không lẫn vào nội dung trình đọc màn hình đọc ra. */
.about__roles-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: var(--c-accent);
}
.about__roles-link::after { content: "→"; }

.about__roles {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  list-style: none;
}
/* Chip ở đây chỉ để ĐỌC, không bấm được — bỏ con trỏ bàn tay kẻo người
   dùng tưởng bấm được rồi bấm hụt. */
.about__roles .tag { cursor: default; }

/* Khung ảnh giữ đúng tỷ lệ ngay cả khi chưa có ảnh, nhờ vậy bố cục không
   nhảy vào lúc ảnh thật được thêm qua trang quản trị. */
.about__photo { border: var(--bw) solid var(--c-border); }

@media (max-width: 900px) {
  .about-card { grid-template-columns: minmax(0, 1fr); }
  /* Một cột rồi thì không còn đáy nào để căn cho thẳng nữa. */
  .about-card__left { gap: var(--s-9); }
}

/* ============================================================
   LƯỚI DỰ ÁN
   Lưới 12 cột. Nhịp thị giác: ô rộng xen ô hẹp để mắt không mỏi (§12.1).
   ============================================================ */
.projects__grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  gap: var(--grid-gap);
}

.project-card { grid-column: span 6; }          /* nửa hàng — mặc định */
.project-card--wide  { grid-column: span 8; }   /* ô phá cách rộng */
.project-card--third { grid-column: span 4; }   /* ô hẹp đi kèm ô rộng */

.project-card > a { display: grid; gap: var(--s-5); height: 100%; align-content: start; }

.project-card__media {
  position: relative;
  aspect-ratio: var(--ar-card);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-bg-elev);
  border: var(--bw) solid var(--c-border);
  display: grid;
  place-items: center;
  padding: var(--s-5);
  transition: border-color var(--d-base) var(--ease);
}
.project-card--wide .project-card__media { aspect-ratio: var(--ar-video); }
.project-card > a:hover .project-card__media { border-color: var(--c-accent); }

.project-card__badge { position: absolute; top: var(--s-4); left: var(--s-4); }

.project-card__title {
  font-size: var(--t-d3);
  transition: color var(--d-fast) var(--ease);
  /* Tên dự án dài (vd "Fanmeeting Nhà Trẻ — Anh Trai Vượt Ngàn Chông Gai")
     phải xuống dòng gọn thay vì tràn khỏi thẻ. */
  overflow-wrap: break-word;
}
.project-card > a:hover .project-card__title { color: var(--c-accent); }

.project-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-3);
  font-size: var(--t-sm);
  color: var(--c-text-dim);
}
/* Dấu phân cách giữa các mẩu meta — dùng ::before nên không lẫn vào
   nội dung trình đọc màn hình đọc ra. */
.project-card__meta > * + *::before {
  content: "·";
  margin-right: var(--s-4);
  opacity: 0.6;
}

/* Ba thẻ "dự án liên quan" luôn CHIA ĐỀU một hàng — cố tình không dùng
   nhịp phá cách rộng/hẹp của trang chủ, vì ở đây ba thẻ ngang vai nhau.
   Selector kèm .projects__grid để thắng các quy tắc .project-card trong
   media query phía dưới file mà không phụ thuộc vào thứ tự dòng. */
.projects__grid .project-card--related { grid-column: span 4; }

/* Dưới 900px, ba cột còn chưa tới 300px mỗi cột — tên dự án dài sẽ vỡ.
   Xuống thẳng một cột thay vì 2+1, vì 2+1 mới đúng là cái mất cân đối. */
@media (max-width: 900px) {
  .projects__grid .project-card--related { grid-column: span 12; }
}

/* Dòng thể loại phía trên tên dự án. Dùng lại đúng lối phân cách bằng
   ::before của .project-card__meta để hai chỗ nhìn cùng một hệ. */
.project-card__kicker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-bottom: var(--s-3);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-accent);
}
.project-card__kicker > * + *::before {
  content: "·";
  margin-right: var(--s-4);
  opacity: 0.6;
}

/* ============================================================
   TRANG BLOG
   ============================================================ */

/* Dải đầu trang có nền riêng để tách khỏi phần danh sách phía dưới.
   Tràn hết bề ngang bằng cách kéo lề âm ra hai bên đúng bằng khoảng
   trắng của khung — không dùng 100vw, vì 100vw còn tính cả bề rộng thanh
   cuộn nên sinh tràn ngang trên máy có thanh cuộn chiếm chỗ. */
.blog-head {
  padding-top: calc(var(--nav-h-lg) + var(--s-10));
  padding-bottom: var(--section-y-sm);
  background: var(--c-bg-elev);
  border-bottom: var(--bw) solid var(--c-border);
}

/* Mắt xích quay lại. Vùng chạm đủ 44px theo §12.3. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap-min);
  font-size: var(--t-sm);
  color: var(--c-text-muted);
}
.back-link::before { content: "‹"; font-size: var(--t-lg); line-height: 1; }
.back-link:hover { color: var(--c-accent); }

.blog-title {
  margin-top: var(--s-4);
  font-size: var(--t-d1);
  line-height: var(--lh-tight);
}
/* Dòng thứ hai đổi sang chữ nghiêng màu nhấn — điểm nhấn thị giác của cả
   trang. Dùng <em> nên trình đọc màn hình cũng nhận ra đây là nhấn mạnh. */
.blog-title em {
  display: block;
  font-style: italic;
  color: var(--c-accent);
}

.blog-head__lede { margin-top: var(--s-6); }

/* Ô tìm kiếm. Là <form> phương thức GET nên TẮT JS VẪN TÌM ĐƯỢC — máy chủ
   đọc tham số và lọc sẵn (§15.1). */
.blog-search {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-8);
  max-width: 34rem;
}
.blog-search .input {
  flex: 1 1 14rem;
  border-radius: var(--r-pill);
  padding-inline: var(--s-6);
}
.blog-search .btn { border-radius: var(--r-pill); }

/* Hàng chip lọc thể loại. Là danh sách LIÊN KẾT, không phải nút bấm —
   mỗi thể loại có địa chỉ riêng, chia sẻ được và công cụ tìm kiếm đọc
   được. */
.blog-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-bottom: var(--s-9);
  list-style: none;
}

.blog-list { margin-top: var(--s-6); }

/* Lưới bài viết: hai cột đều nhau, không mượn nhịp rộng/hẹp của trang chủ
   vì ở đây mọi bài ngang vai nhau. */
.blog-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gap);
}

/* Thẻ bài viết. CẢ THẺ là một liên kết duy nhất — mũi tên góc dưới chỉ là
   dấu hiệu thị giác (aria-hidden), không phải liên kết thứ hai, để trình
   đọc màn hình không đọc hai lần cùng một đích. */
.post-card {
  border-radius: var(--r-xl);
  background: var(--c-bg-elev);
  border: var(--bw) solid var(--c-border);
  transition: border-color var(--d-base) var(--ease);
}
/* Xen kẽ một sắc ấm rất nhạt cho thẻ chẵn, tạo nhịp bàn cờ như bản thiết
   kế. Bản gốc nền sáng dùng kem/xám; ở nền tối tương đương là pha một
   lượng nhỏ màu nhấn vào nền nổi. */
.post-card:nth-child(even) { background: var(--c-bg-elev-warm); }
.post-card:hover { border-color: var(--c-accent); }

.post-card__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--s-6);
  color: inherit;
}

/* Khung chờ ảnh bìa. Luôn dựng dù chưa có ảnh, để các thẻ giữ đúng nhịp
   thay vì bài có ảnh thì cao vống lên. */
.post-card__media {
  aspect-ratio: var(--ar-card);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-bg-inset);
  border: var(--bw) solid var(--c-border);
}
.post-card__media img { width: 100%; height: 100%; object-fit: cover; }

.post-card__num {
  margin-top: var(--s-6);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  color: var(--c-accent);
}

.post-card__title {
  margin-top: var(--s-2);
  font-size: var(--t-d3);
  line-height: var(--lh-snug);
  overflow-wrap: break-word;
  transition: color var(--d-fast) var(--ease);
}
.post-card__link:hover .post-card__title { color: var(--c-accent); }

.post-card__excerpt {
  margin-top: var(--s-4);
  font-size: var(--t-sm);
  line-height: var(--lh-base);
  color: var(--c-text-muted);
}

/* margin-top: auto ở dải chân ghim mũi tên xuống đáy thẻ, nên các thẻ cùng
   hàng có mũi tên thẳng hàng dù đoạn dẫn dài ngắn khác nhau. */
.post-card__foot {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;
  padding-top: var(--s-7);
}
.post-card__go {
  display: grid;
  place-items: center;
  width: var(--ctl-md-h);
  height: var(--ctl-md-h);
  border-radius: var(--r-circle);
  background-color: var(--c-text);
  color: var(--c-bg);
  font-size: var(--t-lg);
  line-height: 1;
  transition: background-color var(--d-base) var(--ease);
}
.post-card__link:hover .post-card__go {
  background-color: var(--c-accent);
  color: var(--c-text-on-accent);
}

/* Dưới 760px hai cột chỉ còn ~330px mỗi cột — tiêu đề dài vỡ thành bốn,
   năm dòng. Xuống một cột. */
@media (max-width: 760px) {
  .blog-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   TRANG CHI TIẾT DỰ ÁN
   ============================================================ */

/* Thanh điều hướng dùng position: fixed nên section đầu tiên phải tự chừa
   chỗ, y như .hero làm ở trang chủ. Thiếu dòng này thì breadcrumb chui
   xuống dưới nav. */
.project-head { padding-top: calc(var(--nav-h-lg) + var(--s-10)); }

.project-hero { margin-top: var(--s-8); }

.project-hero__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
}

.project-facts {
  display: grid;
  /* auto-fit + minmax: nhiều cột ở màn rộng, tự dồn về một cột ở điện
     thoại mà không cần điểm ngắt riêng. */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s-6);
  margin-top: var(--s-9);
  padding-top: var(--s-8);
  border-top: var(--bw) solid var(--c-border);
}
.project-facts__row { display: flex; flex-direction: column; gap: var(--s-2); }
.project-facts dt {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
}
.project-facts dd { font-size: var(--t-base); color: var(--c-text); }

/* Khối kể chuyện: mỗi đoạn cách nhau một nhịp đọc, không dính chùm. */
.project-story + .project-story { margin-top: var(--s-11); }
.project-story p + p { margin-top: var(--s-5); }

/* Thư viện ảnh dự án. auto-fit + minmax nên tự co từ hai cột xuống một
   cột mà không cần điểm ngắt riêng; lúc chưa có ảnh thì ô duy nhất bên
   trong là khoảng chờ, cũng nằm gọn một cột. */
.pj-photos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--grid-gap);
  margin-top: var(--s-6);
}
.pj-videos { margin-top: var(--s-6); }

/* Khung giữ chỗ chờ chèn ảnh/clip. Viền cùng kiểu với khung ảnh ở thẻ dự
   án trang chủ để hai chỗ nhìn ra cùng một hệ. */
.pj-slot {
  border: var(--bw) solid var(--c-border);
  padding: var(--s-5);
}

/* ============================================================
   DỊCH VỤ
   Lưới có đường kẻ liền mạch: chỉ vẽ viền phải + dưới trên mỗi ô,
   viền ngoài do container đảm nhiệm → không có đường kẻ đôi.
   ============================================================ */
.services__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  border-top: var(--bw) solid var(--c-border);
  border-left: var(--bw) solid var(--c-border);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.service {
  padding: var(--s-7) var(--s-6) var(--s-9);
  border-right: var(--bw) solid var(--c-border);
  border-bottom: var(--bw) solid var(--c-border);
  transition: background-color var(--d-base) var(--ease);
}
.service:hover { background: var(--c-bg-elev); }
.service__num {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  font-variant-numeric: tabular-nums;
  color: var(--c-accent);
  line-height: 1;
}
.service__name { margin-block: var(--s-4) var(--s-3); font-size: var(--t-d4); }
.service__desc { font-size: var(--t-sm); color: var(--c-text-muted); max-width: 38ch; }

/* ============================================================
   FAQ
   ============================================================ */
.faq { border-top: var(--bw) solid var(--c-border); }
.faq__item { border-bottom: var(--bw) solid var(--c-border); }
.faq__item h3 { margin: 0; }

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  width: 100%;
  min-height: 76px;
  padding-block: var(--s-5);
  text-align: left;
  cursor: pointer;
  font-family: var(--f-display);
  font-size: var(--t-d4);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-snug);
  transition: color var(--d-fast) var(--ease);
}
.faq__q:hover { color: var(--c-accent); }

.faq__sign {
  position: relative;
  width: var(--icon-lg);
  height: var(--icon-lg);
  flex: none;
  transition: transform var(--d-base) var(--ease);
}
.faq__sign::before,
.faq__sign::after {
  content: "";
  position: absolute;
  top: 50%; left: 0; right: 0;
  height: 1.5px;
  margin-top: -0.75px;
  background: currentColor;
  border-radius: 2px;
}
.faq__sign::after { transform: rotate(90deg); transition: opacity var(--d-base) var(--ease); }
.faq__q[aria-expanded="true"] .faq__sign { transform: rotate(180deg); }
.faq__q[aria-expanded="true"] .faq__sign::after { opacity: 0; }

/* grid-template-rows 0fr→1fr cho phép chạy hiệu ứng chiều cao mà không
   cần biết trước chiều cao nội dung. */
.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--d-base) var(--ease);
}
.faq__a > div { overflow: hidden; }
.faq__item[data-open="true"] .faq__a { grid-template-rows: 1fr; }
.faq__a p { padding-bottom: var(--s-6); color: var(--c-text-muted); max-width: var(--w-prose); }

/* ============================================================
   LIÊN HỆ
   ============================================================ */
.contact { border-top: var(--bw) solid var(--c-border); }
.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: var(--grid-gap) var(--s-11);
  align-items: center;
}
.contact__title { font-size: var(--t-d1); max-width: 13ch; }
.contact__lede { margin-top: var(--s-6); }
.contact__list { display: grid; gap: 0; list-style: none; }

.contact__row {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-height: 64px;
  padding-block: var(--s-3);
  border-bottom: var(--bw) solid var(--c-border);
}
.contact__row:first-child { border-top: var(--bw) solid var(--c-border); }
.contact__key {
  width: 9ch;
  flex: none;
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
}
.contact__val { font-size: var(--t-lg); font-weight: var(--fw-medium); overflow-wrap: anywhere; }
/* Số điện thoại và liên kết mạng xã hội là đích bấm quan trọng nhất trang.
   Là thẻ <a> nội tuyến nên chỉ cao bằng dòng chữ (đo được 26px) — phải
   ép thành khối cao 44px. */
a.contact__val {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
}
a.contact__val:hover { color: var(--c-accent); }

/* ============================================================
   CHÂN TRANG
   ============================================================ */
.footer { border-top: var(--bw) solid var(--c-border); padding-block: var(--s-10) var(--s-6); }
.footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: var(--s-9) var(--s-7);
  margin-bottom: var(--s-9);
}
.footer__brand { display: grid; gap: var(--s-4); align-content: start; }
.footer__tagline { font-size: var(--t-sm); color: var(--c-text-dim); max-width: 36ch; }

.footer__col h2 {
  margin-bottom: var(--s-4);
  font-family: var(--f-body);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
}
.footer__col ul { list-style: none; display: grid; }
.footer__col a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  /* Nhãn ngắn như "Dự án", "TikTok" chỉ rộng 37–39px — dưới ngưỡng chạm.
     min-width kéo bề rộng lên 44px mà không đổi cỡ chữ. */
  min-width: var(--tap-min);
  font-size: var(--t-sm);
  color: var(--c-text-muted);
}
.footer__col a:hover { color: var(--c-accent); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3) var(--s-6);
  padding-top: var(--s-6);
  border-top: var(--bw) solid var(--c-border);
  font-size: var(--t-2xs);
  color: var(--c-text-dim);
}

/* Nút quay đầu trang */
.to-top {
  position: fixed;
  right: var(--gutter);
  bottom: var(--s-6);
  z-index: var(--z-sticky);
  width: var(--ctl-lg-h);
  height: var(--ctl-lg-h);
  display: grid;
  place-items: center;
  border-radius: var(--r-circle);
  background: var(--c-accent);
  color: var(--c-text-on-accent);
  box-shadow: var(--shadow-2);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity var(--d-base) var(--ease),
              transform var(--d-base) var(--ease),
              visibility var(--d-base);
}
.to-top[data-visible="true"] { opacity: 1; visibility: visible; transform: none; }
.to-top svg { width: var(--icon-md); height: var(--icon-md); }

/* ============================================================
   HIỆU ỨNG XUẤT HIỆN KHI CUỘN
   Chỉ có tác dụng khi JS đã chạy và gắn class .js-reveal lên <html>.
   Không có JS → nội dung hiện bình thường (§3.2 nguyên tắc 2).
   ============================================================ */
.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--d-slow) var(--ease-out),
              transform var(--d-slow) var(--ease-out);
}
.js-reveal [data-reveal="in"] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] { opacity: 1; transform: none; }
  /* Người đã tắt hiệu ứng chuyển động vẫn phải thấy phản hồi khi trỏ vào
     mục — chỉ là phản hồi bằng màu, không bằng phóng to. */
  .nav__link:hover,
  .nav__link:focus-visible { scale: none; }
}

/* ============================================================
   ĐÁP ỨNG ĐA THIẾT BỊ (§12.4)
   Breakpoint bám theo NỘI DUNG vỡ ở đâu, không bám tên thiết bị.
   ============================================================ */

/* Laptop nhỏ / iPad ngang */
@media (max-width: 1180px) {
  .project-card       { grid-column: span 6; }
  .project-card--wide { grid-column: span 12; }
  .project-card--third{ grid-column: span 6; }
}

/* Tablet dọc — nav thu gọn thành menu trượt */
@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__burger { display: grid; }
  .nav__inner { height: var(--nav-h); gap: var(--s-4); }

  .hero { min-height: auto; padding-top: calc(var(--nav-h) + var(--s-9)); padding-bottom: var(--s-8); }
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); margin-bottom: var(--s-8); }
  .hero__portrait { max-width: 440px; }
  .hero__title { max-width: 20ch; }

  .about__grid,
  .contact__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
  .contact__title { max-width: 20ch; }

  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8) var(--s-6); }
}

/* Điện thoại lớn */
@media (max-width: 680px) {
  .project-card,
  .project-card--wide,
  .project-card--third { grid-column: span 12; }
  .project-card--wide .project-card__media { aspect-ratio: var(--ar-card); }

  .section-head { flex-direction: column; align-items: stretch; gap: var(--s-5); }
  .section-head .btn { justify-self: start; width: fit-content; }

  .stat__num { font-size: var(--t-d3); }

  .services__grid { border-radius: var(--r-md); }
  .service { padding: var(--s-6) var(--s-5) var(--s-7); }

  .faq__q { font-size: var(--t-base); gap: var(--s-4); min-height: 68px; }
  .footer__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); }
  .footer__brand { margin-bottom: var(--s-2); }
}

/* Điện thoại nhỏ (iPhone SE, Android nhỏ) */
@media (max-width: 400px) {
  .nav__inner { gap: var(--s-2); }

  .hero__cta { display: grid; }
  .hero__cta .btn { width: 100%; }

  .contact__row { flex-wrap: wrap; gap: var(--s-1) var(--s-4); min-height: 0; padding-block: var(--s-4); }
  .contact__key { width: auto; }
  .contact__val { font-size: var(--t-base); }

  .drawer__links a { font-size: var(--t-d3); min-height: 56px; }
}

/* Màn siêu hẹp (280px — Galaxy Fold gập) */
@media (max-width: 320px) {
  /* Bỏ ràng buộc tỉ lệ khung để phần tử tự co theo chiều rộng,
     tránh khoá chiều rộng tối thiểu gây tràn (cạm bẫy §12.4). */
  .hero__portrait { aspect-ratio: auto; min-height: 300px; }
  .lang-switch { display: none; }   /* nhường chỗ, đổi ngôn ngữ có trong menu trượt */
  .brand { font-size: var(--t-base); }
}

/* Điện thoại nằm ngang — chiều cao rất hạn chế */
@media (max-height: 520px) and (orientation: landscape) {
  .hero { min-height: auto; padding-top: calc(var(--nav-h) + var(--s-7)); }
  .hero__wordmark { font-size: clamp(2rem, 8vw, 3.5rem); margin-top: var(--s-5); }
  .hero__portrait { max-width: 280px; }
  .drawer { grid-template-rows: auto 1fr auto; padding-bottom: var(--s-6); }
  .drawer__links a { min-height: 48px; font-size: var(--t-d4); padding-block: var(--s-2); }
}

/* Màn hình rất lớn — giới hạn bề rộng đọc, không để dòng chữ dài lê thê */
@media (min-width: 1920px) {
  .hero__title  { max-width: 14ch; }
  .service__desc { max-width: 34ch; }
}
