/* ═══════════════════════════════════════════════════════════
   HOME TOEIC — GLOBAL STYLESHEET
   Mobile-first · Be Vietnam Pro · #1d6ff2
   Breakpoints: 480px / 768px / 1024px
   ═══════════════════════════════════════════════════════════ */


/* ─────────────────────────────────────────────
   CSS VARIABLES — LIGHT MODE (default)
   ───────────────────────────────────────────── */
:root {
  /* Brand */
  --primary:          #1d6ff2;
  --primary-dark:     #1558c8;
  --primary-light:    #e8f0fe;
  --primary-mid:      #3b82f6;

  /* Nav/Footer — xanh dương thương hiệu (đúng tông nút CTA) */
  --nav-grad:         linear-gradient(120deg, #1558c8 0%, #2f7ffb 100%);
  --gold:             #ffc000;

  /* Backgrounds */
  --bg:               #f5f7fb;
  --bg-card:          #ffffff;
  --bg-nav:           #ffffff;
  --bg-hover:         #f0f4ff;

  /* Text */
  --text:             #0f172a;
  --text-2:           #475569;
  --text-3:           #94a3b8;

  /* Borders */
  --border:           #e2e8f0;
  --border-2:         #cbd5e1;

  /* Semantic colors */
  --success:          #10b981;
  --success-light:    #d1fae5;
  --warning:          #f59e0b;
  --warning-light:    #fef3c7;
  --danger:           #ef4444;
  --danger-light:     #fee2e2;

  /* Shadows */
  --shadow-sm:        0 1px 4px rgba(0,0,0,.06);
  --shadow-md:        0 4px 20px rgba(0,0,0,.08);
  --shadow-lg:        0 8px 40px rgba(0,0,0,.12);
  --shadow-blue:      0 4px 20px rgba(29,111,242,.25);

  /* Layout */
  --nav-h:            60px;   /* mobile default */
  --radius:           14px;
  --radius-sm:        8px;
  --radius-xs:        6px;
  --radius-pill:      999px;
  --max-w:            1160px;

  /* Transitions */
  --transition:       all .2s cubic-bezier(.4,0,.2,1);

  /* Font */
  --font:             'Be Vietnam Pro', 'Segoe UI', system-ui, sans-serif;
}


/* ─────────────────────────────────────────────
   RESET
   ───────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html {
  scroll-behavior: smooth;
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
  background: var(--bg);
}
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  transition: background .3s ease, color .3s ease;
  overflow-x: hidden;
  overscroll-behavior-x: none;
}
.page-body { flex: 1; }
img  { max-width: 100%; display: block; }
a    { color: inherit; text-decoration: none; }
/* appearance:none — Chrome/Safari vẫn giữ 1 phần "chrome" mặc định của nút bấm gốc hệ điều
   hành (ảnh hưởng box-model dù đã border:none/background:none), khiến <button> co hẹp hơn vài
   px so với <a> cùng CSS y hệt (bug thật: .nav-dropdown-trigger lệch tâm so với .nav-links a
   vì đây). */
button { font-family: var(--font); cursor: pointer; border: none; background: none; appearance: none; -webkit-appearance: none; }
ul, ol { list-style: none; }
input, select, textarea { font-family: var(--font); }

/* ═══════════════════════════════════════════════════════════
   SMOOTH PAGE NAVIGATION (View Transitions API)
   Chuyển trang bằng cross-fade thay vì flash trắng đột ngột.
   Trình duyệt chưa hỗ trợ (Firefox cũ...) sẽ tự bỏ qua, chuyển
   trang vẫn hoạt động bình thường như trước — không có rủi ro.
   ═══════════════════════════════════════════════════════════ */
@view-transition {
  navigation: auto;
}

/* ═══════════════════════════════════════════════════════════
   NAVBAR
   ═══════════════════════════════════════════════════════════ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-h);
  background: var(--nav-grad);
  z-index: 500;
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.25), inset 0 -2px 0 0 rgba(255, 192, 0, .5);
  transition: background .3s ease, box-shadow .3s ease;
  /* Giữ navbar "đứng yên" qua transition thay vì cross-fade cùng nội dung
     → thanh menu không còn nhấp nháy/nhảy khi chuyển trang */
  view-transition-name: main-nav;
}
.nav-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  height: 100%;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 16px;
}

/* ── Logo ── */
.nav-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  text-decoration: none;
  min-height: 44px;
}
.nav-logo-img {
  height: 36px;
  width: auto;
  border-radius: 6px;
  object-fit: contain;
  display: block;
  flex-shrink: 0;
}
.nav-logo-fallback {
  font-size: 1rem;
  font-weight: 800;
  color: #ffc000;
}

