:root{--cam:#ea5b0c;--nen:#f6f7f9;--the:#fff;--chu:#1c2430;--mo:#64748b;--vien:#e3e7ec;
 /* §159.47c — mau bao hieu gio THUC TE. Khai thanh BIEN vi con phai doi
    theo nen toi: to mau cung thi chu xanh dam / do dam tren nen #12161c
    doc khong ra. */
 --som:#15803d;--dung:#1d4ed8;--tre:#b91c1c;--vua:#b45309;
 /* §159.57 — mau quan he dia ly trong khoi "ga khac".
    CUNG TINH dung luon mau thuong hieu: day la quan he gan nhat, va cam la
    mau site vẫn dung cho "cai dang o day".
    LIEN KE dung xanh mong ket: khac han cam nen phan biet duoc ngay, nhung
    van la mau tram — no la thong tin phu, khong duoc gianh mat voi noi dung.
    CO Y khong dung --som/--dung/--tre: ba mau do da mang nghia som/dung/muon
    o bang gio thuc te, muon nghia thu hai la day khach doan mo. */
 --ganh:#0f766e;--nen-cung:rgba(234,91,12,.07);--nen-ganh:rgba(15,118,110,.07)}
*{box-sizing:border-box}
body{margin:0;background:var(--nen);color:var(--chu);line-height:1.55;
 font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}
a{color:var(--cam)}
/* Dải cam ăn LÊN cả vùng thanh trạng thái iOS. Cần đủ ba thứ mới ra: thẻ
   `viewport-fit=cover` cho nội dung tràn qua vùng an toàn, `theme-color` để
   trình duyệt tô thanh của nó, và `env(safe-area-inset-top)` ở đây để chữ
   không chui xuống dưới đồng hồ với sóng pin.
   Hai bên cũng phải chừa: xoay ngang thì tai thỏ ăn vào cạnh trái/phải. */
.dau{background:var(--cam);color:#fff;
 padding:calc(14px + env(safe-area-inset-top,0px))
         calc(18px + env(safe-area-inset-right,0px)) 14px
         calc(18px + env(safe-area-inset-left,0px))}
/* §159.49 — hàng thứ hai của header: đồng hồ + tài khoản. Sao nguyên bảng
   màu và hình khối từ `.topbar-row2` của trang đặt vé (viên thuốc nền trắng mờ
   trên dải cam) để hai nơi trông là MỘT sản phẩm, không phải hai site. */
.dau-hang2{display:flex;align-items:center;justify-content:space-between;
 gap:10px;min-width:0}
.dong-ho{flex-shrink:0;font-family:"SF Mono","Consolas","Roboto Mono",monospace;
 font-size:12.5px;color:#fff;background:rgba(255,255,255,.16);border:0;
 border-radius:999px;padding:5px 12px;cursor:pointer;min-height:32px}
.dong-ho:hover{background:rgba(255,255,255,.24)}
.dong-ho:focus-visible{outline:2px solid #fff;outline-offset:2px}
.dong-ho .ngay{color:rgba(255,255,255,.72);margin-right:6px}
.dong-ho .gio{color:#fff;font-weight:700}
.tai-khoan{font-size:12.5px;color:rgba(255,255,255,.92);
 background:rgba(255,255,255,.14);padding:4px 11px;border-radius:999px;
 max-width:min(56vw,230px);overflow:hidden;text-overflow:ellipsis;
 white-space:nowrap}
.tai-khoan::before{content:"";display:inline-block;width:8px;height:8px;
 border-radius:50%;background:#4ade80;margin-right:7px;vertical-align:middle;
 box-shadow:0 0 6px rgba(74,222,128,.9)}
/* §159.50 — chua dang nhap thi cho nay la loi moi dang ky. Nen TRANG DAC tren
   dai cam la tuong phan manh nhat co the dat o day: no phai la thu mat bat
   duoc, khong phai mot cai nhan nua giong o tai khoan.
   Nhap nhay NHE = vien sang phong ra roi tan, khong phai chop tat do mo: chu
   chop tat rat met mat, ma day la mot dong chu phai doc duoc. */
/* MOI luat duoi day phai boc trong `.dau`. Ngay tren kia co
   `.dau a{color:#fff;font-size:18px}` — do uu tien (0,1,1), CAO HON `.dang-ky`
   tran (0,1,0). De tran thi nut ra CHU TRANG TREN NEN TRANG, co chu 18px: da
   dung ra dung nhu vay mot lan, chi thay khi mo trang that va do mau tinh duoc.
   `.dau .dang-ky` la (0,2,0), thang. */
.dau .dang-ky{display:inline-flex;align-items:center;flex-shrink:0;
 font-size:12.5px;font-weight:700;color:var(--cam);background:#fff;
 padding:5px 13px;border-radius:999px;text-decoration:none;min-height:32px;
 line-height:1.45;gap:4px;animation:dk-tho 2.6s ease-in-out infinite}
/* `display:inline-flex` se DE thuoc tinh `hidden` cua HTML neu khong chan —
   dung cai bay da ghi o dau tep, nen luat [hidden] phai di kem. */
.dau .dang-ky[hidden]{display:none}
.dau .dang-ky:hover{background:#fff;color:var(--cam);text-decoration:none}
.dau .dang-ky:focus-visible{outline:2px solid #fff;outline-offset:3px}
/* Do that: nhan day du "Dang ky / Dang nhap" rong 151px. O 320px (iPhone SE)
   hang chi rong 284px, dong ho da an 154px + khe 10px -> chi con 120px cho nut.
   Nen o man hep phai rut, va rut con "Dang nhap" (90px) chu khong phai
   "Dang ky": link tro thang vao man DANG NHAP, de chu "Dang ky" tron thi cai
   nhan noi sai noi no dan toi. Khach chua co tai khoan bam vao van thay ngay
   "Chua co tai khoan? Dang ky ngay" ngay duoi o mat khau.
   Moc 359px chu khong phai 360px: do o 360px thi le phai vua dung 18px.
   `aria-label` giu nguyen ca hai ve de tro doc man hinh khong doc ra mot cai
   nhan cut theo be ngang man hinh. */
@media(max-width:359px){.dau .dang-ky .dk-them{display:none}}

/* §159.51 — menu tai khoan (☰). Sao nguyen hinh khoi `.account-menu` cua trang
   dat ve: the bo 12px, muc bo 8px, ro chuot vao to cam nhat, muc Dang xuat to
   do. Bien mau dung o day (`--the`, `--vien`, `--chu`, `--mo`, `--tre`) deu tu
   lat theo nen toi nen KHONG can luat rieng cho nen toi.
   Moi khoi dat `display` o duoi deu phai co luat `[hidden]` di kem — cai bay
   ghi o dau tep, va no da can nguyen mot vong sua o §159.50. */
/* MOI luat duoi day PHAI boc trong `.dau` — menu nam trong <header class="dau">
   ma ngay tren co `.dau a{color:#fff;font-size:18px;display:inline-flex}` voi do
   uu tien (0,1,1), cao hon `.menu-tk-muc` tran (0,1,0). De tran thi cac muc la
   the <a> dung ra CHI CON CAI ICON: chu trang tren nen trang, co chu 18px, muc
   cao gap doi. Da dung ra dung nhu vay mot lan — y het con loi cua §159.50, cach
   do hai tieng, o cung mot cai `.dau a`. */
.dau .menu-tk{position:absolute;z-index:50;top:calc(100% - 3px);
 right:calc(18px + env(safe-area-inset-right,0px));
 width:max-content;min-width:214px;max-width:calc(100vw - 24px);
 background:var(--the);border:1px solid var(--vien);border-radius:12px;
 padding:6px;box-shadow:0 12px 40px rgba(0,0,0,.22);
 /* `overflow:hidden` — `.account-menu` ben trang dat ve co, minh lam roi. Co
    no thi muc con KHONG THE ve ra ngoai the duoc nua du khau ve lai co truc
    trac. User da chup duoc canh nen the chi phu 4 muc dau, 3 muc con lai de
    ra ngoai dam len bang gio tau (khong tai hien duoc headless). */
 overflow:hidden;
 animation:menu-hien .16s ease-out}
.dau .menu-tk[hidden]{display:none}
/* Mo dan bang opacity, KHONG transform: transform day phan tu len mot lop
   GPU rieng, ma anh chup cua lop do co the bi cu trong khi chu da ve lai dung
   — dung kieu hong user chup duoc. Nhin gan nhu y het. */
@keyframes menu-hien{from{opacity:0}to{opacity:1}}
.dau .menu-tk-muc{display:flex;align-items:center;gap:10px;width:100%;
 text-align:left;background:transparent;border:0;border-radius:8px;
 padding:10px 12px;font-size:14.5px;font-weight:400;font-family:inherit;
 color:var(--chu);cursor:pointer;text-decoration:none;white-space:nowrap}
.dau .menu-tk-muc[hidden]{display:none}
.dau .menu-tk-muc:hover{background:rgba(234,91,12,.1);color:var(--cam)}
.dau .menu-tk-muc.nguy:hover{background:rgba(185,28,28,.1);color:var(--tre)}
.dau .menu-tk-muc:focus-visible{outline:2px solid var(--cam);outline-offset:-2px}
.dau .menu-tk-vach{height:1px;background:var(--vien);margin:5px 4px}
.dau .menu-tk-mui{margin-left:auto;color:var(--mo);font-size:17px;line-height:1;
 transition:transform .16s ease-out}
.dau .menu-tk-muc[aria-expanded="true"] .menu-tk-mui{transform:rotate(90deg)}
.dau .menu-tk-con{display:block;margin:2px 0 2px 10px;padding-left:8px;
 border-left:2px solid var(--vien)}
.dau .menu-tk-con[hidden]{display:none}
.dau .menu-tk-nho{font-size:14px;padding:9px 10px}
@keyframes dk-tho{0%,100%{box-shadow:0 0 0 0 rgba(255,255,255,.6)}
 70%,100%{box-shadow:0 0 0 7px rgba(255,255,255,0)}}

/* --- Lịch âm · hoàng đạo (§159.49) ---------------------------------------
   Chỉ XEM, không chọn ngày: bản trong trang đặt vé là bộ CHỌN ngày đi nên
   mang theo nút chốt, `data-iso`, và cả luồng đặt vé. Ở đây không có gì để
   chọn — bê nguyên là chở theo một mớ trạng thái chết. Phần tính toán thì
   dùng LẠI y nguyên `lunar.js` của trang đặt vé, không chép thuật toán. */
.lich-nen{position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:60;
 display:flex;align-items:flex-end;justify-content:center;
 animation:lich-mo .2s ease-out}
.lich{background:var(--the);color:var(--chu);width:min(420px,calc(100% - 16px));
 margin:0 8px 8px;border:1px solid var(--vien);border-radius:14px;padding:14px;
 box-shadow:0 12px 40px rgba(0,0,0,.22);max-height:calc(100dvh - 16px);
 overflow:auto;animation:lich-len .28s cubic-bezier(.32,.72,0,1)}
.lich-dau{display:flex;align-items:center;justify-content:space-between;
 gap:8px;margin-bottom:10px}
.lich-dau b{font-size:15px}
.lich-nut{width:30px;height:30px;border:1px solid var(--vien);
 background:var(--nen);color:var(--cam);border-radius:8px;cursor:pointer;
 font-size:15px;line-height:1}
.lich-nut:hover{background:var(--the)}
.lich-thu{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;
 font-size:11px;color:var(--mo);text-align:center;margin-bottom:4px}
.lich-luoi{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.lich-o{position:relative;padding:5px 2px;border-radius:8px;text-align:center;
 border:1px solid transparent;cursor:pointer;background:var(--nen)}
.lich-o.trong{background:none;cursor:default}
.lich-o.nay{border-color:var(--cam)}
.lich-o.chon{background:var(--cam);color:#fff}
.lich-o.chon .am,.lich-o.chon .duong{color:#fff}
.lich-o .duong{display:block;font-size:13px;line-height:1.2}
.lich-o .am{display:block;font-size:9px;color:var(--mo);line-height:1}
.lich-o.dau-thang .am{color:#d98a2b;font-weight:700}
.lich-o.hoang::after{content:"";position:absolute;top:4px;right:4px;width:5px;
 height:5px;border-radius:50%;background:#16a34a}
.lich-chi-tiet{margin-top:9px;padding:8px 10px;border-radius:8px;
 background:var(--nen);border:1px solid var(--vien);font-size:11.5px;
 line-height:1.55;color:var(--mo)}
.lich-chi-tiet .cd-duong{color:var(--chu);font-weight:700;font-size:12px}
.lich-chi-tiet .cd-hoang{color:#16a34a;font-weight:700}
@keyframes lich-mo{from{opacity:0}to{opacity:1}}
@keyframes lich-len{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.dau a{color:#fff;text-decoration:none;font-weight:800;font-size:18px;
 display:inline-flex;align-items:center;gap:10px}
.dau-nut{display:flex;align-items:center;gap:8px;flex-shrink:0}
/* Cụm chat góc TRÁI-dưới: góc phải-dưới đã có mục lục + lên đầu trang, chồng
   bốn nút một cột là che mất nội dung trên màn nhỏ. */
.chat{position:fixed;z-index:40;
 left:calc(14px + env(safe-area-inset-left,0px));
 bottom:calc(14px + env(safe-area-inset-bottom,0px));
 display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.chat[hidden]{display:none}
.chat-bang{display:flex;flex-direction:column;gap:8px;
 transform-origin:bottom left;opacity:1;transform:none;
 transition:opacity .18s ease,transform .24s cubic-bezier(.32,.72,0,1),
            display .24s allow-discrete}
.chat-bang[hidden]{display:none;opacity:0;transform:scale(.94) translateY(8px)}
@starting-style{.chat-bang{opacity:0;transform:scale(.94) translateY(8px)}}
.kenh{display:flex;align-items:center;gap:10px;text-decoration:none;
 background:var(--the);color:var(--chu);border:1px solid #cfd6de;
 border-radius:24px;padding:7px 15px 7px 7px;font-size:14.5px;font-weight:600;
 white-space:nowrap;box-shadow:0 3px 14px rgba(28,36,48,.22);
 transition:transform .18s cubic-bezier(.32,.72,0,1)}
.kenh:active{transform:scale(.97)}
.kenh-icon{width:34px;height:34px;border-radius:50%;flex-shrink:0;color:#fff;
 display:flex;align-items:center;justify-content:center}
/* Zalo: nền tròn XANH, bong bóng vẽ bằng `currentColor` nên ra TRẮNG, chữ
   "Zalo" trong bong bóng màu xanh. Làm ngược lại (nền trắng + bong bóng xanh)
   là chữ xanh nằm trên bong bóng xanh — mất hút. Đã dựng thử và nhìn thấy đúng
   cảnh đó. Giống hệt `.support-channel--zalo` của web đặt vé. */
.kenh--zalo .kenh-icon{background:#0068ff;color:#fff}
.kenh--telegram .kenh-icon{background:#229ed9}
.kenh--messenger .kenh-icon{background:linear-gradient(45deg,#006aff 0%,#00b2ff 100%)}
/* Logo lấy đúng bản dùng ở header web đặt vé. Ảnh phải nằm TRONG /giotaugiave/
   (bộ sinh tự chép sang) — để ở web root là khách nước ngoài không tải được,
   đúng cái luật Cloudflare chỉ mở mỗi đường dẫn này. */
.dau img{height:34px;width:auto;display:block;flex-shrink:0}
/* Câu tóm tắt: đây là đoạn Google AI Overview và featured snippet trích, nên
   nó phải dễ đọc chứ không phải chữ phụ mờ nhạt. */
.tomtat{font-size:15.5px;line-height:1.6;margin:2px 0 10px}
/* Ảnh ga: lưới co giãn, KHÔNG cố định chiều cao — ảnh người vận hành tải lên có
   đủ tỉ lệ, ép cứng là méo. `aspect-ratio` + `object-fit` giữ khung đều mà
   không cắt sai trọng tâm quá đáng, và đặt sẵn khung nên KHÔNG gây nhảy bố cục
   (CLS) khi ảnh tải xong. */
.anh-ga{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
 gap:8px;margin:12px 0}
.anh-ga img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;
 border-radius:10px;border:1px solid var(--vien);display:block}
.clip{position:relative;aspect-ratio:16/9;margin:12px 0;border-radius:10px;
 overflow:hidden;border:1px solid var(--vien)}
.clip iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.khung{max-width:960px;margin:0 auto;
 padding:18px calc(18px + env(safe-area-inset-right,0px))
         18px calc(18px + env(safe-area-inset-left,0px))}
.the{background:var(--the);border:1px solid var(--vien);border-radius:12px;padding:18px;margin-bottom:16px}
h1{font-size:22px;margin:0 0 6px}
h2{font-size:17px;margin:22px 0 10px}
.phu{color:var(--mo);font-size:14px;margin:0 0 14px}
table{border-collapse:collapse;width:100%;font-size:14.5px}
th,td{border:1px solid var(--vien);padding:8px 10px;text-align:left}
th{background:#f2f5f8;font-weight:700}
.so{text-align:right;white-space:nowrap}
.giua{text-align:center;white-space:nowrap}
/* Tên loại chỗ dài ("Giường nằm khoang 6 — tầng 3"): không đặt chiều rộng tối
   thiểu thì trên màn hẹp nó gãy thành 4 dòng, hàng cao lêu nghêu. Bảng đã nằm
   trong .cuon nên tràn thì cuộn ngang, không vỡ trang.
   CHỈ áp cho bảng giá. Trước đây áp cho MỌI bảng, nên cột "Tàu" (chữ "SE8") và
   cột "#" (một chữ số) cũng bị ép 132px — phí chỗ của đúng những cột bên phải
   đang cần rộng.
   110px chứ không phải 132px: đo trên màn 430px thì 132px làm bảng rộng 372px
   trong khung 356px ⇒ cột "Cao nhất" bị cắt, phải cuộn ngang mới đọc được giá.
   Hạ xuống 110px thì vừa khít, mà chiều cao hàng KHÔNG đổi (62px cả hai) —
   tên loại chỗ vẫn xuống đúng 2 dòng như cũ. */
table.gia td:first-child{min-width:110px}
/* Cột co về đúng bề rộng nội dung. `width:1px` + `nowrap` là idiom của bảng
   HTML: trình duyệt nới lên vừa nội dung rồi dồn phần dư cho các cột còn lại. */
th.hep,td.hep{width:1px;white-space:nowrap}
/* Cuộn ngang KHÔNG được im lặng. Render thật trên màn 390px: bảng giá bị cắt
   ngang cột "Cao nhất" mà không có dấu hiệu nào cho khách biết là vuốt được —
   họ chỉ thấy một bảng hỏng. Bóng đổ này hiện ở đúng phía CÒN nội dung và tự
   biến mất khi cuộn hết, nên không cần JS (CSP §139 cấm script nội tuyến) và
   cũng không hiện nhầm khi bảng vốn đã vừa màn.
   Cơ chế: hai lớp nền `local` cuộn theo nội dung che đi hai lớp `scroll` đứng
   yên — hết nội dung thì lớp che trùng lên lớp bóng. */
.cuon{overflow-x:auto;-webkit-overflow-scrolling:touch;
 background:
  linear-gradient(to right,var(--the) 40%,rgba(255,255,255,0)) left/28px 100% no-repeat local,
  linear-gradient(to left,var(--the) 40%,rgba(255,255,255,0)) right/28px 100% no-repeat local,
  radial-gradient(farthest-side at 0 50%,rgba(28,36,48,.18),rgba(28,36,48,0)) left/12px 100% no-repeat scroll,
  radial-gradient(farthest-side at 100% 50%,rgba(28,36,48,.18),rgba(28,36,48,0)) right/12px 100% no-repeat scroll}
/* Màn hẹp: bảng giá có 4 cột tiền + cột tên, riêng padding ngang đã ăn 80px
   trong khung 356px. Bớt còn 6px thì số 7 chữ số (1.023.000đ) vừa đủ chỗ trên
   màn 430px mà KHÔNG phải thu nhỏ chữ — mà chữ số chính là thứ khách vào đây
   để đọc. Màn hẹp hơn nữa (360px) thì vẫn phải cuộn ngang: 4 cột tiền không
   thể vừa, và `.cuon` đã lo việc đó. */
@media(max-width:520px){th,td{padding:8px 6px}}
/* --- Chuyển động (§159.22) ------------------------------------------------
   Chuyển trang mượt bằng View Transitions API: CSS THUẦN, không thêm dòng JS
   nào — §139 cấm script nội tuyến và trang này vốn là HTML tĩnh. Trình duyệt
   chưa hỗ trợ thì điều hướng y như cũ, không mất gì (tăng cường dần).

   Nhịp và đường cong lấy theo lối Apple: nhanh, không nảy, ra nhanh vào chậm
   hơn một chút. `cubic-bezier(.32,.72,0,1)` là xấp xỉ của lò xo mà họ hay dùng.

   `.dau` mang tên chuyển cảnh riêng nên dải cam ở đầu trang ĐỨNG YÊN khi
   chuyển trang thay vì nhoè đi rồi hiện lại — đó mới là thứ tạo cảm giác liền
   mạch, không phải hiệu ứng mờ dần. */
@view-transition{navigation:auto}
.dau{view-transition-name:dau}
::view-transition-old(root){animation:ra .16s cubic-bezier(.4,0,1,1) both}
::view-transition-new(root){animation:vao .3s cubic-bezier(.32,.72,0,1) both}
@keyframes ra{to{opacity:0;transform:translateY(-5px)}}
@keyframes vao{from{opacity:0;transform:translateY(9px)}}

/* Thẻ nội dung trôi lên khi vào trang. `backwards` chứ KHÔNG `both`: nếu vì lý
   do nào đó hiệu ứng không chạy thì thẻ vẫn ở trạng thái tự nhiên — chứ để
   `both` mà hỏng là nội dung nằm im ở opacity 0, khách thấy trang trắng. */
.khung>.the{animation:the-vao .4s cubic-bezier(.32,.72,0,1) backwards}
.khung>.the:nth-child(2){animation-delay:.04s}
.khung>.the:nth-child(3){animation-delay:.08s}
.khung>.the:nth-child(n+4){animation-delay:.12s}
@keyframes the-vao{from{opacity:0;transform:translateY(10px)}}

/* Phản hồi khi chạm. Chỉ đụng `transform`/màu — không đụng thứ gây dựng lại bố
   cục, vì trang chủ có tới 1.630 liên kết. */
.luoi a,.nut,.tron,.ml-bang a{
 transition:transform .18s cubic-bezier(.32,.72,0,1),
            background-color .18s ease,border-color .18s ease,color .18s ease}
.luoi a:active,.ml-bang a:active{transform:scale(.985)}
.nut:hover{transform:translateY(-1px)}
.nut:active{transform:scale(.97)}
.tron:active{transform:scale(.9)}

html{scroll-behavior:smooth}

/* Bảng mục lục bung ra từ chính cái nút vừa bấm. `allow-discrete` để hiệu ứng
   ĐÓNG cũng chạy được dù `[hidden]` đặt display:none. */
.ml-bang{transform-origin:bottom right;opacity:1;transform:none;
 transition:opacity .18s ease,transform .24s cubic-bezier(.32,.72,0,1),
            display .24s allow-discrete}
.ml-bang[hidden]{opacity:0;transform:scale(.94) translateY(8px)}
@starting-style{.ml-bang{opacity:0;transform:scale(.94) translateY(8px)}}

/* Ai đã tắt hiệu ứng trong hệ điều hành thì phải được tôn trọng — chuyển động
   không chỉ là thẩm mỹ, với một số người nó gây chóng mặt thật. */
@media(prefers-reduced-motion:reduce){
 *,*::before,*::after{animation-duration:.01ms!important;
  animation-iteration-count:1!important;transition-duration:.01ms!important}
 html{scroll-behavior:auto}
 ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){
  animation:none!important}
}

/* Nút lên đầu trang + mục lục nổi (§159.22). `display:flex` sẽ ĐÈ thuộc tính
   `hidden` của HTML nếu không chặn — đã dính đúng bẫy này một lần ở web đặt vé,
   nên mọi khối đặt display ở đây đều phải có luật [hidden] đi kèm. */
/* `env(safe-area-inset-*)`: trên iPhone có thanh gạt ngang dưới đáy, để 14px
   trơ là nút nằm sát ngay trên nó. */
.noi{position:fixed;z-index:40;
 right:calc(14px + env(safe-area-inset-right,0px));
 bottom:calc(14px + env(safe-area-inset-bottom,0px));
 display:flex;flex-direction:column;align-items:flex-end;gap:10px}
.noi[hidden]{display:none}
/* Nút NỔI TRÊN thẻ trắng, nên viền nhạt như thẻ là nó tan vào nền — ảnh chụp
   iPhone thật cho thấy đúng cảnh đó: cái nút trông như một vệt méo chứ không
   ra hình nút. Cần viền chắc + bóng đổ rõ để tách khỏi thẻ.
   `-webkit-appearance:none` + `padding:0`: iOS Safari tự áp kiểu nút riêng,
   không dập là chữ lệch tâm và kích thước không đúng như khai. */
.tron{-webkit-appearance:none;appearance:none;padding:0;margin:0;
 flex:0 0 auto;box-sizing:border-box;
 width:44px;height:44px;aspect-ratio:1;border-radius:50%;
 display:flex;align-items:center;justify-content:center;
 border:1px solid #cfd6de;background:var(--the);color:var(--chu);
 font:inherit;font-size:19px;line-height:1;cursor:pointer;
 touch-action:manipulation;-webkit-tap-highlight-color:transparent;
 box-shadow:0 3px 14px rgba(28,36,48,.22)}
/* Nút chính (lên đầu trang) tô màu hẳn — nó là việc khách hay làm nhất trên
   trang dài này, và màu đặc thì không bao giờ lẫn vào thẻ trắng. */
.tron.chinh{background:var(--cam);color:#fff;border-color:var(--cam);
 box-shadow:0 3px 14px rgba(234,91,12,.38)}
/* CHỈ đổi màu trên thiết bị THẬT SỰ có con trỏ. Trên cảm ứng, `:hover` dính
   lại sau khi chạm — ảnh chụp của user có đúng cảnh một nút cam một nút trắng
   mà chẳng vì lý do gì. */
@media(hover:hover){
 .tron:hover{background:var(--cam);color:#fff;border-color:var(--cam)}
}
.tron:focus-visible{outline:2px solid var(--cam);outline-offset:2px}
.ml{display:flex;flex-direction:column;align-items:flex-end;gap:10px}
.ml[hidden]{display:none}
.ml-bang{display:flex;flex-direction:column;background:var(--the);
 border:1px solid var(--vien);border-radius:11px;padding:6px;max-width:74vw;
 box-shadow:0 4px 16px rgba(28,36,48,.18)}
.ml-bang[hidden]{display:none}
.ml-bang a{padding:8px 12px;border-radius:7px;text-decoration:none;font-size:14.5px;
 white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ml-bang a:hover{background:var(--nen)}
.ml-bang a[hidden]{display:none}
.nut{display:inline-block;background:var(--cam);color:#fff;text-decoration:none;
 padding:11px 22px;border-radius:9px;font-weight:700;margin-top:6px}
/* §159.67 — khối đặt vé: chọn ngày NGAY TRÊN TRANG TĨNH rồi mang sang trang đặt.
   Là <form method=get> thuần, KHÔNG một dòng JS: CSP ở đây cấm script nội tuyến,
   mà form GET tự dựng đúng `/?ga_di=..&ga_den=..&ngay=..&mac=..`. Tắt JS vẫn chạy.
   `.nut` vốn dành cho thẻ <a>; nút submit là <button> nên phải tự gỡ viền và ép
   thừa kế phông, không thì trình duyệt vẽ nút hệ thống. */
.datve{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-top:10px}
.datve label{font-size:13px;color:var(--mo)}
.datve input[type=date]{padding:10px 12px;font-size:15px;border:1.5px solid var(--vien);
 border-radius:9px;background:var(--the);color:var(--chu);font-family:inherit;
 min-height:44px}
.datve input[type=date]:focus{outline:2px solid var(--cam);outline-offset:1px}
/* Đo thật ở khổ 390px: padding 11px cho nút cao 42px — dưới ngưỡng chạm 44px
   của iOS, và lệch 2px so với ô ngày bên cạnh (44px) trông như đặt lệch. Giữ
   `inline-block` chứ KHÔNG đổi sang inline-flex: nhãn nút là "Đặt vé tàu SE8"
   + <span>từ 304.000đ</span>, mà flex nuốt mất khoảng trắng giữa hai phần
   (đúng lỗi §159.50b đã dính). */
.datve .nut{margin-top:0;border:0;cursor:pointer;font-family:inherit;font-size:15px;
 padding:12px 22px;min-height:44px}
.datve .tu-gia{font-weight:400;opacity:.92}
/* §159.69 — thẻ mời cài ứng dụng.
   NẰM TRONG DÒNG NỘI DUNG, tuyệt đối không phải lớp phủ: Google hạ thứ hạng
   trang di động bật hộp che nội dung khi khách vừa vào, mà 7.817 trang này tồn
   tại CHỈ để lấy khách từ tìm kiếm. Đặt sau phần nội dung chính, trước phần
   điều hướng cuối trang — khách đã có câu trả lời rồi mới mời.
   `hidden` mặc định: JS mới quyết có hiện không (đã cài rồi / đã đóng rồi thì
   thôi). Trang không chạy JS và bot thì không thấy một thẻ chết. */
.thecai{position:relative}
.thecai[hidden]{display:none}
.thecai h2{margin-top:0}
.thecai ul{margin:10px 0 0;padding-left:20px}
.thecai li{margin:5px 0;line-height:1.55}
/* 44px — cùng ngưỡng chạm iOS đã áp cho nút đặt vé. Nút "bỏ qua" mà khó bấm là
   khó chịu đúng vào lúc khách muốn nó biến mất. */
.thecai .thecai-dong{position:absolute;top:6px;right:6px;width:44px;height:44px;
 border:0;border-radius:8px;background:transparent;color:var(--mo);font-size:22px;
 line-height:1;cursor:pointer;font-family:inherit}
.thecai .thecai-dong:hover{background:var(--nen);color:var(--chu)}
.thecai .thecai-dong:focus-visible{outline:2px solid var(--cam);outline-offset:1px}
/* Chừa chỗ cho nút đóng (44px + lề), không thì tiêu đề dài chạy vào dưới nó. */
.thecai h2{padding-right:52px}
.tim{width:100%;padding:11px 13px;font-size:15px;margin:4px 0 12px;
 border:1.5px solid var(--vien);border-radius:9px;background:var(--the);color:var(--chu)}
.tim:focus{outline:2px solid var(--cam);outline-offset:1px;border-color:var(--cam)}
.tim:disabled{opacity:.6}
/* §159.78 — ba cột MỨC vé còn. Bảng 4 cột đã vừa khít khung 316px ở khổ 390px
   (đo thật), nên thêm ba cột là chắc chắn phải trượt ngang. User chốt: dùng
   thanh trượt.
   Trượt ngang mà không GHIM cột đầu thì trượt sang phải là mất dấu đang xem tàu
   nào — bảng thành vô dụng đúng lúc cần nhất. `position:sticky` trên ô đầu mỗi
   hàng giữ cột "Mác tàu" đứng yên. */
/* Nới bảng ra sát mép thẻ hơn. Thẻ có `padding:18px`, tức bảng đang bị bó
   trong 316px ở khổ 390px trong khi nó cần 331–337px. Mượn 12px mỗi bên là
   lấy chỗ từ khoảng trắng — KHÔNG phải từ thông tin, khác hẳn cách bóp chữ
   ghi chú "chạy đến hết" hay làm mờ "(+1)". Vẫn chừa 6px để bảng không dính
   vào viền bo của thẻ. */
.vecon-cuon{position:relative;margin-left:-12px;margin-right:-12px}
.vecon-cuon table{min-width:100%}
.vecon-cuon td:first-child,.vecon-cuon th:first-child{
 position:sticky;left:0;z-index:1;background:var(--the)}
.vecon-cuon th:first-child{background:#f2f5f8}
/* Viền phải của cột ghim: không có nó thì lúc trượt, chữ cột sau chạy sát vào
   cột ghim và trông như dính liền. */
.vecon-cuon td:first-child::after,.vecon-cuon th:first-child::after{
 content:"";position:absolute;top:0;right:0;bottom:0;width:1px;background:var(--vien)}
/* Đầu cột ngày. Cỡ nhỏ hơn thân bảng vì đây là nhãn phụ, không phải dữ liệu. */
.lech{font-size:11.5px;color:var(--mo)}
/* `<caption>` thay cho đoạn `<p class="phu">` cũ đứng trên bảng: cùng một câu,
   nhưng nằm TRONG bảng nên trình đọc màn hình gắn nó vào bảng, và bộ phân tích
   máy biết đây là chú giải của bảng chứ không phải một đoạn văn rời. Không nhân
   đôi chữ — câu cũ đã chuyển vào đây, không để lại bản sao. */
table>caption{caption-side:top;text-align:left;color:var(--mo);font-size:14px;
 margin:0 0 10px;line-height:1.5}
.vecon-th{font-size:11.5px;font-weight:600;line-height:1.15;white-space:nowrap}
/* `width:1%` = bóp cột về đúng bề rộng nội dung. Không có nó thì `table-layout`
   tự động chia phần dư đều cho các cột và ba cột mức phình ra vô ích. */
th.vecon-th,td.vecon{width:1%;padding-left:3px;padding-right:3px}
/* Hai cột giờ chỉ chứa "01:52" mà nền bảng cho `padding:8px 10px` — 20px đệm
   cho ~33px nội dung. Bóp còn 5px mỗi bên trả lại ~20px, vừa đủ để cột ngày
   thứ ba lọt khung ở phần lớn ga. CHỈ áp trong bảng có cột mức: bảng khác
   không chật nên không có lý do làm chúng khác đi. */
.vecon-cuon td[data-den],.vecon-cuon td[data-di],
.vecon-cuon th.giua:not(.vecon-th){padding-left:5px;padding-right:5px}
td.vecon{text-align:center}
/* Ô KHÔNG BIẾT mang lớp riêng thay vì tô xám ở `td.vecon` chung.
   `td.vecon` là (0,1,1) — nó ĐÈ `.vc-nhieu` (0,1,0) và tô xám sạch cả ba màu.
   Mọi phép đo số đều xanh, chỉ ảnh chụp mới lộ ra. Cùng họ bẫy `.dau a`. */
.vc-trong{color:var(--mo)}
/* CHẤM MỨC thay cho chữ (user chốt: chỉ màu + chú thích dưới bảng).
   ĐỒNG BỘ VỚI TỔNG THỂ, không bịa hình mới: trang này đã có sẵn từ vựng cho
   "dấu hiệu trạng thái nhỏ" — chấm tròn có quầng sáng ở `.tai-khoan::before`
   và `.lich-o.hoang::after`. Dùng lại đúng hình đó.
   CỠ CHẤM đổi theo mức là kênh thứ HAI bên cạnh màu: xanh/cam/đỏ đúng là bộ tệ
   nhất với người mù màu (~8% khách nam), chỉ dựa vào màu là loại hẳn nhóm đó
   ra. Cỡ là thuộc tính TĨNH, không phải thứ chạy trong nhịp nháy — nhịp vẫn chỉ
   đổi độ mờ, đúng luật đã ghi ở `tt-nhay`: đổi kích thước theo nhịp là cả hàng
   bảng nhảy từng nhịp, đọc không nổi. */
.vc-cham{display:inline-block;border-radius:50%;background:currentColor;
 width:var(--co,10px);height:var(--co,10px);vertical-align:middle;
 box-shadow:0 0 6px currentColor;
 animation:tt-nhay var(--nhip,2.5s) ease-in-out infinite}
.vc-nhieu{color:var(--som);--co:11px;--nhip:2.5s}
.vc-it{color:var(--vua);--co:9px;--nhip:1.6s}
.vc-gan_het{color:var(--tre);--co:7px;--nhip:.9s}
/* Nhịp nhanh nhất 0,9s = 1,1 lần/giây, vẫn xa dưới ngưỡng 3 Hz của WCAG 2.3.1.
   Dùng LẠI `tt-nhay` của chính bảng này chứ không thêm bộ nhịp thứ hai — cùng
   độ mờ đáy, cùng đường cong, nên ba cột mới thở đúng nhịp với giờ thực tế đã
   có ở hai cột bên trái.
   KHÔNG cần luật `prefers-reduced-motion` riêng: khối toàn cục đã ép
   `animation-iteration-count:1!important` cho mọi thứ. Thêm luật thứ hai chỉ là
   một chỗ nữa phải nhớ khi sửa — đúng lý do đã ghi ngay dưới `tt-nhay`. */
/* Chú thích dưới bảng — chỗ DUY NHẤT còn chữ, vì chấm màu tự nó không nói được
   nó nghĩa là gì. Cỡ chữ và màu theo `.tt-nguon`/`.phu` của trang. */
.vecon-ct{display:flex;flex-wrap:wrap;gap:2px 14px;align-items:center;
 margin:9px 0 0;font-size:12.5px}
/* `>` chứ không phải dấu cách: `.vecon-ct span` ăn cả chấm bên trong và tô
   xám nó — đúng cái bẫy vừa gặp ở `td.vecon`, hai chỗ một lỗi. */
.vecon-ct>span{display:inline-flex;align-items:center;gap:6px;color:var(--mo)}
.vecon-chu{margin-top:-6px;font-size:12.5px}
/* §159.71 — KẾT QUẢ NẰM NGAY DƯỚI Ô TÌM.
   Trước đây gõ xong phải cuộn xuống mới thấy: ba khối kết quả nằm rải phía dưới
   trang, mà trang chủ dài hơn 5 màn hình. Nay kết quả gom lên đây, ngay trong
   cùng thẻ với ô tìm, và các khối phía dưới ẩn đi trong lúc đang lọc. */
.ketqua[hidden]{display:none}
.ketqua{margin:4px 0 12px}
.ketqua .nhom{margin-top:12px}
.ketqua .nhom:first-child{margin-top:0}
.ketqua .nhom h3{margin:0 0 7px;font-size:13px;font-weight:700;color:var(--mo);
 text-transform:uppercase;letter-spacing:.4px}
.ketqua .luoi{margin:0}
.ketqua .them{margin:10px 0 0;font-size:13px;color:var(--mo)}
/* §159.71 — gợi ý ghép chặng khi không có tàu thẳng.
   Đo trên chính dữ liệu đang chạy: chỉ 41,7% cặp ga có tuyến thẳng, còn 52,1%
   phải đi 2 chặng — và toàn bộ 52,1% đó hôm nay trả về "0 kết quả". Đây không
   phải ca hiếm, nó là ca ĐA SỐ. */
.ghepchang[hidden]{display:none}
.ghepchang h2{margin-top:0;font-size:17px}
.ghepchang ol{margin:10px 0 0;padding-left:0;list-style:none;counter-reset:chang}
.ghepchang li{counter-increment:chang;display:flex;align-items:center;gap:10px;
 padding:10px 0;border-top:1px solid var(--vien)}
.ghepchang li::before{content:"Chặng " counter(chang);flex:0 0 auto;font-size:12px;
 font-weight:700;color:var(--cam);background:var(--nen-cung);border-radius:7px;
 padding:5px 9px;white-space:nowrap}
.ghepchang li a{font-weight:600}
/* Tên lớp phải DUY NHẤT: bản đầu đặt là `.noi`, trùng với khối nút nổi
   (chat + lên đầu trang) vốn có `position:fixed;z-index:40` — dòng lưu ý bị
   kéo xuống góc dưới phải màn hình, đè lên nội dung khác. Chỉ lộ ra khi soi
   ảnh chụp production, không lộ ra ở HTML. */
.ghepchang .ghep-luuy{margin:10px 0 0;font-size:13px;color:var(--mo)}
/* §159.46 — gấp đuôi bảng giờ tàu dài. `<details>` gốc: bàn phím và trình đọc
   màn hình dùng được sẵn, không cần JS (CSP cấm script nội tuyến), mà nội dung
   vẫn nằm nguyên trong HTML nên Google đọc đủ. */
/* §159.47c — dấu hiệu GIỜ THỰC TẾ.
   CHỈ giờ do hệ thống định vị trả về mới được bọc `<b>` (xem `dat()` trong
   thoigianthuc.js), nên nhắm đúng thẻ đó là nhắm TRÚNG giờ thực tế — không bao
   giờ đụng nhầm giờ theo biểu đồ. Đây đúng là thứ user hỏi: làm sao phân biệt
   nhanh hai loại giờ trên cùng một bảng.
   Giờ theo biểu đồ vẫn giữ ngay bên cạnh, in mờ gạch ngang, để thấy lệch bao
   nhiêu và để không ai tưởng biểu đồ đã đổi. */
/* §159.48 — khối thời tiết ga. Dùng lại đúng bảng màu và bo góc của site
   (`--the`, `--vien`, `--mo`) để nó trông như một phần của thẻ, không phải
   tiện ích dán thêm. Hiệu ứng: cả khối hiện lên mềm, rồi sáu ô ngày lần lượt
   trôi vào — cùng đường cong `cubic-bezier(.32,.72,0,1)` mà `.the` đang dùng. */
.tt-troi{margin:12px 0 0;padding:12px 14px;border:1px solid var(--vien);
 border-radius:12px;background:linear-gradient(180deg,
 rgba(37,99,235,.06),rgba(37,99,235,0));animation:tt-hien .45s
 cubic-bezier(.32,.72,0,1) backwards}
.tt-nay{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.tt-so{font-size:30px;font-weight:700;line-height:1.1;letter-spacing:-.5px}
.tt-so sup{font-size:14px;font-weight:600;color:var(--mo);margin-left:1px}
.tt-am{display:inline-flex;align-items:center;gap:5px;color:var(--mo);
 font-size:14.5px}
.tt-am svg{color:#3b82f6;animation:tt-tho 2.6s ease-in-out infinite}
/* §159.70 — TỰ XUỐNG DÒNG, không chạy theo ngưỡng màn hình.
   Bản cũ `repeat(6,1fr)` tràn ra ngoài viền khối trên iPhone 14 (user chụp
   ảnh: thẻ T3 nằm hẳn ngoài khung). Lý do không hiển nhiên: `1fr` chính là
   `minmax(AUTO,1fr)`, mà `auto` nghĩa là cột KHÔNG BAO GIỜ co nhỏ hơn nội dung
   của nó. Chữ "30°/24°" cần ~47px ⇒ sáu cột cần 312px, trong khi bề ngang có
   được ở khổ 390px chỉ là 286px.
   Bản vá cũ đặt `overflow-x:auto` trong `@media(max-width:360px)` vì tưởng chỉ
   iPhone SE mới dính — nên 361px trở lên vẫn tràn nguyên. Đó là lý do ở đây
   dùng `auto-fit`: trình duyệt tự tính vừa mấy cột, KHÔNG có ngưỡng nào để đặt
   sai. Điện thoại ra 2 hàng × 3 ngày, máy tính vẫn 1 hàng × 6 ngày. */
.tt-tuan{display:grid;grid-template-columns:repeat(auto-fit,minmax(84px,1fr));
 gap:6px;margin-top:12px}
.tt-ngay{text-align:center;padding:7px 2px;border-radius:9px;
 background:var(--the);border:1px solid var(--vien);
 animation:tt-hien .45s cubic-bezier(.32,.72,0,1) backwards}
.tt-ngay b{display:block;font-size:11.5px;font-weight:600}
.tt-ngay span{display:block;font-size:12.5px;margin-top:2px}
.tt-ngay i{display:block;font-size:11px;font-style:normal;color:var(--mo)}
.tt-ngay:nth-child(1){animation-delay:.05s}
.tt-ngay:nth-child(2){animation-delay:.1s}
.tt-ngay:nth-child(3){animation-delay:.15s}
.tt-ngay:nth-child(4){animation-delay:.2s}
.tt-ngay:nth-child(5){animation-delay:.25s}
.tt-ngay:nth-child(6){animation-delay:.3s}
.tt-nguon{margin:10px 0 0;font-size:11.5px;color:var(--mo)}
@keyframes tt-hien{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes tt-tho{0%,100%{opacity:1}50%{opacity:.45}}
/* Ngưỡng `max-width:360px` cũ ĐÃ GỠ (§159.70): nó vá đúng iPhone SE nhưng để
   nguyên lỗi ở 361px trở lên — tức gần như mọi điện thoại đang dùng. `auto-fit`
   ở trên xử lý mọi bề ngang mà không cần ngưỡng nào. */
.tt-goc{color:var(--mo);font-size:12.5px;text-decoration:line-through}
td[data-den] b,td[data-di] b{
 display:inline-block;padding:1px 6px;border-radius:6px;font-weight:700;
 animation:tt-nhay 1.8s ease-in-out infinite}
tr.tt-som td b{color:var(--som);background:rgba(22,163,74,.15)}
tr.tt-dung td b{color:var(--dung);background:rgba(37,99,235,.15)}
tr.tt-tre td b{color:var(--tre);background:rgba(220,38,38,.15)}
/* Nhịp 1,8 giây = ~0,55 Hz, xa dưới ngưỡng 3 Hz của WCAG 2.3.1 — "nhấp nháy
   NHẸ" chứ không phải chớp giật. Đổi ĐỘ MỜ chứ không đổi kích thước: đổi kích
   thước là cả hàng bảng nhảy theo từng nhịp, đọc không nổi. */
@keyframes tt-nhay{0%,100%{opacity:1}50%{opacity:.5}}
/* KHÔNG cần luật `prefers-reduced-motion` riêng ở đây: khối toàn cục bên
   dưới đã ép `animation-iteration-count:1` cho MỌI thứ, tức nhấp nháy tự
   tắt với ai đã tắt hiệu ứng trong hệ điều hành. Thêm luật thứ hai chỉ là
   một chỗ nữa phải nhớ khi sửa. Màu vẫn giữ nguyên nên vẫn phân biệt
   được — hiệu ứng chỉ là dấu hiệu PHỤ, cùng lý do mỗi giờ thực tế đều
   mang một câu `title` bằng chữ. */
tr.tt-qua td{opacity:.72}
.them{margin:12px 0 0}
/* Nut VIEN CAM, khong phai hop xam: nen `--the` trung dung nen the bao ngoai
   nen ban dau nhin nhu mot o nhap bi khoa, lac han giua bang va nut cam dac
   ngay duoi. Vien cam + chu cam doc ra "bam duoc, nhung phu" - dung vai cua
   no canh nut `Dat ve tau`. `min-height:44px` theo bai hoc 159.31. */
.them>summary{cursor:pointer;list-style:none;
 display:inline-flex;align-items:center;gap:7px;min-height:44px;
 background:transparent;border:1px solid var(--cam);border-radius:999px;
 padding:0 18px;font-size:14.5px;font-weight:600;color:var(--cam);
 user-select:none}
.them>summary::-webkit-details-marker{display:none}
/* Mui ten viet bang KY TU THAT, khong dung escape SO cua CSS.
   Ban dau viet escape kieu backslash-203a qua nhieu lop trich dan, Python doc
   ba chu so dau thanh escape BAT PHAN = U+0083 (ky tu dieu khien) roi thua chu
   `a` - nut hien ra "... [o]a", mo ra thi "... [o]9". Khong loi, khong canh
   bao, chi co mot o vuong tren man hinh khach. Tep CSS da ghi UTF-8, ky tu
   that thi khong lop trich dan nao be duoc.
   Chinh cau chu thich nay luc dau CUNG dinh dung loi do - nen o day tuyet doi
   khong viet backslash kem chu so. */
.them>summary::after{content:"▾";font-size:12px}
.them[open]>summary::after{content:"▴"}
.them[open]>summary .mo-them,.them:not([open])>summary .an-bot{display:none}
.them>summary:focus-visible{outline:2px solid var(--cam);outline-offset:2px}
.them>.cuon{margin-top:12px}
.luoi a[hidden]{display:none}
/* §159.57 — to theo quan he voi ga dang xem. Chi doi VIEN + nen mo + mau dong
   tinh/thanh; ten ga giu nguyen mau chu de danh sach van doc nhu mot khoi. */
.luoi a.cung-tinh{border-color:var(--cam);background:var(--nen-cung)}
.luoi a.cung-tinh small{color:var(--cam)}
.luoi a.lien-ke{border-color:var(--ganh);background:var(--nen-ganh)}
.luoi a.lien-ke small{color:var(--ganh)}
/* Chu giai: mau khong tu no noi len dieu gi — thieu dong nay thi no chi la
   trang tri. Cham mau dung dung ky tu tron, khong dung anh. */
.chu-giai{display:flex;flex-wrap:wrap;gap:6px 14px;margin:0 0 10px;
 font-size:13px;color:var(--mo)}
.chu-giai span{display:inline-flex;align-items:center;gap:6px}
.chu-giai i{width:10px;height:10px;border-radius:3px;border:1px solid;
 flex-shrink:0}
.chu-giai .c-cung{border-color:var(--cam);background:var(--nen-cung)}
.chu-giai .c-ganh{border-color:var(--ganh);background:var(--nen-ganh)}
.luoi{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px}
.luoi a{background:var(--the);border:1px solid var(--vien);border-radius:9px;
 padding:9px 12px;text-decoration:none;color:var(--chu);font-size:14.5px}
/* Màn dọc điện thoại: `minmax(210px,…)` chỉ vừa MỘT cột trong khung 356px, mà
   chữ trung vị chỉ 131px — hơn nửa mỗi ô bỏ trống, và trang dài gấp đôi mức cần
   thiết. Ép đúng 2 cột: mỗi ô 174px, chừa 148px cho chữ.
   `minmax(0,1fr)` chứ không phải `1fr`: ô lưới mặc định không co dưới bề rộng
   nội dung, tên ga dài sẽ đẩy vỡ cột. */
@media(max-width:520px){
 .luoi{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}
 .luoi a{padding:9px 10px}
 /* Mác tàu có thêm hành trình trong `<small>`; nhồi cùng dòng thì 203px không
    vừa 148px. Cho xuống dòng riêng, thành thẻ hai dòng đọc rõ hơn hẳn. */
 .luoi a small{display:block;color:var(--mo);margin-top:2px}
}
/* Hẹp hơn nữa (iPhone SE 320px) thì khung chỉ còn ~256px, 2 cột là 124px mỗi
   ô — chữ trung vị đã 131px, ép nữa là dòng nào cũng gãy. Trả về một cột. */
@media(max-width:360px){.luoi{grid-template-columns:1fr}}
.ghichu{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412;
 border-radius:9px;padding:11px 13px;font-size:13.5px;margin:12px 0}
/* `viewport-fit=cover` cho trang tràn xuống tận đáy, nên chân trang phải tự
   chừa chỗ cho thanh gạt ngang của iPhone, không thì chữ nằm ngay dưới nó. */
.chan{color:var(--mo);font-size:12.5px;text-align:center;
 padding:16px calc(18px + env(safe-area-inset-right,0px))
         calc(30px + env(safe-area-inset-bottom,0px))
         calc(18px + env(safe-area-inset-left,0px))}
/* Dòng nguồn dữ liệu phải BÓ LẠI rồi xuống dòng, không kéo dài hết bề ngang —
   để tràn hai bên thì tuy `text-align:center` vẫn trông như căn trái, đúng cảnh
   chân trang cũ mà user đã chỉ ra. */
.chan p{max-width:34em;margin:0 auto 4px;line-height:1.55}
.chan p:last-child{margin-bottom:0}
/* Nền tối theo HAI đường, và thứ tự dưới đây là có chủ ý:
   1. Chưa chọn gì  → theo hệ điều hành (giữ nguyên hành vi cũ, không ai mất gì);
   2. Đã bấm nút    → `data-theme` trên <html> THẮNG, kể cả khi trái với hệ điều
      hành — người dùng bấm nút là đã nói rõ ý mình.
   `:not([data-theme="light"])` trong khối media chính là chỗ cho ý (2) thắng:
   chọn sáng giữa lúc hệ điều hành đang tối thì vẫn ra sáng.
   Khoá lưu `dsvn_theme` DÙNG CHUNG với trang đặt vé (cùng tên miền, cùng
   localStorage) nên đổi bên nào cũng ăn sang bên kia. */
@media(prefers-color-scheme:dark){
 :root:not([data-theme="light"]){--nen:#12161c;--the:#1a1f27;--chu:#e6e9ee;
  --mo:#9aa4b2;--vien:#2a303c;--som:#4ade80;--dung:#7dabff;--tre:#f87171;--vua:#f59e0b;
 --ganh:#5eead4;--nen-cung:rgba(234,91,12,.14);
 --nen-ganh:rgba(94,234,212,.10)}
 :root:not([data-theme="light"]) th{background:#222833}
 :root:not([data-theme="light"]) .ghichu{background:#2e1e0f;border-color:#7c3a10;
  color:#fbbf24}
 :root:not([data-theme="light"]) .datve input[type=date]{color-scheme:dark}
 :root:not([data-theme="light"]) .vecon-cuon th:first-child{background:#222833}
}
:root[data-theme="dark"]{--nen:#12161c;--the:#1a1f27;--chu:#e6e9ee;
 --mo:#9aa4b2;--vien:#2a303c;--som:#4ade80;--dung:#7dabff;--tre:#f87171;--vua:#f59e0b;
 --ganh:#5eead4;--nen-cung:rgba(234,91,12,.14);
 --nen-ganh:rgba(94,234,212,.10)}
:root[data-theme="dark"] th{background:#222833}
/* §159.78 — cột ghim phải ĐỤC nền theo đúng nền tối, không thì lúc trượt ngang
   chữ của cột sau hiện xuyên qua nó. Cần cả hai nhánh đổi nền, y như ô chọn
   ngày ở §159.67. */
:root[data-theme="dark"] .vecon-cuon th:first-child{background:#222833}
:root[data-theme="dark"] .ghichu{background:#2e1e0f;border-color:#7c3a10;color:#fbbf24}
/* §159.67 — ô chọn ngày là control GỐC của trình duyệt: lịch bật lên và cái
   biểu tượng lịch trong ô do trình duyệt vẽ, không nghe CSS của trang. Không
   khai `color-scheme` thì trên nền tối vẫn bung ra một tấm lịch trắng loá.
   Chỉ khai cho ĐÚNG ô này, không đặt lên `:root` — đặt ở gốc là đổi luôn cách
   vẽ thanh cuộn và mọi control khác trên cả 7.817 trang. */
:root[data-theme="dark"] .datve input[type=date]{color-scheme:dark}
/* Nút đổi nền — cùng hình dáng và cùng icon với trang đặt vé (`.theme-toggle`
   ở `services/web/index.html`), để hai nửa của cùng một site không lệch nhau. */
/* §159.49b — header nay CO HAI HANG nen `.dau` phai la CỘT.
   Ban dau toi de nguyen `.dau` la hang ngang roi nhet hang 2 vao lam item thu
   ba: no nam CUNG HANG, day tieu de "Gio tau · Gia ve" vo ba dong va cat mat
   o tai khoan o mep phai. Bo cuc cua hang 1 khong doi — chi chuyen len
   `.dau-hang1`. (`flex-wrap:wrap` tren `.dau` KHONG dung duoc: o 320px thi
   cum nut se roi xuong dong, hong ca hang dau.) */
.dau{display:flex;flex-direction:column;gap:9px;align-items:stretch;
 position:relative}
.dau-hang1{display:flex;align-items:center;justify-content:space-between;gap:12px}
.doi-nen{width:38px;height:38px;min-width:38px;flex-shrink:0;border-radius:10px;
 border:0;padding:0;-webkit-appearance:none;appearance:none;
 background:rgba(255,255,255,.2);color:#fff;cursor:pointer;
 display:flex;align-items:center;justify-content:center;
 touch-action:manipulation;-webkit-tap-highlight-color:transparent;
 transition:transform .15s cubic-bezier(.32,.72,0,1),background-color .2s}
.doi-nen svg{display:block;width:21px;height:21px;flex-shrink:0}
.doi-nen[hidden]{display:none}
.doi-nen:active{transform:scale(.92)}
.doi-nen:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media(hover:hover){.doi-nen:hover{background:rgba(255,255,255,.28)}}
