:root{
  --ground:#FFFFFF;
  --surface:#FFFFFF;
  --surface-2:#F3F6F3;
  --ink:#182420;
  --ink-soft:#4E5A4C;
  --ink-faint:#7C8577;
  --forest:#0F7A45;
  --forest-bright:#1E9457;
  --forest-pale:#E7F5EC;
  --indigo:#2B3A5E;
  --indigo-pale:#E4E7F0;
  --gold:#B9862E;
  --gold-bright:#D9A94A;
  --clay:#A85426;
  --clay-bright:#C97440;
  --line:rgba(24,36,32,.12);
  --line-strong:rgba(24,36,32,.22);
  --shadow:0 24px 48px -24px rgba(20,28,22,.22);
  --radius-lg:22px;
  --radius-md:14px;
  --radius-sm:8px;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ground:#10160E;
    --surface:#171F16;
    --surface-2:#1F2A1D;
    --ink:#ECE7D4;
    --ink-soft:#B7BFAC;
    --ink-faint:#82897C;
    --forest:#6FBE96;
    --forest-bright:#8CD1AE;
    --forest-pale:#1C2E22;
    --indigo:#8C9EDD;
    --indigo-pale:#1C2333;
    --gold:#E3BE68;
    --gold-bright:#F0D08C;
    --clay:#E28A55;
    --clay-bright:#EFA477;
    --line:rgba(236,231,212,.16);
    --line-strong:rgba(236,231,212,.28);
    --shadow:0 24px 48px -24px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"]{
  --ground:#10160E;
  --surface:#171F16;
  --surface-2:#1F2A1D;
  --ink:#ECE7D4;
  --ink-soft:#B7BFAC;
  --ink-faint:#82897C;
  --forest:#6FBE96;
  --forest-bright:#8CD1AE;
  --forest-pale:#1C2E22;
  --indigo:#8C9EDD;
  --indigo-pale:#1C2333;
  --gold:#E3BE68;
  --gold-bright:#F0D08C;
  --clay:#E28A55;
  --clay-bright:#EFA477;
  --line:rgba(236,231,212,.16);
  --line-strong:rgba(236,231,212,.28);
  --shadow:0 24px 48px -24px rgba(0,0,0,.6);
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:'Be Vietnam Pro',system-ui,sans-serif;
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;cursor:pointer;}
h1,h2,h3,h4{font-family:'Fraunces',serif;margin:0;text-wrap:balance;color:var(--ink);}
p{margin:0;}
.eyebrow{
  font-family:'Be Vietnam Pro',sans-serif;
  font-weight:600;
  font-size:.72rem;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--forest-bright);
}
:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px;border-radius:4px;}
.wrap{max-width:1180px;margin:0 auto;padding-left:28px;padding-right:28px;}
/* Lề ngang của .wrap chỉ là `padding-left/right`, nên BẤT KỲ luật nào viết sau
   mà dùng `padding` rút gọn trên cùng một phần tử .wrap đều xoá sạch nó (cùng
   độ ưu tiên, đứng sau thì thắng) — chữ dính mép màn hình. Đúng chuyện đã xảy
   ra với .topbar-inner, .nav-inner, .breadcrumb-inner, .foot-top, .foot-bottom
   và cả trang .library-detail. Lề dọc cho .wrap: dùng `padding-block`. */
/* pages whose main content is a bare .wrap (not a <section>, which already
   carries 96px vertical padding) need their own breathing room before the
   footer — matches any top-level content .wrap that precedes the footer,
   without touching nav/breadcrumb/topbar wraps nested elsewhere. */
body > .wrap:not(.stats):has(~ footer){padding-bottom:88px;}
@media(max-width:640px){.wrap{padding-left:18px;padding-right:18px;}}

