﻿/* =========================================================================
   BeautyShop — hệ thống thiết kế tối giản.
   Mobile-first theo D-8: vùng chạm ≥44px, cỡ chữ ô nhập ≥16px (chặn iOS tự phóng to),
   mỗi màn một hành động chính.
   ========================================================================= */

/*
   Bảng màu "noir & 24K gold", khớp với ba trang khách xem (wwwroot/css/luxury.css).

   Trước đây file này dùng tông kem + nâu đất #b06a4f, nên đăng nhập xong là người dùng rơi từ một
   website đen-vàng sang một website kem-nâu, tưởng như hai sản phẩm khác nhau. Toàn bộ file viết
   theo token nên đổi tông chỉ cần đổi ở đây; mọi trang quản trị đi theo.

   --on-brand là token MỚI và bắt buộc: nền nhấn giờ là VÀNG SÁNG, nên chữ trên đó phải là màu mực
   tối. Giữ nguyên "color: #fff" như cũ sẽ thành chữ trắng trên nền vàng - gần như không đọc được
   và trượt chuẩn tương phản WCAG.
*/
:root {
    --bg: #0d0b12;
    --surface: #16131f;
    --surface-2: #1f1b2b;
    --line: rgba(197, 168, 128, .22);
    --text: #faf7f2;
    --muted: #9e99a8;
    --brand: #d4af37;
    --brand-dark: #ecd7bf;
    --brand-soft: rgba(212, 175, 55, .14);
    --on-brand: #0c0a10;
    --ok: #34d399;
    --ok-soft: rgba(16, 185, 129, .15);
    --warn: #fbbf24;
    --warn-soft: rgba(245, 158, 11, .14);
    --error: #fca5a5;
    --error-soft: rgba(239, 68, 68, .15);
    --radius: 12px;
    --radius-sm: 8px;
    --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 10px 30px rgba(0, 0, 0, .45);
    --tap: 44px;
    /* Đường cong chung cho chuyển động (2026-10-22): ra / vào = ease-out mạnh, ngăn kéo / sheet = kiểu iOS. */
    --ease-out: cubic-bezier(.23, 1, .32, 1);
    --ease-drawer: cubic-bezier(.32, .72, 0, 1);
}

/*
   color-scheme: dark là MỘT dòng đổi rất nhiều thứ. Nó báo cho trình duyệt biết đây là giao diện
   tối, nên mọi điều khiển do HỆ ĐIỀU HÀNH vẽ tự đổi theo: ô chọn ngày, hộp select, ô tự điền
   (autofill) vốn bị tô vàng chói, thanh cuộn, con trỏ nhập. Thiếu dòng này thì CSS có tối cỡ nào,
   người dùng bấm vào ô chọn ngày vẫn nhận một hộp lịch trắng loá giữa màn hình đen.
*/
:root { color-scheme: dark; }

/* Thanh cuộn mặc định của Windows dày và xám sáng, cắt ngang giao diện đen-vàng trông như lỗi. */
html {
    /* Luôn chừa chỗ thanh cuộn: đổi trang / tab (ngắn ↔ dài, lúc đang tải) không làm thanh đầu nháy, nhích ngang. */
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: rgba(212, 175, 55, .35) transparent;
}

::-webkit-scrollbar { width: 10px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(212, 175, 55, .3); border-radius: 9999px; }
::-webkit-scrollbar-thumb:hover { background: rgba(212, 175, 55, .55); }

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

h1 { font-size: 1.5rem; margin: 0 0 .25rem; letter-spacing: -.01em; }
h2 { font-size: 1.1rem; margin: 0 0 .75rem; }
h3 { font-size: .95rem; margin: 1.5rem 0 .5rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
p { margin: 0 0 1rem; }
a { color: var(--brand-dark); }
code { background: var(--brand-soft); padding: .1em .35em; border-radius: 4px; font-size: .875em; }

.muted { color: var(--muted); }
.hint { color: var(--muted); font-size: .85rem; margin: .5rem 0 0; }
.empty { padding: 2rem; text-align: center; }

/* ---------- Trang chủ / xác thực ---------- */
.landing, .auth-wrap {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 1.25rem;
}

.landing-card, .auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.75rem;
}

.auth-back { display: inline-block; margin-bottom: 1rem; font-size: .875rem; text-decoration: none; }
.landing-actions { display: grid; gap: .75rem; margin-top: 1.5rem; }
.landing-actions .btn { flex-direction: column; align-items: flex-start; padding: .9rem 1rem; }
.landing-actions small { font-weight: 400; opacity: .8; }

.brand-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--brand); display: inline-block; }
.brand-dot-lg { width: 28px; height: 28px; margin-bottom: .75rem; }

/* ---------- Nút ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: var(--tap);
    padding: 0 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    font: inherit;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}

.btn-primary { background: var(--brand); color: var(--on-brand); }
.btn-primary:hover { background: var(--brand-dark); color: var(--on-brand); }
.btn-outline { border-color: var(--line); background: var(--surface); color: var(--text); }
.btn-outline:hover { border-color: var(--brand); }
.btn-ghost { color: var(--muted); }
.btn-ghost:hover { background: var(--brand-soft); color: var(--text); }
.btn-google { background: #ffffff; border-color: var(--line); color: #1f2937; }
.btn-telegram { background: #229ed9; color: #fff; }
.btn-block { display: flex; width: 100%; margin-bottom: .625rem; }
.btn-sm { min-height: 36px; font-size: .875rem; padding: 0 .75rem; }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-row { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0; }

.g-mark {
    display: grid; place-items: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--brand-soft); color: var(--brand-dark); font-weight: 700; font-size: .8rem;
}

/* ---------- Ô nhập ---------- */
.field { display: block; margin-bottom: 1rem; }
.field > span { display: block; font-size: .875rem; font-weight: 600; margin-bottom: .35rem; }

.input, .field input, .field select {
    width: 100%;
    min-height: var(--tap);
    padding: .5rem .75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font: inherit;
    font-size: 16px;   /* dưới 16px iOS tự phóng to trang khi bấm vào ô */
    color: var(--text);
}

.input:focus, .field input:focus { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand); }
.input-sm { min-height: 36px; font-size: .875rem; padding: .25rem .5rem; }

.check { display: flex; gap: .625rem; align-items: flex-start; margin-bottom: 1rem; }
.check > span { min-width: 0; }   /* chữ dài xuống dòng trong cột của nó, không đẩy tràn */

/*
   Ô CHỌN (checkbox / radio) không phải ô nhập chữ.

   Luật ".input, .field input" bên trên dựng khung rộng 100% + viền + chiều cao tối thiểu cho ô nhập chữ. Trước
   đây chỉ có checkbox được miễn, nên nút RADIO trong .field ăn nguyên luật đó: một khung khổng lồ chiếm hết
   chiều rộng, nút tròn phóng to, chữ bị ép xuống một cột hẹp bên phải (người dùng báo 2026-09-18 ở hộp thoại
   huỷ lịch). Liệt kê cả hai loại, và đặt lại mọi thứ luật kia đã áp.
*/
.check input[type=checkbox], .check input[type=radio],
.field input[type=checkbox], .field input[type=radio] {
    width: 20px;
    height: 20px;
    min-height: 0;
    margin-top: .2rem;
    padding: 0;
    flex: none;
    border: 0;
    background: none;
    accent-color: var(--brand);
}

.static-value { min-height: var(--tap); display: flex; align-items: center; }

.divider { display: flex; align-items: center; gap: .75rem; margin: 1.25rem 0; color: var(--muted); font-size: .8rem; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ---------- Thông báo ---------- */
.alert { padding: .75rem 1rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .9rem; border: 1px solid transparent; }
.alert-info { background: var(--brand-soft); border-color: rgba(212,175,55,.35); color: var(--brand-dark); }
.alert-ok { background: var(--ok-soft); border-color: rgba(16,185,129,.35); color: var(--ok); }
.alert-warn { background: var(--warn-soft); border-color: rgba(245,158,11,.35); color: var(--warn); }
.alert-error { background: var(--error-soft); border-color: rgba(239,68,68,.4); color: var(--error); }

/* ---------- Nhãn ---------- */
.badge {
    display: inline-block; padding: .1rem .5rem; border-radius: 999px;
    font-size: .75rem; font-weight: 600; margin-left: .35rem; white-space: nowrap;
}
.badge-ok { background: var(--ok-soft); color: var(--ok); }
.badge-warn { background: var(--warn-soft); color: var(--warn); }
.badge-off { background: rgba(255,255,255,.07); color: var(--muted); }
.badge-role { background: var(--brand-soft); color: var(--brand-dark); }
.pill { display: inline-block; min-width: 20px; padding: 0 .35rem; border-radius: 999px; background: var(--brand); color: var(--on-brand); font-size: .7rem; margin-left: .35rem; }

/* ---------- Khung quản trị ---------- */
.admin-shell { min-height: 100dvh; display: flex; flex-direction: column; }
.admin-top-left { display: flex; align-items: center; gap: .25rem; min-width: 0; }

.admin-top {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .75rem 1rem; background: var(--surface); border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 20;
}

.brand { display: flex; align-items: center; gap: .5rem; font-weight: 700; text-decoration: none; color: var(--text); }
.admin-who { display: flex; align-items: center; gap: .5rem; font-size: .875rem; }
.who-name { display: none; }

/*
   Menu dạng thanh bên, gom 4 nhóm theo việc người dùng đang làm (Vận hành · Bán hàng · Cửa hàng · Hệ thống).
   Trước đây là một hàng ngang 17 mục: màn rộng thì xuống 2 hàng, điện thoại thì phải cuộn ngang và đoán
   mục nào nằm khuất bên phải.

   Dưới 1024px menu thành ngăn kéo trượt từ trái, mở bằng nút ☰. Bật / tắt bằng ô checkbox ẩn + label,
   không cần JS — layout render tĩnh nên @onclick của Blazor không chạy ở đây.
*/
.admin-body { flex: 1; display: flex; align-items: flex-start; min-width: 0; }
.admin-body > .admin-main { flex: 1 1 auto; min-width: 0; }

.nav-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.nav-scrim { display: none; }
.nav-burger {
    display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
    border-radius: var(--radius-sm); font-size: 1.35rem; cursor: pointer; color: var(--text); user-select: none;
}
.nav-burger:hover { background: var(--brand-soft); }

.admin-nav {
    display: flex; flex-direction: column; gap: .1rem; flex: none; width: 236px;
    padding: .75rem .75rem 2rem; background: var(--surface); border-right: 1px solid var(--line);
    position: sticky; top: 61px; height: calc(100dvh - 61px); overflow-y: auto;
}

/* Mục đứng riêng (Tổng quan, Báo cáo) và mục trong nhóm dùng CHUNG màu chữ sáng; tên nhóm dùng màu vàng thương
   hiệu, chữ in hoa nhỏ — nhìn lướt là phân biệt được đâu là tiêu đề nhóm, đâu là trang bấm vào được. */
.nav-group { margin-top: .5rem; }
.nav-group:first-of-type { margin-top: .85rem; }

.nav-group > summary {
    list-style: none; display: flex; align-items: center; gap: .5rem; min-height: 40px;
    padding: .35rem .75rem; border-radius: var(--radius-sm); cursor: pointer; user-select: none;
    color: var(--brand); font-size: .72rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover { background: var(--brand-soft); }
.nav-group > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* Mũi tên: chỉ sang phải khi thu gọn, chỉ xuống khi mở. */
.nav-group > summary::after {
    content: ""; flex: none; width: .42rem; height: .42rem; margin-right: .15rem;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(-45deg); transition: transform .15s ease;
}
.nav-group[open] > summary::after { transform: rotate(45deg); }

.nav-group-title { flex: 1; }

/* Số mục chỉ hiện khi nhóm đang thu gọn: cho biết bên trong có gì mà không phải mở ra. */
.nav-group-count {
    font-size: .68rem; font-weight: 700; letter-spacing: 0; min-width: 1.35rem; padding: .05rem .4rem;
    border-radius: 9999px; text-align: center; color: var(--muted); background: rgba(255, 255, 255, .06);
}
.nav-group[open] .nav-group-count { display: none; }

.nav-group-items {
    display: flex; flex-direction: column; gap: .1rem;
    margin: .1rem 0 .35rem .85rem; padding-left: .5rem; border-left: 1px solid var(--line);
}

.nav-item {
    padding: .5rem .75rem; border-radius: var(--radius-sm); text-decoration: none;
    color: #ddd8e3; font-weight: 500; font-size: .9rem; min-height: 40px;
    display: flex; align-items: center;
}
.nav-item.nav-top { font-weight: 600; }
.nav-item:hover { background: rgba(255, 255, 255, .06); color: var(--text); }
.nav-item.active { background: var(--brand); color: var(--on-brand); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
    .nav-group > summary::after { transition: none; }
}

@media (min-width: 1024px) {
    .nav-burger { display: none; }
}

@media (max-width: 1023px) {
    .admin-nav {
        position: fixed; top: 0; left: 0; bottom: 0; z-index: 40; height: 100dvh;
        width: min(284px, 86vw); padding-top: 1.25rem;
        transform: translateX(-100%); transition: transform .2s ease;
        box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
    }
    .nav-toggle:checked ~ .admin-nav { transform: translateX(0); }
    .nav-toggle:checked ~ .nav-scrim { display: block; position: fixed; inset: 0; z-index: 35; background: rgba(0, 0, 0, .45); }
}

@media (prefers-reduced-motion: reduce) {
    .admin-nav { transition: none; }
}

/* Màn phân quyền */
.perm-group { margin: 1.1rem 0 .35rem; font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.perm-row { align-items: flex-start; padding: .35rem 0; }
.perm-row .hint { display: block; margin-top: .15rem; }
.perm-row.locked { opacity: .5; }

.admin-main, .page-wrap { padding: 1.25rem 1rem 5rem; max-width: 1080px; width: 100%; margin: 0 auto; }
.page-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin-bottom: 1rem; }

/* ---------- Thẻ nội dung ---------- */
.card {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.25rem; margin-bottom: 1.25rem;
}
.card-attention { border-color: var(--brand); }
.card-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.card-head h2 { margin: 0; }

.stack { display: grid; gap: .625rem; }

/* Đông khách cùng lúc: dòng gộp "còn N khách nữa" nằm dưới các thẻ, nhỏ và gọn hơn một thẻ thật. */
.arrival-more { display: block; text-align: center; font-weight: 600; text-decoration: none; }

/* Trang Customer care: hàng ô lọc tự xuống dòng, cột số căn phải, dòng đang chọn nổi lên. */
.cc-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.cc-row .field { flex: 1 1 11rem; margin-bottom: 0; }
.cc-row .cc-grow { flex: 2 1 20rem; }
.cc-chips { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: .75rem; }
.table .num { text-align: right; white-space: nowrap; }
.cc-picked { background: var(--brand-soft); }

/* Dòng phụ xám dưới tên khách / số tiền: gộp nhiều cột cũ vào một ô để bảng còn 5 cột, đọc được trên laptop. */
.cc-sub { display: block; color: var(--muted); font-size: .8rem; }
.cc-sub span { margin-right: .25rem; }

/* Bảng lọc gấp lại được: mở ra mới chiếm chỗ, đóng lại chỉ còn một dòng tóm tắt đang lọc gì. */
.cc-filters > summary { cursor: pointer; list-style: none; padding: .25rem 0; }
.cc-filters > summary::-webkit-details-marker { display: none; }
.cc-filters > summary::before { content: "▸ "; color: var(--muted); }
.cc-filters[open] > summary::before { content: "▾ "; }

/* Bảng chọn dịch vụ trong chi tiết lịch: bấm MỘT cái là thêm ngay, nên các ô phải to bằng ngón tay
   và xếp lưới để lễ tân quét mắt một lượt thấy hết, không phải mở select rồi cuộn. */
/* Dòng "khách làm thêm dịch vụ": nằm giữa dịch vụ cuối và dòng Tổng, nên phải trông như MỘT DÒNG NỮA của bảng.
   Viền đứt = chỗ còn trống, thêm được; chữ mờ để nó không tranh chỗ với con số Tổng ngay bên dưới. Chiều cao và
   lề trái khớp với các dòng dịch vụ phía trên nên cả cột tên vẫn thẳng. */
.svc-add {
    display: flex;
    align-items: center;
    gap: .4rem;
    width: 100%;
    min-height: 40px;
    margin: .15rem 0 .35rem;
    padding: 0 .5rem;
    border: 1px dashed var(--line);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: .9rem;
    text-align: left;
    cursor: pointer;
}

.svc-add:hover:not(:disabled) { border-color: var(--brand); border-style: solid; color: var(--text); background: var(--brand-soft); }
.svc-add:disabled { opacity: .5; cursor: default; }
.svc-add-plus { color: var(--brand); font-weight: 700; }

.svc-pick { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .75rem; background: var(--bg); }
.svc-pick-head { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-bottom: .625rem; }
.svc-pick-head .input { flex: 1 1 10rem; min-width: 0; }
/* Shared/ServicePicker (combo / mẫu gói): popup chồng lên form; hàng nhóm vuốt ngang + lưới chip cuộn trong khung. */
.modal-top { z-index: 110; }
.svc-picker-panel { max-width: 860px; }
.svc-picker-panel .svc-chip { padding-right: 1.9rem; }   /* chừa chỗ dấu ✓ góc phải, không đè lên tên */
.svc-pick-cats { display: flex; gap: .35rem; overflow-x: auto; scrollbar-width: none; padding: .6rem 0 .25rem; }
.svc-pick-cats::-webkit-scrollbar { display: none; }
.svc-pick-cats .chip { flex: none; min-height: 32px; font-size: .8rem; white-space: nowrap; }
.svc-pick-list { max-height: min(60vh, 34rem); overflow-y: auto; margin-top: .25rem; padding-right: .25rem; }
.svc-pick-list .svc-pick-label:first-child { margin-top: .25rem; }
@media (max-width: 639px) { .svc-pick-list { max-height: calc(100dvh - 15rem); } }
.svc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .4rem; }
.svc-chip {
    display: flex; flex-direction: column; gap: .15rem; text-align: left; cursor: pointer;
    padding: .5rem .625rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--bg-soft, transparent); color: inherit; font: inherit; min-height: 44px;
}
.svc-chip:hover:not(:disabled) { border-color: var(--brand); }
.svc-chip:active:not(:disabled) { transform: translateY(1px); }
.svc-chip:disabled { opacity: .5; cursor: default; }
.svc-chip-name { font-weight: 600; }
.svc-chip-meta { color: var(--muted); font-size: .8rem; }