/* ── Links ── */
.nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 1;
}
.nav-links a {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  border-bottom: 2px solid transparent;
  font-size: .88rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  transition: var(--transition);
  white-space: nowrap;
  min-height: 44px; /* tap target */
}
.nav-links a:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}
.nav-links a.active {
  color: #ffffff;
  border-bottom-color: var(--gold);
}
/* display:flex (thay vì inline mặc định) để trung hoà vertical-align:-2px gắn cứng
   trên từng svg icon trong config.js — hack đó chỉnh cho nav ngang cũ (icon+chữ cùng
   1 dòng baseline), giờ dư ra làm icon lệch xuống so với chữ trong sidebar dọc, vì
   flex item bỏ qua vertical-align hoàn toàn. */
.nav-icon { font-size: .9rem; display: inline-flex; align-items: center; }

/* ── Dropdown desktop (VD: "Ôn tập" → Sổ từ vựng / Sổ ngữ pháp) ── */
.nav-dropdown { position: relative; }
.nav-dropdown-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: none;
  background: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  border-bottom: 2px solid transparent;
  font-family: inherit;
  font-size: .88rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  transition: var(--transition);
  white-space: nowrap;
  min-height: 44px;
}
.nav-dropdown-trigger:hover,
.nav-dropdown.open .nav-dropdown-trigger {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}
.nav-dropdown-trigger.active {
  color: #ffffff;
  border-bottom-color: var(--gold);
}
.nav-caret { transition: transform .15s; flex-shrink: 0; }
.nav-dropdown.open .nav-caret { transform: rotate(180deg); }
/* Accordion mở/đóng ngay trong sidebar (VD: Cơ bản, Ôn tập) — chỉ hiển thị ở sidebar dọc
   (desktop, xem @media min-width:768px); mobile dùng bottom-sheet riêng nên ẩn hẳn ở đây. */
.nav-dropdown-menu { display: none; }
.nav-dropdown-menu a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 8px;
  font-size: .85rem;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
}
.nav-dropdown-menu a:hover { background: var(--bg-hover); color: var(--primary); }
.nav-dropdown-menu a.active { color: var(--primary); background: var(--bg-hover); }

/* ── Right side ── */
.nav-right {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
}

/* ── Bottom tab bar (mobile) — ẩn mặc định, hiện lại trong @media max-width:767px ── */
.mobile-tabbar { display: none; }
/* ── Topbar ngang (desktop) — ẩn mặc định, hiện lại trong @media min-width:768px.
   Mobile có thanh logo riêng của chính .nav, không cần topbar này. ── */
.main-topbar { display: none; }

/* ═══════════════════════════════════════════════════════════
   LAYOUT UTILITIES
   ═══════════════════════════════════════════════════════════ */
.container {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 16px;
}
.page-body {
  padding-top: calc(var(--nav-h) + 32px);
  padding-bottom: 32px;
}

/* ═══════════════════════════════════════════════════════════
   PAGE HEADER (banner xanh đầu trang)
   ═══════════════════════════════════════════════════════════ */
.page-header {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  padding: calc(var(--nav-h) + 40px) 16px 44px;
  text-align: center;
  color: #fff;
  position: relative;
  overflow: hidden;
}
.page-header::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.04'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/svg%3E");
}
.page-header-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255,255,255,.15);
  border: 1px solid rgba(255,255,255,.25);
  padding: 4px 14px;
  border-radius: var(--radius-pill);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  margin-bottom: 14px;
}
.page-header h1 {
  font-size: clamp(1.5rem, 4.5vw, 2.5rem);
  font-weight: 800;
  line-height: 1.2;
  margin-bottom: 10px;
  position: relative;
}
.page-header p {
  font-size: clamp(.88rem, 2.5vw, 1rem);
  opacity: .88;
  max-width: 480px;
  margin: 0 auto;
  line-height: 1.7;
  position: relative;
}

/* ═══════════════════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 28px;
  border-radius: var(--radius-pill);
  font-family: var(--font);
  font-size: .92rem;
  font-weight: 700;
  cursor: pointer;
  border: none;
  transition: var(--transition);
  min-height: 48px; /* tap target */
  white-space: nowrap;
  text-decoration: none;
}
.btn-primary {
  background: var(--primary);
  color: #fff;
  box-shadow: var(--shadow-blue);
}
.btn-primary:hover {
  background: var(--primary-dark);
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgba(29,111,242,.35);
}
.btn-outline {
  background: transparent;
  color: var(--primary);
  border: 2px solid var(--primary);
}
.btn-outline:hover { background: var(--primary-light); }
.btn-ghost {
  background: var(--bg-card);
  color: var(--text-2);
  border: 1px solid var(--border);
}
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }

/* ═══════════════════════════════════════════════════════════
   TAGS / BADGES
   ═══════════════════════════════════════════════════════════ */
.tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  white-space: nowrap;
}
.tag-blue   { background: var(--primary-light); color: var(--primary); }
.tag-green  { background: var(--success-light);  color: var(--success); }
.tag-orange { background: var(--warning-light);  color: var(--warning); }
.tag-red    { background: var(--danger-light);   color: var(--danger);  }
.tag-gray   { background: var(--bg); color: var(--text-3); border: 1px solid var(--border); }

/* ═══════════════════════════════════════════════════════════
   TOAST NOTIFICATION
   ═══════════════════════════════════════════════════════════ */
.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: #0f172a;
  color: #fff;
  padding: 11px 22px;
  border-radius: var(--radius-sm);
  font-size: .85rem;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  z-index: 10000;
  white-space: nowrap;
  animation: toastIn .3s ease;
  pointer-events: none;
}
.toast.success { background: var(--success); }
.toast.error   { background: var(--danger);  }
@keyframes toastIn {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ═══════════════════════════════════════════════════════════
   POINTS TOAST — thông báo cộng điểm xếp hạng (làm đề / game từ vựng)
   ═══════════════════════════════════════════════════════════ */
.points-toast {
  position: fixed;
  top: calc(var(--nav-h, 60px) + 12px);
  left: 50%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 22px 10px 14px;
  background: linear-gradient(135deg, #ffe27a, #ffb300);
  color: #3a2400;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .2px;
  box-shadow: 0 8px 22px rgba(255,179,0,.4), 0 2px 8px rgba(0,0,0,.15);
  z-index: 10001;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transform: translateX(-50%) scale(.6) translateY(-10px);
  transition: opacity .15s ease, transform .22s cubic-bezier(.34,1.56,.64,1);
}
.points-toast.show { opacity: 1; transform: translateX(-50%) scale(1) translateY(0); }
.points-toast.hide {
  opacity: 0;
  transform: translateX(-50%) scale(.92) translateY(-16px);
  transition: opacity .2s ease, transform .2s ease;
}
.points-toast .pts-star {
  width: 20px; height: 20px; flex-shrink: 0; color: #fff;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.2));
  animation: ptsStarPop .45s cubic-bezier(.34,1.56,.64,1);
}
@keyframes ptsStarPop {
  0%   { transform: rotate(-40deg) scale(.3); }
  60%  { transform: rotate(20deg) scale(1.3); }
  100% { transform: rotate(0deg) scale(1); }
}
@media (max-width: 767px) {
  .points-toast { top: calc(var(--nav-h, 56px) + 8px); font-size: 13.5px; padding: 9px 18px 9px 12px; }
  .points-toast .pts-star { width: 17px; height: 17px; }
}

/* ═══════════════════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════════════════ */
/* 1 hàng ngang mỏng, độ dày ~bằng topbar (--topbar-h, chỉ tồn tại ở breakpoint desktop —
   fallback 60px cho mobile) — giống chân trang Cloudflare dashboard: mạng xã hội bên trái,
   dòng bản quyền bên phải, không còn nền gradient/khối 3 dòng như trước. */
.footer {
  display: flex;
  align-items: stretch;
  background: var(--bg-card);
  border-top: 1px solid var(--border);
}
/* Chỉ hiện ở desktop (xem @media min-width:768px) — nơi có sidebar dọc cần khớp góc. */
.footer-corner { display: none; }
.footer-row {
  flex: 1;
  min-width: 0;
  min-height: var(--topbar-h, 60px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
}
.footer-social {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}
.footer-social:empty { display: none; }
.fsoc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--bg-hover);
  color: var(--text-2);
  font-size: .78rem;
  font-weight: 600;
  text-decoration: none;
  transition: background .18s, color .18s;
  white-space: nowrap;
}
.fsoc.tiktok:hover   { background: #111;    color: #fff; }
.fsoc.facebook:hover { background: #1877f2; color: #fff; }
.fsoc.youtube:hover  { background: #ff0000; color: #fff; }
.fsoc.zalo:hover     { background: #0068ff; color: #fff; }
.fsoc:hover { color: var(--primary); text-decoration: underline; }
.footer-copyright {
  flex-shrink: 0;
  font-size: .78rem;
  font-weight: 500;
  color: var(--text-3);
  white-space: nowrap;
}


/* ═══════════════════════════════════════════════════════════
   ANIMATIONS
   ═══════════════════════════════════════════════════════════ */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.anim    { animation: fadeUp .45s ease both; }
.anim-d1 { animation-delay: .07s; }
.anim-d2 { animation-delay: .14s; }
.anim-d3 { animation-delay: .21s; }
.anim-d4 { animation-delay: .28s; }

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════ */

/* ── Tablet ≥ 768px — layout kiểu Cloudflare dashboard: 1 topbar ngang mỏng phủ hết
   chiều rộng (chứa logo bên trái + avatar bên phải) và 1 sidebar dọc bên trái NẰM DƯỚI
   topbar đó (thu gọn còn 1 rail chỉ icon, hover/focus vào mới mở rộng hiện chữ). Viền
   phải của ô logo (trong topbar) và viền dưới của topbar giao nhau đúng góc dưới-phải
   ô logo — đó là hiệu ứng "2 viền ngang dọc giao nhau ở góc trên trái". --nav-h về 0 vì
   không còn thanh ngang kiểu cũ chiếm chỗ trên cùng của các trang co-ban.css/
   vocabulary.css/grammar.css (những file đó cộng thêm --nav-h vào padding-top/top nên
   tự động hết phần chừa chỗ cũ, không cần sửa tay từng file). ── */
@media (min-width: 768px) {
  :root {
    --nav-h: 0px;
    --nav-w: 60px;
    --nav-w-open: 220px;
    --topbar-h: 60px;
  }
  .container { padding: 0 24px; }
  /* :has(#mainNav) — CHỈ chừa chỗ sidebar/topbar khi trang thật sự có nav.js dựng lên
     (#mainNav). Trang làm đề (exams/.../de-X.html) load chung style.css nhưng CỐ Ý không
     load nav.js (xem CLAUDE.md) — nếu áp dụng padding vô điều kiện thì trang đó bị dư
     khoảng trống không có gì che vào (bug thật, tái hiện được ở trang làm đề). */
  body:has(#mainNav) { padding-left: var(--nav-w); padding-top: var(--topbar-h); }
  /* Ghim sidebar (#mainNav.pinned) — chừa luôn chỗ rộng, không cần hover. #mainNav.pinned
     (ID + class trong CÙNG :has()) để đủ độ ưu tiên hơn rule body:has(#mainNav) phía trên
     (specificity so theo cột ID trước — chỉ thêm class ở ngoài :has() như body.pinned sẽ KHÔNG
     bao giờ thắng được 1 rule có ID bên trong :has(), dù thêm bao nhiêu class cũng vậy). */
  body:has(#mainNav.pinned) { padding-left: var(--nav-w-open); }
  .page-body { padding-top: 40px; padding-bottom: 32px; }
  .page-header { padding: 52px 24px 52px; }

  /* ── Topbar ngang ── */
  .main-topbar {
    display: flex;
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--topbar-h);
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    z-index: 490;
  }
  .topbar-logo-cell {
    width: var(--nav-w);
    flex-shrink: 0;
    border-right: 1px solid var(--border);
    display: flex;
    align-items: center;
    transition: width .18s ease;
  }
  /* Đồng bộ độ rộng ô logo với sidebar khi hover 1 trong 2 khu vực, hoặc khi đã ghim — để
     viền phải luôn thẳng hàng liền mạch từ topbar xuống sidebar, không bị "gãy khúc". */
  body:has(.nav:is(:hover, :focus-within, .pinned)) .topbar-logo-cell,
  .topbar-logo-cell:hover {
    width: var(--nav-w-open);
  }
  body:has(.topbar-logo-cell:hover) .nav { width: var(--nav-w-open); }

  /* ── Ô góc chân trang — đối xứng với .topbar-logo-cell ở trên cùng ──
     Viền phải của ô này (rộng bằng sidebar) giao với viền trên của .footer ngay tại góc
     dưới-trái, y hệt cách viền phải topbar-logo-cell giao với viền dưới của .main-topbar. */
  /* .footer chỉ cần bù margin theo padding-left THẬT SỰ của body — mà padding-left body chỉ
     đổi lúc .pinned (xem "body:has(#mainNav.pinned){padding-left:...}" ở trên), KHÔNG đổi lúc
     chỉ hover (hover chỉ phóng to nav dạng lớp phủ, không đẩy layout) — nên .footer chỉ có
     đúng 2 trạng thái margin, không có trạng thái hover riêng. */
  body:has(#mainNav) .footer { margin-left: calc(-1 * var(--nav-w)); }
  body:has(#mainNav.pinned) .footer { margin-left: calc(-1 * var(--nav-w-open)); }
  /* KHÔNG tự vẽ border-right ở đây nữa — .footer nằm trong luồng tài liệu bình thường (vị trí
     phụ thuộc tổng chiều cao trang, có thể lệch vài phần trăm px do bo tròn), còn .nav là
     position:fixed;bottom:0 nên luôn neo đúng khung hình mọi lúc. 2 element khác cơ chế định vị
     mà mỗi cái tự vẽ 1 đường viền-phải RIÊNG thì dù toạ độ tính ra "khớp" trên lý thuyết, trình
     duyệt vẫn có thể bo tròn mỗi đường lệch nhau đúng 1px khi vẽ ra màn hình thật — góc giao nhau
     nhìn vẫn "gãy". Bỏ hẳn viền ở đây, để .footer-corner chỉ là ô đệm KHÔNG viền, và dùng chính
     viền phải sẵn có của .nav (đã đúng khớp với topbar phía trên) làm luôn đường dọc ở góc dưới —
     .nav là position:fixed + z-index cao hơn nên luôn đè lên đúng vị trí, chỉ có DUY NHẤT 1
     đường viền dọc trong toàn bộ cột này, không thể lệch với chính nó được. */
  body:has(#mainNav) .footer-corner {
    display: block;
    width: var(--nav-w);
    flex-shrink: 0;
    transition: width .18s ease;
  }
  body:has(#mainNav:is(:hover, :focus-within, .pinned)) .footer-corner,
  .footer-corner:hover {
    width: var(--nav-w-open);
  }
  body:has(.footer-corner:hover) #mainNav { width: var(--nav-w-open); }
  /* .footer-row trước đó chỉ có min-height — nội dung (pill mạng xã hội cao 32.6px + padding
     14px x2) vô tình cao hơn 60px một chút (60.6px), khiến viền trên .footer nhích lên cao hơn
     viền trên .nav-pin-btn (cố định đúng 60px) vài px, làm góc giao nhau bị lệch/gãy khúc thay
     vì là 1 đường thẳng. Ép height CỐ ĐỊNH đúng bằng --topbar-h để 2 viền luôn cùng 1 y-vị-trí. */
  .footer-row { height: var(--topbar-h); }

  .nav-right {
    margin-left: auto;
    align-items: center;
    gap: 10px;
    padding: 0 20px;
  }
  /* auth.js định nghĩa .tts-btn-in màu trắng (hợp nền xanh của thanh ngang cũ) — ghi đè
     bằng #navRight để đủ độ ưu tiên CSS, đổi sang tông xanh cho hợp nền trắng của topbar. */
  #navRight .tts-btn-in {
    background: var(--bg-hover);
    color: var(--primary);
    border-color: var(--border);
  }
  #navRight .tts-btn-in:hover { background: var(--primary-light); border-color: var(--primary); }

  /* ── Sidebar dọc — bắt đầu ngay dưới topbar ── */
  .nav {
    top: var(--topbar-h); left: 0; right: auto; bottom: 0;
    width: var(--nav-w);
    height: calc(100vh - var(--topbar-h));
    transition: width .18s ease;
    /* Rail trung tính (trắng) thay vì gradient xanh của thanh ngang cũ — sidebar app
       dùng màu thương hiệu để làm điểm nhấn (active/hover), không phủ kín cả nền. */
    background: var(--bg-card);
    border-right: 1px solid var(--border);
    box-shadow: 2px 0 16px rgba(15,23,42,.05);
  }
  /* .pinned — ghim mở rộng cố định (bấm nút ở đáy sidebar), không cần hover nữa. Cùng độ ưu
     tiên với :hover/:focus-within (2 class = 2 class) nên không xung đột, ra cùng 1 giá trị. */
  .nav:is(:hover, :focus-within, .pinned) { width: var(--nav-w-open); }

  .nav-inner {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* Đè lại align-items:center kế thừa từ rule mobile (.nav-inner base, dành cho thanh ngang) —
       thiếu dòng này khiến .nav-links co theo bề rộng nội dung rồi bị CĂN GIỮA trong sidebar,
       nên khoảng cách từ mép trái tới icon phụ thuộc menu dài hay ngắn (khác nhau giữa các trang/
       repo có số mục menu khác nhau), thay vì luôn cố định — đúng lỗi user báo: khoảng cách lệch
       giữa web công khai (nhiều mục hơn) và web product (ít mục hơn). */
    height: 100%;
    padding: 12px;
  }
  .nav-logo {
    width: 100%;
    height: 100%;
    padding: 0;
    gap: 0;
    /* KHÔNG còn toggle justify-content (center↔flex-start) — justify-content không animate được,
       nên trước đây icon "nhảy" giật sang trái ngay lúc bắt đầu hover trong khi độ rộng vẫn đang
       chạy mượt, nhìn giật cục. Icon giờ nằm trong 1 "ô" rộng cố định (.nav-logo-img, xem dưới),
       không bao giờ đổi vị trí — chỉ có gap (khoảng cách tới nhãn) chạy mượt 0→10px. */
    transition: gap .18s ease;
  }
  .nav-logo-img {
    /* Ô rộng CỐ ĐỊNH = đúng bề rộng còn lại khi thu gọn (60px rail - 12px lề trái - 12px lề
       phải tương ứng bên các mục menu) — icon-logo vì vậy luôn đứng yên 1 chỗ dù mở hay đóng,
       margin-left:12px thay cho padding-left:12px cũ của .nav-logo (đã bỏ ở trên). */
    width: 36px;
    margin-left: 12px;
  }
  .topbar-logo-cell:hover .nav-logo,
  body:has(.nav:is(:hover, :focus-within, .pinned)) .nav-logo {
    gap: 10px;
  }
  .nav-logo-fallback {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    color: var(--primary-dark);
    transition: max-width .18s ease, opacity .12s ease;
  }
  .topbar-logo-cell:hover .nav-logo-fallback,
  body:has(.nav:is(:hover, :focus-within, .pinned)) .nav-logo-fallback {
    max-width: 140px;
    opacity: 1;
  }

  .nav-links {
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
  }
  .nav-icon svg { width: 20px; height: 20px; }
  /* Ô icon rộng CỐ ĐỊNH cho mục cấp 1 (36px = đúng bề rộng còn lại khi rail thu gọn 60px, trừ
     12px lề trái của .nav-links a bên dưới + 12px lề phải đối xứng) — icon luôn đứng yên 1 chỗ,
     không đổi vị trí giữa lúc thu gọn/mở rộng, khác với cách căn giữa bằng justify-content cũ
     (phải bỏ vì justify-content không animate được, gây giật khi chuyển trạng thái). KHÔNG áp
     dụng cho menu con (.nav-dropdown-menu) — menu con chỉ hiện khi sidebar đã mở rộng sẵn, không
     cần giữ chỗ icon lúc thu gọn. */
  .nav-links > li > a > .nav-icon,
  .nav-links > li > .nav-dropdown-trigger > .nav-icon {
    flex-shrink: 0;
    width: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .nav-links a, .nav-dropdown-trigger {
    width: 100%; /* <button> mặc định không tự lấp đầy <li> như <a> — ép width:100% cho cả
      2 loại thẳng hàng chắc chắn, không phụ thuộc khác biệt box-model giữa thẻ a/button */
    border-radius: var(--radius-sm);
    border-bottom: none;
    border-left: 3px solid transparent;
    padding: 12px 0;
    gap: 0;
    color: var(--text-2);
    transition: gap .18s ease, background .18s, color .18s;
  }
  .nav:is(:hover, :focus-within, .pinned) .nav-links a,
  .nav:is(:hover, :focus-within, .pinned) .nav-dropdown-trigger,
  body:has(.topbar-logo-cell:hover) .nav-links a,
  body:has(.topbar-logo-cell:hover) .nav-dropdown-trigger {
    gap: 10px;
  }
  .nav-links a:hover, .nav-dropdown-trigger:hover,
  .nav-dropdown.open .nav-dropdown-trigger {
    background: var(--bg-hover);
    color: var(--primary);
  }
  .nav-links a.active, .nav-dropdown-trigger.active {
    border-left-color: var(--primary);
    background: var(--bg-hover);
    color: var(--primary);
  }
  .nav-label {
    display: inline-block;
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: max-width .18s ease, opacity .12s ease;
  }
  .nav:is(:hover, :focus-within, .pinned) .nav-label,
  body:has(.topbar-logo-cell:hover) .nav-label {
    max-width: 160px;
    opacity: 1;
  }
  /* Caret của mục accordion (Cơ bản, Ôn tập) — ẩn khi thu gọn (giữ icon canh giữa), hiện
     và đẩy về sát lề phải khi mở rộng. */
  .nav-caret {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    margin-left: 0;
    transition: transform .15s, max-width .18s ease, opacity .12s ease, margin-left .18s ease;
  }
  .nav:is(:hover, :focus-within, .pinned) .nav-caret,
  body:has(.topbar-logo-cell:hover) .nav-caret {
    max-width: 20px;
    opacity: 1;
    margin-left: auto;
  }

  /* Accordion mở/đóng ngay trong sidebar (VD: Cơ bản, Ôn tập) — có gạch dọc nối các mục
     con, giống "Recents" trong Cloudflare dashboard. grid-template-rows 0fr→1fr là kỹ
     thuật CSS thuần để animate chiều cao một khối có nội dung không cố định. */
  .nav-dropdown-menu {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .2s ease;
  }
  /* CHỈ thật sự bung ra khi sidebar đang mở rộng (hover/focus/ghim) — nếu không, mục con vẫn
     ở trạng thái "open" (vì đang đứng đúng trang con, tự bung sẵn) nhưng rail còn đang thu gọn
     60px thì bị vỡ layout (icon con chen chúc trong khoảng hẹp, bug thật tái hiện được bằng
     cách vào thẳng 1 trang con rồi không hover chuột vào sidebar). */
  .nav:is(:hover, :focus-within, .pinned) .nav-dropdown.open .nav-dropdown-menu,
  body:has(.topbar-logo-cell:hover) .nav-dropdown.open .nav-dropdown-menu {
    grid-template-rows: 1fr;
  }
  .nav-dropdown-menu-list {
    overflow: hidden;
    min-height: 0;
    margin: 2px 0 2px 20px;
    padding-left: 14px;
    border-left: 2px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .nav-dropdown-menu a { padding: 8px 10px; gap: 0; }
  .nav:is(:hover, :focus-within, .pinned) .nav-dropdown-menu a,
  body:has(.topbar-logo-cell:hover) .nav-dropdown-menu a { gap: 8px; }

  /* ── Nút ghim sidebar (đáy sidebar) — cao đúng bằng var(--topbar-h), y hệt .footer-row, để
     hàng chứa nút này và hàng chân trang cùng chiều cao khi kéo xuống đáy trang. KHÔNG có
     border-top riêng — thử làm 1 đường kẻ khớp với viền trên .footer nhưng luôn có sai số dưới
     1px giữa 2 phần tử khác cơ chế định vị (xem ghi chú ở .footer-corner phía trên), nhìn vẫn
     "gãy khúc"; bỏ hẳn đường kẻ này thay vì cố khớp 1 thứ không thể khớp tuyệt đối bằng CSS. ── */
  .nav-pin-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    /* .nav-inner có padding:12px quanh 4 cạnh — bù âm để nút này tràn ra sát mép dưới/2 bên
       của sidebar (viền trên trải hết chiều rộng), y hệt cách .footer-row trải hết chiều rộng
       chân trang, thay vì bị thụt vào 12px làm 2 hàng lệch nhau khi cuộn xuống chân trang. */
    width: calc(100% + 24px);
    margin: 0 -12px -12px;
    height: var(--topbar-h);
    color: var(--text-3);
  }
  .nav-pin-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    transition: border-color .15s, color .15s, background .15s;
  }
  .nav-pin-btn:hover .nav-pin-icon { border-color: var(--primary); color: var(--primary); background: var(--bg-hover); }
  .nav-pin-btn.active .nav-pin-icon { border-color: var(--primary); color: var(--primary); }
}

/* ── Desktop ≥ 1024px ── */
@media (min-width: 1024px) {
  :root { --nav-w-open: 230px; }
}

/* ── Mobile < 768px — bottom tab bar (thay cho hamburger) ── */
@media (max-width: 767px) {
  :root { --tabbar-h: 60px; }

  /* Ẩn nav ngang khỏi thanh trên — chuyển xuống tab bar dưới (#navRight do nav.js tự
     chuyển hẳn sang .tab-account, xem placeNavRight() trong nav.js). */
  .nav-links { display: none; }

  /* Chừa chỗ cho tab bar cố định dưới cùng, kể cả khi trang không có footer.
     Chỉ nhích lên 1 chút (tối đa 14px) để né thanh cử chỉ — không lấy nguyên
     safe-area-inset-bottom (có máy lên tới ~34px) vì tạo khoảng trắng dư thừa. */
  :root { --tabbar-safe: min(env(safe-area-inset-bottom), 14px); }
  /* Chỉ chừa chỗ khi trang thật sự có tab bar (index.html, vocabulary.html...) —
     style.css (gốc) được load chung ở cả trang làm bài (de-X.html, xem PATH_TO_ROOT
     trong CLAUDE.md), nơi không có .mobile-tabbar. Trước đây áp dụng cho MỌI body
     nên trang làm bài trên mobile bị dư nguyên 1 mảng trống (đúng bằng --tabbar-h)
     ở đáy màn hình dù chẳng có tab bar nào cần chừa chỗ cả. */
  body:has(.mobile-tabbar) { padding-bottom: calc(var(--tabbar-h) + var(--tabbar-safe)); }

  /* ═══ Bottom tab bar ═══ */
  .mobile-tabbar {
    display: block;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 500;
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 20px rgba(0,0,0,.08);
    padding-bottom: var(--tabbar-safe);
  }
  /* Nhiều nút quá không vừa 1 màn hình → cuộn ngang thay vì bóp nhỏ từng nút.
     flex-basis cố định (không phải 0) để chỉ co lại tới mức tối thiểu rồi
     mới tràn ra ngoài cho phép cuộn, thay vì bóp méo icon. */
  .tabbar-list {
    display: flex;
    align-items: stretch;
    height: var(--tabbar-h);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .tabbar-list::-webkit-scrollbar { display: none; }
  .tab-item { flex: 1 1 68px; min-width: 60px; }
  .tab-item a,
  .tab-account-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: 100%;
    width: 100%;
    color: var(--text-3);
    font-size: .68rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
  }
  /* Chỉ giữ icon, bỏ chữ — dùng quen web sẽ tự nhận ra icon từng mục */
  .tab-label { display: none; }
  .tab-icon { display: flex; }
  .tab-icon svg { width: 24px; height: 24px; }
  .tab-item a.active { color: var(--primary); }
  .tab-item a.active .tab-icon { color: var(--primary); }

  /* Mục có children (VD: Ôn tập) trên tab bar — nút mở bottom-sheet, không phải link */
  .tab-dropdown-trigger {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: 100%;
    width: 100%;
    border: none;
    background: none;
    font-family: inherit;
    color: var(--text-3);
    font-size: .68rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
  }
  .tab-dropdown-trigger.active { color: var(--primary); }
  .tab-dropdown-trigger.active .tab-icon { color: var(--primary); }

  /* Bottom-sheet cho mục có children trên mobile */
  .tab-sheet-overlay {
    position: fixed; inset: 0; z-index: 900;
    background: rgba(15, 23, 42, .4);
    opacity: 0; visibility: hidden;
    transition: opacity .18s, visibility .18s;
  }
  .tab-sheet-overlay.show { opacity: 1; visibility: visible; }
  .tab-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 901;
    background: var(--bg-card);
    border-radius: 18px 18px 0 0;
    padding: 8px 12px calc(16px + var(--tabbar-safe, 0px));
    box-shadow: 0 -8px 30px rgba(0,0,0,.18);
    transform: translateY(100%);
    transition: transform .22s cubic-bezier(.34,1.56,.64,1);
  }
  .tab-sheet-overlay.show .tab-sheet { transform: translateY(0); }
  .tab-sheet-handle {
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--border-2); margin: 4px auto 10px;
  }
  .tab-sheet-list a {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 12px; border-radius: 10px;
    font-size: .92rem; font-weight: 600; color: var(--text-2);
  }
  .tab-sheet-list a:active { background: var(--bg-hover); }
  .tab-sheet-list a.active { color: var(--primary); }
  .tab-sheet-list li + li { border-top: 1px solid var(--border); }

  /* Slot "Tài khoản" — nhận #navRight (avatar/nút đăng nhập) do nav.js chuyển vào */
  .tab-account {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    color: var(--text-3);
    font-size: .68rem;
    font-weight: 600;
  }
  .tab-account #navRight {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: 0;
    gap: 4px;
  }
  /* #_ttsAuthUI và .tts-user-menu (auth.js) vốn là <div> block thường — bọc icon
     trong 1 line box (strut theo line-height kế thừa) khiến khối icon cao hơn
     21px thực tế của .tab-icon, đẩy nhãn "Tài khoản" lệch xuống so với 3 tab
     cạnh bên. Ép flex + center để chiều cao khối icon khớp đúng .tab-icon. */
  .tab-account #_ttsAuthUI,
  .tab-account .tts-user-menu {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /* Ẩn chữ "Đăng nhập" trong nút — .tab-label "Tài khoản" cũng đã ẩn chung với
     các tab khác, chỉ còn icon. gap:0 vì chữ đã ẩn (font-size:0) nhưng gap
     giữa icon và chữ vẫn chiếm chỗ, đẩy icon lệch trái khỏi tâm — bỏ gap để
     icon nằm đúng giữa như .tab-icon. */
  .tab-account .tts-btn-in {
    font-size: 0;
    padding: 0;
    gap: 0;
    border: none;
    box-shadow: none;
    background: transparent;
    color: var(--text-3);
  }
  .tab-account .tts-btn-in svg { width: 24px; height: 24px; }
  .tab-account .tts-avatar-trigger { width: 24px; height: 24px; }

  /* Dropdown tài khoản bung lên trên (không phải xuống dưới) vì trigger giờ ở đáy màn hình */
  .tab-account .tts-dropdown {
    top: auto;
    bottom: calc(100% + 12px);
  }

  /* Toast full-width, nằm trên tab bar */
  .toast {
    left: 16px; right: 16px;
    bottom: calc(var(--tabbar-h) + var(--tabbar-safe) + 12px);
    transform: none;
    white-space: normal;
    text-align: center;
  }
  @keyframes toastIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
}