/* ============ TOPBAR ============ */
.topbar{
  background:var(--forest);
  color:#EFEAD4;
}
.topbar-inner{
  display:flex;align-items:center;gap:14px;
  padding-block:8px;
  font-size:.78rem;
}
.topbar .emblem{
  width:22px;height:22px;flex:none;
}
.topbar-title{
  font-weight:600;letter-spacing:.03em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.topbar-title b{font-weight:700;color:var(--gold-bright);}
.topbar-links{margin-left:auto;display:flex;gap:18px;align-items:center;color:rgba(239,234,212,.82);}
.topbar-links a{white-space:nowrap;}
.topbar-links a:hover{color:#fff;}
/* Bộ chuyển ngôn ngữ là một <nav> lồng bên trong, nên `gap` của
   .topbar-links không với tới hai mục con: chúng dính thành một chuỗi đọc
   ra "Tiếng Việt English" như thể một nhãn duy nhất. Và mục đang xem là
   <span aria-current="true"> — máy đọc màn hình biết, mắt thì không, vì nó
   được tô y hệt liên kết bên cạnh. */
.lang-switch{display:flex;gap:12px;align-items:center;}
.lang-switch [aria-current="true"]{color:#fff;font-weight:600;}

/* ============ NAV ============ */
.nav{
  position:sticky;top:0;z-index:40;
  background:var(--ground);
  border-bottom:1px solid var(--line);
}
.nav-inner{display:flex;align-items:center;gap:32px;padding-block:14px;}
.brand{display:flex;align-items:center;gap:10px;font-family:'Fraunces',serif;font-weight:700;font-size:1.28rem;color:var(--ink);}
.brand .mark{width:34px;height:34px;flex:none;}
.brand small{display:block;font-family:'Be Vietnam Pro',sans-serif;font-weight:500;font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);}
.navlinks{display:flex;gap:26px;margin-left:12px;font-size:.92rem;font-weight:500;color:var(--ink-soft);}
.navlinks a{position:relative;padding:6px 0;}
.navlinks a:hover{color:var(--ink);}
.navlinks a.active{color:var(--forest);}
.navlinks a.active::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;background:var(--gold);border-radius:2px;}
.nav-cta{margin-left:auto;display:flex;align-items:center;gap:14px;}
.btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 20px;border-radius:100px;
  font-weight:600;font-size:.88rem;
  border:1px solid transparent;
  transition:transform .15s ease, box-shadow .15s ease, background .15s ease, color .15s ease;
}
.btn svg{width:16px;height:16px;flex:none;}
.btn-primary{background:var(--forest);color:#F3EFDD;}
.btn-primary:hover{background:var(--forest-bright);transform:translateY(-1px);}
.btn-ghost{border-color:var(--line-strong);color:var(--ink-soft);}
.btn-ghost:hover{border-color:var(--forest);color:var(--forest);}
.navmenu-toggle{display:none;background:none;border:0;color:var(--ink);padding:6px;}
@media(max-width:900px){
  .navlinks{
    display:none;flex-direction:column;gap:0;margin-left:0;
    position:absolute;top:100%;left:0;right:0;
    background:var(--ground);border-bottom:1px solid var(--line);
    padding:8px 0;box-shadow:var(--shadow);
  }
  .navlinks a{padding:13px 28px;width:100%;}
  .nav.menu-open .navlinks{display:flex;}
  .navmenu-toggle{display:block;}
  .nav-cta .btn-ghost{display:none;}
}
@media(max-width:640px){
  /* Tên xã + dòng phụ + nút CTA + nút menu không vừa một hàng: cả ba cùng
     xuống dòng và thanh dính-đầu-trang cao 126px, chiếm 22% màn hình 568px.
     Dòng phụ "xã Cẩm Khê" là tên địa phương nên KHÔNG bỏ; thu nhỏ cả khối. */
  .brand{white-space:nowrap;font-size:1.05rem;line-height:1.15;}
  .brand .mark{width:30px;height:30px;}
  .brand small{font-size:.58rem;}
  .nav-inner{gap:12px;}
  .nav-cta .btn-primary{white-space:nowrap;}
}
@media(max-width:520px){
  .nav-cta .btn-primary{padding:9px 14px;font-size:.8rem;}
}
@media(max-width:420px){
  /* Dưới 420px thì "Di tích số hóa" + CTA + nút menu không vừa một hàng.
     Bỏ CTA: đích của nó (Thư viện 360°) đã nằm trong menu. */
  .nav-cta{display:none;}
  .navmenu-toggle{margin-left:auto;}
}

/* ============ HERO ============ */
.hero{position:relative;overflow:hidden;background:linear-gradient(180deg,#FBF6E4 0%,#F3ECC9 34%,#FFFFFF 100%);}
:root[data-theme="dark"] .hero{background:linear-gradient(180deg,#243421 0%,#1B2A1A 45%,var(--ground) 100%);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .hero{background:linear-gradient(180deg,#243421 0%,#1B2A1A 45%,var(--ground) 100%);}}
.hero-scene{position:relative;height:min(72vh,640px);min-height:460px;}
.hero-layer{position:absolute;inset:0;will-change:transform;transition:transform .25s ease-out;}
.hero-hill-back{background:var(--forest);clip-path:polygon(0 62%,14% 52%,30% 58%,46% 44%,62% 54%,80% 42%,100% 52%,100% 100%,0 100%);opacity:.28;}
.hero-hill-mid{background:var(--forest);clip-path:polygon(0 74%,18% 62%,34% 70%,52% 56%,70% 68%,86% 58%,100% 66%,100% 100%,0 100%);opacity:.5;}
.hero-tea{position:absolute;left:0;right:0;bottom:22%;height:30%;background:repeating-linear-gradient(115deg,var(--forest-bright) 0 10px,var(--forest) 10px 22px);opacity:.55;clip-path:polygon(0 40%,100% 15%,100% 100%,0 100%);}
.hero-river{position:absolute;left:0;right:0;bottom:0;height:24%;background:linear-gradient(180deg,var(--clay) 0%,var(--gold) 55%,var(--clay-bright) 100%);opacity:.85;clip-path:polygon(0 46%,12% 40%,26% 52%,40% 38%,55% 50%,70% 36%,85% 48%,100% 40%,100% 100%,0 100%);}
.hero-sun{position:absolute;right:12%;top:14%;width:120px;height:120px;border-radius:50%;background:radial-gradient(circle,var(--gold-bright) 0%,rgba(217,169,74,0) 70%);opacity:.85;}
.hero-content{
  position:relative;z-index:2;height:100%;
  display:flex;flex-direction:column;justify-content:center;gap:22px;
  padding:40px 0 80px;
}
.hero-content h1{font-size:clamp(2.4rem,5.4vw,4.1rem);font-weight:700;line-height:1.06;color:var(--ink);max-width:14ch;}
:root[data-theme="dark"] .hero-content h1{color:#F3EFDD;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .hero-content h1{color:#F3EFDD;}}
.hero-content .eyebrow{color:var(--clay);}
:root[data-theme="dark"] .hero-content .eyebrow{color:var(--gold-bright);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .hero-content .eyebrow{color:var(--gold-bright);}}
.hero-content p.lede{max-width:46ch;font-size:1.08rem;color:var(--ink-soft);}
:root[data-theme="dark"] .hero-content p.lede{color:#D7DCCB;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .hero-content p.lede{color:#D7DCCB;}}
.hero-actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:6px;}
.btn-clay{background:var(--clay);color:#FBF3E8;}
.btn-clay:hover{background:var(--clay-bright);transform:translateY(-1px);}
.btn-outline{border-color:rgba(26,36,32,.35);color:var(--ink);}
:root[data-theme="dark"] .btn-outline{border-color:rgba(236,231,212,.4);color:#F3EFDD;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .btn-outline{border-color:rgba(236,231,212,.4);color:#F3EFDD;}}
.btn-outline:hover{background:rgba(255,255,255,.18);}

/* ============ BẢN ĐỒ DI TÍCH (trang chủ, #bando) ============
   Dải `--surface-2` để mục này tách khỏi mục trắng phía trên và dải xanh đậm
   của `.medialib` phía dưới, mà không cần thêm một màu nào vào bảng màu. */
.mapsec{background:var(--surface-2);}
/* Khung bản đồ mang bán kính lớn như thẻ, nhưng KHÔNG đổ bóng: nó là một mặt
   phẳng nằm trong dải, không phải một thẻ nổi lên trên dải. */
.mapframe{
  position:relative;border-radius:var(--radius-lg);overflow:hidden;
  border:1px solid var(--line);background:var(--surface);
}
.mapcanvas{width:100%;aspect-ratio:16/9;min-height:320px;}
/* Trên màn hẹp, 16/9 làm bản đồ thành một dải dẹt và các marker chồng lên
   nhau — cao hơn thì tách ra được. */
@media(max-width:760px){.mapcanvas{aspect-ratio:4/5;min-height:380px;}}
.mapcanvas-loi{
  display:flex;align-items:center;justify-content:center;
  color:var(--ink-faint);font-size:.88rem;text-align:center;padding:24px;
}

/* Marker: bóng mái đình, không phải ghim mặc định. Màu theo XẾP HẠNG —
   `--forest` cho cấp tỉnh, `--gold-bright` cho quốc gia (đúng 3/20, nên sự
   ít ỏi tự nói hộ). */
.mapmark{
  color:var(--forest);
  background:var(--surface);
  border:2px solid currentColor;border-radius:50%;
  box-shadow:0 2px 6px rgba(20,28,22,.28);
  display:grid;place-items:center;
}
.mapmark svg{width:20px;height:20px;}
/* Quốc gia: NỀN vàng, icon màu mực — không phải icon vàng trên nền nâu đậm.
   Bản đầu làm ngược lại và ở cỡ 28px nó ra một vòng nâu xỉn, không đọc ra
   vàng, tức mất luôn cái phân biệt duy nhất của 3 di tích quốc gia. */
.mapmark.is-national{color:var(--ink);background:var(--gold-bright);border-color:var(--gold);}
/* Chỉ một trạng thái chuyển động, và nó trả lời hành động của người dùng —
   không có hiệu ứng hover rải rác. */
.mapmark:focus-visible{outline:3px solid var(--gold-bright);outline-offset:2px;}

/* Hộp thoại: nhỏ, ảnh tràn mép trên, rồi tên · huy hiệu · giới thiệu · lối đi.
   Bán kính nhỏ hơn khung bản đồ, để hai thứ không trông như cùng một mặt. */
.mappop .leaflet-popup-content-wrapper{
  border-radius:var(--radius-md);padding:0;overflow:hidden;
  background:var(--surface);color:var(--ink);box-shadow:var(--shadow);
}
.mappop .leaflet-popup-content{margin:0;width:268px !important;line-height:1.5;}
.mappop .leaflet-popup-tip{background:var(--surface);}
/* Hộp ở DƯỚI marker (heritage-map.js `datViTri`): mũi lên cạnh trên, quay ngược.
   Hộp ở hai bên: bỏ mũi — hộp đã trượt dọc nên mũi không chỉ đúng được nữa. */
/* Điện thoại: khung bản đồ ~358x447, hộp 268x300 thì trên hay dưới marker
   đều không vừa và hộp buộc phải đè lên marker. Hộp gọn lại (~232x220) để
   phần lớn marker còn chỗ đặt hộp bên cạnh. */
@media(max-width:760px){
  .mappop .leaflet-popup-content{width:232px !important;}
  .mappop-anh{aspect-ratio:21/9;}
  .mappop-than{padding:10px 12px 12px;gap:6px;}
}
.mappop.mappop-duoi .leaflet-popup-tip-container{top:-19px;transform:rotate(180deg);}
.mappop.mappop-phai .leaflet-popup-tip-container,
.mappop.mappop-trai .leaflet-popup-tip-container{display:none;}
.mappop-anh{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;}
.mappop-than{padding:12px 14px 14px;display:flex;flex-direction:column;gap:8px;align-items:flex-start;}
.mappop-than h4{
  font-family:'Be Vietnam Pro',sans-serif;font-weight:600;font-size:.95rem;
  color:var(--ink);margin:0;line-height:1.3;
}
/* `line-clamp` là hàng rào cứng, không phải trang trí: `TOM_TAT_TU` cắt theo
   SỐ TỪ, mà một câu 14 từ tiếng Việt vẫn có thể xuống ba dòng ở 268px. Kẹp hai
   dòng thì hộp thoại có chiều cao đoán được ở mọi di tích. */
.mappop-than p{
  margin:0;font-size:.82rem;color:var(--ink-soft);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.mappop-lien-ket{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:2px;}
.mappop-lien-ket a{
  font-size:.82rem;font-weight:600;color:var(--forest);
  text-decoration:underline;text-underline-offset:3px;
}
.mappop-lien-ket a:hover{color:var(--forest-bright);}

/* Chú giải: chìa khoá đọc bản đồ, nên nhỏ và nằm dưới — không phải tiêu đề. */
.mapkey{
  list-style:none;margin:14px 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:8px 22px;
  font-size:.82rem;color:var(--ink-soft);
}
.mapkey li{display:flex;align-items:center;gap:8px;}
.mapkey-dot{
  width:13px;height:13px;border-radius:50%;flex:none;
  border:2px solid var(--forest);background:var(--surface);
}
.mapkey-dot.is-national{border-color:var(--gold);background:var(--gold-bright);}
.mapempty{
  margin:0;padding:22px;border:1px dashed var(--line-strong);
  border-radius:var(--radius-lg);color:var(--ink-soft);font-size:.92rem;
}
.mapempty a{color:var(--forest);font-weight:600;text-decoration:underline;text-underline-offset:3px;}

/* --- Hero ảnh thật: slider cắt từ ảnh 360 khảo sát --------------------------
   Cùng chiều cao với `.hero-scene` để `.hero-content` (height:100%, nằm trong
   một `.wrap` position:absolute) không đổi bố cục giữa hai nhánh. */
.hero-slider{position:relative;height:min(72vh,640px);min-height:460px;overflow:hidden;}
.hero-slide{position:absolute;inset:0;margin:0;opacity:0;transition:opacity .9s ease-in-out;}
.hero-slide.is-active{opacity:1;}
.hero-slide img{width:100%;height:100%;object-fit:cover;display:block;}
/* Ảnh khảo sát chụp giữa trưa, trời trắng gắt. Không có lớp phủ này thì chữ
   hero (ngay cả khi đã chuyển sang màu trắng) nằm trên nền sáng và mất hẳn.
   Phủ nặng bên TRÁI vì cột chữ nằm bên trái; bên phải giữ ảnh gần như nguyên. */
.hero-shade{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(90deg,rgba(14,22,16,.82) 0%,rgba(14,22,16,.62) 38%,rgba(14,22,16,.12) 72%,rgba(14,22,16,.04) 100%),
    /* Dải dưới phải đủ đậm tới tận mép: chú thích và hàng nút nằm ở góc PHẢI
       DƯỚI, nơi lớp phủ ngang phía trên đã nhạt gần hết. Đo trên ảnh bìa Chùa
       Khánh Long — chú thích rơi đúng vào một bức tường nắng và gần như không
       đọc được với dải cũ (.45 tắt dần ở 32%). */
    linear-gradient(0deg,rgba(14,22,16,.66) 0%,rgba(14,22,16,.34) 20%,rgba(14,22,16,0) 46%);
}
/* `bottom` phải tránh dải quicknav: `.stats` có `margin-top:-56px` và
   `z-index:3`, nên nó phủ lên đúng 56px cuối của hero. Mọi thứ đặt thấp hơn
   mốc đó sẽ bị một thẻ trắng che mất một nửa. Ở <=760px `.stats` bỏ chồng lấn
   (`margin-top:20px`), nên breakpoint dưới cùng hạ cả hai xuống lại. */
.hero-slide-cap{
  position:absolute;right:20px;bottom:124px;z-index:2;max-width:min(42ch,60%);
  text-align:right;text-shadow:0 1px 10px rgba(0,0,0,.55);
}
.hero-slide-cap a{color:inherit;text-decoration:none;}
.hero-slide-cap a:hover strong{text-decoration:underline;text-underline-offset:3px;}
.hero-slide-cap strong{display:block;color:#FFF;font-size:1.02rem;font-weight:700;letter-spacing:.01em;}
.hero-slide-cap span{display:block;color:rgba(255,255,255,.82);font-size:.82rem;margin-top:2px;}
/* Chỉ hiện khi main.js gắn `.is-live`: không có JS thì đây là những cái nút
   bấm không làm gì, tệ hơn hẳn so với không có nút nào. */
.hero-nav{display:none;}
.hero-slider.is-live .hero-nav{
  position:absolute;right:20px;bottom:76px;z-index:3;
  display:flex;align-items:center;gap:10px;
}
.hero-arrow{
  width:34px;height:34px;flex:0 0 auto;display:grid;place-items:center;
  border:1px solid rgba(255,255,255,.45);border-radius:50%;
  background:rgba(14,22,16,.34);color:#FFF;cursor:pointer;
  transition:background .18s ease,border-color .18s ease;
}
.hero-arrow svg{width:16px;height:16px;}
.hero-arrow:hover{background:rgba(14,22,16,.6);border-color:rgba(255,255,255,.8);}
.hero-dots{display:flex;gap:8px;}
.hero-dots button{
  width:9px;height:9px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:rgba(255,255,255,.42);transition:background .18s ease,width .18s ease;
}
.hero-dots button[aria-selected="true"]{background:#FFF;width:26px;border-radius:5px;}
.hero-arrow:focus-visible,.hero-dots button:focus-visible{outline:2px solid #FFF;outline-offset:3px;}

/* Chữ hero trên nền ảnh: luôn sáng, ở CẢ hai chế độ sáng/tối — nền ở đây là
   tấm ảnh cộng lớp phủ tối, không phải nền trang, nên bảng màu theo theme
   không áp dụng. Phải thắng cả các quy tắc `[data-theme]` phía trên. */
.hero-photo .hero-content h1,
:root[data-theme="dark"] .hero-photo .hero-content h1{color:#FFF;text-shadow:0 2px 18px rgba(0,0,0,.4);}
.hero-photo .hero-content .eyebrow,
:root[data-theme="dark"] .hero-photo .hero-content .eyebrow{color:var(--gold-bright);}
.hero-photo .hero-content p.lede,
:root[data-theme="dark"] .hero-photo .hero-content p.lede{color:rgba(255,255,255,.88);text-shadow:0 1px 12px rgba(0,0,0,.4);}
.hero-photo .btn-outline,
:root[data-theme="dark"] .hero-photo .btn-outline{border-color:rgba(255,255,255,.55);color:#FFF;}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .hero-photo .hero-content h1{color:#FFF;}
  :root:not([data-theme="light"]) .hero-photo .hero-content .eyebrow{color:var(--gold-bright);}
  :root:not([data-theme="light"]) .hero-photo .hero-content p.lede{color:rgba(255,255,255,.88);}
  :root:not([data-theme="light"]) .hero-photo .btn-outline{border-color:rgba(255,255,255,.55);color:#FFF;}
}

@media(max-width:760px){
  /* Trên màn hẹp, cột chữ chiếm cả bề ngang nên lớp phủ phải đều, không dồn
     sang trái nữa. */
  .hero-shade{background:linear-gradient(0deg,rgba(14,22,16,.78) 0%,rgba(14,22,16,.52) 55%,rgba(14,22,16,.4) 100%);}
  /* Chú thích lên trên hàng nút để hai thứ không chồng nhau ở bề ngang hẹp. */
  .hero-slide-cap{left:20px;right:20px;bottom:64px;max-width:none;text-align:left;}
  .hero-slider.is-live .hero-nav{left:20px;right:auto;bottom:22px;}
}
@media(prefers-reduced-motion:reduce){
  .hero-slide{transition:none;}
}

/* quick-access strip overlapping hero */
.stats{
  position:relative;z-index:3;margin-top:-56px;
}
@media(max-width:760px){
  /* on narrow screens the hero's illustrated hill layer can show a sliver
     above the card in the overlap zone — drop the overlap instead of
     fighting the illustration pixel-by-pixel per viewport width */
  .stats{margin-top:20px;}
}
.quicknav{
  background:var(--surface);border-radius:var(--radius-lg);box-shadow:var(--shadow);
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border:1px solid var(--line);
}
.qn-item{
  display:flex;align-items:center;gap:14px;
  padding:20px 20px;
  border:none;border-right:1px solid var(--line);
  background:none;
  text-align:left;color:var(--ink);width:100%;
  transition:background .15s ease;
}
.qn-item:last-child{border-right:none;}
.qn-item:hover{background:var(--forest-pale);}
.qn-icon{
  width:42px;height:42px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--forest-pale);color:var(--forest);
  transition:background .15s ease,color .15s ease;
}
.qn-icon svg{width:19px;height:19px;}
.qn-item:hover .qn-icon{background:var(--forest);color:#fff;}
.qn-text{flex:1;min-width:0;}
.qn-label{display:block;font-weight:600;font-size:.94rem;color:var(--ink);}
.qn-sub{display:block;font-size:.75rem;color:var(--ink-faint);margin-top:1px;}
.qn-arrow{flex:none;color:var(--ink-faint);transition:transform .15s ease,color .15s ease;}
.qn-item:hover .qn-arrow{transform:translateX(3px);color:var(--forest);}
/* Mốc cũ là 760px, nhưng bốn cột đã vỡ từ trước đó: ở 768px mỗi nhãn xuống ba
   dòng. `minmax(0,1fr)` thì bắt buộc — với `1fr` mặc định, ô không co xuống
   dưới bề rộng nội dung tối thiểu, và ở 320px cả lưới rộng 377px, cột phải bị
   cắt cụt ngoài màn hình. */
@media(max-width:1000px){
  .quicknav{grid-template-columns:repeat(2,minmax(0,1fr));}
  .qn-item:nth-child(2){border-right:none;}
  .qn-item:nth-child(3),.qn-item:nth-child(4){border-top:1px solid var(--line);}
}
/* Hai cột ở bề ngang điện thoại cho mỗi ô ~170px: nhãn xuống ba dòng, dòng mô
   tả bị cắt. Một cột thì biểu tượng, nhãn, mô tả và mũi tên nằm gọn một hàng. */
@media(max-width:640px){
  .quicknav{grid-template-columns:minmax(0,1fr);}
  .qn-item{border-right:none;border-top:1px solid var(--line);}
  .qn-item:first-child{border-top:none;}
}

/* compact facts row inside intro section */
.intro-facts{display:flex;flex-wrap:wrap;gap:8px 26px;margin-top:24px;padding-top:20px;border-top:1px solid var(--line);}
.intro-facts span{font-weight:600;font-size:.92rem;color:var(--ink);font-variant-numeric:tabular-nums;}
.intro-facts span i{font-style:normal;font-weight:400;color:var(--ink-faint);font-size:.82rem;margin-left:3px;}

/* ============ SECTION SCAFFOLD ============ */
section{padding:96px 0;}
.section-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;margin-bottom:42px;flex-wrap:wrap;}
.section-head h2{font-size:clamp(1.7rem,3vw,2.3rem);font-weight:600;margin-top:8px;}
.section-head .sub{max-width:52ch;color:var(--ink-soft);margin-top:10px;}
.section-link{font-weight:600;font-size:.9rem;color:var(--forest);display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}
:root[data-theme="dark"] .section-link{color:var(--forest-bright);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .section-link{color:var(--forest-bright);}}
.section-link:hover{gap:10px;}

/* ============ DESTINATION GRID ============ */
/* .dest-card is the shared card shell, reused by .dest-grid-3 (national
   feature grid) and .dest-grid-5 (general attractions) below — it has no
   bento/asymmetric span logic of its own, each grid container is a plain
   uniform grid so cards never depend on their position/index. */
.dest-card{
  border-radius:var(--radius-md);overflow:hidden;background:var(--surface);
  border:1px solid var(--line);
  display:flex;flex-direction:column;
  transition:transform .2s ease, box-shadow .2s ease;
}
.dest-card:hover{transform:translateY(-4px);box-shadow:var(--shadow);}
.dest-media{position:relative;aspect-ratio:4/3;overflow:hidden;}
.dest-media .scene{position:absolute;inset:0;}
.dest-tag{
  position:absolute;top:12px;left:12px;z-index:2;
  background:rgba(16,22,14,.55);backdrop-filter:blur(6px);
  color:#F3EFDD;font-size:.68rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;
  padding:5px 10px;border-radius:100px;display:flex;align-items:center;gap:5px;
}
.dest-tag svg{width:12px;height:12px;}
.dest-body{padding:18px 20px 20px;display:flex;flex-direction:column;gap:6px;flex:1;}
.dest-body h3{font-size:1.12rem;font-weight:600;}
.dest-body p{font-size:.88rem;color:var(--ink-soft);}
.dest-body .go{margin-top:auto;padding-top:10px;font-size:.82rem;font-weight:600;color:var(--forest);display:flex;align-items:center;gap:5px;}
:root[data-theme="dark"] .dest-body .go{color:var(--forest-bright);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .dest-body .go{color:var(--forest-bright);}}

/* scene gradient variants for illustration cards */
.scene-river{background:linear-gradient(160deg,#E7D9A4 0%,#D9A94A 42%,#A85426 100%);}
.scene-river::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(100deg,rgba(255,255,255,.18) 0 3px,transparent 3px 26px);}
.scene-tea{background:linear-gradient(165deg,var(--forest-bright) 0%,var(--forest) 70%);}
.scene-tea::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(120deg,rgba(255,255,255,.14) 0 6px,transparent 6px 18px);}
.scene-dinh{background:linear-gradient(165deg,#B9862E 0%,#7C5A22 100%);}
.scene-dinh::before{content:"";position:absolute;left:50%;bottom:18%;width:64%;height:40%;transform:translateX(-50%);background:#F1EEDC0f;clip-path:polygon(0 100%,8% 40%,50% 0,92% 40%,100% 100%);border:2px solid rgba(241,238,220,.5);border-bottom:none;}
.scene-non{background:linear-gradient(165deg,#D9A94A 0%,#A85426 100%);}
.scene-non::before{content:"";position:absolute;left:50%;bottom:20%;width:56%;aspect-ratio:2/1;transform:translateX(-50%);border-radius:50% 50% 0 0/100% 100% 0 0;background:rgba(241,238,220,.16);border:2px solid rgba(241,238,220,.55);border-bottom:none;}
.scene-cho{background:linear-gradient(165deg,#8C6A2E 0%,#4E3A19 100%);}
.scene-amthuc{background:linear-gradient(165deg,var(--forest-bright) 0%,#123321 55%,#7C5A22 100%);}
.scene-ruong{background:linear-gradient(165deg,#D9A94A 0%,#8C6A2E 100%);}
.scene-ruong::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(88deg,rgba(255,255,255,.16) 0 4px,transparent 4px 16px);}
.scene-co{background:linear-gradient(165deg,#234232 0%,#0F2118 100%);}
.scene-co::before{content:"";position:absolute;left:20%;bottom:10%;width:2px;height:70%;background:rgba(241,238,220,.4);box-shadow:34% 6% 0 -2px rgba(241,238,220,.35),60% 0 0 -4px rgba(241,238,220,.3);}
.scene-nvh{background:linear-gradient(165deg,#2B3A5E 0%,#16203A 100%);}
.scene-nvh::before{content:"";position:absolute;left:50%;bottom:22%;width:58%;height:34%;transform:translateX(-50%);background:rgba(241,238,220,.08);border:2px solid rgba(241,238,220,.45);border-bottom:none;}

/* ============ MEDIA LIBRARY ============ */
.medialib{background:var(--forest);color:#F1EEDC;position:relative;overflow:hidden;}
.medialib::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 15% 20%,rgba(217,169,74,.16),transparent 55%),radial-gradient(circle at 85% 80%,rgba(168,84,38,.18),transparent 55%);}
.medialib .wrap{position:relative;z-index:1;}
.medialib .eyebrow{color:var(--gold-bright);}
.medialib .section-head h2{color:#F8F5E6;}
.medialib .section-head .sub{color:rgba(241,238,220,.72);}
.medialib .section-head .sub a{color:var(--gold-bright);}
/* Nút "Xem toàn bộ thư viện" nằm trên dải xanh đậm của `.medialib`, nhưng
   `.btn-outline` đóng cứng chữ `--ink` (#182420) và viền rgba(26,36,32,.35) —
   tức chữ tối trên nền tối. Đo được: chữ 2,96:1 (WCAG AA cần 4,5:1 cho chữ
   thường) và viền ~1,47:1 (thành phần giao diện cần 3:1), nghĩa là gần như
   không thấy viền.

   Đổi hẳn sang nút ĐẶC màu kem thay vì chỉ làm sáng viền: đây là lối đi duy
   nhất ra khỏi khối thư viện ở mục này, không phải một lựa chọn thứ cấp. Chữ
   `--forest` trên nền kem là 4,63:1 — đạt AA.

   Cùng loại lỗi với `.hero-photo .btn-outline` phía dưới: một nút được tô màu
   cho nền sáng, đặt lên một nền tối, và không ai đổi màu chữ theo. */
.medialib .btn-outline{
  background:#F1EEDC;border-color:#F1EEDC;color:var(--forest);
}
.medialib .btn-outline:hover{background:#FFF;border-color:#FFF;color:var(--forest);}
.medialib .btn-outline:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px;}

/* search box: hands off to /tim-kiem/, this page runs no search of its own */
.medialib-search{display:flex;gap:8px;align-items:center;}
.medialib-search input{
  min-width:min(260px,60vw);padding:10px 16px;border-radius:100px;
  background:rgba(241,238,220,.08);border:1px solid rgba(241,238,220,.2);
  color:#F8F5E6;font-size:.86rem;font-family:inherit;
}
.medialib-search input::placeholder{color:rgba(241,238,220,.5);}
.medialib-search input:focus-visible{outline:2px solid var(--gold-bright);outline-offset:1px;}
.medialib-search button{
  padding:10px 18px;border-radius:100px;border:1px solid var(--gold-bright);
  background:var(--gold-bright);color:#2B2007;font-weight:600;font-size:.86rem;
  font-family:inherit;cursor:pointer;
}

.medialib-toolbar{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:26px;}
.medialib-clear{font-size:.82rem;color:rgba(241,238,220,.7);white-space:nowrap;}
.medialib-clear:hover{color:#fff;}
.medialib-count{font-size:.84rem;color:rgba(241,238,220,.72);}
.medialib-count strong{color:#F8F5E6;}

/* Mỗi di tích một mục: tiêu đề dẫn sang trang di tích, số đếm bên phải.
   `padding:0` là bắt buộc, không phải dọn dẹp: luật chung `section{padding:96px 0}`
   ở trên dành cho các dải lớn của trang, mà đây là <section> LỒNG bên trong
   một dải như thế — để nguyên thì mỗi nhóm tự đội thêm 192px khoảng trắng,
   và hai di tích cạnh nhau cách nhau gần cả màn hình. */
.lib-group{margin-bottom:34px;padding:0;}
.detail-main .detail-section{padding:0;margin-bottom:34px;}
.lib-group:last-of-type{margin-bottom:0;}
.lib-group-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding-bottom:10px;margin-bottom:16px;
  border-bottom:1px solid rgba(241,238,220,.16);
  font-size:1.08rem;font-weight:600;color:#F8F5E6;
}
.lib-group-head a{color:#F8F5E6;}
.lib-group-head a:hover{color:var(--gold-bright);}
.lib-group-head .media-count{color:rgba(241,238,220,.66);font-size:.8rem;}

/* Thẻ tour là <button>, phải trông y hệt thẻ <a> bên cạnh nó. */
button.medcard{padding:0;border:1px solid rgba(241,238,220,.14);font:inherit;text-align:left;cursor:pointer;width:100%;}
button.medcard[disabled]{opacity:.5;cursor:default;}

.library-empty{
  padding:36px;border-radius:var(--radius-md);text-align:center;
  border:1px dashed rgba(241,238,220,.28);color:rgba(241,238,220,.78);
}
.library-empty .btn{margin-top:16px;}

/* ============ HỘP THOẠI TOUR 360° ============ */
.tour-dialog{
  border:0;padding:0;background:transparent;max-width:none;max-height:none;
  width:100%;height:100%;
}
.tour-dialog::backdrop{background:rgba(10,14,9,.82);}
.tour-dialog-frame{
  position:absolute;inset:24px;display:flex;flex-direction:column;
  border-radius:var(--radius-md);overflow:hidden;background:#0A0E09;
}
@media(max-width:700px){.tour-dialog-frame{inset:0;border-radius:0;}}
/* iPhone không có Fullscreen API cho phần tử thường — lớp phủ thay thế. */
.tour-dialog-frame.is-fake-fullscreen{position:fixed;inset:0;border-radius:0;z-index:1300;}
.tour-dialog-bar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 14px;background:var(--surface);color:var(--ink);
}
.tour-dialog-title{font-weight:600;font-size:.9rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tour-dialog-actions{display:flex;gap:8px;flex:none;}
.tour-btn{
  width:34px;height:34px;border-radius:50%;border:1px solid var(--line-strong);
  background:var(--surface);color:var(--ink-soft);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.tour-btn:hover{border-color:var(--forest);color:var(--forest);}
.tour-dialog-stage{flex:1 1 auto;min-height:0;}
.tour-dialog-stage iframe{display:block;width:100%;height:100%;border:0;background:#0A0E09;}


.tabbar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:28px;}
.tab{
  display:flex;align-items:center;gap:8px;
  padding:10px 18px;border-radius:100px;
  background:rgba(241,238,220,.08);border:1px solid rgba(241,238,220,.16);
  color:rgba(241,238,220,.78);font-weight:600;font-size:.86rem;
  transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.tab svg{width:16px;height:16px;}
.tab[aria-current="page"]{background:var(--gold-bright);color:#2B2007;border-color:var(--gold-bright);}
.tab:hover:not([aria-current="page"]){border-color:rgba(241,238,220,.4);color:#F8F5E6;}

.medgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;}
@media(max-width:900px){.medgrid{grid-template-columns:repeat(2,1fr);}}
.medcard{
  position:relative;border-radius:var(--radius-md);overflow:hidden;
  aspect-ratio:4/3;border:1px solid rgba(241,238,220,.14);
  background:#1A2118;
}
.medcard .scene{position:absolute;inset:0;}
/* Lớp phủ phải còn ĐỦ ĐẬM ở dải chữ, không chỉ ở sát đáy thẻ. Gradient cũ
   (`.82` rồi tắt ở 75%) để tên thẻ nằm đúng chỗ đã nhạt: đo ra chỉ ~0,45 alpha
   tại đó, tức chữ #F8F5E6 trên một khoảng trời trắng còn 3,13:1 — dưới ngưỡng
   4,5:1 của WCAG AA. Thấy rõ trên thẻ "Chùa Vân Ngư" (nền vàng son) và "Đình
   Sơn Cương" (nền trời sáng).

   Giữ 0,68 xuyên qua dải chữ thì trường hợp xấu nhất (gần như trắng) lên
   6,01:1.

   Lề trên GIỮ NGUYÊN 14px. Bản sửa đầu nâng lên 26px cho gradient có chỗ
   chuyển, và đo ra thành: thẻ trên điện thoại cao 126px mà khối chữ chiếm
   106px — lớp phủ ăn 84% tấm ảnh. Không cần: gradient nằm trong chính khối
   này, chỉ cần alpha tại dải chữ đủ đậm, không cần khối cao hơn. */
.medcard-info{
  position:absolute;left:0;right:0;bottom:0;padding:14px 14px 12px;
  background:linear-gradient(0deg,rgba(10,14,9,.92) 0%,rgba(10,14,9,.68) 58%,rgba(10,14,9,0) 100%);
}
.medcard-info h4{font-family:'Be Vietnam Pro',sans-serif;font-weight:600;font-size:.92rem;color:#F8F5E6;}
.medcard-info .hint{font-size:.72rem;color:rgba(241,238,220,.68);margin-top:2px;display:flex;align-items:center;gap:5px;}
.medbadge{
  position:absolute;top:10px;right:10px;z-index:2;
  width:30px;height:30px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(16,22,14,.65);backdrop-filter:blur(4px);
  border:1px solid rgba(241,238,220,.3);color:#F8F5E6;
}
.medbadge svg{width:15px;height:15px;}
.medcard.type-360 .medbadge,.medcard.type-video .medbadge{background:var(--clay);border-color:var(--clay);}
.medcard.type-tour .medbadge{background:var(--gold-bright);color:#2B2007;border-color:var(--gold-bright);}
.medcard .playbtn{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:52px;height:52px;border-radius:50%;
  background:rgba(16,22,14,.55);border:1.5px solid rgba(241,238,220,.7);
  display:flex;align-items:center;justify-content:center;color:#F8F5E6;
  transition:transform .2s ease, background .2s ease;
}
.medcard:hover .playbtn{transform:translate(-50%,-50%) scale(1.08);background:var(--clay);}
.medcard .playbtn svg{width:20px;height:20px;}
.medcard.type-tour .scenecount{
  position:absolute;left:12px;top:12px;display:flex;gap:4px;
}
.medcard.type-tour .scenecount span{width:6px;height:6px;border-radius:50%;background:rgba(241,238,220,.5);}
.medcard.type-tour .scenecount span:first-child{background:var(--gold-bright);}
.medcard{cursor:pointer;}
.medcard:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px;}
/* library pages (sub-project 5): cards are real links, thumbnails are real <img>s */
a.medcard{display:block;color:inherit;}
.medcard-thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
.medcard.type-panorama .medbadge,.medcard.type-audio .medbadge{background:var(--clay);border-color:var(--clay);}
a.tab{text-decoration:none;}
.tab-count{font-weight:500;opacity:.75;}
.medialib .pagination{margin-top:40px;}

/* scene variants (dark set for media lib) */
.mscene-song{background:linear-gradient(160deg,#4A3B18 0%,#A85426 55%,#D9A94A 100%);}
.mscene-doi{background:linear-gradient(165deg,#2E5A44 0%,#16281D 100%);}
.mscene-dinh{background:linear-gradient(165deg,#5C4419 0%,#2A1E0C 100%);}
.mscene-cho{background:linear-gradient(165deg,#3C7A5C 0%,#123321 100%);}
.mscene-non{background:linear-gradient(165deg,#8C6A2E 0%,#3A2A10 100%);}
.mscene-hoanghon{background:linear-gradient(160deg,#D9A94A 0%,#A85426 45%,#3B2410 100%);}
/* .scene-placeholder's own default is a light gradient (fine on heritage/
   news cards) - .medcard-info h4 is near-white text over a scrim, so a
   thumbnail-less media card needs a dark placeholder for the title to stay
   legible. Scoped to .medcard only. */
.medcard .scene-placeholder{background:linear-gradient(165deg,#2E5A44 0%,#16281D 100%);}

/* ============ IMMERSIVE VIEWER (mock lightbox) ============ */
.viewer-overlay{
  position:fixed;inset:0;z-index:100;
  background:rgba(30,38,30,.6);
  display:none;align-items:center;justify-content:center;
  padding:24px;
}
.viewer-overlay.open{display:flex;}
.viewer-panel{
  width:min(1080px,100%);
  background:var(--surface);border-radius:var(--radius-lg);overflow:hidden;
  border:1px solid var(--line);
  box-shadow:0 40px 80px -20px rgba(20,28,22,.35);
}
.viewer-stage{position:relative;aspect-ratio:16/9;overflow:hidden;background:#DCEBDF;}
.pano-track{
  position:absolute;top:0;bottom:0;left:0;width:220%;
  display:flex;
  animation:panoDrift 34s linear infinite;
}
@media(prefers-reduced-motion:reduce){.pano-track{animation:none;}}
.viewer-stage:hover .pano-track{animation-play-state:paused;}
@keyframes panoDrift{0%{transform:translateX(0);}100%{transform:translateX(-54.5%);}}
.pano-seg{flex:none;width:50%;height:100%;position:relative;}
.pano-seg.a{background:linear-gradient(180deg,#EAF2D8 0%,#BFDDC4 45%,#6FA987 100%);}
.pano-seg.b{background:linear-gradient(180deg,#F1EDC9 0%,#CBE0C0 45%,#5F9C7C 100%);}
.pano-hill{position:absolute;left:0;right:0;bottom:0;height:46%;background:#2F5D45;}
.pano-seg.a .pano-hill{clip-path:polygon(0 60%,10% 40%,24% 55%,38% 30%,54% 50%,70% 25%,88% 45%,100% 30%,100% 100%,0 100%);}
.pano-seg.b .pano-hill{clip-path:polygon(0 45%,16% 60%,30% 35%,46% 55%,60% 30%,78% 52%,92% 34%,100% 48%,100% 100%,0 100%);}
.pano-river{position:absolute;left:0;right:0;bottom:0;height:14%;background:linear-gradient(180deg,#A85426,#D9A94A);opacity:.9;}
.pano-tea{position:absolute;left:0;right:0;bottom:14%;height:20%;background:repeating-linear-gradient(115deg,#3C7A5C 0 9px,#234232 9px 20px);}
.hotspot{
  position:absolute;width:16px;height:16px;border-radius:50%;
  background:var(--gold-bright);border:2px solid #fff;
  box-shadow:0 0 0 6px rgba(217,169,74,.28);
  z-index:3;
}
.hotspot::after{
  content:attr(data-label);
  position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%);
  background:rgba(10,14,9,.88);color:#F8F5E6;font-size:.74rem;font-weight:600;
  padding:6px 10px;border-radius:8px;white-space:nowrap;
  opacity:0;pointer-events:none;transition:opacity .15s ease;
}
.hotspot:hover::after,.hotspot:focus-visible::after{opacity:1;}
.viewer-chrome{position:absolute;inset:0;z-index:4;pointer-events:none;display:flex;flex-direction:column;justify-content:space-between;padding:16px;}
.viewer-chrome > *{pointer-events:auto;}
.viewer-topbar{display:flex;justify-content:space-between;align-items:flex-start;}
.viewer-badge{background:rgba(10,14,9,.6);backdrop-filter:blur(6px);color:#F8F5E6;font-size:.76rem;font-weight:600;padding:7px 12px;border-radius:100px;display:flex;align-items:center;gap:6px;}
.viewer-badge svg{width:13px;height:13px;}
.viewer-close{width:36px;height:36px;border-radius:50%;background:rgba(10,14,9,.6);backdrop-filter:blur(6px);color:#F8F5E6;border:none;display:flex;align-items:center;justify-content:center;}
.viewer-close:hover{background:var(--clay);}
.viewer-controls{display:flex;justify-content:center;gap:10px;}
.viewer-ctrl{width:38px;height:38px;border-radius:50%;background:rgba(10,14,9,.6);backdrop-filter:blur(6px);color:#F8F5E6;border:1px solid rgba(241,238,220,.2);display:flex;align-items:center;justify-content:center;transition:background .15s ease;}
.viewer-ctrl svg{width:16px;height:16px;}
.viewer-ctrl:hover{background:var(--forest-bright);}
.viewer-compass{position:absolute;top:16px;left:50%;transform:translateX(-50%);width:52px;height:52px;border-radius:50%;background:rgba(10,14,9,.55);backdrop-filter:blur(6px);border:1px solid rgba(241,238,220,.25);display:flex;align-items:center;justify-content:center;}
.viewer-compass svg{width:22px;height:22px;}
.scenebar{display:flex;gap:10px;padding:14px 16px;background:var(--surface-2);overflow-x:auto;}
.scenebar-item{flex:none;width:118px;cursor:pointer;border-radius:10px;overflow:hidden;border:2px solid transparent;opacity:.65;transition:opacity .15s ease,border-color .15s ease;}
.scenebar-item.active{opacity:1;border-color:var(--gold-bright);}
.scenebar-item:hover{opacity:1;}
.scenebar-thumb{aspect-ratio:16/10;position:relative;}
.scenebar-label{font-size:.7rem;font-weight:600;color:var(--ink);padding:5px 7px;background:var(--surface);}
.viewer-caption{padding:16px 20px 20px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;align-items:flex-end;background:var(--surface);}
.viewer-caption h3{color:var(--ink);font-size:1.15rem;}
.viewer-caption p{color:var(--ink-soft);font-size:.86rem;margin-top:4px;max-width:52ch;}

/* ============ NEWS ============ */
.news{background:var(--surface-2);}
.news-grid{display:grid;grid-template-columns:1.3fr 1fr 1fr;gap:0;border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden;background:var(--surface);}
.news-item{padding:26px 26px;border-left:1px solid var(--line);display:flex;flex-direction:column;gap:10px;}
.news-item:first-child{border-left:none;}
.news-date{font-size:.72rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--clay);}
.news-item h4{font-size:1.02rem;font-weight:600;line-height:1.35;}
.news-item p{font-size:.86rem;color:var(--ink-soft);}
@media(max-width:900px){.news-grid{grid-template-columns:1fr;}.news-item{border-left:none;border-top:1px solid var(--line);}.news-item:first-child{border-top:none;}}

/* ============ FOOTER ============ */
footer{background:var(--forest);color:rgba(241,238,220,.82);}
/* Ba cột, không bốn: cột "Chính quyền" đã bỏ vì cả bốn liên kết của nó là
   `href="#"` — chân trang hứa bốn trang không tồn tại. */
.foot-top{padding-block:64px 40px;display:grid;grid-template-columns:1.6fr 1fr 1fr;gap:36px;}
@media(max-width:860px){.foot-top{grid-template-columns:repeat(2,minmax(0,1fr));}}
/* Một ô `1fr` không co xuống dưới bề rộng nội dung tối thiểu, mà cột "Liên hệ"
   chứa địa chỉ email 231px không ngắt được: ở 320px chân trang đẩy cả trang
   tràn ngang. Một cột, và cho chuỗi dài được phép ngắt. */
@media(max-width:640px){
  .foot-top{grid-template-columns:minmax(0,1fr);gap:28px;}
  .foot-col ul{overflow-wrap:anywhere;}
}
.foot-brand{display:flex;align-items:center;gap:10px;font-family:'Fraunces',serif;font-weight:700;font-size:1.2rem;color:#F8F5E6;}
/* Cùng logo với header. Nền ô logo (#0F7A45) trùng nền footer nên thêm viền
   mảnh để ô vẫn đọc được là một ô. */
.foot-brand .mark{width:34px;height:34px;flex:none;border-radius:8.5px;box-shadow:0 0 0 1px rgba(241,238,220,.35);}
.foot-brand small{display:block;font-family:'Be Vietnam Pro',sans-serif;font-weight:500;font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:rgba(241,238,220,.6);}
.foot-col h5{font-size:.76rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--gold-bright);margin-bottom:14px;}
.foot-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px;font-size:.88rem;}
.foot-col a:hover{color:#fff;}
.foot-p{font-size:.86rem;color:rgba(241,238,220,.68);margin-top:14px;max-width:34ch;}
.foot-bottom{border-top:1px solid rgba(241,238,220,.16);padding-block:18px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;font-size:.78rem;color:rgba(241,238,220,.55);}

.breadcrumb{background:var(--surface-2);border-bottom:1px solid var(--line);}
.breadcrumb-inner{display:flex;align-items:center;gap:8px;padding-block:13px;font-size:.83rem;color:var(--ink-faint);flex-wrap:wrap;}
.breadcrumb-inner a{color:var(--ink-soft);font-weight:500;}
.breadcrumb-inner a:hover{color:var(--forest);}
.breadcrumb-inner .current{color:var(--ink);font-weight:600;}
.page-header{padding:52px 0 8px;}
.page-header h1{font-size:clamp(2rem,4vw,2.7rem);font-weight:700;margin-top:10px;}
.page-header .sub{max-width:62ch;color:var(--ink-soft);margin-top:14px;font-size:1.02rem;}

/* light-background filter tabs (listing pages) */
.tabbar-light{display:flex;gap:8px;flex-wrap:wrap;margin:34px 0 6px;}
.tab-light{display:flex;align-items:center;gap:8px;padding:9px 17px;border-radius:100px;background:var(--surface-2);border:1px solid var(--line);color:var(--ink-soft);font-weight:600;font-size:.85rem;transition:background .15s ease,color .15s ease,border-color .15s ease;}
.tab-light svg{width:15px;height:15px;}
.tab-light[aria-selected="true"]{background:var(--forest);color:#fff;border-color:var(--forest);}
.tab-light:hover:not([aria-selected="true"]){border-color:var(--forest);color:var(--forest);}

/* pagination */
.pagination{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:52px;flex-wrap:wrap;}
.page-num{min-width:38px;height:38px;padding:0 8px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:.86rem;color:var(--ink-soft);border:1px solid var(--line);background:var(--surface);transition:background .15s ease,color .15s ease,border-color .15s ease;}
.page-num.active{background:var(--forest);color:#fff;border-color:var(--forest);}
.page-num:hover:not(.active){border-color:var(--forest);color:var(--forest);}

/* two-column detail layout */
.detail-layout{display:grid;grid-template-columns:1.9fr minmax(0,1fr);gap:48px;align-items:start;margin-top:36px;}
.detail-layout > *{min-width:0;}
@media(max-width:900px){.detail-layout{grid-template-columns:minmax(0,1fr);}}
.prose h2{font-size:1.28rem;font-weight:600;margin:30px 0 12px;}
.prose h2:first-child{margin-top:0;}
.prose p{color:var(--ink-soft);margin-bottom:14px;line-height:1.75;}

/* rich-HTML article body. Danh sách thẻ được phép nay ở
   django-backend/apps/core/sanitize.py (ALLOWED_CONTENT_TAGS) — dùng chung
   cho cả tin tức lẫn mô tả di tích, không còn là hằng số riêng của news. */
.article-body p{color:var(--ink-soft);margin-bottom:16px;line-height:1.75;}
.article-body p:last-child{margin-bottom:0;}
.article-body strong{color:var(--ink);font-weight:700;}
.article-body em{font-style:italic;}
.article-body u{text-decoration:underline;}
.article-body s{text-decoration:line-through;}
.article-body h1,.article-body h2,.article-body h3,.article-body h4,.article-body h5,.article-body h6{
  color:var(--ink);font-weight:600;margin:30px 0 12px;text-wrap:balance;
}
.article-body h1:first-child,.article-body h2:first-child,.article-body h3:first-child,
.article-body h4:first-child,.article-body h5:first-child,.article-body h6:first-child{margin-top:0;}
.article-body h1{font-size:1.9rem;}
.article-body h2{font-size:1.6rem;}
.article-body h3{font-size:1.32rem;}
.article-body h4{font-size:1.12rem;}
.article-body h5{font-size:1rem;}
.article-body h6{font-size:.92rem;text-transform:uppercase;letter-spacing:.04em;}
.article-body ul,.article-body ol{margin:0 0 16px;padding-left:1.4em;color:var(--ink-soft);line-height:1.75;}
.article-body ul{list-style:disc;}
.article-body ol{list-style:decimal;}
.article-body li{margin-bottom:6px;}
.article-body li:last-child{margin-bottom:0;}
.article-body blockquote{
  margin:0 0 16px;padding:4px 0 4px 18px;
  border-left:3px solid var(--forest);
  color:var(--ink-soft);font-style:italic;
}
.article-body a{color:var(--forest);text-decoration:underline;text-underline-offset:2px;}
.article-body a:hover{color:var(--forest-bright);}
.article-body img{border-radius:var(--radius-md);margin:8px 0 16px;}

/* --- HTML giàu định dạng do RichTextEditor sinh ra -----------------------
   Danh sách thẻ đầy đủ nằm ở django-backend/apps/core/sanitize.py. Thẻ nào
   qua được bộ lọc đó mà không có kiểu ở đây thì lên trang công khai trần
   trụi, nên hai tệp phải đi cùng nhau. */

/* Khung ảnh/video. Bề rộng là `style="width:N%"` nội tuyến do người biên tập
   kéo tay đặt; ở đây chỉ lo căn lề và phần chú thích. */
.article-body .rt-figure{margin:20px 0;max-width:100%;}
.article-body .rt-figure img,.article-body .rt-figure video{
  display:block;width:100%;height:auto;border-radius:var(--radius-md);margin:0;
}
.article-body .rt-figure figcaption{
  margin-top:8px;font-size:.82rem;line-height:1.5;color:var(--ink-faint);text-align:center;
}
.article-body .rt-figure figcaption:empty{display:none;}
/* Căn lề bằng lề tự động chứ không phải `float`: chữ chảy vòng quanh ảnh trên
   một cột hẹp thì rối hơn là đẹp, và bố cục khối cho ra đúng thứ người biên
   tập nhìn thấy trong trình soạn thảo. */
.article-body .rt-align-center{margin-left:auto;margin-right:auto;}
.article-body .rt-align-left{margin-right:auto;}
.article-body .rt-align-right{margin-left:auto;}

/* Trên màn hình hẹp, một khung rộng 25% là một con tem. `!important` ở đây là
   cần: bề rộng kia là style nội tuyến, không có cách nào khác để thắng nó. */
@media(max-width:640px){
  .article-body .rt-figure{width:100% !important;}
}

/* Bảng */
.article-body table{width:100%;border-collapse:collapse;margin:0 0 18px;font-size:.9rem;}
.article-body th,.article-body td{
  border:1px solid var(--line);padding:8px 10px;text-align:left;vertical-align:top;color:var(--ink-soft);
}
.article-body th{background:var(--surface-2);color:var(--ink);font-weight:600;}
.article-body td p,.article-body th p{margin-bottom:0;}
/* Bảng nhiều cột không co được xuống bề ngang điện thoại; cho nó cuộn ngang
   thay vì để nó đẩy vỡ cả trang. */
@media(max-width:640px){
  .article-body table{display:block;overflow-x:auto;}
}

/* Mã */
.article-body code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.86em;
  background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:1px 5px;color:var(--ink);
}
.article-body pre{
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius-md);
  padding:14px 16px;margin:0 0 18px;overflow-x:auto;
}
.article-body pre code{background:none;border:none;padding:0;font-size:.84rem;line-height:1.6;}

/* Đường kẻ ngang, chỉ số trên/dưới */
.article-body hr{border:none;border-top:1px solid var(--line);margin:26px 0;}
.article-body sub,.article-body sup{font-size:.75em;line-height:0;}
.article-body sup{vertical-align:super;}
.article-body sub{vertical-align:sub;}

/* Màu chữ. Nội dung chỉ mang cái TÊN (`rt-color-do`); sắc độ thật do đây
   quyết định, và phải khác nhau giữa hai chế độ. Bảng màu chọn cho nền sáng
   đo được 5.0-7.6:1 trên nền trắng nhưng chỉ 2.4-3.7:1 trên nền tối — dưới
   ngưỡng 4.5:1 của WCAG AA. Đó chính là lý do màu không được lưu thành mã
   hex trong nội dung: một giá trị đã nằm trong `style` nội tuyến thì không
   quy tắc nào ở đây với tới được nữa. */
.article-body .rt-color-do{color:#B91C1C;}
.article-body .rt-color-cam{color:#C2410C;}
.article-body .rt-color-xanh-la{color:#15803D;}
.article-body .rt-color-xanh-duong{color:#1D4ED8;}
.article-body .rt-color-xam{color:#4B5563;}

/* Màu TỰ CHỌN thì không có tên để ánh xạ lại, nên nó là mã màu nội tuyến và
   không quy tắc nào ở đây ghi đè được (trừ khi dùng !important, thứ sẽ xoá
   luôn lựa chọn của người viết). Nâng độ sáng là cách giữ được sắc màu họ
   chọn mà vẫn đọc được trên nền tối. Chỉ nhắm span có `style` màu — màu có
   tên dùng `class` nên không dính. */

/* Sắc độ sáng hơn cho nền tối, giữ nguyên tông màu. */
:root[data-theme="dark"] .article-body .rt-color-do{color:#F87171;}
:root[data-theme="dark"] .article-body .rt-color-cam{color:#FB923C;}
:root[data-theme="dark"] .article-body .rt-color-xanh-la{color:#4ADE80;}
:root[data-theme="dark"] .article-body .rt-color-xanh-duong{color:#60A5FA;}
:root[data-theme="dark"] .article-body .rt-color-xam{color:#9CA3AF;}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .article-body .rt-color-do{color:#F87171;}
  :root:not([data-theme="light"]) .article-body .rt-color-cam{color:#FB923C;}
  :root:not([data-theme="light"]) .article-body .rt-color-xanh-la{color:#4ADE80;}
  :root:not([data-theme="light"]) .article-body .rt-color-xanh-duong{color:#60A5FA;}
  :root:not([data-theme="light"]) .article-body .rt-color-xam{color:#9CA3AF;}
}

/* Chữ tô nền. Màu nền tới từ style nội tuyến và luôn là màu nhạt; Tiptap kèm
   theo `color:inherit`, thứ mà ở giao diện tối nghĩa là chữ sáng trên nền
   nhạt — không đọc được. Ghim màu chữ tối, và `!important` vì đối thủ là một
   style nội tuyến. */
.article-body mark{border-radius:4px;padding:0 3px;color:#1A1A1A !important;}


.aside{display:flex;flex-direction:column;gap:20px;}
@media(min-width:901px){.aside{position:sticky;top:88px;}}
.aside-card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius-md);padding:22px;}
.aside-card h3{font-size:.78rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--forest);margin-bottom:14px;}
.aside-fact{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-top:1px solid var(--line);font-size:.86rem;}
.aside-fact:first-of-type{border-top:none;padding-top:0;}
.aside-fact .k{color:var(--ink-faint);}
.aside-fact .v{color:var(--ink);font-weight:600;text-align:right;}
/* Nhãn trái / giá trị phải căn lề phải: ở bề ngang điện thoại cả hai cùng
   xuống dòng và cụm chữ so le hai bên, rất khó đọc. Xếp dọc, cùng căn trái. */
@media(max-width:640px){
  .aside-fact{flex-direction:column;gap:2px;}
  .aside-fact .v{text-align:left;}
}
.aside-cta{margin-top:14px;width:100%;justify-content:center;}
.related-mini{display:flex;gap:12px;padding:10px 0;border-top:1px solid var(--line);align-items:center;}
.related-mini:first-of-type{border-top:none;padding-top:0;}
.related-mini .thumb{width:56px;height:56px;border-radius:10px;flex:none;position:relative;overflow:hidden;}
.related-mini h4{font-size:.84rem;font-weight:600;line-height:1.35;}
.related-mini p{font-size:.72rem;color:var(--ink-faint);margin-top:2px;}

/* detail hero banner */
.detail-hero{position:relative;height:min(46vh,400px);min-height:260px;border-radius:var(--radius-lg);overflow:hidden;margin-top:26px;}
.detail-hero .scene{position:absolute;inset:0;}
.detail-hero-shade{position:absolute;inset:0;background:linear-gradient(0deg,rgba(10,14,9,.72) 0%,rgba(10,14,9,.05) 60%);}
.detail-hero-content{position:absolute;left:0;right:0;bottom:0;padding:28px 32px;color:#fff;z-index:1;}
.detail-hero-content .eyebrow{color:var(--gold-bright);}
.detail-hero-content h1{color:#fff;font-size:clamp(1.7rem,3.2vw,2.5rem);}
.detail-hero-content .meta{display:flex;gap:16px;margin-top:10px;font-size:.86rem;color:rgba(255,255,255,.82);flex-wrap:wrap;}

.detail-hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
.detail-hero-content .meta a{color:var(--gold-bright);}

/* section + group headings above the media grids */
.media-section-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;font-size:1.28rem;font-weight:600;margin-bottom:14px;}
/* Ba phần tử (tên mục, số đếm, lối sang thư viện) với `space-between`: trên
   điện thoại phần tử thứ ba rơi xuống dòng dưới và dạt về trái, còn hai phần
   tử trên bị đẩy ra hai mép — mỗi mục xếp một kiểu. Xếp từ trái sang. */
@media(max-width:640px){.media-section-head{justify-content:flex-start;gap:4px 12px;}}
.media-section-all{font-size:.82rem;font-weight:500;color:var(--forest);white-space:nowrap;}
.media-group-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:1rem;font-weight:600;margin:18px 0 10px;}
.media-count{font-size:.78rem;font-weight:500;color:var(--ink-faint);}

/* spoken-guide card - a card, deliberately not a .mini-media tile */
.audio-card{display:flex;gap:14px;align-items:center;padding:14px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-2);cursor:pointer;}
.audio-card:hover,.audio-card:focus-visible{border-color:var(--forest);}
.audio-card-cover{position:relative;flex:0 0 84px;width:84px;aspect-ratio:1/1;border-radius:var(--radius-sm);overflow:hidden;}
.audio-card-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
.audio-card-cover .scene{position:absolute;inset:0;}
.audio-card-cover .medbadge{width:24px;height:24px;top:6px;right:6px;}
.audio-card-cover .medbadge svg{width:12px;height:12px;}
/* `flex:1` chứ không chỉ `min-width:0`: thiếu nó thì khối này co về bề rộng
   nội dung và thanh <audio> bên trong chỉ còn khoảng 180px — vừa đủ hiện nút
   phát và cái menu ba chấm, không còn chỗ cho thanh kéo tua. */
.audio-card-body{flex:1 1 auto;min-width:0;}
.audio-card-title{font-weight:600;font-size:.94rem;}
.audio-card-list{margin:6px 0 0;padding-left:18px;font-size:.8rem;color:var(--ink-soft);}
.audio-card-list li{margin-top:2px;}

/* Phải đứng SAU các luật .audio-card-* ở trên, không phải trong khối thư
   viện phía trước: `.audio-card-cover{flex:0 0 84px}` là shorthand, nên một
   `flex-basis:auto` viết trước nó trong tệp sẽ bị nó ghi đè và thẻ không
   bao giờ xếp dọc trên điện thoại. */
.audio-block .audio-card{align-items:flex-start;}
.audio-card audio{width:100%;margin-top:10px;}
.audio-card-list a{color:var(--ink-soft);}
.audio-card-list a:hover{color:var(--forest);}
@media(max-width:640px){
  /* `align-items:stretch`: trong flex cột, `center` của luật gốc làm con co
     lại vừa nội dung — thanh <audio> chỉ còn 170px giữa một thẻ rộng 354px. */
  .audio-card{flex-direction:column;align-items:stretch;}
  .audio-block .audio-card{align-items:stretch;}
  .audio-card-cover{flex:0 0 auto;width:100%;aspect-ratio:16/9;}
}

/* aside: thumbnail list (nearby places) */
.aside-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px;}
.aside-list a{display:flex;gap:10px;align-items:center;}
.aside-list img,.aside-list .scene{flex:0 0 52px;width:52px;height:52px;border-radius:var(--radius-sm);object-fit:cover;display:block;}
.aside-list-text{min-width:0;display:flex;flex-direction:column;}
.aside-list-text strong{font-size:.85rem;font-weight:600;line-height:1.3;}
.aside-list-text small{font-size:.74rem;color:var(--ink-faint);}

/* mini media grid used inside destination detail */
.mini-media-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:8px;}
@media(max-width:640px){.mini-media-grid{grid-template-columns:repeat(2,1fr);}}
.mini-media{position:relative;aspect-ratio:1/1;border-radius:var(--radius-sm);overflow:hidden;cursor:pointer;}
.mini-media .scene{position:absolute;inset:0;}
.mini-media .medbadge{width:26px;height:26px;top:8px;right:8px;}
.mini-media .medbadge svg{width:13px;height:13px;}

/* map placeholder */
.map-placeholder{position:relative;aspect-ratio:16/10;border-radius:var(--radius-md);overflow:hidden;border:1px solid var(--line);background:linear-gradient(160deg,#EAF3EC 0%,#D9EBE0 100%);}
:root[data-theme="dark"] .map-placeholder{background:linear-gradient(160deg,#182A1E 0%,#10190F 100%);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .map-placeholder{background:linear-gradient(160deg,#182A1E 0%,#10190F 100%);}}
.map-placeholder svg{position:absolute;inset:0;width:100%;height:100%;}
.map-pin{position:absolute;left:50%;top:46%;transform:translate(-50%,-100%);color:var(--clay);filter:drop-shadow(0 3px 6px rgba(0,0,0,.25));}
.map-pin svg{width:34px;height:34px;}

/* contact form */
.form-grid{display:flex;flex-direction:column;gap:16px;margin-top:26px;}
.form-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;}
@media(max-width:640px){.form-row{grid-template-columns:minmax(0,1fr);}}
.field{display:flex;flex-direction:column;gap:6px;}
.field label{font-size:.82rem;font-weight:600;color:var(--ink-soft);}
.field input,.field textarea{
  border:1px solid var(--line-strong);border-radius:10px;padding:12px 14px;
  font-family:inherit;font-size:.92rem;color:var(--ink);background:var(--surface);
  transition:border-color .15s ease,box-shadow .15s ease;
}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--forest);box-shadow:0 0 0 3px var(--forest-pale);}
.field textarea{resize:vertical;min-height:130px;font-family:inherit;}
/* `cols` mặc định của <textarea> là 20 ký tự — đó là bề rộng nội tại tối
   thiểu, và ô lưới `1fr` (của .form-row lẫn .detail-layout) không co xuống
   dưới nó: ở 320px cả cột nội dung rộng 321px, tràn ra ngoài màn hình. */
.field input,.field textarea{min-width:0;}
.contact-item{display:flex;gap:14px;padding:16px 0;border-top:1px solid var(--line);}
.contact-item:first-child{border-top:none;padding-top:0;}
.contact-item .ic{width:38px;height:38px;border-radius:50%;background:var(--forest-pale);color:var(--forest);display:flex;align-items:center;justify-content:center;flex:none;}
.contact-item .ic svg{width:17px;height:17px;}
.contact-item h4{font-size:.9rem;font-weight:600;}
.contact-item p{font-size:.85rem;color:var(--ink-soft);margin-top:2px;}

/* article (news detail) */
.article-hero{aspect-ratio:16/7;border-radius:var(--radius-lg);overflow:hidden;position:relative;margin:26px 0 32px;}
@media(max-width:640px){.article-hero{aspect-ratio:4/3;}}
.article-meta{display:flex;gap:14px;align-items:center;font-size:.82rem;color:var(--ink-faint);margin-top:14px;flex-wrap:wrap;}
.article-meta .tag{color:var(--clay);font-weight:600;text-transform:uppercase;letter-spacing:.05em;font-size:.72rem;}

/* helper: mockup ribbon so this reads clearly as a design mockup */
.mock-ribbon{
  position:fixed;bottom:18px;right:18px;z-index:200;
  background:var(--surface);color:var(--ink-soft);
  border:1px solid var(--line-strong);border-radius:100px;
  padding:9px 16px;font-size:.74rem;font-weight:600;
  box-shadow:var(--shadow);display:flex;align-items:center;gap:8px;
}
.mock-ribbon span.dot{width:7px;height:7px;border-radius:50%;background:var(--clay);}
@media(max-width:640px){.mock-ribbon{left:18px;right:18px;justify-content:center;}}


/* ============ HERITAGE CARD ADD-ONS (learned from Yen Bai public site) ============ */
.rank-badge{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 13px;border-radius:100px;font-size:.72rem;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;
  background:rgba(12,16,10,.62);backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.22);
}
.rank-badge svg{width:13px;height:13px;}
.rank-national{color:var(--gold-bright);border-color:rgba(217,169,74,.55);}
.rank-provincial{color:#EDEBDD;border-color:rgba(255,255,255,.3);}
/* on light (non-photo) surfaces — e.g. sidebar fact rows — swap to a flat, opaque treatment */
.aside-card .rank-badge,.detail-main .rank-badge{
  background:none;backdrop-filter:none;border:none;padding:0;
}
.aside-card .rank-national,.detail-main .rank-national{color:var(--gold);}
.aside-card .rank-provincial,.detail-main .rank-provincial{color:var(--indigo);}

.dest-location{display:flex;align-items:center;gap:5px;font-size:.78rem;color:var(--ink-faint);font-weight:600;}
.dest-location svg{width:12px;height:12px;flex:none;color:var(--clay);}

.dest-stats{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:auto;padding-top:12px;border-top:1px solid var(--line);}
.stat-chip{display:flex;align-items:center;gap:5px;font-size:.75rem;font-weight:600;color:var(--ink-soft);}
.stat-chip svg{width:13px;height:13px;color:var(--forest);}

.status-pill{display:inline-flex;align-items:center;gap:5px;font-size:.7rem;font-weight:700;padding:4px 10px;border-radius:100px;}
.status-pill svg{width:10px;height:10px;}
.status-live{background:var(--forest-pale);color:var(--forest);}
.status-pending{background:var(--surface-2);color:var(--ink-faint);border:1px solid var(--line);}

/* national feature grid (priority placement) */
.national-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;}
@media(max-width:900px){.national-grid{grid-template-columns:1fr;}}
.national-card{
  position:relative;border-radius:var(--radius-lg);overflow:hidden;
  border:1px solid var(--line);background:var(--surface);
  box-shadow:0 20px 40px -28px rgba(20,28,22,.35);
  transition:transform .2s ease, box-shadow .2s ease;
}
.national-card:hover{transform:translateY(-4px);}
.national-card::before{
  content:"";position:absolute;inset:0 0 auto 0;height:5px;
  background:linear-gradient(90deg,var(--gold),var(--gold-bright),var(--gold));
}
.national-card .dest-media{aspect-ratio:16/11;}
.national-card .dest-body{padding:20px 22px 22px;display:flex;flex-direction:column;gap:8px;}
.national-card .dest-body h3{font-size:1.22rem;}

/* compact directory rows (provincial tier) */
.area-group{margin-top:44px;}
.area-heading{
  display:flex;align-items:baseline;gap:10px;margin-bottom:16px;
  padding-bottom:10px;border-bottom:1px solid var(--line);
}
.area-heading h3{font-size:1.02rem;font-weight:700;}
.area-heading .count{font-size:.78rem;color:var(--ink-faint);font-weight:600;}
.heritage-row-list{display:flex;flex-direction:column;}
.heritage-row{
  display:flex;align-items:center;gap:16px;padding:14px 6px;
  border-top:1px solid var(--line);transition:background .15s ease;
}
.heritage-row:first-child{border-top:none;}
.heritage-row:hover{background:var(--surface-2);}
.heritage-row .thumb{width:64px;height:64px;border-radius:12px;flex:none;position:relative;overflow:hidden;}
.heritage-row .thumb .scene{position:absolute;inset:0;}
.heritage-row .info{flex:1;min-width:0;}
.heritage-row .info h4{font-size:.96rem;font-weight:600;}
.heritage-row .info .meta-line{font-size:.78rem;color:var(--ink-faint);margin-top:3px;display:flex;flex-wrap:wrap;gap:4px 10px;}
.heritage-row .chev{flex:none;color:var(--ink-faint);}
@media(max-width:640px){
  .heritage-row .thumb{width:52px;height:52px;}
}

/* pairing note (dinh + chua cung lang) */
.pair-note{
  display:flex;align-items:center;gap:10px;margin-top:20px;padding:14px 16px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius-sm);
  font-size:.86rem;color:var(--ink-soft);
}
.pair-note svg{width:18px;height:18px;flex:none;color:var(--forest);}
.pair-note a{color:var(--forest);font-weight:600;}

/* sub-nav within listing (tier filter) */
.tier-tabs{display:flex;gap:8px;margin:8px 0 4px;}

.dest-grid-5{display:grid;grid-template-columns:repeat(5,1fr);gap:20px;}
@media(max-width:1100px){.dest-grid-5{grid-template-columns:repeat(3,1fr);}}
@media(max-width:640px){.dest-grid-5{grid-template-columns:repeat(2,1fr);}}

.dest-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;}
@media(max-width:900px){.dest-grid-3{grid-template-columns:1fr;}}

.media-badge-overlay{position:absolute;top:12px;left:12px;z-index:2;}

/* Real light/dark toggle button (main.js), added on top of the mockup's
   port - the mockup only ever scaffolded the CSS custom-property tokens
   for both modes, never a way for a visitor to choose one explicitly.
   Styled identically to .topbar-links a so it sits naturally among the
   language/search links. */
.topbar-links button[data-theme-toggle]{
  background:none;border:none;padding:0;margin:0;color:inherit;
  font:inherit;cursor:pointer;display:inline-flex;align-items:center;
}
.topbar-links button[data-theme-toggle]:hover{color:#fff;}

.scene-placeholder {
  background: linear-gradient(135deg, var(--color-surface-muted, #e8e4d8), var(--color-surface, #f6f3ea));
}

.dest-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}

.rank-filter{display:flex;flex-wrap:wrap;gap:10px;margin:24px 0;}
.rank-filter-chip{
  padding:8px 18px;border-radius:100px;
  border:1px solid var(--surface-2);background:var(--surface);
  color:var(--ink-soft);font-weight:600;font-size:.85rem;text-decoration:none;
}
.rank-filter-chip:hover{border-color:var(--forest);color:var(--forest);}
.rank-filter-chip.active{background:var(--forest);color:#F3EFDD;border-color:var(--forest);}

.site-map{aspect-ratio:16/10;border-radius:var(--radius-md);overflow:hidden;border:1px solid var(--line);}
/* Khung khi nguồn tile trả lỗi — xem `tileerror` trong leaflet-init.js. Một
   lưới xám im lặng không nói được gì; dòng chữ này nói, và liên kết chỉ đường
   bên trong vẫn chạy vì nó không dùng tile nào cả. */
.site-map-loi{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  background:var(--surface-soft,var(--surface));border:1px dashed var(--line-strong);
  color:var(--ink-faint);font-size:.86rem;text-align:center;padding:16px;
}
.site-map-loi p{margin:0;}
.site-map-loi a{color:var(--forest);font-weight:600;}

.media-viewer-modal{
  /* Above 1000: Leaflet gives `.leaflet-control` z-index 1000, and the
     heritage detail page has a map on it. At 100 the map's zoom control
     painted over the open viewer and swallowed clicks aimed at the video
     player underneath it (caught driving the real page, 13/09/2026). */
  position:fixed;inset:0;z-index:1100;
  background:rgba(30,38,30,.6);
  display:none;align-items:center;justify-content:center;
  padding:24px;
}
.media-viewer-modal.open{display:flex;}
.media-viewer-panel{
  position:relative;width:min(1080px,100%);
  background:var(--surface);border-radius:var(--radius-lg);overflow:hidden;
  border:1px solid var(--line);
  box-shadow:0 40px 80px -20px rgba(20,28,22,.35);
}
.media-viewer-mount{aspect-ratio:16/9;background:#0A0E09;}
.media-viewer-close{position:absolute;top:16px;right:16px;z-index:4;}

/* ============ LIBRARY DETAIL (sub-project 5) ============ */
.library-detail{padding-block:32px 96px;}
.library-viewer-panel{width:100%;}
.library-viewer-mount{aspect-ratio:16/9;background:#0A0E09;}
.library-viewer-fallback{display:flex;align-items:center;justify-content:center;height:100%;min-height:240px;color:#F8F5E6;padding:24px;text-align:center;}
.library-fallback{aspect-ratio:16/9;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;background:var(--surface-2);color:var(--ink-soft);text-align:center;padding:24px;}
.library-detail-head{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-top:26px;align-items:flex-end;}
.library-detail-head h1{font-size:1.7rem;}
.library-detail-head .sub{color:var(--ink-soft);margin-top:8px;max-width:60ch;}
.library-detail-head .sub a{color:var(--forest);font-weight:600;}
.library-related-title{font-size:1.15rem;font-weight:600;margin-top:56px;margin-bottom:20px;}

.library-detail-meta{display:flex;gap:16px;flex-wrap:wrap;margin-top:6px;font-size:.82rem;color:var(--ink-faint);}
.library-detail-meta a{color:var(--forest);}
.library-subtitle{margin-top:32px;max-width:70ch;}
.library-subtitle h2{font-size:1.1rem;font-weight:600;margin-bottom:10px;}

/* ============ MEDIA VIEWER CHROME (packages/media-viewer .mv-* hooks) ============ */
/* album/audio drivers add their own nav below the stage, so the 16:9 mount
   must stop forcing its height once one of them is inside it.
   Both mounts, not just the modal one: the library detail page puts the same
   drivers in .library-viewer-mount, where the album's stage + nav + thumb
   strip used to overflow a box still being held at 16/9. */
.media-viewer-mount:has(.mv-album),.media-viewer-mount:has(.mv-audio),
.library-viewer-mount:has(.mv-album),.library-viewer-mount:has(.mv-audio){aspect-ratio:auto;}

/* Khung phát khoá cứng 16/9 mà không có trần theo chiều cao khung nhìn: trên
   điện thoại xoay ngang (844×390 — đúng tư thế người ta xem video) nó cao
   474px trong một khung nhìn cao 390px, nên thanh điều khiển nằm dưới mép
   màn hình và phải cuộn mới bấm được nút kế tiếp. Chặn theo `svh` (chiều cao
   khung nhìn lúc thanh địa chỉ của trình duyệt đang hiện, nếu không thì trần
   này rộng hơn màn hình thật). Ảnh đã `max-height:100%`, <video> mặc định
   `object-fit:contain`, còn canvas của PSV/three.js tự nghe ResizeObserver —
   nên chỉ đóng khung lại chứ không có gì méo.
   Trừ .mv-album/.mv-audio: khung của chúng bao cả thanh điều khiển và dải
   ảnh nhỏ bên dưới, chặn ở đây sẽ cắt mất, trần của chúng nằm ở .mv-stage. */
.media-viewer-mount:not(:has(.mv-album,.mv-audio)),
.library-viewer-mount:not(:has(.mv-album,.mv-audio)){
  width:100%;
  max-height:calc(100vh - 96px);
  max-height:calc(100svh - 96px);
}
.mv-stage{max-height:calc(100vh - 150px);max-height:calc(100svh - 150px);}
.mv-album{display:flex;flex-direction:column;background:#0A0E09;}
.mv-stage{position:relative;aspect-ratio:16/9;background:#0A0E09;overflow:hidden;display:flex;align-items:center;justify-content:center;}
.mv-stage img{display:block;max-width:100%;max-height:100%;margin:auto;}

/* A 360 photo needs the stage, not a letterbox.
   Measured on the Laravel site (commit 0590a962): the project owner reported
   our panorama viewer felt wrong beside a 3DVista tour, and the difference
   was not the projection or the field of view - both matched - it was that
   the tour filled the whole window while ours sat in a 16/9 box halfway down
   a long page. A 360 photo seen through a slot reads as a photo; the same
   photo at near-full height reads as standing in the place. */
.mv-album--panorama .mv-stage{aspect-ratio:auto;height:min(78vh,860px);min-height:min(340px,calc(100vh - 150px));min-height:min(340px,calc(100svh - 150px));}
@media(max-width:700px){.mv-album--panorama .mv-stage{height:min(62vh,520px);}}

/* An uploaded tour bundle brings its own UI, so it gets the whole box and
   a taller one than 16/9 - it is the page's subject, not an illustration. */
.mv-tour-frame{display:block;width:100%;height:100%;border:0;background:#0A0E09;}
.library-viewer-mount:has(.mv-tour-frame){aspect-ratio:auto;height:min(78vh,860px);min-height:360px;}
@media(max-width:700px){.library-viewer-mount:has(.mv-tour-frame){height:min(70vh,560px);}}
/* Tour dựng từ `scene_config` không phải iframe: nó là `.psv-container` nằm
   thẳng trong khung, nên không dính luật trên và vẫn bị nhốt trong ô 16/9 —
   một tour 360 cao 218px trên điện thoại. Cùng lập luận với panorama ở trên:
   nhìn qua khe thì là tấm ảnh, cao gần hết màn hình mới là đang đứng ở đó. */
.library-viewer-mount:has(> .psv-container),
.library-viewer-mount:has(> .mv-sphere-canvas){aspect-ratio:auto;height:min(78vh,860px);}
@media(max-width:700px){
  .library-viewer-mount:has(> .psv-container),
  .library-viewer-mount:has(> .mv-sphere-canvas){height:min(70vh,560px);}
}
.mv-nav{display:flex;align-items:center;justify-content:center;gap:14px;padding:12px 16px;background:var(--surface);color:var(--ink);}
.mv-prev,.mv-next{padding:8px 18px;border-radius:100px;border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);font-weight:600;font-size:.84rem;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;}
.mv-prev:hover:not(:disabled),.mv-next:hover:not(:disabled){background:var(--forest);color:#F3EFDD;border-color:var(--forest);}
.mv-prev:disabled,.mv-next:disabled{opacity:.4;cursor:default;}
.mv-counter{font-size:.82rem;color:var(--ink-soft);font-weight:600;min-width:4ch;text-align:center;}
.mv-caption{flex:1 1 auto;min-width:0;font-size:.84rem;color:var(--ink-soft);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mv-fullscreen{padding:8px 14px;border-radius:100px;border:1px solid var(--line-strong);background:var(--surface);color:var(--ink-soft);font-weight:600;font-size:.8rem;cursor:pointer;}
.mv-fullscreen:hover{border-color:var(--forest);color:var(--forest);}
/* iOS has no element fullscreen - album.ts falls back to this class. Fixed
   rather than the real thing: no escape key, but the panorama fills the
   phone instead of sitting in a third of it. */
.mv-album--fake-fullscreen{position:fixed;inset:0;z-index:1200;border-radius:0;}
.mv-album--fake-fullscreen .mv-stage{aspect-ratio:auto;flex:1 1 auto;height:auto;}
.mv-thumbs{display:flex;gap:10px;padding:12px 16px;background:var(--surface-2);overflow-x:auto;}
.mv-thumb{flex:none;width:96px;aspect-ratio:16/10;border-radius:10px;overflow:hidden;border:2px solid transparent;padding:0;background:#1A2118;opacity:.65;cursor:pointer;transition:opacity .15s ease,border-color .15s ease;}
.mv-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.mv-thumb:hover,.mv-thumb[aria-current="true"]{opacity:1;}
.mv-thumb[aria-current="true"]{border-color:var(--gold-bright);}
/* Ở bề ngang điện thoại, hàng điều khiển có tới 5 phần tử: chú thích bị cắt
   còn "Cổng…" và nút toàn màn hình xuống hai dòng. Cho chú thích đứng riêng
   một dòng phía trên, các nút gọn lại vừa một hàng. */
@media(max-width:640px){
  .mv-nav{flex-wrap:wrap;gap:8px;}
  .mv-caption{order:-1;flex-basis:100%;white-space:normal;}
  /* Không còn `.mv-skip-*` ở đây: hai nút đó thuộc trình phát âm thanh, nay
     là nút tròn 38px chứ không phải nút chữ, và `padding` của luật này làm
     méo chúng. Cỡ cho màn hẹp của chúng nằm ở `@media(max-width:520px)`. */
  .mv-prev,.mv-next,.mv-fullscreen{padding:8px 12px;font-size:.78rem;}
}
/* Thanh điều khiển video 360 (sphere-video.ts) dựng bằng style nội tuyến, nên
   chỉ `!important` mới ghi đè được — cùng tình huống với `.rt-figure` ở trên.
   Ở bề ngang điện thoại, 6 nút 34px + thanh tua + đồng hồ không vừa một hàng:
   thanh tự xuống hai dòng, cao 90px, che 40% khung hình vốn chỉ cao 218px —
   và thanh tua thì bị ép còn một mẩu vì phải chia hàng với mấy cái nút. Cho
   thanh tua hẳn một dòng riêng, các nút gọn lại vừa hàng còn lại. */
@media(max-width:640px){
  .mv-video-controls{gap:4px !important;padding:6px 8px !important;}
  .mv-video-controls .mv-video-seek{order:-1;flex:1 1 100% !important;min-width:0 !important;}
  .mv-video-controls .mv-video-btn{width:30px !important;height:30px !important;}
  .mv-video-controls .mv-video-time{font-size:12px;}
  /* Ô chọn chất lượng chen vào hàng nút là đẩy thanh xuống ba dòng. Cho nó
     ngồi cạnh thanh tua: "Tự động (4K)" đo được 110px ở cỡ chữ này, 116 là
     dư cho nhãn rộng nhất (HD); 128 = 116 + khoảng cách 4 + margin 2+2 của
     input range + 4px dư cho lẻ điểm ảnh — không đủ chỗ cho nút phát lọt lên
     theo. `:has` để iOS, nơi không có ô chọn, giữ nguyên bố cục cũ. */
  .mv-video-controls:has(.mv-video-quality) .mv-video-seek{order:-2;flex-basis:calc(100% - 128px) !important;}
  .mv-video-controls .mv-video-quality{order:-1;width:116px;height:30px !important;font-size:12px;}
}

.mv-audio{display:flex;flex-direction:column;gap:16px;padding:24px 24px 8px;background:var(--surface);color:var(--ink);}
/* `controls` đã tắt (drivers/audio.ts), nên thẻ không vẽ gì — nhưng nó vẫn
   phải ở trong DOM để phát. `display:none` chứ không chỉ để mặc định: một
   `<audio>` không controls vẫn chiếm một dòng trống trong flex column. */
.mv-audio-player{display:none;}

/* ---- đầu thẻ: ảnh bìa + tên bài ---- */
.mv-audio-head{display:flex;align-items:center;gap:16px;min-width:0;}
/* Vuông và `object-fit:cover`: ảnh bìa ở đây là ảnh bìa di tích tỉ lệ 3:2, và
   một khung 3:2 cạnh hai dòng chữ thì cao hơn phần chữ, đẩy cả thẻ ra. */
.mv-audio-art{
  flex:0 0 auto;width:88px;height:88px;border-radius:var(--radius-md);
  object-fit:cover;background:var(--line);
}
.mv-audio-meta{min-width:0;display:flex;flex-direction:column;gap:3px;}
/* `text-align:left`, không phải center như trước: tên bài nay nằm cạnh ảnh
   bìa, và chữ canh giữa bên phải một khối vuông trông như đặt lệch. */
.mv-title{
  font-family:'Be Vietnam Pro',sans-serif;font-weight:600;font-size:1.05rem;
  text-align:left;line-height:1.35;
}
.mv-audio-pos{
  margin:0;font-size:.78rem;font-weight:600;color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}

/* ---- thanh tiến độ ---- */
.mv-audio-progress{display:flex;flex-direction:column;gap:2px;}
/* `appearance:none` + tự vẽ, vì thanh mặc định của mỗi trình duyệt một kiểu
   và không ăn màu của theme. Chiều cao vùng bấm giữ 20px dù vạch chỉ 5px:
   một vạch 5px là mục tiêu không bấm nổi trên điện thoại.

   Phần đã phát tô bằng gradient đọc `--tien-do` (driver đặt biến này mỗi
   `timeupdate`). Không dùng `::-moz-range-progress` cho Firefox và gradient
   cho Chrome — một cách cho cả hai thì chỉ có một chỗ sai được. */
.mv-audio-seek{
  flex:0 0 auto;width:100%;min-width:0;height:20px;margin:0;padding:0;
  appearance:none;-webkit-appearance:none;background:transparent;cursor:pointer;
}
.mv-audio-seek::-webkit-slider-runnable-track{
  height:5px;border-radius:3px;
  background:linear-gradient(to right,
    var(--forest) 0 calc(var(--tien-do,0) * 1%),
    var(--line-strong) calc(var(--tien-do,0) * 1%) 100%);
}
.mv-audio-seek::-moz-range-track{
  height:5px;border-radius:3px;
  background:linear-gradient(to right,
    var(--forest) 0 calc(var(--tien-do,0) * 1%),
    var(--line-strong) calc(var(--tien-do,0) * 1%) 100%);
}
.mv-audio-seek::-webkit-slider-thumb{
  appearance:none;-webkit-appearance:none;margin-top:-5px;
  width:15px;height:15px;border-radius:50%;background:var(--forest);border:2px solid var(--surface);
  box-shadow:0 1px 3px rgba(0,0,0,.25);
}
.mv-audio-seek::-moz-range-thumb{
  width:15px;height:15px;border-radius:50%;background:var(--forest);border:2px solid var(--surface);
}
.mv-audio-seek:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px;border-radius:4px;}
.mv-audio-seek:disabled{cursor:default;}
/* Hai mốc ở hai ĐẦU: bên trái đang ở đâu, bên phải còn bao lâu. */
.mv-audio-times{
  display:flex;justify-content:space-between;
  font-size:.76rem;font-weight:600;color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}

/* ---- hàng transport ---- */
/* Grid ba cột, KHÔNG phải flex: nút phát phải nằm đúng giữa thẻ. Với flex và
   khối âm lượng ở bên phải, nó lệch sang trái đúng bằng nửa bề rộng khối đó.
   Cột 1 để trống cố ý — nó là đối trọng của cột âm lượng. */
.mv-audio-transport{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;
  padding-bottom:4px;
}
.mv-audio-keys{grid-column:2;display:flex;align-items:center;gap:10px;}
.mv-audio-vol{grid-column:3;justify-self:end;display:flex;align-items:center;gap:6px;}

.mv-audio-play{
  flex:0 0 auto;width:52px;height:52px;border-radius:50%;border:0;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--forest);color:#F3EFDD;
  transition:background .15s ease,transform .12s ease;
}
:root[data-theme="dark"] .mv-audio-play{color:#12241C;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .mv-audio-play{color:#12241C;}}
.mv-audio-play:hover{background:var(--forest-bright);}
.mv-audio-play:active{transform:scale(.96);}
.mv-audio-play svg{width:24px;height:24px;}

/* Nút phụ trong hàng transport: tròn, trong suốt, nhỏ hơn nút phát. Số giây
   nằm TRONG icon (drivers/sphere-video-controls.ts `taoNutTua`) nên nút vuông
   vức như mọi nút khác — bản trước gắn nhãn chữ `-15s` cạnh icon và nút rộng
   gấp ba nút phát. */
.mv-prev,.mv-next,.mv-skip-back,.mv-skip-forward,.mv-audio-mute{
  flex:0 0 auto;width:38px;height:38px;padding:0;border-radius:50%;
  border:0;background:transparent;color:var(--ink-soft);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .15s ease,color .15s ease;
}
.mv-prev svg,.mv-next svg,.mv-skip-back svg,.mv-skip-forward svg,.mv-audio-mute svg{
  width:20px;height:20px;
}
.mv-prev:hover,.mv-next:hover,.mv-skip-back:hover,.mv-skip-forward:hover,.mv-audio-mute:hover{
  background:var(--line);color:var(--forest);
}
.mv-prev:disabled,.mv-next:disabled{opacity:.35;cursor:default;background:transparent;}
.mv-prev:focus-visible,.mv-next:focus-visible,.mv-skip-back:focus-visible,
.mv-skip-forward:focus-visible,.mv-audio-mute:focus-visible,.mv-audio-play:focus-visible{
  outline:2px solid var(--gold-bright);outline-offset:2px;
}

/* ---- âm lượng ---- */
.mv-audio-volume{
  width:78px;height:18px;margin:0;padding:0;
  appearance:none;-webkit-appearance:none;background:transparent;cursor:pointer;
}
.mv-audio-volume::-webkit-slider-runnable-track{
  height:4px;border-radius:2px;
  background:linear-gradient(to right,
    var(--ink-faint) 0 calc(var(--tien-do,100) * 1%),
    var(--line-strong) calc(var(--tien-do,100) * 1%) 100%);
}
.mv-audio-volume::-moz-range-track{
  height:4px;border-radius:2px;
  background:linear-gradient(to right,
    var(--ink-faint) 0 calc(var(--tien-do,100) * 1%),
    var(--line-strong) calc(var(--tien-do,100) * 1%) 100%);
}
.mv-audio-volume::-webkit-slider-thumb{
  appearance:none;-webkit-appearance:none;margin-top:-4px;
  width:12px;height:12px;border-radius:50%;background:var(--ink-soft);border:0;
}
.mv-audio-volume::-moz-range-thumb{
  width:12px;height:12px;border-radius:50%;background:var(--ink-soft);border:0;
}
.mv-audio-volume:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px;border-radius:4px;}

/* ---- bảng lời thuyết minh ---- */
.mv-audio-transcript{border-top:1px solid var(--line);padding-top:12px;}
.mv-audio-transcript > summary{
  cursor:pointer;font-size:.82rem;font-weight:600;color:var(--forest);
  list-style:none;display:flex;align-items:center;gap:6px;
}
.mv-audio-transcript > summary::-webkit-details-marker{display:none;}
.mv-audio-transcript > summary::before{
  content:"";width:0;height:0;flex:none;
  border-left:5px solid currentColor;border-top:4px solid transparent;border-bottom:4px solid transparent;
  transition:transform .15s ease;
}
.mv-audio-transcript[open] > summary::before{transform:rotate(90deg);}
:root[data-theme="dark"] .mv-audio-transcript > summary{color:var(--forest-bright);}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .mv-audio-transcript > summary{color:var(--forest-bright);}}
/* Trần chiều cao + cuộn: một bản thuyết minh dài đẩy mọi thứ dưới nó ra khỏi
   màn hình, mà trên trang di tích thứ nằm dưới là bài giới thiệu. */
.mv-audio-transcript-text{
  margin-top:10px;max-height:min(46vh,340px);overflow-y:auto;
  font-size:.88rem;line-height:1.75;color:var(--ink-soft);
}

/* Luật viên-thuốc cũ cho `.mv-skip-back/.mv-skip-forward` đã bỏ khỏi ĐÂY.
   Nó viết sau khối `.mv-audio-*` phía trên nên vẫn thắng dù hai bên cùng độ
   ưu tiên — đúng cái bẫy thứ tự mà chú thích ngay bên dưới đã cảnh báo một
   lần. Hai nút đó nay tròn, phẳng, cùng cỡ mọi nút phụ khác, và số giây vẽ
   trong icon (`taoNutTua`). */

/* PHẢI ĐỨNG SAU các luật .mv-audio-* ở trên. Khối này từng nằm trước chúng và
   không có tác dụng gì: cùng độ ưu tiên thì luật viết sau thắng, nên
   `.mv-audio-seek{flex:1 1 auto}` ghi đè lại `flex:1 1 100%` ở đây — đo được
   ở 390px thanh tua vẫn chỉ 140px.

   Ở bề ngang điện thoại, hàng điều khiển có nút phát 42 + đồng hồ ~74 + ô tốc
   độ ~52 + khoảng cách, chỉ còn chừng 90px cho thanh tua. Cho thanh tua hẳn
   một dòng riêng — nó là thứ cần bề ngang nhất — rồi nút phát, đồng hồ và ô
   tốc độ chia nhau dòng dưới. */
@media(max-width:520px){
  /* Lề khung ngoài thu lại — nó nằm trong một thẻ đã có lề riêng. */
  .mv-audio{padding:18px 14px 8px;}
  .mv-audio-art{width:66px;height:66px;}
  .mv-audio-head{gap:12px;}
  .mv-title{font-size:.98rem;}
  .mv-audio-keys{gap:4px;}
  .mv-prev,.mv-next,.mv-skip-back,.mv-skip-forward,.mv-audio-mute{width:34px;height:34px;}
  .mv-audio-play{width:46px;height:46px;}
  .mv-audio-play svg{width:21px;height:21px;}
  /* THANH âm lượng ẩn ở bề ngang điện thoại, NÚT tắt tiếng thì không: máy nào
     cũng có nút âm lượng cứng bên cạnh, nhưng "im ngay lập tức" thì chỉ nút
     này làm được bằng một lần bấm. Đo ở 390px: cả năm nút transport cộng thanh
     78px vượt quá bề ngang và nút phát bị đẩy khỏi tâm. */
  .mv-audio-volume{display:none;}
}

.mv-playlist{list-style:none;margin:0;padding:0 0 16px;display:flex;flex-direction:column;}
.mv-playlist-item{display:block;width:100%;text-align:left;padding:10px 14px;border:0;border-top:1px solid var(--line);background:none;color:var(--ink-soft);font:inherit;font-size:.86rem;cursor:pointer;}
.mv-playlist li:first-child .mv-playlist-item{border-top:0;}
.mv-playlist-item:hover{color:var(--forest);}
.mv-playlist-item[aria-current="true"]{color:var(--ink);font-weight:600;}
.mv-hotspot{cursor:pointer;}
.mv-hotspot .mv-hotspot-dot{animation:mvPulse 2s ease-out infinite;}
@keyframes mvPulse{0%{box-shadow:0 0 0 4px rgba(217,169,74,.45);}100%{box-shadow:0 0 0 14px rgba(217,169,74,0);}}
@media(prefers-reduced-motion:reduce){.mv-hotspot .mv-hotspot-dot{animation:none;}}

/* ---- search page ---- */
.search-form{display:flex;gap:10px;margin-top:22px;max-width:560px;}
.search-form input{flex:1;min-width:0;padding:12px 16px;border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--ink);font-size:.95rem;}
.search-form input:focus{outline:none;border-color:var(--forest);box-shadow:0 0 0 3px var(--forest-pale);}
.search-form button{padding:12px 22px;border:none;border-radius:10px;background:var(--forest);color:#F8F5E6;font-weight:600;cursor:pointer;font-size:.9rem;}
.search-form button:hover{filter:brightness(1.1);}
.search-count{margin-top:26px;}
.search-sort{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:16px 0 4px;font-size:.83rem;color:var(--ink-faint);}
.search-sort a{color:var(--ink-soft);font-weight:500;}
.search-sort a.active{color:var(--forest);font-weight:700;}
.search-sort a:hover{color:var(--forest);}
.search-results{display:flex;flex-direction:column;margin-top:8px;}
.search-result{display:block;padding:22px 4px;border-bottom:1px solid var(--line);}
.search-result h3{font-size:1.05rem;font-weight:600;margin-top:6px;color:var(--ink);}
.search-result:hover h3{color:var(--forest);}
.search-snippet{color:var(--ink-soft);font-size:.9rem;margin-top:6px;max-width:75ch;}
.search-meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:.72rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--clay);}
.search-kind{display:inline-block;padding:2px 10px;border-radius:999px;border:1px solid var(--line);color:var(--ink-soft);letter-spacing:.04em;}
.search-empty{margin-top:26px;}
@media(max-width:600px){.search-form{flex-direction:column;}.search-form button{width:100%;}}

/* In dark mode --forest flips to a light mint (#6FBE96); the fixed cream
   text these forest-filled controls use in light mode drops to ~1.9:1
   contrast on it. Dark ink on the mint instead - same approach as
   .tab[aria-current="page"]'s dark-on-gold. */
:root[data-theme="dark"] .btn-primary{color:#12241C;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .btn-primary{color:#12241C;}}
:root[data-theme="dark"] .rank-filter-chip.active{color:#12241C;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .rank-filter-chip.active{color:#12241C;}}
:root[data-theme="dark"] .search-form button{color:#12241C;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .search-form button{color:#12241C;}}

/* ---- contact page ---- */
.field-error{color:var(--clay);font-size:.8rem;margin-top:4px;}
.hp-field{position:absolute;left:-9999px;opacity:0;pointer-events:none;}
.form-success{background:var(--forest-pale);border:1px solid var(--forest);color:var(--ink);border-radius:10px;padding:12px 16px;margin-top:18px;}