/* Nhãn luật của món đang bán (Shared/SaleFlags): hạn · tích điểm · tính lượt. Có = xanh, không = mờ. */
.price-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: .25rem .75rem; margin: .3rem 0 .1rem; }
.price-line .price-now { font-size: 1.2rem; font-weight: 800; color: var(--brand); }
.price-line .price-was { font-size: .9rem; color: var(--muted); }
.price-line .price-save { font-size: .75rem; font-weight: 700; color: var(--ok); background: var(--ok-soft); border-radius: 999px; padding: .1rem .55rem; }
.sale-flags { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .3rem; }
.sale-flags .sf {
    font-size: .72rem; line-height: 1.2; padding: .15rem .45rem; border-radius: 999px; white-space: nowrap;
    border: 1px solid var(--line); color: var(--text);
}
.sale-flags .sf.on { border-color: rgba(52, 211, 153, .45); background: var(--ok-soft); color: var(--ok); }
.sale-flags .sf.off { border-color: rgba(239, 68, 68, .55); background: var(--error-soft); color: var(--error); }   /* ✗ phải nổi như ✓ (chủ shop 2026-10-12) */

/* Nhãn khối trong khung "khách làm thêm": 📦 trong gói · 🎁 combo · dịch vụ trả tiền (chủ shop chọn 2026-10-04). */
.svc-pick-label { font-size: .78rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; margin: .75rem 0 .35rem; }

/* Ô dịch vụ trong gói: viền xanh — đọc ra ngay "bấm là trừ buổi, khách không trả tiền". */
.svc-chip.pkg { border-color: var(--ok); background: var(--ok-soft); }
.svc-chip.pkg .svc-chip-meta { color: var(--ok); font-weight: 600; }

/* Đã thêm mấy lần: con số nhỏ ở góc nút, và viền nút đổi màu cho dễ thấy. */
.svc-chip { position: relative; }
.svc-chip.picked { border-color: var(--brand); background: var(--brand-soft); }
.svc-chip-n {
    position: absolute; top: .25rem; right: .3rem; min-width: 1.25rem; height: 1.25rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 999px; background: var(--brand); color: #fff;
    font-size: .72rem; font-weight: 700; line-height: 1;
}

/* ServicePicker Repeat (combo lặp dịch vụ): nút − nhỏ góc dưới phải, nằm NGOÀI chip (nút trong nút là HTML sai). */
.svc-chip-wrap { position: relative; display: grid; }
.svc-chip-minus {
    position: absolute; bottom: .25rem; right: .3rem; width: 1.6rem; height: 1.6rem; padding: 0;
    border: 1px solid var(--brand); border-radius: 999px; background: var(--bg); color: var(--brand);
    font: inherit; font-weight: 700; line-height: 1; cursor: pointer;
}

/* Dòng dịch vụ trong lịch: LƯỚI cột cố định nên tên thẳng tên, ô chọn thợ thẳng ô chọn thợ, giá thẳng giá.
   Dòng không sửa được vẫn chiếm đủ 5 ô (ô cuối để trống) — nếu không, các dòng lại lệch nhau. */
/* Cột cuối rộng 2.5rem để chứa trọn nút ✕ 36px. Trước đây cột chỉ 1.5rem (24px) mà nút cao 36px và còn
   margin-left, nên nó bị bóp méo và lệch khỏi hàng — người dùng nêu 2026-09-20: "nhìn không hài hoà". */
.svc-row {
    display: grid;
    grid-template-columns: minmax(6rem, 1fr) 9.5rem 5.5rem 5rem 2.5rem;
    align-items: center; gap: .5rem; padding: .3rem 0;
    border-bottom: 1px solid var(--line);
}
.svc-row:last-of-type { border-bottom: 0; }

/* Dòng tổng / thưởng / coupon / khách trả: cùng lưới, nhưng gộp hai cột giữa thành một ô ghi chú,
   nên con số tiền vẫn thẳng hàng với giá của từng dịch vụ. */
.svc-sum { grid-template-columns: minmax(6rem, 1fr) 15rem 5rem 2.5rem; }
.svc-sum .svc-note { color: var(--muted); font-size: .85rem; }
.svc-due { border-top: 1px solid var(--line); }
.svc-due .svc, .svc-due .price strong { color: var(--brand); font-weight: 700; }
.svc-due .price strong { font-size: 1.15em; }
.svc-minus .svc, .svc-minus .price { color: var(--muted); }

/* ===== Form thẻ trả cọc ngay trong trang =====
   Ô thẻ là iframe của Square: mình chỉ tạo khung, KHÔNG tô màu bên trong được. Nền sáng cho ô thẻ là cố ý —
   iframe của Square mặc định chữ tối, đặt nền tối vào là chữ đen trên đen. */
.pay-card { background: #fff; border-radius: .5rem; padding: .25rem .5rem; min-height: 56px; margin: .5rem 0; }

/* Đang mở form: KHÔNG để một hộp trắng trơn đứng im — nền tối + nhịp thở cho thấy nó đang làm việc.
   Nền chỉ chuyển sang trắng khi iframe của Square đã thật sự hiện ra (xem square-pay.js). */
.pay-card-loading {
    background: var(--surface);
    border: 1px dashed var(--line);
    animation: pay-card-breathe 1.4s ease-in-out infinite;
}

/* Không mở được thì gỡ hẳn khung đi, nhường chỗ cho lời nhắn + đường trả tiền khác. */
.pay-card-failed { display: none; }

@keyframes pay-card-breathe {
    0%, 100% { opacity: .55; }
    50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .pay-card-loading { animation: none; opacity: .8; }
}
.pay-amount { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .25rem; }

/* ===== Khung chờ của form thanh toán =====
   Mặc định: khung chờ HIỆN, phần thật ẨN. JS thêm .pay-ready khi ô thẻ đã dựng xong thì đổi ngược lại — nên
   khách không bao giờ nhìn một vùng trắng không rõ đang tải hay đã hỏng. */
/*
   Khung chờ PHỦ LÊN, không ẩn phần thật.

   Bản đầu dùng .pay-live { display: none } cho tới khi xong — sai nặng: ô thẻ bị display:none nên iframe của
   Square cao 0px, phép kiểm "iframe đã hiện chưa" thất bại, và trang báo "Card payment can't open on this page
   right now" dù mọi cấu hình đều đúng (người dùng báo 2026-09-18). Thư viện cần một cái ô CÓ KÍCH THƯỚC THẬT
   để vẽ vào.

   Nay phần thật luôn có layout bình thường; khung chờ là một lớp phủ tuyệt đối che nó, và bị bỏ khi form dựng
   xong. Khách vẫn không thấy form nửa vời, mà Square vẫn có chỗ thật để làm việc.
*/
.pay-shell { position: relative; }

.pay-skeleton {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: grid;
    align-content: center;
    gap: .5rem;
    padding: .5rem;
    background: var(--surface);
    border-radius: var(--radius-sm);
}

.pay-shell.pay-ready .pay-skeleton { display: none; }

.pay-skel {
    border-radius: .5rem;
    background: linear-gradient(90deg, var(--surface) 25%, var(--brand-soft) 37%, var(--surface) 63%);
    background-size: 400% 100%;
    animation: pay-skel-shine 1.4s ease-in-out infinite;
}

.pay-skel-wallet { height: 48px; }
.pay-skel-card { height: 56px; }
.pay-skel-btn { height: 44px; opacity: .6; }
.pay-skel-note { margin: .25rem 0 0; font-size: .85rem; color: var(--muted); text-align: center; }

@keyframes pay-skel-shine {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
    .pay-skel { animation: none; }
}

/* Ví điện tử: nút do Square vẽ vào trong ô của mình, nên ở đây chỉ lo KHUNG và khoảng cách.
   Ẩn sẵn bằng thuộc tính hidden — chỉ hiện khi thiết bị thật sự dùng được (xem square-pay.js). */
.pay-wallets { display: grid; gap: .5rem; margin: .5rem 0; }
.pay-wallets[hidden] { display: none; }
.pay-wallet-btn { min-height: 48px; }
.pay-wallet-btn > * { width: 100%; }

/*
   Nút Apple Pay phải do MÌNH vẽ (SDK của Square không có applePay.attach), và Apple bắt dùng đúng hình dáng của
   họ. Safari dựng hình nút từ chính thuộc tính này — không phải CSS trang trí, mà là một điều khiển của hệ
   thống. Trình duyệt nào không hiểu thì nút trông như nút thường, nhưng lúc đó applePay() đã ném lỗi từ trước
   nên nút cũng chẳng được tạo ra.
*/
/* Chỉ đường sang Safari cho khách mở link từ Telegram/Messenger trên iPhone. */
.pay-safari-hint {
    margin: .25rem 0 .75rem;
    padding: .6rem .75rem;
    border: 1px dashed var(--line);
    border-radius: .5rem;
    background: var(--brand-soft);
    color: var(--text);
    font-size: .85rem;
    line-height: 1.5;
}

.pay-safari-hint[hidden] { display: none; }

.pay-kbd {
    display: inline-block;
    padding: 0 .35rem;
    border: 1px solid var(--line);
    border-radius: .3rem;
    background: var(--surface);
    font-weight: 700;
    letter-spacing: .1em;
}

.apple-pay-btn {
    -webkit-appearance: -apple-pay-button;
    appearance: -apple-pay-button;
    -apple-pay-button-type: buy;
    -apple-pay-button-style: black;
    width: 100%;
    height: 48px;
    border: 0;
    border-radius: .5rem;
    cursor: pointer;
}
.pay-amount strong { font-size: 1.35rem; color: var(--brand-dark); }
.pay-status { min-height: 1.25rem; font-size: .875rem; color: var(--muted); margin: .25rem 0 .5rem; }
.pay-status-error { color: var(--danger, #f87171); }
.pay-or { display: flex; align-items: center; gap: .75rem; margin: 1.25rem 0 .75rem; color: var(--muted); font-size: .85rem; }
.pay-or::before, .pay-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Hộp thoại trả cọc: ở NGAY TRONG trang đặt lịch, không mở tab mới (người dùng yêu cầu 2026-09-18). */
.pay-modal {
    position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
    background: rgba(9, 8, 12, .78); padding: 1rem; overflow: auto; overscroll-behavior: contain;
    animation: pay-modal-fade 200ms ease both;
}
body:has(.pay-modal) { overflow: hidden; }   /* hộp mở thì trang nền không cuộn theo */
/* Hộp giữa màn: nở nhẹ từ 0.96 + mờ dần, 200ms (2026-10-22) — không còn bật "cái rụp". */
.pay-modal-card {
    width: 100%; max-width: 26rem; background: var(--surface); color: var(--text);
    border: 1px solid var(--line); border-radius: var(--radius); padding: 1.25rem;
    animation: pay-modal-pop 200ms var(--ease-out) both;
}
.pay-modal-card:focus { outline: none; }
@keyframes pay-modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pay-modal-pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .pay-modal-card { animation-name: pay-modal-fade; }
}
.pay-modal-head { display: flex; justify-content: space-between; align-items: center; gap: .5rem; margin-bottom: .5rem; }
.pay-modal-head h2 { margin: 0; font-size: 1.1rem; }
.pay-close { background: transparent; border: 0; color: var(--muted); font-size: 1.5rem; line-height: 1; cursor: pointer; min-height: 44px; min-width: 44px;
    touch-action: manipulation; -webkit-tap-highlight-color: transparent; transition: transform 160ms var(--ease-out); }
.pay-close:active { transform: scale(.92); transition-duration: 100ms; }

/* Hai lựa chọn loại trừ nhau (tra bằng Telegram / bằng email): nút dính nhau cho thấy rõ là CHỌN MỘT. */
.seg { display: flex; gap: 0; margin-bottom: .75rem; border: 1px solid var(--line); border-radius: .5rem; overflow: hidden; }
.seg-btn {
    flex: 1; padding: .6rem .5rem; font: inherit; font-size: .9rem; cursor: pointer;
    background: transparent; border: 0; color: var(--muted); min-height: 44px;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--line); }
/* Nút đang chọn: nền vàng MỜ của chính giao diện tối + gạch chân vàng. Trước đây dùng var(--ok-bg) —
   một token KHÔNG tồn tại, nên rơi về #f0fdf4 gần trắng, chữ --text cũng gần trắng → không đọc được gì
   (người dùng báo 2026-09-18). Giao diện này tối từ đầu tới cuối; đừng bao giờ đặt nền sáng vào đây. */
.seg-btn.on {
    background: var(--brand-soft); color: var(--text); font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--brand);
}

/* Thưởng thân thiết: khoản shop tự trừ cho khách, phải nhảy ra khỏi trang chứ không lẫn vào các dòng giảm giá. */
.svc-reward { background: var(--ok-soft); border-radius: .4rem; }
.svc-reward .svc, .svc-reward .price { color: var(--ok); }
.svc-reward .svc-note { color: var(--ok); opacity: .8; font-size: .85rem; }
.svc-row .price { text-align: right; }
.svc-row .svc-dur { text-align: right; white-space: nowrap; }
.svc-staff { width: 100%; min-width: 0; }
.input-xs { padding: .2rem .35rem; font-size: .85rem; height: auto; }

@media (max-width: 640px) {
    /* Điện thoại: tên chiếm cả hàng trên, thợ / thời lượng / giá / gỡ xuống hàng dưới nhưng vẫn thẳng cột. */
    .svc-row { grid-template-columns: 1fr 4.5rem 4.5rem 2.5rem; }
    .svc-row .svc { grid-column: 1 / -1; }
    .svc-sum { grid-template-columns: 1fr 5rem 2.5rem; }
    .svc-sum .svc-note { display: none; }
}

/* Sổ tin nhắn: một dòng một tin, bấm mới mở toàn văn. Dòng tóm tắt KHÔNG được xuống dòng, nếu không
   danh sách lại cao như cũ — phần nội dung cắt bằng ellipsis. */
.msg-list { display: grid; gap: .25rem; }
.msg { border-bottom: 1px solid var(--line); }
.msg > summary {
    display: flex; gap: .5rem; align-items: baseline; cursor: pointer; list-style: none;
    padding: .5rem .25rem; overflow: hidden; white-space: nowrap;
}
.msg > summary::-webkit-details-marker { display: none; }
.msg-time { color: var(--muted); font-variant-numeric: tabular-nums; flex: none; }
.msg-who { font-weight: 600; flex: none; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; }
.msg-what { color: var(--muted); flex: none; max-width: 11rem; overflow: hidden; text-overflow: ellipsis; }
.msg-line { color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.msg-body { white-space: pre-wrap; padding: .5rem .75rem; border-left: 3px solid var(--line); margin: 0 0 .5rem .25rem; }
.msg-meta, .msg-err { margin: 0 0 .5rem .25rem; color: var(--muted); font-size: .85rem; }
.msg-err { color: var(--warn); }
@media (max-width: 640px) {
    .msg > summary { flex-wrap: wrap; white-space: normal; }
    .msg-line { flex-basis: 100%; }
}

/* Một mã đã tặng trong đợt, kèm nút thu hồi. */
.cc-code { align-items: center; gap: .5rem; padding: .35rem 0; border-bottom: 1px solid var(--line); }
.cc-code:last-child { border-bottom: 0; }

/* Ô quét mã trên thanh công cụ Lịch hẹn: đầu đọc USB gõ vào ô rồi tự Enter. */
.scan-inline { display: flex; gap: .4rem; align-items: center; }
.scan-inline .input { min-width: 11rem; }
@media (max-width: 640px) {
    .scan-inline { width: 100%; }
    .scan-inline .input { flex: 1; min-width: 0; }
}

.row-card {
    display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; align-items: center;
    padding: .875rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--bg);
}
/* Phần chữ co lại nhường chỗ (flex 1 1 18rem) để nút luôn đứng cùng hàng, sát phải — trước đây dòng nào chữ dài là nút rớt xuống
   dưới bên trái, dòng ngắn thì nút bên phải (chủ shop 2026-10-20). Màn hẹp hơn 18rem + nút thì nút xuống hàng, vẫn sát phải. */
.row-main { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1 1 18rem; overflow-wrap: anywhere; }
.row-main .muted { font-size: .85rem; }
.row-actions { display: flex; flex-wrap: wrap; gap: .375rem; align-items: center; justify-content: flex-end; margin-left: auto; }
/* Nút trong dòng có màu (chủ shop 2026-10-20: chữ xám trơn trông thiếu chuyên nghiệp): việc thường = vàng nhạt,
   việc phá huỷ (Xoá, Vô hiệu, Hoàn tiền, Từ chối) = đỏ nhạt (.is-danger). Cùng bộ màu với tablet (.btn-tone). */
.row-actions .btn-ghost, .kc-actions .btn-ghost { background: var(--brand-soft); border-color: rgba(212, 175, 55, .3); color: var(--brand); }
.row-actions .btn-ghost:hover, .kc-actions .btn-ghost:hover { background: rgba(212, 175, 55, .24); border-color: var(--brand); color: var(--text); }
.btn-ghost.is-danger { color: var(--error); }
.row-actions .btn-ghost.is-danger, .kc-actions .btn-ghost.is-danger { background: var(--error-soft); border-color: rgba(239, 68, 68, .35); }
.btn-ghost.is-danger:hover { background: rgba(239, 68, 68, .26); border-color: rgba(239, 68, 68, .6); color: #fecaca; }

/* ---------- Thống kê ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; margin-bottom: 1.5rem; }
.stat {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1rem; display: flex; flex-direction: column; gap: .15rem;
}
.stat-alert { border-color: var(--brand); background: var(--brand-soft); }
.stat-num { font-size: 1.75rem; font-weight: 700; line-height: 1.1; }
.stat-label { font-size: .8rem; color: var(--muted); }
.stat-link { font-size: .8rem; font-weight: 600; margin-top: .35rem; text-decoration: none; }

/* ---------- Bảng ---------- */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.table th, .table td { text-align: left; padding: .625rem .5rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table th { font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); font-weight: 600; }
.col-check { text-align: center !important; width: 1%; white-space: nowrap; }
.col-check input[type=checkbox] { width: 20px; height: 20px; }

/* ---------- Danh sách khoá-giá trị ---------- */
.kv { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: .5rem 1rem; margin: 0; }
.kv dt { color: var(--muted); font-size: .875rem; }
.kv dd { margin: 0; }

.chip-list { list-style: none; padding: 0; margin: 0 0 1rem; display: grid; gap: .5rem; }
.chip { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .5rem .75rem; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: .875rem; }

/* ---------- Thanh công cụ / tab ---------- */
.toolbar { display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
.toolbar .input { max-width: 260px; }
.tabs { display: flex; gap: .25rem; }
.tab {
    min-height: 40px; padding: 0 .875rem; border: 1px solid var(--line); background: var(--surface);
    border-radius: var(--radius-sm); font: inherit; font-size: .875rem; font-weight: 600; color: var(--muted); cursor: pointer;
}
.tab.active { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
/* Tab đầu trang nối các trang cùng nhóm (CatalogTabs). Một thanh có nền riêng, tab đang mở nổi lên viền vàng —
   rõ hơn bản gạch chân mảnh (chủ shop 2026-10-19: khó nhìn) và vẫn khác nút .tab lọc trong trang (nền vàng đặc). */
.page-tabs {
    display: inline-flex; gap: .25rem; max-width: 100%; overflow-x: auto; margin-bottom: 1rem; padding: .25rem;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
}
.page-tab {
    display: inline-flex; align-items: center; min-height: 40px; padding: 0 1.15rem; white-space: nowrap;
    border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; cursor: pointer;
    font-family: inherit; font-size: .95rem; font-weight: 600; color: var(--muted); text-decoration: none; transition: background .15s, color .15s;
}
.page-tab:hover { color: var(--text); background: var(--surface); }
.page-tab.active { color: var(--brand); background: var(--brand-soft); border-color: var(--brand); font-weight: 700; }
@media (max-width: 640px) {
    /* Điện thoại: thanh tab trải hết chiều ngang, các tab chia đều — không còn tab cuối bị cắt mép (chủ shop 2026-10-20). */
    .page-tabs { display: flex; width: 100%; }
    .page-tab { flex: 1 1 auto; justify-content: center; padding: 0 .6rem; }
}

.grid-2 { display: grid; grid-template-columns: 1fr; gap: 0 1rem; }

/* ---------- Hành động chính dính đáy trên mobile ---------- */
.sticky-actions {
    position: sticky; bottom: 0; padding: .75rem 0;
    background: linear-gradient(to top, var(--bg) 70%, transparent);
}
.sticky-actions .btn { width: 100%; }

.test-accounts ul { margin: .5rem 0 0; padding-left: 1.1rem; font-size: .85rem; color: var(--muted); }
.test-accounts li { margin-bottom: .2rem; }

/* ---------- Màn hình rộng ---------- */
@media (min-width: 700px) {
    .who-name { display: inline; }
    .grid-2 { grid-template-columns: 1fr 1fr; }
    .sticky-actions .btn { width: auto; min-width: 200px; }
}

@media (max-width: 699px) {
    .table-commands thead { display: none; }
    .table-commands tr { display: grid; grid-template-columns: 1fr 1fr; gap: .35rem; padding: .75rem 0; border-bottom: 1px solid var(--line); }
    .table-commands td { border: 0; padding: .15rem .25rem; }
    .table-commands td[data-label]::before { content: attr(data-label) ": "; color: var(--muted); font-size: .75rem; }
    .table-commands td:first-child { grid-column: 1 / -1; }
}

/* ---------- Lỗi Blazor ---------- */
#blazor-error-ui {
    display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
    background: var(--warn-soft); border-top: 1px solid rgba(245,158,11,.35); padding: .75rem 1.25rem; box-shadow: var(--shadow);
}
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* =========================================================================
   Ô giải thích thu gọn (HelpNote)
   Mặc định đóng để trang gọn; mở ra thì đọc thoải mái trên cả điện thoại.
   ========================================================================= */
.help {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    margin: 0 0 1.25rem;
    overflow: hidden;
}

.help > summary {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: var(--tap);
    padding: 0 .875rem;
    cursor: pointer;
    list-style: none;
    font-size: .875rem;
    font-weight: 600;
    color: var(--muted);
    user-select: none;
}

.help > summary::-webkit-details-marker { display: none; }
.help > summary:hover { background: var(--brand-soft); color: var(--text); }
.help[open] > summary { border-bottom: 1px solid var(--line); color: var(--text); }

.help-icon {
    display: grid;
    place-items: center;
    flex: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--brand-soft);
    color: var(--brand-dark);
    font-size: .75rem;
    font-weight: 700;
}

.help[open] .help-icon { background: var(--brand); color: var(--on-brand); }

.help-body {
    padding: 1rem .875rem;
    font-size: .9rem;
    line-height: 1.6;
    max-width: 68ch;
}

.help-wide .help-body { max-width: none; }
.help-body > :last-child { margin-bottom: 0; }
.help-body ul, .help-body ol { padding-left: 1.2rem; margin: 0 0 .75rem; }
.help-body li { margin-bottom: .35rem; }
.help-body strong { color: var(--text); }
.help-body table { width: 100%; border-collapse: collapse; font-size: .85rem; margin-bottom: .75rem; }
.help-body th, .help-body td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid var(--line); }

/* =========================================================================
   Đặt lịch — thiết kế cho điện thoại trước
   ========================================================================= */

/* Thanh tiến trình các bước */
.wizard-steps { display: flex; gap: .25rem; margin-bottom: 1.25rem; }
.wizard-step {
    flex: 1;
    height: 4px;
    border-radius: 2px;
    background: var(--line);
}
.wizard-step.done { background: var(--brand); }
.wizard-step.current { background: var(--brand); opacity: .55; }
.wizard-caption { font-size: .8rem; color: var(--muted); margin-bottom: 1rem; }

/* Thẻ chọn (dịch vụ, KTV, chi nhánh) — cả thẻ là vùng bấm, không phải cái ô vuông tí xíu */
.pick-list { display: grid; gap: .625rem; margin-bottom: 1.25rem; }

.pick {
    display: flex;
    align-items: center;
    gap: .75rem;
    width: 100%;
    min-height: 60px;
    padding: .75rem .875rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.pick:hover { border-color: var(--brand); }
.pick.selected { border-color: var(--brand); background: var(--brand-soft); }
.pick-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.pick-name { font-weight: 600; }
.pick-meta { font-size: .8rem; color: var(--muted); }
.pick-price { font-weight: 700; white-space: nowrap; }
.pick-check {
    flex: none; width: 24px; height: 24px; border-radius: 50%;
    border: 2px solid var(--line); display: grid; place-items: center;
    font-size: .8rem; color: transparent;
}
.pick.selected .pick-check { border-color: var(--brand); background: var(--brand); color: var(--on-brand); }

/* Chọn ngày: dải ngang cuộn được bằng ngón tay */
.day-strip {
    display: flex; gap: .5rem; overflow-x: auto; padding-bottom: .5rem; margin-bottom: 1rem;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
}
.day-chip {
    flex: none; scroll-snap-align: start;
    min-width: 64px; min-height: 68px; padding: .5rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface); font: inherit; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .1rem;
}
.day-chip .dow { font-size: .7rem; color: var(--muted); text-transform: uppercase; }
.day-chip .dom { font-size: 1.15rem; font-weight: 700; }
.day-chip.selected { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.day-chip.selected .dow { color: rgba(255,255,255,.85); }
.day-chip:disabled { opacity: .4; cursor: not-allowed; }

/* Chọn giờ: lưới chip, 3 cột trên điện thoại */
.slot-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin-bottom: 1.25rem; }
.slot {
    min-height: var(--tap); padding: .5rem .25rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--surface); font: inherit; font-weight: 600; font-size: .95rem;
    cursor: pointer;
}
.slot:hover { border-color: var(--brand); }
.slot.selected { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }

.slot-empty {
    padding: 1.5rem 1rem; text-align: center; color: var(--muted);
    border: 1px dashed var(--line); border-radius: var(--radius-sm); margin-bottom: 1.25rem;
}

/* Tóm tắt trước khi xác nhận */
.summary-card { border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; margin-bottom: 1.25rem; }
.summary-row { display: flex; justify-content: space-between; gap: 1rem; padding: .75rem .875rem; border-bottom: 1px solid var(--line); }
.summary-row:last-child { border-bottom: 0; }
.summary-row .label { color: var(--muted); font-size: .875rem; }
.summary-total { background: var(--brand-soft); font-weight: 700; }

/* Điều hướng bước — dính đáy màn hình điện thoại, ngón cái với tới được */
.wizard-nav {
    position: sticky; bottom: 0; z-index: 10;
    display: flex; gap: .5rem; padding: .75rem 0;
    background: linear-gradient(to top, var(--bg) 65%, transparent);
}
.wizard-nav .btn { flex: 1; }
.wizard-nav .btn-back { flex: 0 0 auto; min-width: 64px; }

/* Mã đặt chỗ sau khi đặt xong */
.code-box {
    text-align: center; padding: 1.5rem 1rem; margin-bottom: 1.25rem;
    border: 2px dashed var(--brand); border-radius: var(--radius); background: var(--brand-soft);
}
.code-box .code {
    font-size: 2rem; font-weight: 800; letter-spacing: .12em;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--brand-dark);
}

/* Lịch trong ngày của lễ tân — thẻ trên điện thoại, hàng trên máy tính */
.day-list { display: grid; gap: .625rem; }
.bk-card {
    display: grid; gap: .5rem; padding: .875rem;
    border: 1px solid var(--line); border-left: 4px solid var(--line);
    border-radius: var(--radius-sm); background: var(--surface);
}
.bk-card.st-1 { border-left-color: var(--warn); }   /* chờ xác nhận */
.bk-card.st-2 { border-left-color: var(--brand); }
.bk-card.st-3 { border-left-color: var(--ok); }
.bk-card.st-4 { border-left-color: #6b7f6f; }
.bk-card.st-5, .bk-card.st-6 { border-left-color: #6b6578; opacity: .6; }
/*
   Lịch CÒN NỢ CỌC: chỗ chưa chắc chắn, nhưng nó nằm lẫn với lịch đã chắc trong cùng danh sách. Viền trái
   vàng-gạch + nền ấm để lễ tân nhìn một giây là biết (người dùng nêu 2026-09-18). Đặt SAU các luật .st-* nên
   nó thắng màu theo trạng thái — nợ tiền là thông tin quan trọng hơn "chờ xác nhận" hay "đã xác nhận".
*/
.bk-card.bk-unpaid {
    border-left-color: var(--warn);
    border-left-style: dashed;
    background: linear-gradient(90deg, var(--warn-soft) 0%, var(--surface) 42%);
}

.bk-time { font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------- Khối "chờ trả cọc": chỗ giữ tạm, tách khỏi danh sách làm việc ---------- */
.holds {
    border: 1px dashed var(--warn);
    border-radius: var(--radius-sm);
    background: var(--warn-soft);
    padding: .5rem .75rem;
    margin-bottom: 1rem;
}

.holds > summary {
    cursor: pointer;
    list-style: none;
    min-height: var(--tap);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
    font-weight: 600;
    color: var(--warn);
}

.holds > summary::-webkit-details-marker { display: none; }
.holds > summary .n { background: var(--warn); color: #241a05; border-radius: 999px; padding: 0 .45rem; font-size: .8rem; }
.holds > summary .muted { font-weight: 400; font-size: .85rem; }
.holds .bk-rows { margin-top: .5rem; }
.holds .bk-row-hold { border-left: 3px solid var(--warn); }

/* Đồng hồ trong dòng: không xuống hàng, không đổi chiều rộng khi số đổi. */
.hold-clock-inline { display: inline-flex; gap: .25rem; }
.hold-clock-inline strong { font-variant-numeric: tabular-nums; color: var(--warn); }
.hold-clock-inline.hold-soon strong { color: var(--danger, #f87171); }
.hold-clock-inline.hold-over strong { color: var(--muted); }
.bk-head { display: flex; justify-content: space-between; align-items: baseline; gap: .75rem; }
.bk-lines { font-size: .85rem; color: var(--muted); }
.bk-actions { display: flex; flex-wrap: wrap; gap: .375rem; }

@media (min-width: 700px) {
    .slot-grid { grid-template-columns: repeat(6, 1fr); }
    .wizard-nav { position: static; background: none; }
    .wizard-nav .btn { flex: 0 0 auto; min-width: 160px; }
}

@media (min-width: 900px) {
    .slot-grid { grid-template-columns: repeat(8, 1fr); }
}

/* =========================================================================
   Báo cáo — biểu đồ vẽ bằng CSS thuần.
   Không nạp thư viện biểu đồ: dữ liệu ở đây là vài chục cột, một trang báo cáo
   không đáng để tải thêm hàng trăm KB JavaScript và một điểm hỏng nữa.
   ========================================================================= */

/* Bốn con số lớn đầu trang */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; margin-bottom: 1.5rem; }
.kpi {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1rem; display: flex; flex-direction: column; gap: .15rem;
}
.kpi-main { border-color: var(--brand); background: var(--brand-soft); }
.kpi-num { font-size: 1.6rem; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; }
.kpi-label { font-size: .8rem; color: var(--muted); }
.kpi-note { font-size: .75rem; color: var(--muted); margin-top: .25rem; }

/* Biểu đồ cột theo ngày */
.bars { display: flex; align-items: flex-end; gap: 3px; height: 160px; overflow-x: auto; padding-bottom: .25rem; }
.bar-col { flex: 1 0 22px; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 2px; height: 100%; }
.bar-stack { width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 2px; height: 100%; }
.bar {
    width: 45%; min-height: 2px; border-radius: 3px 3px 0 0;
    transition: opacity .12s ease;
}
.bar-cash { background: var(--brand); }
.bar-earned { background: #6ee7b7; }
.bar-col:hover .bar { opacity: .75; }
.bar-label { font-size: .65rem; color: var(--muted); white-space: nowrap; }

.legend { display: flex; flex-wrap: wrap; gap: 1rem; font-size: .8rem; color: var(--muted); margin-top: .5rem; }
.legend span { display: inline-flex; align-items: center; gap: .35rem; }
.swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }

/* Bản đồ nhiệt giờ cao điểm */
.heat-wrap { overflow-x: auto; }
.heat { border-collapse: collapse; font-size: .7rem; }
.heat th { padding: 2px 4px; color: var(--muted); font-weight: 600; text-align: center; }
.heat td { padding: 0; }
.heat-cell {
    width: 22px; height: 22px; border-radius: 3px; display: block;
    background: var(--line);
}
.heat-row-label { text-align: right !important; padding-right: .5rem !important; white-space: nowrap; }

/* Thanh tỉ lệ nằm ngang (lấp đầy, xếp hạng) */
.meter { display: flex; align-items: center; gap: .625rem; margin-bottom: .5rem; }
.meter-name { flex: 0 0 90px; font-size: .875rem; }
.meter-track { flex: 1; height: 20px; background: var(--line); border-radius: 4px; overflow: hidden; }
.meter-fill { height: 100%; background: var(--brand); border-radius: 4px; }
.meter-fill.warn { background: var(--warn); }
.meter-fill.low { background: #6b6578; }
.meter-value { flex: 0 0 auto; font-size: .8rem; font-variant-numeric: tabular-nums; color: var(--muted); min-width: 88px; text-align: right; }

@media (min-width: 700px) {
    .kpi-num { font-size: 1.9rem; }
    .bars { height: 200px; }
    .meter-name { flex-basis: 130px; }
}

/* =========================================================================
   Màn hình danh mục dài (Dịch vụ, Kỹ thuật viên)

   VẤN ĐỀ CŨ: nút "+ Thêm" nằm CUỐI danh sách, và form sửa hiện ra NGAY DƯỚI nút đó. Với 17 dịch vụ
   đã phải cuộn; với 60 dịch vụ thì muốn thêm một món phải cuộn hết trang, và sửa một món ở đầu danh
   sách thì bấm "Sửa" xong màn hình không đổi gì — form nằm tít dưới đáy, người dùng tưởng nút hỏng.

   CÁCH SỬA:
     1. Thanh công cụ DÍNH ở đầu: tiêu đề, ô tìm, nút thêm luôn trong tầm mắt dù cuộn tới đâu.
     2. Form sửa thành CỬA SỔ NỔI giữa màn hình, không phụ thuộc vị trí cuộn.
     3. Nhóm THU GỌN ĐƯỢC kèm số lượng, để lướt qua cấu trúc trước rồi mới mở đúng nhóm cần.
   ========================================================================= */

.list-toolbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
    padding: .85rem 0;
    margin-bottom: .5rem;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}

.list-toolbar h1 { margin: 0; flex: none; }
.list-toolbar .spacer { flex: 1 1 auto; }

.list-search {
    flex: 1 1 220px;
    max-width: 340px;
    min-height: var(--tap);
    padding: 0 .9rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--text);
    /* 16px: nhỏ hơn thì iOS tự phóng to trang khi chạm vào ô nhập. */
    font-size: 1rem;
    font-family: inherit;
}

.list-search::placeholder { color: var(--muted); }
.list-search:focus { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand); }

.list-count { color: var(--muted); font-size: .85rem; }

/* ---------- Nhóm thu gọn ---------- */

.group-block {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    margin-bottom: .75rem;
    overflow: hidden;
}

.group-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .75rem;
    background: rgba(212, 175, 55, .06);
    border-bottom: 1px solid var(--line);
}

.group-toggle {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 1 1 auto;
    min-height: 40px;
    padding: 0;
    background: transparent;
    border: 0;
    color: var(--text);
    font: inherit;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}

.group-toggle .caret { color: var(--brand); font-size: .75rem; width: 1rem; flex: none; }
.group-toggle .group-name { text-transform: uppercase; letter-spacing: .06em; font-size: .8rem; }
.group-toggle .group-num { color: var(--muted); font-weight: 600; font-size: .8rem; }

.group-body { padding: .6rem; display: grid; gap: .5rem; }
.group-body:empty { display: none; }

/* Hàng trong nhóm: viền mảnh thay vì thẻ nổi, để 60 dòng không thành 60 hộp chen nhau. */
.group-body .row-card {
    background: var(--bg);
    border: 1px solid rgba(255, 255, 255, .07);
    border-radius: var(--radius-sm);
}

.group-body .row-card:hover { border-color: rgba(212, 175, 55, .35); }

/* ---------- Cửa sổ nổi để sửa ---------- */

.modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 1rem;
    overflow-y: auto;
}

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .72);
    backdrop-filter: blur(3px);
}

.modal-panel {
    position: relative;
    width: 100%;
    max-width: 720px;
    margin: 2rem 0 4rem;
    background: var(--surface);
    border: 1px solid var(--brand-soft);
    border-radius: var(--radius);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .7);
    padding: 1.25rem;
}

.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
    padding-bottom: .75rem;
    border-bottom: 1px solid var(--line);
}

.modal-head h2 { margin: 0; }

.modal-close {
    min-width: var(--tap);
    min-height: var(--tap);
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--muted);
    font-size: 1.1rem;
    cursor: pointer;
}

.modal-close:hover { color: var(--text); border-color: var(--brand); }

/* Hàng nút của cửa sổ dính ở đáy: form dài (dịch vụ có 10 ô) thì nút Lưu luôn trong tầm tay. */
.modal-foot {
    position: sticky;
    bottom: -1.25rem;
    display: flex;
    gap: .5rem;
    margin: 1.25rem -1.25rem -1.25rem;
    padding: .85rem 1.25rem;
    background: var(--surface);
    border-top: 1px solid var(--line);
}

.modal-foot .btn-primary { margin-left: auto; }

/* Con số trên tab: đi kèm chữ nên phải nhỏ và tròn, đủ để đọc lướt mà không kéo mắt khỏi tên tab. */
.tab-n {
    display: inline-block;
    min-width: 1.35rem;
    margin-left: .3rem;
    padding: 0 .3rem;
    border-radius: 9999px;
    background: var(--brand-soft);
    border: 1px solid var(--line);
    font-size: .75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

/* Tab đang mở: con số bám theo màu chữ của tab, nếu không nó trông như một nhãn rời. */
.tab.active .tab-n { border-color: var(--brand); color: var(--brand); }

/* Số lịch của NGÀY đang chọn, nằm ngay cạnh ô chọn ngày — bấm ‹ › là con số đổi theo. */
.day-n {
    display: inline-flex;
    align-items: baseline;
    gap: .25rem;
    padding: .2rem .5rem;
    border-radius: 9999px;
    border: 1px solid var(--line);
    color: var(--muted);
    font-size: .8rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Đang thật sự xem ngày đó thì con số sáng lên; còn lại nó chỉ là thông tin của ngày sắp chọn. */
.day-n.on { border-color: var(--brand); color: var(--brand); background: var(--brand-soft); }
.day-n-lbl { font-weight: 400; font-size: .75rem; }

.ahead-total { color: var(--muted); font-size: .8rem; white-space: nowrap; }
.ahead-total strong { color: var(--text); font-variant-numeric: tabular-nums; }

/* Hai dấu trên mục Lịch hẹn, hai màu vì hai việc khác nhau:
     XANH — còn mấy khách sẽ tới hôm nay (khối lượng còn lại của ca, chuyện bình thường);
     ĐỎ   — vừa có người check-in (có người đang đứng đợi NGAY LÚC NÀY, phải ra đón).
   Cùng màu thì mắt gộp chúng làm một và mất luôn ý nghĩa của cả hai. */
.nav-badge-today {
    background: var(--ok-soft);
    border: 1px solid rgba(52, 211, 153, .5);
    color: var(--ok);
    font-weight: 700;
}

.nav-badge-new {
    background: var(--error-soft);
    border: 1px solid rgba(239, 68, 68, .45);
    color: var(--error);
    font-weight: 700;
    animation: nav-new-pulse 1.6s ease-in-out infinite;
}

/* Nhấp nháy nhẹ để bắt mắt giữa một menu đứng yên — tắt hẳn cho ai không chịu được chuyển động. */
@keyframes nav-new-pulse { 50% { opacity: .45; } }

@media (prefers-reduced-motion: reduce) {
    .nav-badge-new { animation: none; }
}

/* ===== Lịch sử dùng coupon (trang tài khoản khách) =====
   Mỗi lần dùng là một khối: dòng đầu ngày giờ + số tiền mã gánh, rồi từng dịch vụ với người làm và giá. */
.use-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }

/* Tab Coupon ở hồ sơ khách (2026-10-20): mỗi coupon một thẻ bấm được, mở lịch sử dùng ngay dưới. */
.kc-tip { font-size: .85rem; }
.kc-group { display: flex; align-items: center; gap: .5rem; margin: 1.1rem 0 .55rem; font-size: .8rem; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.kc-group span { padding: 0 .45rem; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text); letter-spacing: 0; }
.kc-list { display: grid; gap: .6rem; }
.kc { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); overflow: hidden; transition: border-color .2s ease; }
.kc:hover, .kc.is-open { border-color: rgba(212, 175, 55, .45); }
.kc-head {
    display: grid; grid-template-columns: minmax(0, 1fr) auto 1.25rem; align-items: center; gap: .55rem 1rem;
    width: 100%; padding: .9rem 1rem; border: 0; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.kc-head:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.kc-id { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .6rem; min-width: 0; }
.kc-id .cp-code { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }
.kc-batch { font-size: .85rem; color: var(--muted); overflow-wrap: anywhere; }
.kc-amount { display: flex; align-items: baseline; gap: .3rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.kc-amount strong { font-size: 1.35rem; color: var(--brand); }
.kc-amount span { color: var(--muted); font-size: .9rem; }
.kc-chevron { width: .55rem; height: .55rem; justify-self: center; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(45deg) translateY(-2px); transition: transform .2s ease; }
.kc.is-open .kc-chevron { transform: rotate(-135deg) translateY(-2px); border-color: var(--brand); }
.kc-bar { grid-column: 1 / -1; height: 5px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.kc-bar > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--brand), #ecd27a); }
.kc-meta { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .9rem; font-size: .85rem; color: var(--muted); }
.kc-held { color: var(--warn); }
.kc.is-spent .kc-amount strong { color: var(--muted); }
.kc.is-void .kc-amount strong { text-decoration: line-through; }
.kc.is-spent .kc-id .cp-code { color: var(--muted); }
.kc-body { padding: .2rem 1rem 1rem; border-top: 1px solid var(--line); background: var(--surface); }
.kc-body > .use-list { margin-top: .85rem; }
.kc-body > p { margin: .85rem 0 0; }
.kc-actions { display: flex; flex-wrap: wrap; gap: .375rem; justify-content: flex-end; margin-top: .85rem; }
.kc-owner { color: var(--text); font-weight: 600; }
.kc-facts { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .8rem; margin: .85rem 0 0; font-size: .85rem; color: var(--muted); overflow-wrap: anywhere; }
.kc-note { margin: .85rem 0 0; }
.kc-expiry { margin-top: .85rem; align-items: center; }
.kc-more { margin-top: .75rem; }
.kc-trace { margin-top: 1.5rem; }
.kc-trace > summary { display: flex; align-items: center; justify-content: space-between; gap: .5rem; cursor: pointer; list-style: none; }
.kc-trace > summary::-webkit-details-marker { display: none; }
.kc-trace > summary h2 { margin: 0; font-size: 1.05rem; }
.kc-trace > summary::after { content: ""; width: .5rem; height: .5rem; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(45deg); transition: transform .2s ease; }
.kc-trace[open] > summary::after { transform: rotate(-135deg); }
.kc-trace[open] > summary { margin-bottom: .6rem; }
@media (max-width: 560px) {
    /* Điện thoại: số tiền xuống hàng thứ hai, mã + tên loại có trọn hàng đầu. */
    .kc-head { grid-template-columns: minmax(0, 1fr) 1.25rem; }
    .kc-amount { grid-row: 2; grid-column: 1; }
    .kc-chevron { grid-row: 1; grid-column: 2; }
    .kc-body { padding: .2rem .75rem .85rem; }
}
.use { border: 1px solid var(--line); border-radius: var(--radius); padding: .7rem .85rem; }
.use-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.use-when { font-weight: 700; }
.use-paid { font-weight: 700; color: var(--brand); font-variant-numeric: tabular-nums; white-space: nowrap; }
.use-sub { font-size: .85rem; margin-top: .15rem; }

/* Kiểu dùng: dòng ngắn ngay dưới số tiền, vì đó là câu trả lời cho "sao lại trừ?". */
.use-kind { font-size: .85rem; margin-top: .15rem; color: var(--ok); }

/* Mất cọc vì huỷ lịch: viền và chữ đỏ. Đây là tiền MẤT, không phải tiền đổi lấy dịch vụ — nhìn phải khác ngay. */
.use-forfeit { border-color: rgba(239, 68, 68, .45); }
.use-forfeit .use-kind { color: var(--error); }
.use-forfeit .use-paid { color: var(--error); }

.use-lines { list-style: none; margin: .5rem 0 0; padding: .5rem 0 0; border-top: 1px solid var(--line); display: grid; gap: .3rem; }
.use-lines > li {
    display: grid;
    grid-template-columns: minmax(6rem, 1fr) minmax(4rem, auto) 5rem;
    gap: .5rem; align-items: baseline; font-size: .9rem;
}
.use-lines .price { text-align: right; font-variant-numeric: tabular-nums; }

/* Công cụ coupon gập lại: mặc định chỉ một dòng tiêu đề, mở ra khi cần. */
details.coupon-apply > summary {
    cursor: pointer;
    padding: .35rem 0;
    font-weight: 600;
    color: var(--text);
    list-style: none;
}
details.coupon-apply > summary::-webkit-details-marker { display: none; }
details.coupon-apply > summary::before { content: "▸ "; color: var(--muted); }
details.coupon-apply[open] > summary::before { content: "▾ "; }

/* ---------- Thanh thanh toán dính đáy (trang Lịch hẹn) ----------
   Người dùng yêu cầu 2026-09-19: mở hộp thanh toán là phải THẤY NGAY hai nút tiền mặt / thẻ, không phải kéo
   xuống. Hai thanh sticky chồng nhau (thanh tiền, rồi thanh Đóng/Huỷ) nên thanh tiền phải nằm TRÊN, và nền đục
   để chữ phía dưới không lộ qua. */
.pay-bar {
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem .6rem;
    border-top: 2px solid var(--brand-soft);
}

/* HÀNG 1: tiền bên trái, hai nút hình thức và nút hoàn thành bám sát nhau bên phải.
   HÀNG 2: Đóng / Huỷ lịch, CỐ Ý cho xuống dòng riêng và canh phải — nhồi sáu nút một hàng trong hộp 640px thì
   trình duyệt tự ngắt ở chỗ xấu, và hai nút nguy hiểm lại nằm cạnh nút thu tiền. */
.pay-sum { display: flex; align-items: baseline; gap: .4rem; margin-right: auto; }
.pay-label { color: var(--muted); font-size: .85rem; }
.pay-amount { font-size: 1.25rem; font-weight: 700; color: var(--text); line-height: 1.2; }
.pay-note { color: var(--muted); font-size: .8rem; }

.pay-side { display: flex; gap: .4rem; flex: 1 0 100%; justify-content: flex-end; }

/* Điểm như tiền: mục gập "💎 Điểm" dưới Coupon (2026-10-18 — trước nằm trong thanh dính đáy, rối mắt): ô điểm = $, Tối đa, Áp điểm. */
.pay-points { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; padding: .5rem 0; }
.pay-points-act { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-left: auto; }
.pay-points-amt { width: 7rem; }
.pay-points-off { color: var(--muted); }
.pay-points-err { flex: 1 0 100%; color: var(--error); font-weight: 600; font-size: .85rem; }
.pts-undo { padding: .1rem .45rem; font-size: .8rem; border: 1px solid currentColor; border-radius: .4rem;
            background: transparent; color: var(--ok); cursor: pointer; }
.pts-undo:disabled { opacity: .5; cursor: default; }

/* Lỗi thu tiền: một hàng riêng trên cùng của thanh dính đáy, để luôn trong tầm mắt. */
.pay-bar > .alert { flex: 1 0 100%; margin: 0; }

/* Nút hoàn thành: bỏ margin-left:auto của .modal-foot — cụm tiền đã đẩy sang phải rồi. */
.pay-bar .btn-primary { margin-left: 0; }

/* Trong thanh thì hai nút hình thức là CHIP NHỎ nằm cạnh nhau: .method-big vốn có flex:1 1 140px nên trong hộp
   hẹp nó giãn ra rồi rớt xuống hai dòng — đó là chỗ làm thanh cao gấp ba và trông lệch. */
.method-compact .method-picker { display: flex; flex-wrap: nowrap; gap: .4rem; margin: 0; }
.method-compact .method-big {
    flex: 0 0 auto;
    min-height: 40px;
    padding: .45rem .8rem;
    font-size: .9rem;
    white-space: nowrap;
    border-radius: 10px;
}

@media (max-width: 639px) {
    /* Màn hẹp: tiền một dòng, hai nút hình thức một dòng, nút hoàn thành trọn chiều ngang — vẫn trong tầm mắt. */
    .pay-sum { flex: 1 0 100%; margin-right: 0; }
    .method-compact { flex: 1 1 auto; }
    .method-compact .method-big { flex: 1 1 0; }
    .pay-bar .btn-primary { flex: 1 0 100%; order: 3; }
    .pay-side { order: 4; }

    /* Điện thoại (chủ shop 2026-11-06): áp coupon xong, số "Còn thu" trên thanh STICKY không vẽ lại tới khi kéo xuống hết —
       trình duyệt di động giữ ảnh cũ của phần tử sticky trong hộp cuộn (translateZ cũng không chữa được). Nên trên điện thoại
       bỏ sticky: hộp cao đúng một màn hình, chia ba tầng — đầu · thân TỰ CUỘN · thanh tiền là tầng đáy thường, luôn nằm đó. */
    .modal-panel:has(> .pay-bar) { height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
    .modal:has(> .modal-panel > .pay-bar) { overflow: hidden; }   /* một lớp cuộn duy nhất là phần thân */
    /* Thân phủ tới SÁT MÉP (lề trong chuyển vào padding): để lề của hộp ngoài thì vuốt sát mép phải chạm vào hộp ngoài
       — hộp đó không cuộn, nên "vuốt không ăn" (chủ shop 2026-11-06). */
    .modal-panel:has(> .pay-bar) > .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
                                                 margin: 0 -1.25rem; padding: 0 1.25rem; }
    .modal-panel:has(> .pay-bar) > .pay-bar { position: static; flex: none; }
}

@media (max-width: 639px) {
    /* Tiêu đề chiếm trọn một dòng, ô tìm và bộ đếm xuống dòng dưới. Nhồi cả ba lên một hàng ở
       390px thì bộ đếm bị đẩy ra khỏi mép màn hình. */
    .list-toolbar h1 { font-size: 1.25rem; flex: 1 0 100%; }
    .list-search { max-width: none; }
    .modal { padding: 0; }
    .modal-panel { margin: 0; min-height: 100dvh; border-radius: 0; border: 0; }
}

/* ---------- Chip nhiều lựa chọn ----------
   Dùng cho ô chọn kỹ năng của kỹ thuật viên. Trước đây mỗi dịch vụ là một hàng chiếm trọn chiều
   ngang: 17 dịch vụ đã phải cuộn trong hộp, 60 dịch vụ thì không dùng nổi. Chip xếp theo dòng nên
   cùng diện tích đó chứa được gấp năm sáu lần, và mắt quét một lượt là thấy hết đã tick những gì. */

/* Mỗi nhóm là một ô riêng, nền nhạt hơn nền trang — tách nhóm bằng khối chứ không bằng chữ to/màu gắt (chủ shop
   2026-10-09: chữ hoa vàng + vạch + nút "Chọn hết" rời rạc nhìn rối). Nút chọn hết dồn về mép phải, cùng một chỗ ở mọi nhóm. */
.skills-head { display: flex; align-items: center; gap: .6rem; margin: 1.25rem 0 .75rem; }
.skills-head h3 { margin: 0; }
.skills-head h3 .muted { font-weight: 400; }
.skills-count, .chip-group-head .n {
    font-size: .78rem; font-variant-numeric: tabular-nums; color: var(--muted);
    padding: .1rem .5rem; border-radius: 999px; background: var(--brand-soft); white-space: nowrap;
}
.skills-head .chip-all { margin-left: auto; }

.chip-group {
    margin-bottom: .6rem;
    padding: .7rem .85rem .85rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.chip-group-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem; }
/* Font nạp chỉ có tới 700 — đặt 800 là trình duyệt tự làm đậm giả, nét nhoè. */
.chip-group-head .name { font-size: .95rem; font-weight: 600; color: var(--brand); }
.chip-group-head .chip-all { margin-left: auto; }

.chip-all {
    border: 1px solid var(--line); background: transparent; color: var(--brand);
    font: inherit; font-size: .8rem; font-weight: 600;
    padding: .25rem .7rem; border-radius: 999px; cursor: pointer; white-space: nowrap;
}
.chip-all:hover { border-color: var(--brand); background: var(--brand-soft); }

.chips { display: flex; flex-wrap: wrap; gap: .4rem; }

.chip {
    min-height: 36px;
    padding: 0 .8rem;
    border-radius: 9999px;
    border: 1px solid var(--line);
    background: var(--bg);
    color: var(--text);
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}

.chip:hover { border-color: var(--brand); }

.chip.selected {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--on-brand);
    font-weight: 700;
}

/* Trong ô nhóm kỹ năng: vàng dành cho tên nhóm. Chip phân biệt bằng ĐỘ SÁNG + dấu ✓ chứ không bằng màu — chọn hết cả nhóm
   mà chip cũng vàng đậm thì cả màn hình một màu (chủ shop 2026-10-09). Chưa chọn: chữ mờ, nền trong; đã chọn: nền vàng rất nhạt,
   chữ màu kem — nhạt hơn hẳn vàng của tên nhóm. */
.chip-group .chip {
    min-height: 32px; padding: .3rem .75rem; font-size: .82rem; line-height: 1.3; text-align: left;
    background: transparent; color: var(--muted);
}
.chip-group .chip:hover { color: var(--text); border-color: rgba(212, 175, 55, .5); }
.chip-group .chip.selected {
    background: rgba(212, 175, 55, .12); border-color: rgba(212, 175, 55, .32); color: #efe4c4; font-weight: 500;
}
.chip-group .chip.selected::before { content: "✓"; color: var(--brand); font-weight: 700; margin-right: .4rem; }

/* =========================================================================
     4. MÀN HÌNH LỊCH HẸN
     Lễ tân cần đọc một thẻ trong hai giây: ai, số nào, làm gì, bao nhiêu tiền, đã chốt chưa.
     Vì vậy mọi thứ nằm trên thẻ chứ không giấu sau một cú bấm "xem chi tiết".
   ========================================================================= */

/* Hàng chọn khoảng thời gian + hàng bộ lọc.
   Trên điện thoại chúng TRƯỢT NGANG chứ không xuống dòng: mười cái nút xuống dòng thì đẩy danh sách
   xuống quá màn hình, mở trang lên chỉ thấy toàn nút. */
.scope-row { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-bottom: .6rem; }

.day-picker { display: flex; align-items: center; gap: .35rem; }
.day-picker .input { width: auto; }

.input-sm { min-height: 36px; padding: 0 .6rem; font-size: .85rem; width: auto; }

.filter-strip {
    display: flex;
    gap: .4rem;
    margin-bottom: .5rem;
    overflow-x: auto;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.filter-strip > * { flex: 0 0 auto; }
.filter-strip::-webkit-scrollbar { height: 4px; }
.filter-strip::-webkit-scrollbar-thumb { background: var(--brand-soft); border-radius: 2px; }

.chip-btn {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 34px;
    padding: 0 .75rem;
    border-radius: 9999px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--muted);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
    transition: border-color .12s ease, color .12s ease, background .12s ease;
}

.chip-btn:hover { border-color: var(--brand); color: var(--text); }
.chip-btn .n { font-variant-numeric: tabular-nums; font-weight: 700; opacity: .75; }

.chip-btn.selected {
    background: var(--brand-soft);
    border-color: var(--brand);
    color: var(--text);
    font-weight: 700;
}

/* Vạch ngày: danh sách trải dài hai tháng thì phải biết mình đang đọc ngày nào. */
.day-sep {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin: 1.4rem 0 .6rem;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--line);
    font-size: .95rem;
    letter-spacing: .02em;
}

.day-sep .muted { font-size: .82rem; font-weight: 400; }

.bk-who { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }

/* Số điện thoại là thứ lễ tân bấm nhiều nhất — trên điện thoại nó gọi thẳng. */
.bk-phone {
    color: var(--brand);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
    border-bottom: 1px dotted rgba(212, 175, 55, .5);
}

.bk-phone:hover { color: var(--brand-dark); }

.bk-line {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem;
    padding: .15rem 0;
}

.bk-line .svc { color: var(--text); font-weight: 600; }
.bk-line .price { margin-left: auto; color: var(--text); font-variant-numeric: tabular-nums; }

.bk-meta { display: flex; flex-wrap: wrap; gap: .35rem; }

.tag {
    padding: .15rem .5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--muted);
    font-size: .78rem;
}

.tag-ok { border-color: rgba(16, 185, 129, .35); color: var(--ok); }
.tag-warn { border-color: rgba(245, 158, 11, .4); color: var(--warn); }

.bk-notes {
    display: grid;
    gap: .25rem;
    padding: .5rem .65rem;
    border-left: 2px solid var(--brand-soft);
    background: var(--bg);
    border-radius: var(--radius-sm);
    font-size: .85rem;
    color: var(--muted);
}

.bk-notes strong { color: var(--text); }

.modal-body { display: grid; gap: .75rem; }

/* Nút của việc không lấy lại được. Màu đỏ ở đây là để người ta khựng lại nửa giây. */
.btn-danger { background: var(--error); border-color: var(--error); color: #2b0a0a; font-weight: 700; }
.btn-danger:hover { background: #f87171; border-color: #f87171; color: #2b0a0a; }
.modal-foot .btn-danger { margin-left: auto; }

/* ---------- Lịch cũ: một DÒNG cho một lịch, bấm vào mới mở chi tiết ----------
   Màn hình tra cứu khác hẳn màn hình làm việc. Ở đây người ta lướt tìm một cái tên trong hàng trăm
   lịch, nên mỗi lịch phải gọn bằng một dòng; chi tiết và nhật ký nằm trong cửa sổ mở ra sau. */

.bk-rows { display: grid; gap: .3rem; }

.bk-row {
    display: flex;
    align-items: center;
    gap: .65rem;
    width: 100%;
    padding: .55rem .7rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.bk-row:hover { border-color: var(--brand); }
.bk-row.st-1 { border-left-color: var(--warn); }
.bk-row.st-2 { border-left-color: var(--brand); }
.bk-row.st-3 { border-left-color: var(--ok); }
.bk-row.st-4 { border-left-color: #6b7f6f; }
.bk-row.st-5, .bk-row.st-6 { border-left-color: #6b6578; }

.bk-row .r-time { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; font-size: .9rem; }

/* min-width: 0 là thứ duy nhất cho phép ô giữa co lại; thiếu nó thì tên dài đẩy giá tiền ra khỏi
   màn hình điện thoại thay vì bị cắt bằng dấu ba chấm. */
.bk-row .r-main { flex: 1 1 auto; min-width: 0; display: grid; }
.bk-row .r-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bk-row .r-svc { color: var(--muted); font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bk-row .r-right { flex: none; display: flex; align-items: center; gap: .5rem; }
.bk-row .r-money { font-variant-numeric: tabular-nums; font-size: .85rem; }

/* ---------- Nhật ký thay đổi ---------- */

.tl-title { margin: .5rem 0 .25rem; font-size: .95rem; }

.timeline { list-style: none; margin: 0; padding: 0 0 0 .75rem; border-left: 2px solid var(--brand-soft); display: grid; gap: .5rem; }

.timeline li { display: grid; gap: .1rem; position: relative; font-size: .85rem; }

.timeline li::before {
    content: "";
    position: absolute;
    left: -1.08rem;
    top: .45rem;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand);
}

.tl-when { color: var(--muted); font-size: .78rem; font-variant-numeric: tabular-nums; }
.tl-who { color: var(--muted); margin-left: .35rem; }

/* Bốn ô số liệu thấp hơn trên điện thoại — chúng là thông tin liếc qua, không phải nội dung chính. */
@media (max-width: 639px) {
    .stat-grid-tight { grid-template-columns: 1fr 1fr; gap: .5rem; }
    .stat-grid-tight .stat { padding: .55rem .7rem; }
    .stat-grid-tight .stat-num { font-size: 1.25rem; }
    .stat-grid-tight .stat-label { font-size: .72rem; }

    .bk-row { gap: .5rem; padding: .5rem .55rem; }
    .bk-row .r-right { flex-direction: column; align-items: flex-end; gap: .15rem; }
    .bk-row .r-right .badge { font-size: .68rem; }

    .day-sep { margin: 1rem 0 .45rem; font-size: .88rem; }
    .bk-card { padding: .7rem; }
    .bk-line .price { margin-left: auto; }
}

/* Ô sửa tên lệnh Telegram: dấu "/" đứng ngoài ô nhập để không ai gõ nhầm nó vào trong. */
.cmd-edit { display: inline-flex; align-items: center; gap: .15rem; }
.cmd-edit .slash { color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.cmd-name {
    width: 9.5rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .85rem;
}
.cmd-name:disabled { color: var(--muted); background: var(--bg); cursor: not-allowed; }

/* Hàng dịch vụ: tên tiếng Anh và giá phải đọc được ngay, không phải mở hộp thoại mới thấy. */
.row-en { color: var(--brand); font-size: .85rem; }
.row-price { color: var(--text); font-variant-numeric: tabular-nums; }
.row-was { text-decoration: line-through; opacity: .65; margin-left: .3rem; }

/* Ô số điện thoại trong bảng người dùng: ô nhập và nút Lưu nằm cùng một dòng, không tách hai hàng. */
.phone-cell { display: flex; align-items: center; gap: .3rem; }
/* Danh sách Người dùng (NguoiDung.razor) — thiết kế lại 2026-10-14: dòng tóm tắt + khung "Sửa" */
.u-list { display: grid; gap: .6rem; margin-top: .75rem; }
.u-item { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.u-item.open { border-color: var(--brand); }
.u-row { display: flex; align-items: center; gap: .9rem; padding: .8rem 1rem; }
.u-avatar { flex: none; width: 2.4rem; height: 2.4rem; border-radius: 50%; display: grid; place-items: center;
    background: var(--brand-soft); color: var(--brand); font-weight: 700; }
.u-main { flex: 1; min-width: 0; display: grid; gap: .25rem; }
.u-name { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.u-name strong { font-size: 1rem; }
.u-meta { display: flex; flex-wrap: wrap; gap: .2rem 1.1rem; color: var(--muted); font-size: .85rem; }
.u-dim { opacity: .7; }
.u-warn-txt { color: var(--warn); font-size: .85rem; }
.u-actions { flex: none; display: flex; gap: .4rem; align-items: center; }
.u-edit { border-top: 1px solid var(--line); padding: 1rem; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.5rem; }
.u-field { display: grid; gap: .35rem; align-content: start; }
.u-field > label { font-size: .75rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.u-field .hint { margin: 0; font-size: .78rem; }
.u-wide { grid-column: 1 / -1; }
.u-ctl { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; min-height: 2.25rem; }
.u-ctl .input { width: 11rem; }
.u-checks { gap: .4rem .9rem; }
.u-check { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }
.u-foot { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;
    border-top: 1px dashed var(--line); padding-top: .8rem; font-size: .85rem; }
.u-foot-actions { display: flex; gap: .4rem; }
.u-danger { color: var(--error); }
@media (max-width: 720px) {
    .u-row { flex-wrap: wrap; }
    .u-actions { width: 100%; justify-content: flex-end; }
    .u-edit { grid-template-columns: 1fr; }
}
.link-staff { padding: 0; color: var(--muted); font-size: .8rem; background: none; border: 0; text-decoration: underline dotted; cursor: pointer; }
.link-staff:hover { color: var(--brand); }
.phone-cell .input { width: 8.5rem; font-variant-numeric: tabular-nums; }

/* ===================== Khách thân thiết + coupon ===================== */
.loy-rules { display: grid; gap: .5rem; margin-bottom: .75rem; }
.loy-rule { display: grid; grid-template-columns: 1fr 1fr auto auto; gap: .5rem; align-items: end; padding: .5rem .75rem; border: 1px solid var(--line); border-radius: 10px; }
.loy-rule .field { margin-bottom: 0; }
.loy-rule.off { opacity: .55; }
.loy-toggle { margin: 0 0 .6rem; }
@media (max-width: 560px) { .loy-rule { grid-template-columns: 1fr 1fr; } }
.loy-preview { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: .35rem; margin-bottom: .5rem; }
.loy-cell { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 48px; border: 1px solid var(--line); border-radius: 8px; font-size: .8rem; color: var(--muted); }
.loy-cell.hit { border-color: var(--brand); color: var(--text); box-shadow: inset 0 0 0 1px var(--brand); }
.loy-n { font-variant-numeric: tabular-nums; }
.loy-amt { font-weight: 700; }
.row-card:has(.loy-rewards) { flex-wrap: wrap; }
.loy-rewards { flex: 1 1 100%; display: grid; gap: .4rem; padding-top: .5rem; margin-top: .25rem; border-top: 1px dashed var(--line); }
.loy-reward { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; justify-content: space-between; }
.cp-counts { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .25rem; }
.cp-inline { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: .5rem; }
.cp-inline .input-sm { max-width: 220px; }
.cp-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .04em; }

/* Tên mã trên dòng hoá đơn là một LIÊN KẾT: gạch chân đứt để thấy bấm được, nhưng không tô màu rực như nút —
   nó nằm trong bảng tiền, chỗ mà mọi thứ sáng lên đều tranh chỗ với con số. */
.cp-link {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}

.cp-link:hover { color: var(--brand); }

/* Bảng thông số trong hộp chi tiết mã: nhãn nhỏ ở trên, số đậm ở dưới, tự xếp theo bề ngang. */
.cp-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: .5rem .75rem;
    margin-bottom: .75rem;
}

.cp-facts > div { display: flex; flex-direction: column; gap: .1rem; }
.cp-facts span { font-size: .78rem; }
.cp-facts strong { font-variant-numeric: tabular-nums; }
.cp-search { flex: 1 1 220px; min-width: 0; }
/* Ô tìm coupon (Khách hàng → Coupon): ô tìm to, giãn hết chỗ; điện thoại thì ô tìm một hàng riêng, hai ô lọc chia đôi hàng dưới
   (chủ shop 2026-10-20: trong .filter-strip ô tìm bị co còn một mẩu). */
/* Chạm sớm đã được nhận, chờ trang nối máy chủ rồi bấm lại (early-click.js). */
.early-tap { outline: 2px solid var(--brand); outline-offset: 2px; opacity: .8; }
/* Điểm / quà của lượt trong thẻ lịch (2026-10-20). */
.bk-perks { display: grid; gap: .35rem; margin: .75rem 0; padding: .6rem .8rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.bk-perk { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; font-size: .9rem; }
.bk-perk .plus { color: var(--ok); white-space: nowrap; }
.bk-perk.is-revoked > strong { text-decoration: line-through; color: var(--muted); }
.scan-ask { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem .75rem; }
.scan-ask-actions { display: flex; flex-wrap: wrap; gap: .4rem; }
.cp-finder { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: .75rem; }
.cp-finder .cp-search { flex: 1 1 320px; min-height: 44px; font-size: 1rem; }
.cp-finder select { flex: 0 1 auto; min-height: 44px; }
@media (max-width: 640px) {
    /* Hàng 1: ô tìm + nút camera; hàng 2: hai ô lọc chia đôi. */
    .cp-finder { display: grid; grid-template-columns: 1fr 1fr auto; }
    .cp-finder .cp-search { grid-column: 1 / 3; }
    .cp-finder .cam-btn { grid-column: 3; }
    .cp-finder select { min-width: 0; }
    .cp-finder select:last-of-type { grid-column: 2 / 4; }
    .cp-finder .list-count { order: 5; grid-column: 1 / -1; }
}

/* ---------- Nút + hộp quét QR bằng camera (CameraScan, 2026-10-20) ---------- */
.cam-btn { display: inline-flex; align-items: center; gap: .4rem; min-height: 44px; padding: 0 .85rem; flex: 0 0 auto; }
.cam-btn svg { color: var(--brand); }
.cam-frame { position: relative; overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--radius); background: #000; }
.cam-frame video { width: 100%; height: 100%; object-fit: cover; display: block; }
.cam-reticle { position: absolute; inset: 18%; border: 2px solid rgba(212, 175, 55, .9); border-radius: 14px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, .35); pointer-events: none; }
.cam-msg { position: absolute; inset: 0; display: grid; place-items: center; padding: 1.5rem; text-align: center;
    background: rgba(0, 0, 0, .7); color: var(--text); font-size: .95rem; }
.cam-foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-top: .75rem; }
@media (max-width: 640px) {
    .cam-btn-label { display: none; }
    .cam-btn { padding: 0 .7rem; }
}
.cp-pick { justify-content: flex-start; text-align: left; }
.seg { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .75rem; }
.coupon-apply { margin-top: .75rem; padding-top: .5rem; border-top: 1px solid var(--line); }

/* ===== Hai cụm coupon ở quầy phải NHÌN LÀ THẤY =====
   Trước đây cả hai nhãn đều dùng .muted nên chìm nghỉm giữa một hộp toàn chữ xám, lễ tân không nhận ra mình
   đang có sẵn coupon để bấm (người dùng nêu 2026-09-20).

   Chọn màu: nền tối + vàng đồng là màu thương hiệu, nên vàng KHÔNG dùng để nhấn ở đây được — nó lẫn với nút
   chính. Coupon lấy XANH NGỌC (--ok): đọc ra "tiền sẵn có", và trong hộp này chưa có gì màu đó. Việc GỠ thì
   không cần màu riêng nữa: nút ✕ đã nằm ngay trên dòng của từng mã, giống hệt dòng dịch vụ. */
.cp-lead { font-weight: 700; font-size: .85rem; }

.cp-have {
    padding: .5rem .6rem;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(52, 211, 153, .35);
    background: var(--ok-soft);
}

.cp-have .cp-lead { color: var(--ok); }

/* Chip coupon: viền và chữ xanh ngọc, đậm hơn chip lọc thường vì đây là nút LÀM RA TIỀN cho hoá đơn. */
.chip-coupon {
    border-color: rgba(52, 211, 153, .5);
    color: var(--ok);
    font-weight: 600;
}

.chip-coupon:hover { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); }

/* ===== Nhật ký gập lại ===== */
.tl-box { margin-top: .75rem; border-top: 1px solid var(--line); padding-top: .5rem; }

.tl-box > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: .4rem;
    color: var(--muted);
}

.tl-box > summary::-webkit-details-marker { display: none; }

/* Mũi tên tự vẽ: quay xuống khi mở, để biết còn gì bên dưới mà không cần đọc chữ. */
.tl-box > summary::before {
    content: "▸";
    font-size: .8rem;
    transition: transform .15s ease;
}

.tl-box[open] > summary::before { transform: rotate(90deg); }
.tl-box > summary:hover { color: var(--text); }

.tl-count {
    min-width: 1.4rem;
    padding: 0 .35rem;
    border-radius: 9999px;
    background: var(--surface-2);
    border: 1px solid var(--line);
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.tl-box > .timeline { margin-top: .5rem; }
.method-picker { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .35rem; }
.perk-list { list-style: none; padding: 0; margin: .5rem 0 0; display: grid; gap: .4rem; }
.perk-list li { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; justify-content: space-between; padding: .5rem .75rem; border: 1px solid var(--line); border-radius: 10px; }

/* ===================== Mã QR ===================== */
.qr-card { text-align: center; }
.qr-img { display: block; margin: .5rem auto; width: 240px; max-width: 100%; height: auto; background: #fff; padding: 10px; border-radius: 14px; image-rendering: pixelated; }
.scan-form { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.scan-form .input { flex: 1 1 240px; min-width: 0; font-size: 1.05rem; }
.cp-balance { font-size: 1.25rem; margin: .25rem 0; }

/* ===================== Bán coupon tại tiệm ===================== */
.sold-card { text-align: center; padding: 1rem; border: 1px dashed var(--line); border-radius: var(--radius); }
.sold-value { font-size: 2rem; font-weight: 700; }
.sold-code { font-size: 1.6rem; font-weight: 700; letter-spacing: .12em; margin: .25rem 0; }
.sold-sent { list-style: none; padding: 0; margin: 1rem 0 0; display: grid; gap: .35rem; }

/* Bấm "In" thì chỉ in thẻ coupon, không in cả trang quản trị. */
@media print {
    body * { visibility: hidden; }
    .sold-body, .sold-body * { visibility: visible; }
    .sold-body { position: absolute; left: 0; top: 0; width: 100%; }
    .sold-sent, .sold-body .alert { display: none; }
}

/* Nút chọn tiền mặt / thẻ khi bán tại tiệm: to, dễ bấm đúng trên điện thoại. */
.method-big { min-height: 48px; flex: 1 1 140px; justify-content: center; font-size: 1rem; }


/* ===== Thanh toán tại quầy (Lịch hẹn) ===== */
.checkout-box {
    margin-top: 1rem; padding: 1rem; border-radius: var(--radius); border: 1px solid var(--brand);
    background: var(--brand-soft); display: flex; flex-direction: column; gap: .5rem;
}
.checkout-box h3 { margin: 0 0 .25rem; color: var(--brand); }
.checkout-box .checkout-due { border-top: 1px solid var(--line); padding-top: .5rem; font-size: 1.05rem; }
/* Ô VUÔNG 36px, căn giữa trong cột của nó — cùng chiều cao với nút .btn-sm bên cạnh nên cả hàng thẳng nhau. */
.item-remove {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; margin: 0; padding: 0;
    border-radius: var(--radius-sm); cursor: pointer; line-height: 1;
    border: 1px solid rgba(239, 68, 68, .45); background: transparent; color: var(--error);
    font-size: .95rem; font-weight: 600;
}
.item-remove:hover { background: var(--error-soft); }

/* ===== Gộp hồ sơ khách ===== */
.merge-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: .75rem; margin-top: .75rem; }
.merge-side {
    display: flex; flex-direction: column; gap: .3rem; padding: .9rem; border-radius: var(--radius);
    border: 1px solid var(--line); background: var(--surface-2); cursor: pointer;
}
.merge-side.keep { border-color: var(--ok); box-shadow: inset 0 0 0 1px var(--ok); }
.merge-side.drop { opacity: .85; }
.merge-choice { display: flex; align-items: center; gap: .5rem; font-weight: 700; color: var(--brand); }
.merge-pick { width: 100%; text-align: left; cursor: pointer; }

/* ===== Báo cáo chốt ngày ===== */
.daily-close .daily-total td { border-top: 2px solid var(--line); }

/* Số việc chờ xử lý trên menu */
.nav-badge {
    margin-left: auto; min-width: 1.4rem; padding: .05rem .45rem; border-radius: 9999px; text-align: center;
    font-size: .72rem; font-weight: 700; color: #fff; background: #dc2626;
}

/* Khách làm thêm dịch vụ trong màn Thanh toán */
.add-service { display: flex; flex-direction: column; gap: .5rem; padding: .6rem; border-radius: var(--radius-sm); background: var(--surface-2); }

/* ===== Khách tự check-in: chuông trên thanh đầu trang + thẻ thông báo ===== */
.arrivals-bell {
    display: inline-flex; align-items: center; gap: .35rem; min-height: 36px; padding: .25rem .7rem; border-radius: 9999px;
    background: var(--ok-soft); border: 1px solid var(--ok); color: var(--ok); font-weight: 700; font-size: .85rem; text-decoration: none;
    white-space: nowrap;
}
/* display:inline-flex ở trên đè thuộc tính hidden → chuông "0 khách" vẫn hiện khi chẳng có ai. */
.arrivals-bell[hidden] { display: none; }

/* Thanh trên cùng của portal trên điện thoại: một hàng, không chữ nào xuống dòng (chủ shop 2026-10-10). Chuông chỉ còn
   🙋 + số; huy hiệu vai trò nhường chỗ (đã ghi ở trang Tổng quan). */
@media (max-width: 639px) {
    .admin-top { gap: .5rem; padding: .6rem .75rem; }
    .brand, .admin-who .btn, .badge-role { white-space: nowrap; }
    .brand { min-width: 0; }
    .brand-dot { flex-shrink: 0; }
    .brand span:last-child { overflow: hidden; text-overflow: ellipsis; }
    .admin-who { gap: .35rem; flex-shrink: 0; }
    .admin-who .btn { padding: 0 .5rem; }
    .arrivals-bell { padding: .2rem .55rem; }
    .arrivals-bell .bell-txt, .admin-who .badge-role { display: none; }
}
.arrivals-toasts {
    position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; flex-direction: column; gap: .5rem;
    width: min(340px, calc(100vw - 32px));
}
.arrival-toast {
    position: relative; display: flex; flex-direction: column; gap: .2rem; padding: .8rem 2.4rem .8rem .9rem;
    border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--ok); box-shadow: var(--shadow);
}
.arrival-toast a { color: var(--brand); font-weight: 700; text-decoration: none; margin-top: .2rem; }
.arrival-toast span { color: var(--muted); font-size: .85rem; }
.arrival-close {
    position: absolute; top: .35rem; right: .35rem; width: 32px; height: 32px; border: 0; border-radius: var(--radius-sm);
    background: transparent; color: var(--muted); cursor: pointer;
}
.arrival-close:hover { background: var(--brand-soft); color: var(--text); }


/* ---------- Mã ghép đôi tablet ---------- */
/* Chủ shop đọc mã này qua cả quầy cho người đang cầm tablet, nên nó phải to hơn mọi thứ khác trên
   trang. Giãn chữ và tabular-nums để không ai nhầm khi đọc từng ký tự một. */
.pair-code {
    font-size: clamp(2.2rem, 9vw, 3.4rem); font-weight: 800; letter-spacing: .28em;
    font-variant-numeric: tabular-nums; color: var(--brand); margin: .5rem 0 .75rem;
    /* letter-spacing đẩy khoảng trống ra sau ký tự cuối, làm mã nhìn lệch trái nếu không bù lại. */
    text-indent: .28em; text-align: center; word-break: break-all;
}

.alert-card { border-color: var(--warn); }

/* ===== Portal: phản hồi bấm tức thì (js/admin-press.js) =====
   Máy chủ ở Mỹ: mỗi cú bấm ~0,3s mới thấy kết quả. Lún + tối NGAY lúc bấm (CSS thuần); chưa có trả lời sau 0,12s
   thì nút mờ đi + vạch tiến trình mảnh trên đỉnh. Chỉ đổi vẻ ngoài — không khoá, không chặn cú bấm nào. */
.admin-shell button:not(:disabled):active,
.admin-shell a.btn:active { transform: translateY(1px); filter: brightness(.92); }

.admin-shell .bs-wait { opacity: .65; cursor: progress; transition: opacity .15s ease; }

.bs-progress {
    position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 10000;
    pointer-events: none; opacity: 0; overflow: hidden; transition: opacity .15s ease;
}
.bs-progress::before {
    content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 35%;
    background: linear-gradient(90deg, transparent, var(--brand), transparent);
    transform: translateX(-100%);
}
.bs-progress.on { opacity: 1; }
.bs-progress.on::before { animation: bs-slide 0.9s ease-in-out infinite; }
@keyframes bs-slide { from { transform: translateX(-100%); } to { transform: translateX(300%); } }

@media (prefers-reduced-motion: reduce) {
    .bs-progress.on::before { animation: none; width: 100%; transform: none; opacity: .6; }
}

/* Extra của dòng dịch vụ trên Lịch hẹn (migration 086): chip nhỏ dưới tên, bật = nền đậm. */
.extra-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.3rem; }
/* Extra = ô tick (chủ shop 2026-10-16): viền vàng đặc + nhãn EXTRA + ô vuông trống khi CHƯA chọn, ô vàng có ✓ khi đã chọn. */
.extra-chips .chip {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; padding: 0.3rem 0.7rem 0.3rem 0.45rem;
    border-radius: 8px; cursor: pointer; border: 1.5px solid rgba(212, 175, 55, .55); background: rgba(212, 175, 55, .06); color: inherit;
}
.extra-chips .chip strong { color: var(--brand); }
.extra-chips .chip.chip-on { border-color: var(--brand); background: var(--brand-soft); font-weight: 600; }
.extra-chips .chip:disabled { cursor: default; opacity: 0.75; }
.extra-box {
    display: inline-grid; place-items: center; width: 1.05rem; height: 1.05rem; flex: none; border-radius: 4px;
    border: 2px solid var(--brand); font-size: 0.75rem; font-weight: 900; line-height: 1;
}
.chip-on .extra-box { background: var(--brand); color: #0c0a10; }
.extra-tag { font-size: 0.62rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; padding: 0.05rem 0.35rem;
    border-radius: 4px; background: rgba(212, 175, 55, .2); color: var(--brand); }
.extra-state { font-size: 0.7rem; color: var(--muted); font-weight: 400; }

/* Nút dạng chữ (vd "Show code" ở coupon trong tài khoản khách). */
.btn-link { background: none; border: 0; padding: 0 .3rem; color: var(--brand); cursor: pointer; font-size: .8rem; text-decoration: underline; }

/* Lịch hẹn — "còn thiếu" khi coupon chưa phủ hết, và các nguồn tính lượt thân thiết (2026-10-12: trước đây dồn một dòng, rối). */
.pay-short { display: flex; flex-direction: column; gap: .2rem; margin: .5rem 0; padding: .6rem .8rem; border-radius: 10px;
    border: 1px solid rgba(251, 191, 36, .45); background: rgba(245, 158, 11, .12); font-size: .85rem; }
.pay-short-amt { font-weight: 800; font-size: 1rem; color: #fbbf24; }
.loyalty-sources { margin: .75rem 0; padding: .7rem .8rem; border-radius: 12px; border: 1px solid var(--line); display: flex; flex-direction: column; gap: .35rem; }
.loy-head { display: flex; flex-direction: column; gap: .1rem; margin-bottom: .2rem; }
.loy-head .muted { font-size: .78rem; }
.loy-row { display: flex; align-items: center; gap: .6rem; padding: .4rem .2rem; border-top: 1px solid var(--line); cursor: pointer; }
.loy-row input { width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--brand); }
.loy-kind { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; padding: .1rem .45rem;
    border-radius: 999px; background: var(--brand-soft); color: var(--brand); flex-shrink: 0; }
.loy-label { flex: 1; min-width: 0; }
.loy-amt { font-weight: 700; white-space: nowrap; }
/* Ô "Tính lượt thân thiết" tự động + cảnh báo nguồn không tính lượt (2026-10-18). */
.loy-main { border-top: 0; }
.loy-why { display: block; color: var(--muted); font-size: .85rem; }
.loy-warn { font-size: .85rem; color: var(--warn); padding: .3rem .2rem; border-top: 1px solid var(--line); }

/* Màn cảm ứng (portal mở trên điện thoại để quét QR, tablet): nút nhỏ phải đủ 44px cho ngón tay, và các nút trên
   thẻ lịch cách nhau thêm chút để không chạm nhầm "Không đến" cạnh "Khách đã đến" (rà soát giao diện 2026-10-12).
   Chỉ áp cho con trỏ thô — máy tính có chuột giữ cỡ gọn như cũ. */
@media (pointer: coarse) {
    .btn-sm, .chip-btn { min-height: 44px; }
    .item-remove { width: 44px; height: 44px; }
    .bk-actions { gap: .6rem; }
}

/* Thanh bảo trì (bảo trì 2026-10-13) — App.razor vẽ, js/maintenance.js đếm ngược. Nằm TRONG luồng trang ở trên cùng (đẩy nội dung
   xuống, không đè lên thanh đầu trang sticky của portal / trang khách). Màu tự đặt, không dựa biến của portal: trang khách dùng chung.
   Đỏ khi đang bảo trì; nâu hổ phách khi đang đếm ngược. */
.mt-bar { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: .35rem .6rem;
          padding: .55rem 1rem; background: #7c4a03; color: #fff7e6; font: 500 .9rem/1.4 "Plus Jakarta Sans", system-ui, sans-serif;
          text-align: center; position: relative; z-index: 50; }
.mt-bar[hidden] { display: none; }
.mt-bar.is-draining { background: #9a3412; }
.mt-bar.is-active { background: #b91c1c; color: #fff; }
.mt-bar .mt-count { font-variant-numeric: tabular-nums; font-size: 1rem; letter-spacing: .02em; }
.mt-bar .mt-msg { opacity: .92; }
/* Portal lúc bảo trì (2026-10-13): AdminLayout không vẽ trang, chỉ vẽ khung thông báo này. */
.mt-lock { max-width: 560px; margin: 3rem auto; padding: 1.5rem; text-align: center; }

/* Lễ tân giúp mở thẻ quà tặng (GiftHelp.razor, 2026-10-14) */
.gift-help-code { display: flex; gap: 1rem; align-items: center; margin-top: .6rem; }
.gift-help-code img { background: #fff; padding: 6px; border-radius: 8px; }

/* Đổi cọc thành quà (CompensationBox.razor, 2026-10-14) */
.comp-box { flex-basis: 100%; margin-top: .6rem; padding: .8rem 1rem; border: 1px dashed var(--line); border-radius: 10px; background: var(--surface-2); }
.comp-row { display: flex; align-items: center; gap: .8rem; margin-top: .5rem; }
.comp-row .check { margin: 0; min-width: 9rem; }
.comp-sub { margin: .2rem 0 0 1.6rem; display: grid; gap: .1rem; }
.comp-sub .check { margin: 0; font-size: .85rem; }
.text-warn { color: var(--warn); }

/* Quà cho lần sau (CheckoutGiftBox.razor, chủ shop 2026-10-16): nút to, chạm được bằng ngón tay ở quầy. */
.pay-gift { margin-right: auto; min-height: 44px; border-color: var(--brand); font-weight: 600; }
.cg-box { display: grid; gap: .6rem; }
.cg-lead { margin: 0; }
.cg-cap { padding: .5rem .75rem; border-radius: 8px; background: var(--brand-soft); font-size: .9rem; }
.cg-seg { margin: 0; }
.cg-seg .seg-btn { min-height: 52px; font-size: 1rem; }
.cg-seg .seg-btn:disabled { opacity: .45; cursor: not-allowed; }
.cg-quick { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.cg-chip, .cg-type {
    min-height: 56px; font: inherit; font-size: 1.1rem; font-weight: 700; cursor: pointer;
    border: 2px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--text);
}
.cg-chip.on, .cg-type.on { border-color: var(--brand); background: var(--brand-soft); }
.cg-field { margin: 0; }
.cg-convert { font-size: 1.05rem; }
.cg-types { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: .5rem; }
.cg-type { display: grid; gap: .1rem; padding: .6rem; text-align: left; }
.cg-type span { font-size: .85rem; font-weight: 500; }
.cg-type small { color: var(--muted); font-size: .75rem; font-weight: 400; }
.cg-actions .cg-go { flex: 1; min-height: 52px; font-size: 1.05rem; }
.cg-given ul { margin: .3rem 0 0; padding-left: 1.1rem; }
.cg-revoked { text-decoration: line-through; color: var(--muted); }

/* Phí không đến chưa thu (NoShowFeeBox.razor, 2026-10-14) */
.fee-box { margin: .75rem 0; padding: .7rem .9rem; border: 1px solid var(--warn); border-radius: 10px; background: var(--warn-soft); display: grid; gap: .5rem; }
.fee-row { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; justify-content: space-between; }
.fee-actions { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }

/* ===== Lối tắt trang tài khoản khách (2026-10-15): thẻ kính tối, icon nét vàng, nhấc nhẹ khi rê, mũi tên trượt. ===== */
.quick-actions {
    display: grid; grid-template-columns: 1.35fr 1fr 1fr; grid-auto-rows: 1fr; gap: .75rem; margin: 0 0 1.25rem;
}
.qa {
    position: relative; display: flex; align-items: center; gap: .85rem; padding: 1rem 1.1rem; border-radius: 16px;
    text-decoration: none; color: var(--text); overflow: hidden;
    background: linear-gradient(180deg, rgba(255, 255, 255, .055) 0%, rgba(255, 255, 255, .02) 100%);
    border: 1px solid rgba(255, 255, 255, .09);
    transition: transform 200ms var(--ease-out), border-color 200ms ease, box-shadow 200ms ease, background 200ms ease;
    animation: qa-in 300ms var(--ease-out) both;
    -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
/* Trang mở thường xuyên → vào nhanh, so le ngắn (thẻ cuối xong ~0,46s thay vì 0,7s). */
.qa:nth-child(2) { animation-delay: 40ms; } .qa:nth-child(3) { animation-delay: 80ms; }
.qa:nth-child(4) { animation-delay: 120ms; } .qa:nth-child(5) { animation-delay: 160ms; }
@keyframes qa-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.qa::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 200ms ease;
    background: radial-gradient(120% 90% at 0% 0%, rgba(212, 175, 55, .16) 0%, transparent 60%);
}
/* Rê chuột chỉ trên máy có chuột — điện thoại chạm xong thẻ không còn "nổi kẹt". */
@media (hover: hover) and (pointer: fine) {
    .qa:hover { transform: translateY(-3px); border-color: rgba(212, 175, 55, .55); box-shadow: 0 14px 34px rgba(0, 0, 0, .5), 0 0 0 1px rgba(212, 175, 55, .08); }
    .qa:hover::after { opacity: 1; }
    .qa:hover .qa-icon { transform: scale(1.07); box-shadow: inset 0 0 0 1px var(--brand), 0 0 18px rgba(212, 175, 55, .3); }
    .qa:hover .qa-arrow { opacity: 1; transform: none; }
}
.qa:active { transform: scale(.97); transition-duration: 100ms; }
.qa:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.qa-icon {
    flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; border-radius: 50%;
    background: var(--brand-soft); color: var(--brand); box-shadow: inset 0 0 0 1px rgba(212, 175, 55, .4);
    transition: transform 200ms var(--ease-out), box-shadow 200ms ease;
}
.qa-text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.qa-text strong { font-size: .95rem; }
.qa-text small { color: var(--muted); font-size: .78rem; line-height: 1.35; }
.qa-arrow { margin-left: auto; color: var(--brand); opacity: .45; transform: translateX(-4px); transition: transform 200ms var(--ease-out), opacity 200ms ease; }
/* Đặt lịch là việc chính: thẻ to, nền vàng nhạt, chiếm hai hàng bên trái. */
.qa-primary {
    grid-row: span 2; flex-direction: column; align-items: flex-start; justify-content: flex-end; gap: 1rem; padding: 1.35rem;
    background: linear-gradient(145deg, rgba(212, 175, 55, .22) 0%, rgba(212, 175, 55, .06) 55%, rgba(216, 155, 145, .08) 100%);
    border-color: rgba(212, 175, 55, .45);
}
.qa-primary .qa-icon { width: 3.25rem; height: 3.25rem; background: var(--brand); color: var(--on-brand); box-shadow: 0 6px 20px rgba(212, 175, 55, .35); }
.qa-primary .qa-text strong { font-size: 1.2rem; }
.qa-primary .qa-arrow { position: absolute; right: 1.2rem; bottom: 1.2rem; font-size: 1.2rem; }
@media (max-width: 720px) {
    .quick-actions { grid-template-columns: 1fr 1fr; grid-auto-rows: auto; }
    .qa-primary { grid-row: auto; grid-column: span 2; flex-direction: row; align-items: center; }
    .qa { padding: .85rem; gap: .65rem; }
    .qa-text small { display: none; }
    .qa-primary .qa-text small { display: block; }
    .qa-primary .qa-arrow { position: static; }
    .qa:not(.qa-primary) .qa-arrow { display: none; }
    .qa-icon { width: 2.4rem; height: 2.4rem; }
}
.page-head .btn { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
    .qa, .qa-icon, .qa-arrow, .qa::after { transition: none; animation: none; }
}

/* Luật coupon tặng trên trang tài khoản khách (2026-10-15). */
.gift-rule {
    display: block; margin-top: .35rem; padding: .45rem .65rem; border-radius: 8px; font-size: .8rem; line-height: 1.4;
    color: var(--brand-dark); background: var(--brand-soft); border: 1px solid rgba(212, 175, 55, .3);
}

/* ---------- Portal khách (/account) — ví thành viên, tab dưới (2026-10-17) ---------- */
/* Chủ shop: trang quá dài. Thẻ + ba ô số luôn hiện, còn lại chia bốn tab; điện thoại có thanh tab cố định dưới đáy. */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.acct { padding-bottom: calc(88px + env(safe-area-inset-bottom)); display: grid; gap: 1rem; }
.acct > * { min-width: 0; }
.acct .alert { margin-bottom: 0; }

.acct-hero {
    position: relative; padding: 1.1rem 1.1rem 1rem; border-radius: 18px;
    background: linear-gradient(150deg, rgba(212, 175, 55, .16), var(--luxe-surface-card) 45%, rgba(216, 155, 145, .08));
    border: 1px solid var(--luxe-border-bright);
    box-shadow: 0 18px 44px rgba(0, 0, 0, .5), inset 0 0 0 1px var(--luxe-gold-glow);
}
.acct-eyebrow { margin: 0; font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .14em; color: var(--luxe-gold-light); }
.acct-hero h1 {
    font-family: var(--font-serif); font-size: clamp(1.4rem, 6vw, 1.9rem); color: var(--luxe-pearl);
    overflow-wrap: anywhere; margin: .15rem 0 .6rem;
}
.acct-hero-id { display: grid; grid-template-columns: 72px 1fr; gap: .8rem; align-items: center; }
.acct-hero-meta { display: grid; gap: .2rem; min-width: 0; }
.acct-qr-thumb {
    width: 72px; height: 72px; padding: 5px; border: 0; border-radius: 10px; background: #fff; cursor: pointer;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .4);
}
.acct-qr-thumb img { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.acct-qr-thumb:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.acct-hero-code { font-family: ui-monospace, Consolas, monospace; letter-spacing: .06em; white-space: nowrap; color: var(--luxe-pearl); }
.acct-qr-big { text-align: center; margin-top: .9rem; }
.acct-newcode { display: grid; justify-items: center; gap: .25rem; }
.acct-newcode .btn-row { margin: 0; }
.acct-newcode-ok { color: var(--ok); }
.acct-hero-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: .6rem; }
.acct-staff-hint { flex-basis: 100%; max-width: 34ch; margin: 0; }

.acct-stats { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: .5rem; }
.acct-stat {
    position: relative; min-width: 0; min-height: 72px; padding: .6rem .7rem; text-align: left; cursor: pointer;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); color: var(--text);
    transition: border-color .2s ease, transform 160ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
    .acct-stat:hover { border-color: var(--luxe-border-bright); }
}
/* Nhấn có phản hồi (2026-10-22): điện thoại không có hover, bấm mà không thấy gì cho tới khi máy chủ trả lời. */
.acct .btn, .acct-stat, .acct-tab, .acct-teaser, .acct-pts-row, .acct-sheet-close, .acct-qr-thumb, .acct-heads li > button {
    -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.acct .btn { transition: background .12s ease, border-color .12s ease, transform 160ms var(--ease-out); }
.acct .btn:active:not(:disabled), .acct-stat:active, .acct-tab:active, .acct-teaser:active,
.acct-sheet-close:active, .acct-qr-thumb:active, .acct-heads li > button:active { transform: scale(.97); transition-duration: 100ms; }
.acct-tab { transition: transform 160ms var(--ease-out), color .15s ease; }
.acct-sheet-close, .acct-qr-thumb, .acct-heads li > button, .acct-teaser { transition: transform 160ms var(--ease-out); }
.acct-pts-row { transition: background-color .12s ease; }
.acct-pts-row:active { background-color: rgba(212, 175, 55, .08); }
.acct-stat strong {
    display: block; font-family: var(--font-serif); font-size: clamp(1rem, 4.6vw, 1.25rem); color: var(--luxe-gold-light);
    font-variant-numeric: tabular-nums; overflow-wrap: anywhere; /* số tiền không bao giờ bị cắt "…" */
}
.acct-stat small { display: block; font-size: .75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.acct-stat:focus-visible, .acct-tab:focus-visible, .acct-teaser:focus-visible,
.acct-heads button:focus-visible, .acct details > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.acct-dot {
    position: absolute; top: .4rem; right: .4rem; width: 8px; height: 8px; border-radius: 50%;
    background: var(--warn); box-shadow: 0 0 0 3px var(--warn-soft);
}
.acct-teaser {
    width: 100%; min-height: var(--tap); padding: 0 .2rem; text-align: left; cursor: pointer;
    background: none; border: 0; color: var(--luxe-gold-light); font: inherit; font-size: .9rem;
}

.acct-tabs {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; display: grid; grid-template-columns: repeat(3, 1fr);
    padding-bottom: env(safe-area-inset-bottom); background: rgba(9, 8, 12, .95); border-top: 1px solid rgba(212, 175, 55, .22);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.acct-tab {
    position: relative; min-height: 60px; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .2rem; font: inherit; font-size: .75rem; color: var(--muted); background: none; border: 0; cursor: pointer;
}
.acct-tab[aria-current] { color: var(--brand); }
.acct-tab[aria-current]::before {
    content: ""; position: absolute; top: 0; width: 24px; height: 3px; border-radius: 0 0 3px 3px; background: var(--brand);
}
.acct-tab .acct-dot { top: 8px; right: calc(50% - 18px); }

.acct-panel { min-width: 0; scroll-margin-top: 64px; }
.acct-panel:focus { outline: none; }
.acct-cols, .acct-col, .acct-narrow { display: grid; gap: 1rem; min-width: 0; }
.acct-sec { display: grid; gap: .6rem; padding-top: 1rem; border-top: 1px solid var(--luxe-border); min-width: 0; }
.acct-sec > p { margin: 0; }
.acct-narrow > .acct-sec:first-child,
.acct-cols > .acct-col:first-child > .acct-sec:first-child,
.acct-cols > .acct-col:first-child:empty + .acct-col > .acct-sec:first-child { border-top: 0; padding-top: 0; }
.acct-label { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.acct-label h2 { margin: 0; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .14em; color: var(--luxe-gold-light); }
.acct-gold { color: var(--luxe-gold-light); }
.acct-big { font-family: var(--font-serif); font-size: 1.4rem; color: var(--luxe-gold-light); }

.acct-voucher {
    border: 1px dashed var(--luxe-border-bright); border-radius: 12px; padding: .7rem .9rem;
    display: flex; flex-wrap: wrap; gap: .3rem .6rem; align-items: baseline;
}
.acct-voucher strong { font-family: var(--font-serif); color: var(--luxe-gold-light); }

.acct-tickets { list-style: none; padding: 0; margin: 0; display: grid; gap: .75rem; }
.acct-ticket {
    position: relative; padding: 1rem 1.1rem; border-radius: 16px; border: 1px dashed var(--luxe-border-bright);
    background:
        radial-gradient(circle at 0 50%, var(--bg) 9px, transparent 10px),
        radial-gradient(circle at 100% 50%, var(--bg) 9px, transparent 10px),
        var(--surface);
    display: grid; gap: .35rem; min-width: 0;
}
.acct-ticket-amt { font-family: var(--font-serif); font-size: 1.35rem; color: var(--luxe-gold-light); }
/* Lịch sử dùng ngay trong thẻ coupon + coupon đã dùng hết (2026-10-20: bỏ tab Activity). */
.acct-hist-toggle { align-self: flex-start; margin-top: .25rem; }
.acct-uses { margin-top: .5rem; }
.use-points { display: flex; flex-wrap: wrap; gap: .25rem 1rem; margin-top: .25rem; font-size: .85rem; color: var(--ok); }
.acct-used { margin-top: .75rem; }
.acct-used > summary { cursor: pointer; color: var(--luxe-muted); font-size: .9rem; padding: .35rem 0; }
.acct-used[open] > summary { margin-bottom: .5rem; }
.acct-ticket.is-used { opacity: .85; }
/* Popup lịch sử điểm: điện thoại trượt từ dưới lên, máy tính giữa màn. */
.acct-sheet { position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-end; justify-content: center; }
body:has(.acct-sheet) { overflow: hidden; }   /* popup mở thì trang nền không cuộn theo */
.acct-sheet-scrim { position: absolute; inset: 0; background: rgba(6, 4, 12, .72); animation: acct-fade 200ms ease both; }
.acct-sheet-panel {
    position: relative; width: 100%; max-width: 560px; max-height: 82dvh; overflow-y: auto; overscroll-behavior: contain;
    padding: 1rem 1.15rem 1.4rem;
    background: var(--surface, #16131f); border: 1px solid var(--line); border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 40px rgba(0, 0, 0, .5); animation: acct-sheet-up 320ms var(--ease-drawer) both;
}
.acct-sheet-panel:focus { outline: none; }
/* Điện thoại: trượt lên từ mép dưới (100% = chính chiều cao sheet). Máy tính: giữa màn, nở nhẹ từ 0.96. */
@keyframes acct-sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes acct-sheet-pop { from { transform: scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes acct-fade { from { opacity: 0; } to { opacity: 1; } }
@media (min-width: 700px) {
    .acct-sheet { align-items: center; padding: 1.5rem; }
    .acct-sheet-panel { border-radius: 18px; animation: acct-sheet-pop 200ms var(--ease-out) both; }
}
.acct-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: .35rem; }
.acct-sheet-head h2 { margin: 0; font-size: 1.15rem; }
.acct-sheet-close { width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--text); cursor: pointer; }
.acct-sheet-sum { margin: 0 0 .75rem; }
.acct-pts { list-style: none; margin: 0; padding: 0; }
.acct-pts > li { border-top: 1px solid var(--line); }
.acct-pts-row { display: flex; align-items: center; justify-content: space-between; gap: .75rem; width: 100%; padding: .65rem 0;
    border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.acct-pts > li.is-open { background: rgba(212, 175, 55, .05); }
.acct-pts-detail { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1rem; margin: 0 0 .75rem; padding: .6rem .75rem;
    border-radius: 12px; background: var(--surface-2, rgba(255, 255, 255, .04)); font-size: .88rem;
    animation: acct-detail-in 150ms var(--ease-out) both; }
@keyframes acct-detail-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.acct-pts-detail dt { color: var(--luxe-muted); }
.acct-pts-detail dd { margin: 0; }
.acct-pts-main { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.acct-pts-main .muted { font-size: .82rem; }
.acct-pts .plus { color: var(--ok); }
.acct-pts .minus { color: var(--error); }
.acct-ticket-amt small { font-family: inherit; font-size: .8rem; }
.acct-ticket-top { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; min-width: 0; }
.acct-ticket .gift-rule { margin-top: 0; }
.acct-pkg {
    padding: 1rem 1.1rem; border-radius: 16px; border: 1px solid var(--luxe-border); background: var(--surface);
    display: grid; gap: .4rem; min-width: 0;
}
.acct-pkg .btn { justify-self: start; }
.acct-pkg .alert { margin: 0; }
.acct-meter { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.acct-meter > span { display: block; height: 100%; background: var(--luxe-gold-gradient); }

.acct-list { list-style: none; padding: 0; margin: 0; }
.acct-list li {
    display: flex; justify-content: space-between; gap: 1rem; min-height: 40px; align-items: center;
    border-bottom: 1px solid var(--line); font-size: .9rem;
}
.acct-list .plus, .acct-list .minus { font-variant-numeric: tabular-nums; white-space: nowrap; }
.acct-list .plus { color: var(--ok); }
.acct-list .minus { color: var(--error); }

.acct-heads-sec { margin-top: 0; }
.acct-heads { list-style: none; padding: 0; margin: 0; display: grid; gap: .4rem; }
.acct-heads li > button {
    width: 100%; min-height: var(--tap); text-align: left; cursor: pointer; font: inherit; font-size: .9rem;
    background: var(--warn-soft); border: 0; border-radius: var(--radius-sm); color: var(--text); padding: .55rem .8rem;
}

.acct details > summary, .acct-more > summary {
    list-style: none; min-height: var(--tap); display: flex; align-items: center; gap: .5rem; cursor: pointer; color: var(--luxe-gold-light);
}
.acct details > summary::-webkit-details-marker { display: none; }
.acct details > summary::after { content: "›"; font-size: 1.2rem; transition: transform 200ms var(--ease-out); }
.acct details[open] > summary::after { transform: rotate(90deg); }

.acct-actions { display: grid; gap: .5rem; }
.acct-actions .btn { width: 100%; min-height: 48px; }
.acct .btn-link { min-height: var(--tap); padding: 0 .6rem; }
.acct dd, .acct .cp-code { overflow-wrap: anywhere; }
.acct .use-lines > li > span { min-width: 0; }
.acct .use-lines > li > span:first-child { overflow-wrap: anywhere; }
.acct .card { margin: 0; }
.acct .quick-actions { margin-bottom: 0; }

@media (max-width: 480px) {
    .acct .kv { grid-template-columns: 1fr; gap: .15rem; }
    .acct .kv dt { margin-top: .5rem; }
    /* lịch sử gói: dịch vụ một dòng, nhân viên + trạng thái xuống dưới — cột 5rem bẻ chữ từng ký tự */
    .acct .use-lines > li { grid-template-columns: 1fr auto; }
    .acct .use-lines > li > span:first-child { grid-column: 1 / -1; }
}
@media (min-width: 900px) {
    .page-wrap.acct { max-width: 980px; padding-bottom: 5rem; }
    .acct-hero { display: grid; grid-template-columns: 1fr auto; column-gap: 1.5rem; padding: 1.5rem 1.75rem; }
    .acct-hero > * { grid-column: 1; }
    .acct-hero-actions { margin: 0; grid-column: 2; grid-row: 1 / span 2; align-self: start; justify-self: end; }
    .acct-qr-big { grid-column: 2; grid-row: 3 / span 2; margin-top: 0; }
    .acct-stats { max-width: 640px; width: 100%; justify-self: center; }
    .acct-tabs {
        position: sticky; top: 56px; z-index: 20; inset: auto; display: inline-flex; justify-self: center; gap: .25rem;
        padding: .25rem; border: 1px solid var(--line); border-radius: 999px; background: rgba(9, 8, 12, .92);
    }
    .acct-tab { min-height: var(--tap); flex-direction: row; padding: 0 1.1rem; border-radius: 999px; font-size: .85rem; }
    .acct-tab svg, .acct-tab[aria-current]::before { display: none; }
    .acct-tab[aria-current] { background: var(--brand); color: var(--on-brand); }
    .acct-tab .acct-dot { position: static; margin-left: .2rem; }
    .acct-cols { grid-template-columns: 1fr 1fr; gap: 1.5rem; align-items: start; }
    .acct-cols > .acct-col > .acct-sec:first-child { border-top: 0; padding-top: 0; }
    .acct-narrow { max-width: 720px; width: 100%; margin: 0 auto; }
}
@media (prefers-reduced-motion: reduce) {
    .acct * { transition: none; }
    /* Giảm chuyển động = bỏ trượt / nở, giữ mờ dần cho dễ hiểu. */
    .acct-sheet-panel, .acct-pts-detail { animation: acct-fade 150ms ease both; }
    .acct .btn:active, .acct-stat:active, .acct-tab:active, .acct-teaser:active,
    .acct-sheet-close:active, .acct-qr-thumb:active, .acct-heads li > button:active { transform: none; }
}
