/* =========================================
   1. FONTS & VARIABLES
   ========================================= */
@import url('https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@400;500;600;700;800&family=Noto+Sans:wght@400;500;600;700&display=swap');

* {
    box-sizing: border-box;
}

:root {
    --font-sans: 'Be Vietnam Pro', 'Noto Sans', sans-serif;
    --color-brand-navy: #18212f;
    --color-action: #0f766e;
    --color-action-hover: #115e59;
    --color-info: #2563eb;
    --color-surface-teal: #f0fdfa;
    --color-surface-blue: #eff6ff;
    --color-primary: var(--color-brand-navy);
    --color-primary-hover: #101827;
    --color-secondary: var(--color-action);
    --color-accent: #d97706;
    --color-surface: #ffffff;
    --color-background: #f8fafc;
    --color-border: #e2e8f0;
    --color-text: #0f172a;
    --color-muted-text: #64748b;
    --color-text-muted: var(--color-muted-text);
    --color-success: #15803d;
    --color-warning: #d97706;
    --color-warning-surface: #fffbeb;
    --color-danger: #dc2626;
    --color-focus-ring: rgba(37, 99, 235, 0.32);
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --radius-control: 10px;
    --radius-surface: 12px;
    --shadow-surface: 0 2px 10px rgba(15, 23, 42, 0.06);
    --shadow-action: 0 6px 14px rgba(15, 118, 110, 0.18);
    --motion-fast: 180ms;
    --bs-primary: var(--color-action);
    --bs-primary-rgb: 15, 118, 110;
    --bs-link-color: var(--color-action);
    --bs-link-hover-color: var(--color-action-hover);
    /* Màu giao diện chính */
    --bg-app: var(--color-background);
    --bg-sidebar: var(--color-brand-navy);
    --text-sidebar: #f8fafc;
    
    /* Màu trạng thái phòng */
    --c-green: linear-gradient(135deg, #159f87 0%, #0f766e 100%);  /* Phòng trống */
    --c-orange: linear-gradient(135deg, #d18a28 0%, #a96313 100%); /* Đang ở */
    --c-yellow: linear-gradient(135deg, #c58a28 0%, #986218 100%); /* Bẩn */
    --c-blue: linear-gradient(135deg, #4d759f 0%, #315a83 100%);   /* Đặt trước */
    --c-purple: linear-gradient(135deg, #806aa4 0%, #614981 100%); /* Giờ */
    
    /* Màu Login */
    --login-bg-start: #0f172a;
    --login-bg-end: #1e293b;
}

/* =========================================
   2. GLOBAL & DASHBOARD LAYOUT
   ========================================= */
body {
    font-family: var(--font-sans);
    background-color: var(--bg-app);
    font-size: 14px;
    height: 100vh;
    margin: 0;
    overflow: hidden; /* Tránh thanh cuộn thừa */
}

/* Mặc định body cho Dashboard là flex ngang (Sidebar - Content) */
body:not(.login-page) {
    display: flex; 
}

/* --- SIDEBAR --- */
.app-sidebar {
    width: 240px;
    display: flex;
    height: 100vh;
    flex-direction: column;
    flex-shrink: 0;
    color: var(--text-sidebar);
    background: linear-gradient(180deg, var(--color-brand-navy) 0%, var(--color-primary-hover) 100%);
    box-shadow: 4px 0 18px rgba(15, 23, 42, 0.1);
    z-index: 100;
}

.sidebar-brand {
    display: flex;
    gap: 10px;
    min-height: 64px;
    align-items: center;
    padding: 0 var(--space-4);
    font-size: 18px;
    font-weight: 800;
    color: #fff;
    background: rgba(255, 255, 255, 0.035);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    letter-spacing: 0.02em;
}

.menu-list {
    flex: 1 1 auto;
    list-style: none;
    margin: var(--space-3) 0;
    padding: 0 var(--space-1);
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, 0.35) transparent;
}

.menu-header {
    margin-top: var(--space-3);
    padding: var(--space-2) var(--space-4) var(--space-1);
    color: #94a3b8;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.menu-item a {
    display: flex;
    min-height: 44px;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-1) var(--space-2);
    padding: 10px var(--space-3);
    color: #94a3b8;
    border-radius: var(--radius-control);
    font-weight: 550;
    text-decoration: none;
    transition:
        color var(--motion-fast) ease,
        background-color var(--motion-fast) ease,
        box-shadow var(--motion-fast) ease;
    touch-action: manipulation;
}

.menu-item a:hover, .menu-item a.active {
    color: #fff;
    background: rgba(255, 255, 255, 0.09);
}

.menu-item a.active {
    background: rgba(45, 212, 191, 0.12);
    box-shadow: inset 3px 0 #2dd4bf;
}

.menu-item i {
    width: 20px;
    flex: 0 0 20px;
    text-align: center;
}

.sidebar-footer {
    flex: 0 0 auto;
    padding: var(--space-3);
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.sidebar-logout {
    display: flex;
    min-height: 44px;
    align-items: center;
    gap: var(--space-3);
    padding: 10px var(--space-3);
    color: #fecaca;
    border-radius: var(--radius-control);
    font-weight: 600;
    text-decoration: none;
    transition:
        color var(--motion-fast) ease,
        background-color var(--motion-fast) ease;
}

.sidebar-logout:hover {
    color: #fff;
    background: rgba(220, 38, 38, 0.16);
}

.sidebar-backdrop { display: none; }
.sidebar-backdrop[hidden] { display: none !important; }

/* --- CONTENT AREA --- */
.app-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.top-bar {
    height: 60px;
    background: white;
    border-bottom: none;
    box-shadow: 0 4px 15px -3px rgba(0,0,0,0.03);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 24px;
    z-index: 10;
}

.main-area {
    padding: 24px;
    overflow-y: auto;
    height: calc(100vh - 60px);
}

.page-title {
    font-weight: 700;
    color: #334155;
    text-transform: uppercase;
    margin: 0;
    letter-spacing: -0.5px;
}

.card-box {
    background: white;
    border-radius: 12px;
    box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05);
    padding: 24px;
}

/* =========================================
   3. COMPONENT: ROOM CARD
   ========================================= */
.room-card {
    --room-accent: var(--color-action);
    --room-tint: var(--color-surface-teal);
    position: relative;
    color: var(--color-text);
    background: linear-gradient(135deg, var(--room-tint) 0%, var(--color-surface) 72%);
    min-height: 140px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    margin-bottom: 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
    overflow: hidden;
    transition:
        border-color var(--motion-fast) ease,
        box-shadow var(--motion-fast) ease,
        transform var(--motion-fast) ease;
}

.room-card::before {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 4px;
    background: var(--room-accent);
    content: '';
}

.room-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
}

.rc-head { padding: 12px 16px; display: flex; justify-content: space-between; align-items: flex-start; }
.rc-num { font-size: 28px; font-weight: 800; line-height: 1; letter-spacing: -1px; }
.rc-body { flex-grow: 1; display: flex; align-items: center; justify-content: center; }
.rc-foot { padding: 8px 16px; background: rgba(0,0,0,0.15); font-size: 12px; display: flex; justify-content: space-between; font-weight: 600; }

/* Trạng thái phòng */
.st-free { background: var(--c-green); }
.st-occupied { background: var(--c-orange); }
.st-hourly { background: var(--c-purple); }
.st-dirty { background: var(--c-yellow); color: #fff; }
.room-card--available { --room-accent: #0f766e; --room-tint: #f0fdfa; }
.room-card--booked { --room-accent: #2563eb; --room-tint: #eff6ff; }
.room-card--occupied { --room-accent: #d97706; --room-tint: #fffbeb; }
.room-card--hourly { --room-accent: #7c3aed; --room-tint: #f5f3ff; }
.room-card--overdue { --room-accent: #dc2626; --room-tint: #fef2f2; }
.room-card--dirty { --room-accent: #ca8a04; --room-tint: #fefce8; }
.room-card--maintenance { --room-accent: #64748b; --room-tint: #f8fafc; }
.room-card__header, .room-card__footer { padding: 12px 16px; display:flex; justify-content:space-between; align-items:center; }
.room-card__number { display:block; font-size:28px; line-height:1; }
.room-card__body { min-height:86px; padding:8px 16px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; text-align:center; }
.room-card { height: 205px; }
.room-card__footer { background:rgba(255,255,255,.72); font-size:12px; }
.room-card__action, .room-card__notice { border:0; background:transparent; color:inherit; font-weight:700; }
.room-card__notice { background:rgba(255,255,255,.18); border-radius:6px; padding:3px 6px; font-size:11px; max-width:100%; }

/* Room card: compact operational hierarchy */
.room-card {
    height: 188px;
    min-height: 188px;
    margin-bottom: 0;
    border-radius: 12px;
    box-shadow: 0 3px 10px rgba(15, 23, 42, 0.16);
    transition: box-shadow 180ms ease, transform 180ms ease;
}

.app-topbar {
    min-height: 64px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 10px 24px;
    background: rgba(255,255,255,.96);
    border-bottom: 1px solid var(--color-border);
    box-shadow: 0 1px 2px rgba(15,23,42,.04);
}
.app-topbar__identity, .app-topbar__user { display:flex; align-items:center; gap:10px; }
.app-topbar__identity strong { display:block; color:var(--color-text); font-size:14px; }
.app-topbar__eyebrow { display:block; color:var(--color-muted-text); font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; }
.app-topbar__user {
    min-height: 44px;
    padding: 0 var(--space-3);
    color: var(--color-muted-text);
    background: var(--color-surface);
    border: 1px solid transparent;
    border-radius: var(--radius-control);
    font-family: var(--font-sans);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition:
        color var(--motion-fast) ease,
        background-color var(--motion-fast) ease,
        border-color var(--motion-fast) ease;
}
.app-topbar__user:hover,
.app-topbar__user[aria-expanded="true"] {
    color: var(--color-text);
    background: var(--color-surface-teal);
    border-color: #99f6e4;
}
.app-topbar__user .fa-user-circle { color: var(--color-action); font-size: 20px; }
.app-topbar__account-chevron { color: var(--color-muted-text); font-size: 10px; }
.app-account-menu {
    min-width: 220px;
    padding: var(--space-2);
    border-color: var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: 0 16px 36px rgba(15, 23, 42, 0.16);
}
.app-account-menu__summary { display: grid; gap: 2px; padding: var(--space-2) var(--space-3); }
.app-account-menu__summary span { color: var(--color-muted-text); font-size: 11px; }
.app-account-menu__summary strong { color: var(--color-text); font-size: 14px; }
.app-account-menu__logout {
    display: flex;
    min-height: 44px;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-danger);
    border-radius: 8px;
    font-weight: 600;
}
.app-account-menu__logout:hover,
.app-account-menu__logout:focus { color: #b91c1c; background: #fef2f2; }

.app-content > .container-fluid, .app-content > .container { overflow-y:auto; }
.app-content .card { border:1px solid var(--color-border); border-radius:var(--radius-surface); box-shadow:var(--shadow-surface); }
.app-content .table > :not(caption) > * > * { padding:12px 14px; border-color:#edf1f6; }
.app-content .table thead th { color:#475569; font-size:11px; letter-spacing:.04em; text-transform:uppercase; white-space:nowrap; }
.app-content .btn {
    display: inline-flex;
    min-height: 44px;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0 var(--space-4);
    border-radius: var(--radius-control);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
    transition:
        background-color var(--motion-fast) ease,
        border-color var(--motion-fast) ease,
        color var(--motion-fast) ease,
        box-shadow var(--motion-fast) ease,
        transform var(--motion-fast) ease;
    touch-action: manipulation;
}

.app-content .btn-sm {
    min-height: 36px;
    padding: 0 var(--space-3);
    font-size: 13px;
}

.page-header .btn-sm {
    min-height: 44px;
}

.app-content .btn-lg {
    min-height: 48px;
    padding: 0 20px;
    font-size: 15px;
}

.btn-icon {
    display: inline-grid;
    min-width: 44px;
    min-height: 44px;
    flex: 0 0 44px;
    place-items: center;
    padding: 0;
    border-radius: var(--radius-control);
    touch-action: manipulation;
}

.app-content .btn:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(15, 23, 42, 0.12);
}

.app-content .btn:active:not(:disabled) {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
}

.app-content .btn:focus-visible {
    outline: 3px solid var(--color-info);
    outline-offset: 2px;
}

.app-content .btn:disabled,
.app-content .btn[aria-disabled="true"] {
    opacity: 0.48;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

.app-content .btn[aria-busy="true"] {
    cursor: wait;
}

.app-content .btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--color-action);
    --bs-btn-border-color: var(--color-action);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--color-action-hover);
    --bs-btn-hover-border-color: var(--color-action-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--color-action-hover);
    --bs-btn-active-border-color: var(--color-action-hover);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: var(--color-action);
    --bs-btn-disabled-border-color: var(--color-action);
}

.app-content .btn-primary:hover:not(:disabled) {
    box-shadow: var(--shadow-action);
}

/* Outline-primary theo token hành động (bootstrap precompiled là xanh dương) */
.app-content .btn-outline-primary {
    --bs-btn-color: var(--color-action);
    --bs-btn-border-color: var(--color-action);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--color-action);
    --bs-btn-hover-border-color: var(--color-action);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--color-action-hover);
    --bs-btn-active-border-color: var(--color-action-hover);
    --bs-btn-disabled-color: var(--color-action);
    --bs-btn-disabled-border-color: var(--color-action);
}

.app-content .btn-info {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--color-info);
    --bs-btn-border-color: var(--color-info);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #1d4ed8;
    --bs-btn-hover-border-color: #1d4ed8;
}

.app-content .btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--color-success);
    --bs-btn-border-color: var(--color-success);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #166534;
    --bs-btn-hover-border-color: #166534;
}

.app-content .btn-warning {
    --bs-btn-color: #422006;
    --bs-btn-bg: var(--color-warning);
    --bs-btn-border-color: var(--color-warning);
    --bs-btn-hover-color: #422006;
    --bs-btn-hover-bg: #f59e0b;
    --bs-btn-hover-border-color: #f59e0b;
}

.app-content .btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--color-danger);
    --bs-btn-border-color: var(--color-danger);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #b91c1c;
    --bs-btn-hover-border-color: #b91c1c;
}

.app-content .form-control,
.app-content .form-select {
    min-height: 44px;
    border-color: #cbd5e1;
    border-radius: var(--radius-control);
}

/* Tên sản phẩm bên phải dấu hiệu — dựng bằng CHỮ THẬT của trang, không nhúng
   tệp lockup. Chữ trong tệp ấy là `<text>` sống với phông Sora/Manrope mà app
   không nạp (app dùng Be Vietnam Pro), nên trình duyệt sẽ lặng lẽ thay phông
   khác; và màu chữ trong tệp là navy đậm, làm cho nền sáng chứ không phải cho
   thanh bên tối. */
.sidebar-brand__name {
    font-size: 15px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
    color: #fff;
}

.sidebar-brand__icon {
    flex: 0 0 auto;
    margin-right: 8px;
    font-size: 16px;
}

.sidebar-brand__hotel {
    min-width: 0;
    overflow: hidden;
    font-size: 16px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-brand__product {
    margin-left: 8px;
    color: #d9a441;
    font-size: 13px;
    letter-spacing: 0.08em;
}

.sidebar-support-banner {
    display: grid;
    gap: 2px;
    padding: 10px 16px 8px;
    color: #fcd34d;
    font-size: 11px;
    line-height: 1.25;
}

.sidebar-support-banner span { color: #94a3b8; text-transform: uppercase; letter-spacing: 0.08em; }
.sidebar-support-banner strong { overflow: hidden; color: #f8fafc; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-support-banner a { color: #fcd34d; text-decoration: none; }
.sidebar-support-banner a:hover { text-decoration: underline; }

.room-card:hover {
    transform: translateY(-2px);
    border-color: #cbd5e1;
    box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
}

.room-card--orderable { cursor: pointer; }
.room-card--orderable:active { transform: translateY(0); }

.room-card__header {
    min-height: 58px;
    padding: 12px 14px 8px;
}

.room-card__number {
    font-size: 24px;
    font-weight: 800;
    letter-spacing: -0.04em;
}

.room-card__type {
    display: block;
    margin-top: 3px;
    color: var(--color-muted-text);
    font-size: 11px;
}

.room-card__status-icon {
    display: inline-grid;
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    place-items: center;
    color: var(--room-accent);
    background: var(--color-surface);
    border: 1px solid color-mix(in srgb, var(--room-accent) 22%, var(--color-border));
    border-radius: 10px;
}

.room-card__body {
    min-height: 70px;
    padding: 4px 14px 10px;
    align-items: flex-start;
    justify-content: center;
    gap: 6px;
    text-align: left;
}

.room-card__eyebrow {
    color: var(--room-accent);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.04em;
}

.room-card__detail {
    display: -webkit-box;
    overflow: hidden;
    color: var(--color-muted-text);
    font-size: 12px;
    line-height: 1.35;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

.room-card__footer {
    min-height: 48px;
    padding: 6px 10px 6px 14px;
    background: rgba(255, 255, 255, 0.72);
    border-top: 1px solid var(--color-border);
}

.room-card__action {
    min-height: 36px;
    padding: 7px 10px;
    color: var(--room-accent);
    border-radius: 7px;
    cursor: pointer;
    transition: background-color 180ms ease, color 180ms ease;
}

.room-card__action:hover:not(:disabled),
.room-card__action:focus-visible {
    background: var(--room-tint);
}

.room-card .status-badge {
    max-width: 92px;
    padding: 4px 6px;
    overflow: hidden;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    font-size: 10px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.room-card .status-badge--available { color: #065f46; background: #ecfdf5; border-color: #a7f3d0; }
.room-card .status-badge--booked { color: #1d4ed8; background: #eff6ff; border-color: #bfdbfe; }
.room-card .status-badge--occupied { color: #92400e; background: #fffbeb; border-color: #fde68a; }
.room-card .status-badge--hourly { color: #6d28d9; background: #f5f3ff; border-color: #ddd6fe; }
.room-card .status-badge--overdue { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
.room-card .status-badge--dirty { color: #854d0e; background: #fefce8; border-color: #fde047; }
.room-card .status-badge--maintenance { color: #475569; background: #f8fafc; border-color: #cbd5e1; }

@media (prefers-reduced-motion: reduce) {
    .room-card,
    .room-card__action {
        transition: none;
    }

    .room-card:hover {
        transform: none;
    }
}

/* Staff and audit administration */
.staff-form-card,
.admin-panel-header {
    border-color: var(--color-border);
}

.staff-form-card {
    overflow: hidden;
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
}

.admin-panel-header {
    display: flex;
    min-height: 76px;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: linear-gradient(115deg, var(--color-surface) 35%, var(--color-surface-blue) 100%);
}

.admin-panel-title {
    margin: 0;
    color: var(--color-primary);
    font-size: 16px;
    font-weight: 750;
}

.admin-panel-description {
    margin: var(--space-1) 0 0;
    color: var(--color-muted-text);
    font-size: 12px;
}

.staff-password-reset {
    display: grid;
    min-width: 260px;
    align-items: center;
    grid-template-columns: minmax(180px, 1fr) 44px;
    gap: var(--space-2);
}

.audit-table-footer {
    display: flex;
    min-height: 66px;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface);
    border-top-color: var(--color-border);
}

.audit-detail-toggle { min-height: 36px; cursor: pointer; }
.audit-detail-row > td { padding: 0 var(--space-3) var(--space-3); background: var(--color-surface-sunk, #f6f7f9); }
.audit-detail-data {
    padding: var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-control);
    font-size: 14px;
    line-height: 1.5;
}

@media (max-width: 767.98px) {
    .staff-management,
    .audit-log-page { padding: 16px !important; }
    .audit-table-footer { align-items: stretch; flex-direction: column; }
    .audit-table-footer .btn-group { width: 100%; }
    .audit-table-footer .btn { flex: 1; }
}

/* Room map toolbar: separate context, controls and operational counts. */
.room-map-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 24px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.room-map-toolbar__primary,
.room-map-toolbar__title,
.room-map-toolbar__controls,
.room-map-toolbar__stats {
    display: flex;
    align-items: center;
}

.room-map-toolbar__primary { min-width: 0; gap: 24px; }
.room-map-toolbar__title { min-width: 210px; gap: 10px; }
.room-map-toolbar__icon { display: grid; width: 34px; height: 34px; place-items: center; color: var(--color-primary); background: #e8eefc; border-radius: 9px; }
.room-map-toolbar__title h1 { margin: 0; color: var(--color-text); font-size: 18px; font-weight: 800; line-height: 1.2; }
.room-map-toolbar__title p { margin: 2px 0 0; color: var(--color-muted-text); font-size: 12px; }
.room-map-toolbar__controls { gap: 10px; }
.room-map-toolbar__controls .form-select { width: 170px; min-height: 44px; border-color: var(--color-border); font-size: 13px; }
.room-map-toolbar__controls .btn { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 44px; padding-inline: 16px; font-size: 13px; }
.room-map-toolbar__stats { gap: 8px; padding-left: 16px; border-left: 1px solid var(--color-border); }
.room-map-toolbar__stats .status-badge { min-height: 32px; padding: 6px 9px; border: 1px solid transparent; font-size: 12px; }
.room-map-toolbar__stats strong { margin-left: 2px; font-size: 13px; }
.status-badge--occupied { color: #9f1239; background: #fff1f2; border-color: #fecdd3 !important; }
.status-badge--dirty { color: #92400e; background: #fffbeb; border-color: #fde68a !important; }
.status-badge--available { color: #065f46; background: #ecfdf5; border-color: #a7f3d0 !important; }

.room-map-grid-shell { padding-top: var(--space-4); padding-bottom: var(--space-5); }
.room-map-state-column .data-state {
    min-height: 260px;
    background: var(--color-surface);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-surface);
}
.data-state--loading .data-state__icon { color: var(--color-info); background: var(--color-surface-blue); }
.data-state--error .data-state__icon { color: var(--color-danger); background: #fef2f2; }
.data-state--empty .data-state__icon { color: var(--color-action); background: var(--color-surface-teal); }

.existing-order-summary {
    margin: 10px 12px 0;
    padding: 10px;
    background: #f8fafc;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.existing-order-summary__header,
.existing-order-summary__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.existing-order-summary__header { color: var(--color-text); font-size: 12px; font-weight: 800; }
.existing-order-summary__header strong { color: var(--color-primary); }
.existing-order-summary__list { max-height: 72px; margin-top: 6px; overflow-y: auto; color: var(--color-muted-text); font-size: 12px; line-height: 1.55; }
.existing-order-summary__item { padding: 2px 0; color: var(--color-text); }

@media (max-width: 1199.98px) {
    .room-map-toolbar__primary { width: 100%; justify-content: space-between; }
    .room-map-toolbar__stats { padding-left: 0; border-left: 0; }
}

@media (max-width: 767.98px) {
    .room-map-toolbar { padding: 12px 16px; }
    .room-map-toolbar__primary { align-items: flex-start; flex-direction: column; gap: 12px; }
    .room-map-toolbar__controls { width: 100%; }
    .room-map-toolbar__controls .form-select { flex: 1; width: auto; }
    .room-map-toolbar__stats { flex-wrap: wrap; }
}

/* =========================================
   4. COMPONENT: TIMELINE — lưới phòng × ngày (spec 15-08)
   ========================================= */

.tl-page { --tlg-row-h: 48px; --tlg-rooms-w: 196px; }

/* --- Heading + thẻ thống kê --- */
.tlg-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.tlg-eyebrow { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--color-muted-text); font-weight: 600; }
.tlg-title { font-size: 24px; font-weight: 700; letter-spacing: -.01em; margin: 4px 0 0; color: var(--color-text); }
.tlg-stats { display: flex; gap: 10px; flex-wrap: wrap; }
.tlg-stat { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 12px; padding: 10px 16px; min-width: 104px; }
.tlg-stat__label { font-size: 11px; color: var(--color-muted-text); font-weight: 600; letter-spacing: .02em; }
.tlg-stat__row { display: flex; align-items: baseline; gap: 6px; margin-top: 2px; }
.tlg-stat__value { font-size: 20px; font-weight: 700; letter-spacing: -.02em; color: var(--color-text); }
.tlg-stat__suffix { font-size: 11px; color: #94a3b8; font-weight: 500; }

/* --- Toolbar một hàng --- */
.tlg-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 12px; padding: 10px 14px; box-shadow: 0 2px 10px rgba(15, 23, 42, .05); }
.tlg-nav { display: flex; align-items: center; gap: 2px; }
.tlg-nav__btn { width: 34px; height: 34px; border: 0; border-radius: 8px; background: transparent; display: inline-flex; align-items: center; justify-content: center; color: #475569; font-size: 13px; cursor: pointer; }
.tlg-nav__btn:hover { background: #f1f5f9; color: var(--color-text); }
.tlg-nav__today { height: 34px; padding: 0 12px; border: 0; border-radius: 8px; background: transparent; font-size: 13px; font-weight: 600; color: #334155; cursor: pointer; }
.tlg-nav__today:hover { background: #f1f5f9; }
.tlg-range { font-size: 13px; font-weight: 600; color: var(--color-text); min-width: 136px; white-space: nowrap; }
.tlg-divider { width: 1px; height: 24px; background: var(--color-border); flex: none; }
.tlg-seg { display: flex; background: #f1f5f9; border-radius: 9px; padding: 3px; gap: 2px; }
.tlg-seg__btn { border: 0; background: transparent; padding: 5px 10px; border-radius: 7px; font-size: 12.5px; font-weight: 600; color: var(--color-muted-text); cursor: pointer; white-space: nowrap; }
.tlg-seg__btn.active { background: var(--color-surface); color: var(--color-text); box-shadow: 0 1px 2px rgba(15, 23, 42, .10); }
.tlg-filter { width: auto; min-width: 150px; height: 36px; border-radius: 9px; font-size: 13px; font-weight: 600; color: #334155; }
.tlg-spacer { flex: 1; min-width: 12px; }
.tlg-btn { height: 36px; padding: 0 16px; border-radius: 9px; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; cursor: pointer; }
.tlg-btn--ghost { border: 1px solid var(--color-border); background: var(--color-surface); color: #334155; }
.tlg-btn--ghost:hover { background: #f8fafc; border-color: #cbd5e1; }
.tlg-btn--primary { border: 1px solid var(--color-action); background: var(--color-action); color: #fff; }
.tlg-btn--primary:hover { background: var(--color-action-hover); border-color: var(--color-action-hover); }

/* --- Legend chấm màu --- */
.tlg-legend { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; padding: 0 2px; }
.tlg-legend__item { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: #475569; }
.tlg-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.tlg-dot--booked { background: var(--color-info); }
.tlg-dot--staying { background: var(--color-action); }
.tlg-dot--hourly { background: #7c3aed; }
.tlg-dot--overstay { background: var(--color-danger); }

/* --- Khung lưới --- */
.timeline-card .card-body { overflow-x: auto; }
.tlg { min-width: 760px; background: var(--color-surface); }
.tlg-head { display: flex; border-bottom: 1px solid var(--color-border); }
.tlg-rooms-head { width: var(--tlg-rooms-w); flex: none; box-sizing: border-box; padding: 10px 16px; border-right: 1px solid var(--color-border); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: #94a3b8; font-weight: 600; }
.tlg-cols { flex: 1; min-width: 0; display: flex; position: relative; }
.tlg-col-head { flex: 1; min-width: 0; box-sizing: border-box; padding: 8px 12px; border-right: 1px solid var(--color-border); overflow: hidden; }
.tlg-col-head--today { background: var(--color-surface-teal); }
.tlg-col-head--weekend { background: #fbfcfe; }
.tlg-col-dow { font-size: 11px; color: #94a3b8; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.tlg-col-num { font-size: 14px; font-weight: 600; margin-top: 2px; color: var(--color-text); }
.tlg-col-head--today .tlg-col-num { color: var(--color-action); font-weight: 700; }
.tlg--dense .tlg-col-head { padding: 8px 2px; text-align: center; }
.tlg--dense .tlg-col-num { font-size: 12px; }
.tlg--hours .tlg-col-head { padding: 8px 4px; text-align: center; }
.tlg--hours .tlg-col-num { font-size: 11px; margin-top: 0; color: #64748b; }

/* Hàng cao theo SỐ TẦNG thanh đang xếp trong nó. Một tầng là chiều cao cũ, nên
   hàng nào không có thanh chồng nhau trông y như trước. */
.tlg-row { display: flex; border-bottom: 1px solid #f1f5f9; height: calc(var(--tlg-row-h) * var(--tlg-lanes, 1)); }
.tlg-row--group { display: block; height: auto; padding: 7px 16px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--color-muted-text); background: var(--color-background); border-bottom: 1px solid var(--color-border); }
.tlg-room-cell { width: var(--tlg-rooms-w); flex: none; box-sizing: border-box; padding: 0 16px; border-right: 1px solid var(--color-border); display: flex; align-items: center; gap: 10px; }
.tlg-room-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: #cbd5e1; }
.tlg-room-dot--busy { background: var(--color-action); }
.tlg-room-info { min-width: 0; }
.tlg-room-num { font-size: 14px; font-weight: 600; letter-spacing: -.01em; color: var(--color-text); line-height: 1.25; }
.tlg-room-type { font-size: 11px; color: #94a3b8; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tlg-cells { flex: 1; min-width: 0; position: relative; display: flex; }
.tlg-cell { flex: 1; min-width: 0; border-right: 1px solid #f1f5f9; cursor: cell; transition: background .12s ease, box-shadow .12s ease; }
.tlg-cell:hover { background: var(--color-surface-teal); box-shadow: inset 0 0 0 1px #99f6e4; }
.tlg-cell--weekend { background: #fcfdfe; }

.tlg-nowline { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--color-danger); opacity: .75; pointer-events: none; z-index: 5; }
.tlg-head .tlg-nowline::before { content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 8px; height: 8px; border-radius: 50%; background: var(--color-danger); }

/* --- Thanh booking: nền nhạt + sọc trạng thái 3px --- */
/* `top` tính từ tầng, `height` cố định — KHÔNG dùng `bottom` nữa, vì với hàng
   nhiều tầng thì "cách đáy 5px" kéo mọi thanh dài xuống hết hàng. */
.tlg-bar { position: absolute; top: calc(var(--tlg-lane, 0) * var(--tlg-row-h) + 5px); height: calc(var(--tlg-row-h) - 10px); margin-left: 2px; box-sizing: border-box; border-radius: 7px; display: flex; align-items: center; gap: 8px; padding: 0 10px 0 12px; font-size: 12.5px; cursor: pointer; overflow: hidden; z-index: 3; box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .04); transition: filter .12s ease; }
.tlg-bar:hover { filter: brightness(.97); }
.tlg-bar__stripe { position: absolute; left: 0; top: 0; bottom: 0; }
.tlg-bar__icon { font-size: 11px; flex: none; }
.tlg-bar__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.tlg-bar__meta { margin-left: auto; font-size: 11px; font-weight: 500; opacity: .75; white-space: nowrap; flex: none; }
/* KHỐI TRÁI = TRẠNG THÁI. Nền đậm dùng đúng bốn màu của chấm chú thích ngay
   trên lưới, icon trắng nằm trong.

   Màu bão hoà dồn vào một khối 28px thay vì trải kín thanh: đọc được ngay mà
   cả lưới vẫn yên. Tô đậm kín thanh thì mọi thứ cùng hét và chẳng gì nổi bật;
   tô nhạt kín thanh thì bốn sắc gần trắng cả bốn, không phân biệt nổi. Khối
   nhỏ đậm là chỗ đứng giữa hai cái đó.

   Icon là tín hiệu thứ hai, không phụ thuộc màu — xem TLG_STATUS_ICONS. */
.tlg-bar { padding-left: 36px; }
.tlg-bar__stripe {
    width: 28px; border-radius: 7px 0 0 7px;
    display: flex; align-items: center; justify-content: center;
}
.tlg-bar__stripe .tlg-bar__icon { color: #fff; font-size: 12px; }
.tlg-bar--booked .tlg-bar__stripe { background: var(--color-info); }
.tlg-bar--staying .tlg-bar__stripe { background: var(--color-action); }
.tlg-bar--hourly .tlg-bar__stripe { background: #7c3aed; }
.tlg-bar--overstay .tlg-bar__stripe { background: var(--color-danger); }

/* NỀN DÀI = ĐOÀN. Sắc NHẠT, chữ đậm cùng sắc — đây là vùng lớn nên phải yên.

   Thứ tự tám sắc xếp sao cho hai số LIỀN NHAU khác hẳn nhau trên vòng màu: màu
   gán theo thứ tự xuất hiện, nên hai đoàn cạnh nhau luôn nhận hai số liền nhau.
   Xếp chàm ngay cạnh tím sẽ cho hai đoàn hai sắc gần như một. */
.tlg-bar--single { background: #f1f5f9; color: #334155; }
.tlg-bar--g0 { background: #fff1e6; color: #7c2d12; }  /* cam */
.tlg-bar--g1 { background: #e6f6fa; color: #155e75; }  /* mòng két */
.tlg-bar--g2 { background: #fdecf3; color: #9d174d; }  /* hồng sen */
.tlg-bar--g3 { background: #e7f6ec; color: #14532d; }  /* lục */
.tlg-bar--g4 { background: #f5eeff; color: #5b21b6; }  /* tím */
.tlg-bar--g5 { background: #fdf4dd; color: #713f12; }  /* vàng nghệ */
.tlg-bar--g6 { background: #eaeafc; color: #3730a3; }  /* chàm */
.tlg-bar--g7 { background: #f5eee6; color: #78350f; }  /* nâu */

/* Thanh quá giờ: viền đỏ rõ nét. Nó nổi vì là thanh DUY NHẤT có viền, không
   phải vì chói hơn — nền vẫn nhạt như mọi thanh khác. */
.tlg-bar--overstay { box-shadow: inset 0 0 0 2px var(--color-danger); }

.tlg-legend__item--note { color: #64748b; gap: 6px; }
.tlg-legend__item--note i { font-size: 11px; }

.tlg-hint { margin: 10px 2px 0; font-size: 12px; color: #94a3b8; }

@media (max-width: 767.98px) {
    .tl-page { --tlg-rooms-w: 132px; }
    .tlg-range { min-width: 0; }
    .tlg-spacer { display: none; }
}

/* =========================================
   TIMELINE CARD & LEGEND
   ========================================= */
.timeline-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
    overflow: hidden;
}

.room-map-toolbar { box-shadow: 0 2px 10px rgba(15,23,42,.05); }

.timeline-inline-notice.data-state {
    display: flex;
    min-height: auto;
    align-items: center;
    justify-content: flex-start;
    flex-direction: row;
    gap: 8px;
    margin: 0 16px 16px;
    padding: 12px 14px;
    background: var(--color-surface-blue);
    border: 1px solid #bfdbfe;
    border-radius: var(--radius-control);
    font-size: 0.875rem;
    text-align: left;
}

.timeline-inline-notice .data-state__icon {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    margin: 0;
    border-radius: 10px;
    font-size: 16px;
}

.timeline-inline-notice__content { display: grid; gap: 2px; }

.timeline-state {
    min-height: 550px;
    background: linear-gradient(180deg, var(--color-surface) 0%, #f8fafc 100%);
}

.timeline-state .data-state { min-height: 550px; }
.timeline-state .data-state--loading .data-state__icon { color: var(--color-info); background: var(--color-surface-blue); }
.timeline-state .data-state--error .data-state__icon { color: var(--color-danger); background: #fef2f2; }
.timeline-state .data-state--empty .data-state__icon { color: var(--color-action); background: var(--color-surface-teal); }





.hover-light { transition: all 0.2s; cursor: pointer; }
.hover-light:hover { color: #fff !important; transform: scale(1.1); }

/* =========================================
   5. PAGE: LOGIN SCREEN
   ========================================= */
/* Class đặc biệt cho thẻ body của trang login */
body.login-page {
    min-height: 100vh;
    min-height: 100dvh;
    height: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6) var(--space-4);
    overflow-x: hidden;
    overflow-y: auto;
    color: var(--color-text);
    background:
        radial-gradient(circle at 12% 18%, rgba(45, 212, 191, 0.2), transparent 30%),
        radial-gradient(circle at 88% 82%, rgba(59, 130, 246, 0.16), transparent 32%),
        linear-gradient(135deg, var(--login-bg-start) 0%, var(--login-bg-end) 100%);
    font-family: var(--font-sans);
}

.login-shell {
    display: grid;
    width: 100%;
    place-items: center;
}

.login-card {
    width: min(440px, 100%);
    padding: 36px;
    background: var(--color-surface);
    border: 1px solid rgba(255, 255, 255, 0.72);
    border-radius: 20px;
    box-shadow: 0 24px 64px rgba(2, 6, 23, 0.28);
    text-align: center;
}

.login-header {
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-bottom: var(--space-5);
}

/* Lockup: dấu hiệu bên trái, tên sản phẩm bên phải — cùng hình với thanh bên. */
.login-lockup {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: var(--space-3);
}
.login-lockup__name {
    margin: 0;
    font-size: 26px;
    font-weight: 800;
    letter-spacing: .01em;
    color: var(--color-text);
    white-space: nowrap;
}

/* Thẻ bọc dấu hiệu. Tệp logo gốc mang sẵn `width/height` 120, nên kích thước
   thật đặt ở đây và hình bên trong kéo cho vừa. */
.logo-hotel-pos { display: inline-flex; flex: none; }
.logo-hotel-pos svg { display: block; width: 100%; height: 100%; }

/* Ẩn khỏi MẮT, giữ cho trình đọc màn hình.

   Bootstrap có sẵn lớp này, nhưng màn đăng nhập KHÔNG nạp Bootstrap — nó chỉ
   nạp `style.css` và FontAwesome. Dùng lớp của thư viện ở đó thì nó lặng lẽ
   không làm gì, và dòng chữ đáng lẽ ẩn vẫn nằm giữa màn hình. Khai ở đây thì
   mọi trang đều có, kể cả trang không có Bootstrap. */
.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.login-brand-mark {
    display: inline-grid;
    width: 64px;
    height: 64px;
    place-items: center;
    margin-bottom: var(--space-3);
    color: #fff;
    background: linear-gradient(145deg, var(--color-action), var(--color-action-hover));
    border-radius: 18px;
    box-shadow: var(--shadow-action);
    font-size: 26px;
}

.login-eyebrow {
    margin: 0 0 var(--space-1);
    color: var(--color-action);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.login-header h1 {
    margin: 0;
    color: var(--color-brand-navy);
    font-size: 28px;
    font-weight: 800;
    line-height: 1.25;
}

.login-intro {
    max-width: 330px;
    margin: var(--space-2) 0 0;
    color: var(--color-muted-text);
    font-size: 14px;
    line-height: 1.55;
}

/* Form Styles */
/* `.input-group` là HÀNG NGANG của Bootstrap (ô nhập + phần đính kèm), không
   phải khối trường có nhãn. Lề dưới ở đây từng làm mọi hàng lọc cao hơn ô nhập
   20px: màn Khách hàng ra hàng 64px trong khi ô nhập 44px nên nút "Tìm kiếm"
   (`align-items: stretch`) thò xuống dưới; màn Cấu hình phòng & giá thì ô
   "Tìm phòng" nằm cao hơn hai ô select cạnh nó đúng 20px. Khoảng cách giữa các
   trường là việc của lớp bố cục bao ngoài (`gap`, `mb-*`). */
.input-group { position: relative; text-align: left; }
.input-group label { display: block; margin-bottom: 5px; color: #34495e; font-weight: 500; font-size: 14px; }

.login-form {
    display: grid;
    gap: var(--space-4);
    text-align: left;
}

.login-field label {
    display: inline-block;
    margin-bottom: var(--space-2);
    color: var(--color-text);
    font-size: 13px;
    font-weight: 650;
}

.input-wrapper { position: relative; }
.input-wrapper .input-leading-icon {
    position: absolute;
    z-index: 1;
    top: 50%;
    left: var(--space-4);
    color: var(--color-muted-text);
    pointer-events: none;
    transform: translateY(-50%);
}
.input-wrapper input {
    width: 100%;
    min-height: 52px;
    padding: 0 var(--space-4) 0 46px;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid #cbd5e1;
    border-radius: var(--radius-control);
    outline: none;
    font-family: var(--font-sans);
    font-size: 16px;
    transition:
        border-color var(--motion-fast) ease,
        box-shadow var(--motion-fast) ease;
}

.input-wrapper--password input { padding-right: 58px; }
.input-wrapper input::placeholder { color: #94a3b8; }

.input-wrapper input:focus-visible {
    border-color: var(--color-info);
    outline: 3px solid var(--color-info);
    outline-offset: 1px;
    box-shadow: 0 0 0 1px var(--color-surface);
}

.login-password-toggle {
    position: absolute;
    top: 4px;
    right: 4px;
    display: inline-grid;
    min-width: 44px;
    min-height: 44px;
    place-items: center;
    padding: 0;
    color: var(--color-muted-text);
    background: transparent;
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    transition:
        color var(--motion-fast) ease,
        background-color var(--motion-fast) ease;
    touch-action: manipulation;
}

.login-password-toggle:hover {
    color: var(--color-info);
    background: var(--color-surface-blue);
}

.login-password-toggle:focus-visible,
.btn-login:focus-visible {
    outline: 3px solid var(--color-info);
    outline-offset: 2px;
}

.checkbox-group {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-muted-text);
    font-size: 14px;
}
.checkbox-group input {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--color-action);
    cursor: pointer;
}
.checkbox-group label {
    display: inline-flex;
    min-height: 44px;
    align-items: center;
    cursor: pointer;
}

/* Button */
.btn-login {
    display: inline-flex;
    width: 100%;
    min-height: 48px;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0 var(--space-4);
    color: #fff;
    background: var(--color-action);
    border: none;
    border-radius: var(--radius-control);
    box-shadow: var(--shadow-action);
    font-family: var(--font-sans);
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    transition:
        background-color var(--motion-fast) ease,
        box-shadow var(--motion-fast) ease,
        transform var(--motion-fast) ease;
    touch-action: manipulation;
}
.btn-login:hover {
    background: var(--color-action-hover);
    box-shadow: 0 8px 18px rgba(15, 118, 110, 0.24);
    transform: translateY(-1px);
}
.btn-login:active { transform: translateY(0); }
.btn-login:disabled {
    opacity: 0.62;
    cursor: wait;
    box-shadow: none;
    transform: none;
}

.login-form-status {
    min-height: 18px;
    margin: calc(var(--space-2) * -1) 0 0;
    color: var(--color-muted-text);
    font-size: 12px;
    line-height: 1.5;
    text-align: center;
}

.login-footer {
    margin-top: var(--space-2);
    color: var(--color-muted-text);
    font-size: 12px;
    line-height: 1.5;
}

/* Alert Messages */
.alert {
    padding: 12px;
    border-radius: 8px;
    margin-bottom: 20px;
    font-size: 14px;
    text-align: left;
    display: flex;
    align-items: center;
}
.alert-danger { background-color: #fee2e2; color: #dc2626; border: 1px solid #fecaca; }
.alert-info { background-color: #e0f2fe; color: #0284c7; border: 1px solid #bae6fd; }
.alert i { margin-right: 10px; }
.alert-success {
    background-color: #d1e7dd;
    color: #0f5132;
    border: 1px solid #badbcc;
}

.login-page .alert {
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-control);
    line-height: 1.45;
}

.login-page .alert i { margin-right: 0; }

@media (max-width: 575.98px) {
    body.login-page { padding: var(--space-4); }

    .login-card {
        padding: 28px 20px 24px;
        border-radius: 16px;
    }

    .login-brand-mark {
        width: 56px;
        height: 56px;
        border-radius: 16px;
        font-size: 23px;
    }

    .login-header h1 { font-size: 25px; }
}

/* =========================================
   BOOKING DETAIL (POS-LIKE)
   ========================================= */
.bd-pos-modal {
    border: 0;
    border-radius: 0;
    overflow: hidden;
    height: 100vh;
    display: flex;
    flex-direction: column;
}

.bd-pos-header {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.bd-pos-modal .modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.bd-pos-modal .modal-footer {
    border-top: 1px solid #e6ebf2;
    background: #fff;
}

.bd-pos-layout {
    height: 100%;
}

.bd-sidebar {
    background: #f5f7fb;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.bd-service-catalog-wrap {
    max-height: calc(100vh - 225px);
    overflow-y: auto;
}

.bd-sidebar-tab-bar {
    flex: 0 0 auto;
}

.bd-sidebar-tab-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.bd-sidebar-pane {
    height: 100%;
    overflow-y: auto;
}

/* Segmented dùng chung trong modal (tab sidebar POS...) */
.pos-seg { display: inline-flex; background: #f1f5f9; border-radius: 9px; padding: 3px; gap: 2px; }
.pos-seg--full { display: flex; width: 100%; }
.pos-seg--full .pos-seg__btn { flex: 1; }
.pos-seg__btn { border: 0; background: transparent; padding: 6px 12px; border-radius: 7px; font-size: 12.5px; font-weight: 600; color: var(--color-muted-text); cursor: pointer; text-align: center; white-space: nowrap; }
.pos-seg__btn.active { background: var(--color-surface); color: var(--color-text); box-shadow: 0 1px 2px rgba(15, 23, 42, .10); }

.bd-service-item {
    border: 1px solid #dee3eb;
    border-radius: 10px;
    padding: 10px;
    background: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

.bd-service-item:hover {
    border-color: var(--color-action);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.bd-service-price {
    color: var(--color-action);
    font-weight: 600;
}

.bd-invoice-grand-total {
    font-size: 24px;
    letter-spacing: -.02em;
    color: var(--color-text);
}

.bd-main-panel {
    background: #fff;
    min-height: 0;
}

.bd-invoice-table thead th {
    background: var(--color-surface);
    color: #94a3b8;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--color-border);
}

.bd-invoice-table tbody td {
    border-top: 1px solid #f1f5f9;
    border-bottom: 0;
    font-size: 13.5px;
}

.bd-invoice-table td,
.bd-invoice-table th {
    vertical-align: middle;
}

@media (max-width: 991.98px) {
    .bd-pos-layout {
        height: auto;
        min-height: 100%;
    }

    .bd-service-catalog-wrap {
        max-height: 35vh;
    }
}

/* Shared operational dashboard components */
:where(a, button, input, select, textarea):focus-visible {
    outline: 3px solid var(--color-focus-ring);
    outline-offset: 2px;
}

.input-wrapper input:focus-visible {
    outline: 3px solid var(--color-focus-ring);
    outline-offset: 2px;
}

.customer-action-button,
.modal .btn-close {
    min-width: 44px;
    min-height: 44px;
}

.customer-action-button {
    display: inline-grid;
    place-items: center;
}

.modal .btn-close {
    flex: 0 0 44px;
    padding: 0;
    background-position: center;
}

.skip-link {
    position: fixed;
    z-index: 1000;
    top: 8px;
    left: 8px;
    padding: 10px 14px;
    color: #fff;
    background: var(--color-primary);
    border-radius: 8px;
    transform: translateY(-150%);
    transition: transform 180ms ease;
}

.skip-link:focus { transform: translateY(0); color: #fff; }

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    min-height: 60px;
    padding: 12px 24px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.page-header__title {
    margin: 0;
    color: var(--color-text);
    font-size: 18px;
    font-weight: 750;
}

.page-header__eyebrow {
    color: var(--color-primary);
    font-size: 11px;
    font-weight: 750;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.page-header__description {
    margin-top: 4px;
    color: var(--color-muted-text);
    font-size: 13px;
    line-height: 1.4;
}

.page-header__actions,
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.filter-bar {
    padding: 12px 24px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.customer-search-bar {
    display: flex;
    /* stretch de nut cao dung bang o nhap — align center tung lech tren Safari */
    align-items: stretch;
    gap: 10px;
}

.customer-search-bar__input { flex: 1 1 360px; }
.customer-search-bar__button {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.data-filter-bar {
    display: block;
    padding: 0;
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
}

.data-filter-bar .card-body { padding: var(--space-4); }

/* BỐN cột: hai ô ngày, ô cách nhìn, rồi cụm nút chiếm phần còn lại.
   Khai ba cột trong khi hàng có bốn phần tử thì cụm nút rơi xuống hàng sau và
   xếp bậc thang — đúng thứ vừa xảy ra khi thêm ô "Cách nhìn". */
.billing-filter-layout {
    display: grid;
    grid-template-columns:
        minmax(180px, 240px) minmax(180px, 240px) minmax(170px, 220px) 1fr;
    align-items: end;
    gap: var(--space-3);
}

.billing-filter-field { min-width: 0; }
.billing-filter-field .form-label {
    margin-bottom: var(--space-1);
    color: var(--color-muted-text);
    font-size: 12px;
    font-weight: 700;
}
.billing-filter-field .form-control { min-height: 44px; }
.billing-filter-actions { justify-content: flex-end; }

.data-table-card {
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
}

.data-table-shell { min-height: 240px; }

/* Trang bảng chia trang vừa màn hình (Hoá đơn cũ, Sổ Quỹ): khít đúng vùng nội
   dung — không dôi ra ngoài màn — và là một cột flex để thanh phân trang ghim
   được xuống đáy. `flex:1 + min-height:0` lấp đúng phần còn lại dưới thanh tiêu
   đề, không hơn, nếu không thanh phân trang tràn khỏi màn. */
.data-fit-page {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}
.data-pagination {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    /* Ghim xuống đáy vùng nội dung. Số dòng (reserved trong JS) được tính vừa
       khít chiều cao còn lại nên margin auto này gần như bằng 0 — thanh nằm sát
       đáy mà bảng vẫn lấp đầy, không hở mảng trống ở giữa. */
    margin-top: auto;
    padding-top: var(--space-4);
    padding-bottom: var(--space-4);   /* chừa khoảng thở với mép dưới, không quá sát */
}
.data-pagination:empty { display: none; }
.data-page-controls {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
}
.data-page-btn {
    min-width: 40px;
    height: 40px;
    padding: 0 var(--space-3);
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-primary);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease, transform .1s ease;
}
.data-page-btn:hover:not(:disabled):not(.active) {
    background: var(--color-surface-teal);
    border-color: var(--color-action);
    color: var(--color-action);
    transform: translateY(-1px);
}
.data-page-btn:focus-visible {
    outline: 3px solid var(--color-focus-ring);
    outline-offset: 2px;
}
.data-page-btn.active {
    background: var(--color-action);
    border-color: var(--color-action);
    color: #fff;
    box-shadow: 0 6px 16px -6px rgba(15, 118, 110, 0.55);
}
.data-page-btn:disabled {
    opacity: .4;
    cursor: default;
}
.data-page-gap {
    min-width: 32px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-muted-text);
}
.table-responsive {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.data-table-state-row > td { padding: 0 !important; background: var(--color-surface); }
.data-table-state-row:hover > td { background: var(--color-surface) !important; }
.data-table-state-row .data-state { min-height: 240px; }
.data-table-state-row .data-state--loading .data-state__icon { color: var(--color-info); background: var(--color-surface-blue); }
.data-table-state-row .data-state--error .data-state__icon { color: var(--color-danger); background: #fef2f2; }
.data-table-state-row .data-state--empty .data-state__icon { color: var(--color-action); background: var(--color-surface-teal); }

.table-row-actions {
    flex-wrap: nowrap;
    justify-content: flex-end;
}

.billing-money-column { min-width: 132px; }
.billing-quantity-column { min-width: 42px; }

@media (max-width: 991.98px) {
    .billing-filter-layout { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .billing-filter-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

@media (max-width: 575.98px) {
    .app-content .form-control,
    .app-content .form-select { font-size: 16px; }

    .customer-search-bar { align-items: stretch; flex-direction: column; }
    .customer-search-bar__button { width: 100%; }
    .billing-filter-layout { grid-template-columns: minmax(0, 1fr); }
    .billing-filter-actions { grid-column: auto; }
    .billing-filter-actions .btn { flex: 1 1 auto; }
}

/* Shared modal shell for short operational actions. */
.operation-modal { max-width: 540px; }
.operation-modal.operation-modal--wide { max-width: 860px; }
.operation-modal .modal-content { overflow: hidden; border: 1px solid var(--color-border); border-radius: 14px; box-shadow: 0 20px 48px rgba(24, 33, 47, 0.2); }
.operation-modal .modal-header { min-height: 64px; padding: 16px 20px; border-bottom: 1px solid var(--color-border); }
.operation-modal .modal-title { color: inherit; font-size: 16px; font-weight: 750; }
.operation-modal .modal-body { max-height: min(66vh, 680px); padding: 20px; overflow-y: auto; }
.operation-modal .modal-footer { gap: 8px; padding: 14px 20px; background: #fbfaf8; border-top: 1px solid var(--color-border); }
.operation-modal .form-label { margin-bottom: 6px; color: var(--color-text); font-size: 13px; font-weight: 650; }
.operation-modal--danger .modal-footer { background: #fff8f7; }
.operation-modal__header--teal { color: #fff; background: #0f766e; border-bottom-color: #0f766e !important; }
.operation-modal__header--danger { color: #fff; background: var(--color-danger); border-bottom-color: var(--color-danger) !important; }
.operation-modal__header--neutral { color: var(--color-text); background: #f8fafc; }

/* Đầu tối cho modal toàn màn (Chi tiết hoá đơn). Lấy navy CỦA APP, không mượn
   `bg-dark` của Bootstrap: hai màu nhìn gần như nhau (#18212f và #212529) nên
   không ai phát hiện, nhưng màu ấy đi nhờ một biến của thư viện khác — đổi thư
   viện hay thư viện đổi bảng màu là nó trôi theo, im lặng. */
.workflow-modal__header--navy {
    color: #fff;
    background: var(--color-brand-navy);
    border-bottom-color: var(--color-brand-navy) !important;
}

.operation-form-section {
    min-width: 0;
    margin: 0 0 var(--space-4);
    padding: var(--space-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-control);
}

.operation-form-section:last-child { margin-bottom: 0; }
.operation-form-section--accent { background: var(--color-surface-teal); border-color: #b9e5db; }
.operation-form-section__title {
    float: none;
    width: auto;
    margin: 0 0 var(--space-3);
    padding: 0;
    color: var(--color-text);
    font-size: 14px;
    font-weight: 750;
}

.pricing-panel-header {
    display: flex;
    min-height: 84px;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.pricing-panel-title {
    margin: 0;
    color: var(--color-text);
    font-size: 16px;
    font-weight: 750;
    line-height: 1.35;
}

.pricing-panel-title i { color: var(--color-action); }
.pricing-panel-description { margin: var(--space-1) 0 0; color: var(--color-muted-text); font-size: 12px; line-height: 1.45; }
.pricing-table { min-width: 680px; }
.pricing-table--base { min-width: 720px; }
.pricing-col-daily { width: 190px; }
.pricing-col-hourly { width: 250px; }
.pricing-col-actions { width: 68px; }
.pricing-room-cell { display: grid; justify-items: start; gap: var(--space-2); }
.pricing-room-number { color: var(--color-text); font-size: 16px; line-height: 1.25; }
.pricing-input-group { min-width: 150px; }
.pricing-input-label { width: 52px; justify-content: center; color: var(--color-muted-text); font-weight: 700; }
.pricing-hourly-stack { display: grid; gap: var(--space-1); }
.pricing-rule-name { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin-bottom: var(--space-1); }
.pricing-rule-range { display: block; color: var(--color-info); font-size: 12px; }
.pricing-rule-days { display: flex; flex-wrap: wrap; gap: 4px; margin-top: var(--space-2); color: var(--color-muted-text); font-size: 12px; }
.pricing-day-badge {
    display: inline-flex;
    min-width: 28px;
    min-height: 24px;
    align-items: center;
    justify-content: center;
    padding: 3px 6px;
    color: #475569;
    background: #f1f5f9;
    border: 1px solid #cbd5e1;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}
.pricing-day-badge--weekend { color: #9f1239; background: #fff1f2; border-color: #fecdd3; }
.pricing-rule-price { color: #047857; }
.pricing-weekday-picker { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pricing-weekday-picker .form-check {
    display: inline-flex;
    min-height: 36px;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 6px 10px 6px 32px;
    background: #f8fafc;
    border: 1px solid var(--color-border);
    border-radius: 999px;
}
.pricing-weekday-picker__weekend { color: #9f1239; background: #fff1f2 !important; border-color: #fecdd3 !important; }

/* Room configuration groups the operational room list and default rates. */
.settings-page-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-2);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-control);
    box-shadow: var(--shadow-surface);
}
.settings-page-tabs__link {
    display: inline-flex;
    min-height: 44px;
    align-items: center;
    gap: var(--space-2);
    padding: 10px 14px;
    color: var(--color-muted-text);
    border: 1px solid transparent;
    border-radius: calc(var(--radius-control) - 2px);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.25;
    text-decoration: none;
    transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.settings-page-tabs__link:hover { color: var(--color-primary); background: var(--color-surface-teal); }
.settings-page-tabs__link.is-active { color: #fff; background: var(--color-primary); border-color: var(--color-primary); box-shadow: 0 3px 9px rgba(15, 118, 110, 0.22); }
.settings-page-tabs__link:focus-visible { outline: 3px solid rgba(14, 116, 144, 0.35); outline-offset: 2px; }

.room-settings-filter-layout {
    display: grid;
    grid-template-columns: minmax(220px, 1.4fr) minmax(170px, .8fr) minmax(170px, .8fr);
    align-items: end;
    gap: var(--space-3);
}
.room-settings-filter-field { min-width: 0; }
.room-settings-filter-field .form-label { margin-bottom: var(--space-1); color: var(--color-muted-text); font-size: 12px; font-weight: 700; }
.room-settings-filter-field .form-control,
.room-settings-filter-field .form-select { min-height: 44px; }
.room-settings-table { min-width: 810px; }
.room-settings-room-cell { display: grid; justify-items: start; gap: var(--space-2); }
.room-settings-room-number { color: var(--color-text); font-size: 16px; line-height: 1.25; }
.room-settings-price { min-width: 144px; color: #047857; }
.room-settings-hourly { min-width: 210px; }
.room-settings-hourly span { display: block; color: var(--color-muted-text); font-size: 12px; line-height: 1.55; }
.room-settings-booking-notice { display: block; margin-top: var(--space-2); color: #a16207; font-size: 11px; font-weight: 700; line-height: 1.35; }
.room-settings-page .form-switch { min-height: 44px; display: flex; align-items: center; gap: var(--space-2); }
.room-settings-page .form-switch .form-check-input { margin: 0; }

@media (max-width: 991.98px) {
    .room-settings-filter-layout { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .room-settings-filter-field--search { grid-column: 1 / -1; }
}

@media (max-width: 575.98px) {
    .settings-page-tabs__link { flex: 1 1 100%; justify-content: center; }
    .room-settings-filter-layout { grid-template-columns: minmax(0, 1fr); }
    .room-settings-filter-field--search { grid-column: auto; }
}

.finance-filter-layout {
    display: grid;
    grid-template-columns: minmax(180px, 220px) minmax(0, 1fr) auto minmax(220px, auto);
    align-items: end;
    gap: var(--space-3);
}

.finance-filter-field { min-width: 0; }
.finance-filter-field .form-label,
.cashier-period-fieldset > .form-label {
    margin-bottom: var(--space-1);
    color: var(--color-muted-text);
    font-size: 12px;
    font-weight: 700;
}
.finance-filter-field .form-control,
.finance-filter-field .form-select { min-height: 44px; }
.finance-custom-range { display: grid; grid-template-columns: repeat(2, minmax(160px, 220px)); gap: var(--space-2); }
.finance-filter-actions { align-self: end; }
.finance-period-label { margin: 0; color: var(--color-muted-text); font-size: 12px; line-height: 1.45; text-align: right; }
.finance-kpi-grid .kpi-card { height: 100%; }
.finance-panel-header { min-height: 64px; padding: var(--space-4); background: var(--color-surface); border-bottom: 1px solid var(--color-border); }
.finance-panel-title { margin: 0; color: var(--color-text); font-size: 16px; font-weight: 750; line-height: 1.35; }
.finance-panel-title i { color: var(--color-action); }
.finance-chart-card { overflow: hidden; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-surface); box-shadow: var(--shadow-surface); }
.finance-chart-body { min-height: 360px; padding: var(--space-4); }
.finance-chart-body > .data-state { min-height: 320px; }
.finance-chart-content { display: grid; gap: var(--space-3); }
.finance-chart-canvas { position: relative; height: 280px; min-height: 280px; }
.finance-chart-summary { margin: 0; padding: var(--space-3); color: var(--color-muted-text); background: #f8fafc; border: 1px solid var(--color-border); border-radius: var(--radius-control); font-size: 12px; line-height: 1.5; }
.finance-positive { color: #047857 !important; }
.finance-negative { color: var(--color-danger) !important; }

.cashier-filter-layout { display: flex; flex-wrap: wrap; align-items: end; gap: var(--space-4); }
.cashier-period-fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.finance-period-pills { display: flex; flex-wrap: wrap; }
.cashier-custom-toggle { min-height: 44px; display: flex; align-items: center; gap: var(--space-2); margin: 0; }
.cashier-custom-toggle .form-check-input { margin-top: 0; }
.deposit-print-card .card-body { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(360px, 560px); align-items: end; gap: var(--space-4); }
.deposit-print-form { display: grid; grid-template-columns: minmax(180px, 1fr) auto; align-items: end; gap: var(--space-2); }
.deposit-print-card #deposit-print-status { grid-column: 1 / -1; }

.expense-filter-layout { display: grid; grid-template-columns: minmax(160px, 200px) minmax(160px, 200px) minmax(180px, 220px) auto minmax(280px, 1fr); align-items: end; gap: var(--space-3); }
.expense-total-card { min-height: 86px; padding: var(--space-3) var(--space-4); }
.expense-sync-panel { padding: var(--space-4); background: var(--color-surface); border: 1px solid #b9e5db; border-radius: var(--radius-control); }

@media (max-width: 1199.98px) {
    .finance-filter-layout { grid-template-columns: minmax(180px, 220px) 1fr auto; }
    .finance-custom-range { grid-column: span 2; }
    .finance-period-label { grid-column: 1 / -1; text-align: left; }
    .expense-filter-layout { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .expense-total-card { grid-column: span 2; }
}

@media (max-width: 767.98px) {
    .pricing-panel-header { min-height: 0; flex-direction: column; }
    .operation-form-section { padding: var(--space-3); }
    .finance-filter-layout,
    .expense-filter-layout { grid-template-columns: minmax(0, 1fr); }
    .finance-custom-range { grid-column: auto; grid-template-columns: minmax(0, 1fr); }
    .finance-filter-actions .btn { width: 100%; }
    .expense-total-card { grid-column: auto; }
    .deposit-print-card .card-body,
    .deposit-print-form { grid-template-columns: minmax(0, 1fr); }
    .finance-chart-body { min-height: 320px; padding: var(--space-3); }
    .finance-chart-canvas { height: 240px; min-height: 240px; }
}

.warehouse-batch-list { display: grid; gap: var(--space-3); }
.warehouse-batch-list .data-state { min-height: 180px; padding: var(--space-4); }
.warehouse-batch-card { display: grid; gap: var(--space-2); padding: var(--space-4); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-control); }
.warehouse-batch-card__meta { margin: 0; color: var(--color-muted-text); font-size: 13px; }
.warehouse-batch-card__movements { min-height: 20px; color: var(--color-muted-text); font-size: 12px; line-height: 1.5; }
.btn-icon--compact { margin-left: var(--space-2); }

/* Upload-first CCCD QR reader for desktop operations. */
.qr-import-modal-body { display: grid; gap: 16px; padding: 20px; }
.qr-upload-dropzone { display: grid; min-height: 190px; place-items: center; align-content: center; gap: 5px; padding: 24px; border: 1.5px dashed var(--color-border); border-radius: 12px; background: #fbfcfe; color: var(--color-text); cursor: pointer; text-align: center; transition: border-color 180ms ease, background-color 180ms ease, box-shadow 180ms ease; }
.qr-upload-dropzone:hover, .qr-upload-dropzone:focus-within { border-color: var(--color-action); background: var(--color-surface-teal); box-shadow: 0 0 0 3px rgba(18, 133, 111, 0.12); }
.qr-upload-icon { display: inline-grid; width: 48px; height: 48px; place-items: center; border-radius: 14px; background: #dff4ed; color: var(--color-primary); font-size: 20px; }
.qr-image-preview-wrap { display: grid; justify-items: center; gap: 10px; padding: 12px; border: 1px solid var(--color-border); border-radius: 12px; background: #fff; }
.qr-image-preview-wrap img { display: block; max-width: 100%; max-height: 220px; border-radius: 8px; object-fit: contain; }
.qr-upload-status { min-height: 22px; color: var(--color-text-muted); font-size: 13px; text-align: center; }
.qr-upload-status[data-state="loading"] { color: var(--color-primary); }
.qr-upload-status[data-state="success"] { color: #157347; font-weight: 650; }
.qr-upload-status[data-state="error"] { color: #b42318; }
.qr-camera-panel { overflow: hidden; border: 1px solid var(--color-border); border-radius: 12px; background: #111827; }
.qr-camera-panel #qr-reader { width: 100%; border: 0 !important; }

/* Complex booking, order and billing workflows use a larger workspace. */
.workflow-modal--wide { max-width: min(1100px, calc(100vw - 48px)); }
.workflow-modal--wide .modal-content { overflow: hidden; border: 1px solid var(--color-border); border-radius: 16px; box-shadow: 0 24px 56px rgba(24, 33, 47, 0.26); }
.workflow-modal--wide .modal-header { min-height: 68px; padding: 16px 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.18); }
.workflow-modal--wide .modal-body { max-height: min(74vh, 760px); overflow-y: auto; }
.workflow-modal--wide .modal-footer { position: sticky; bottom: 0; z-index: 2; padding: 14px 20px; background: #fbfaf8; border-top: 1px solid var(--color-border); }
.workflow-modal--fullscreen { width: calc(100vw - 32px); max-width: 1440px; height: calc(100vh - 32px); margin: 16px auto; }
.workflow-modal--fullscreen .modal-content { height: 100%; overflow: hidden; border: 1px solid var(--color-border); border-radius: 16px; box-shadow: 0 24px 56px rgba(24, 33, 47, 0.26); }
.workflow-modal--fullscreen .modal-body { min-height: 0; overflow-y: auto; }
.workflow-modal--fullscreen .modal-footer { flex: 0 0 auto; padding: 14px 20px; background: #fbfaf8; border-top: 1px solid var(--color-border); }
@media (max-width: 991.98px) { .workflow-modal--wide, .workflow-modal--fullscreen { width: calc(100vw - 24px); max-width: none; height: calc(100vh - 24px); margin: 12px auto; } }

.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.25;
}

.status-badge--success { color: #065f46; background: #ecfdf5; border: 1px solid #a7f3d0; }
.status-badge--info { color: #1d4ed8; background: #eff6ff; border: 1px solid #bfdbfe; }
.status-badge--neutral { color: #475569; background: #f8fafc; border: 1px solid #cbd5e1; }
.status-badge--warning { color: #92400e; background: #fffbeb; border: 1px solid #fde68a; }
.status-badge--danger { color: #b91c1c; background: #fef2f2; border: 1px solid #fecaca; }

.button-group {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.numeric-tabular,
.kpi-card__value,
.app-content .table .text-end {
    font-variant-numeric: tabular-nums;
}

.kpi-card {
    display: flex;
    min-height: 96px;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4);
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-surface);
    box-shadow: var(--shadow-surface);
}

.kpi-card--teal { background: var(--color-surface-teal); }
.kpi-card--blue { background: var(--color-surface-blue); }
.kpi-card--warning { background: var(--color-warning-surface); border-color: #fde68a; }
.kpi-card--danger { background: #fef2f2; border-color: #fecaca; }

.kpi-card__icon {
    display: inline-grid;
    width: 46px;
    height: 46px;
    flex: 0 0 46px;
    place-items: center;
    color: var(--color-action);
    background: rgba(255, 255, 255, 0.72);
    border: 1px solid var(--color-border);
    border-radius: 14px;
    font-size: 18px;
}

.kpi-card--warning .kpi-card__icon { color: #b45309; border-color: #fde68a; }
.kpi-card--danger .kpi-card__icon { color: var(--color-danger); border-color: #fecaca; }
.kpi-card__meta { display: block; margin-top: var(--space-1); color: var(--color-muted-text); font-size: 12px; }

.kpi-card__label {
    margin: 0 0 var(--space-1);
    color: var(--color-muted-text);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.kpi-card__value {
    margin: 0;
    color: var(--color-text);
    font-size: 26px;
    font-weight: 700;
    line-height: 1.2;
}

.data-state {
    display: flex;
    min-height: 180px;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-5);
    color: var(--color-muted-text);
    text-align: center;
}

.data-state__icon {
    display: inline-grid;
    width: 48px;
    height: 48px;
    place-items: center;
    margin-bottom: var(--space-1);
    color: var(--color-action);
    background: var(--color-surface-teal);
    border-radius: 14px;
    font-size: 20px;
}

.data-state__title {
    margin: 0;
    color: var(--color-text);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.4;
}

.data-state__description {
    max-width: 520px;
    margin: 0;
    color: var(--color-muted-text);
    font-size: 13px;
    line-height: 1.5;
}

.data-state__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.sidebar-toggle {
    display: none;
}

@media (max-width: 991.98px) {
    body:not(.login-page) {
        min-width: 0;
    }

    body.sidebar-open { overflow: hidden; }

    .app-sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        width: min(280px, 85vw);
        transform: translateX(-100%);
        transition: transform 180ms ease;
        z-index: 200;
    }

    .app-sidebar.is-open {
        transform: translateX(0);
    }

    .sidebar-backdrop {
        position: fixed;
        z-index: 190;
        inset: 0;
        display: block;
        width: 100%;
        height: 100%;
        padding: 0;
        background: rgba(15, 23, 42, 0.52);
        border: 0;
        cursor: pointer;
    }

    .app-content {
        width: 100%;
    }

    .app-content .btn-sm {
        min-height: 44px;
    }

    .sidebar-toggle {
        display: inline-grid;
        width: 44px;
        height: 44px;
        place-items: center;
        margin: 0;
        color: var(--color-primary);
        background: var(--color-surface);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-control);
        cursor: pointer;
        touch-action: manipulation;
    }

    .page-header,
    .filter-bar {
        padding-right: 16px;
        padding-left: 16px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-content .btn,
    .btn-icon,
    .app-sidebar,
    .skip-link {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }

    .app-content .btn:hover:not(:disabled) {
        transform: none;
    }
}


/* Nut hanh dong tren card phong: khong ngat dong */
.room-card-action, .room-card .btn, .room-card button { white-space: nowrap; }

/* PROMAX: select tren mobile toi thieu 16px de iOS khong tu zoom */
@media (max-width: 576px) {
    select.form-select, .form-select-sm { font-size: 16px; }
}


/* =========================================
   POS MODAL — ngôn ngữ thiết kế 15-08 (dùng chung mọi modal luồng phòng)
   ========================================= */

.pos-modal .modal-content { border: 0; border-radius: 16px; box-shadow: 0 24px 60px rgba(15, 23, 42, .18); overflow: hidden; }
.pos-modal .modal-header { align-items: flex-start; min-height: 0; padding: 18px 24px 14px; background: var(--color-surface); border-bottom: 1px solid var(--color-border); }
.pos-modal .modal-title { font-size: 18px; font-weight: 700; letter-spacing: -.01em; color: var(--color-text); }
.pos-modal .modal-footer { background: var(--color-surface); border-top: 1px solid var(--color-border); padding: 12px 24px; }
.pos-subtitle { font-size: 12.5px; color: var(--color-muted-text); margin-top: 3px; }
.pos-title-accent { color: var(--color-action); }

.pos-split { display: grid; grid-template-columns: minmax(0, 1fr) 280px; align-items: stretch; }
.pos-main { padding: 20px 24px 24px; min-width: 0; }
.pos-summary { background: var(--color-background); border-left: 1px solid var(--color-border); padding: 20px; display: flex; flex-direction: column; }
.pos-summary-empty { font-size: 12.5px; color: #94a3b8; margin-top: 12px; }
.pos-summary-line { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 13px; margin-top: 12px; }
.pos-summary-muted { color: var(--color-muted-text); }
.pos-summary-divider { height: 1px; background: var(--color-border); margin: 14px 0; }
.pos-summary-total { display: flex; justify-content: space-between; align-items: baseline; font-size: 12.5px; font-weight: 600; }
.pos-summary-total span:last-child { font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
.pos-summary-flex { flex: 1 1 auto; min-height: 16px; }
.pos-note-amber { background: var(--color-warning-surface); border: 1px solid #fde68a; border-radius: 10px; padding: 10px 12px; font-size: 11.5px; color: #92400e; line-height: 1.5; }

.pos-label { display: block; font-size: 11px; font-weight: 600; color: var(--color-muted-text); margin-bottom: 5px; }
.pos-section-label { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #94a3b8; }
.pos-divider { border: 0; border-top: 1px solid var(--color-border); margin: 20px 0; opacity: 1; }
.pos-link-btn { border: 0; background: none; padding: 0; font-size: 11px; font-weight: 700; color: var(--color-action); cursor: pointer; }
.pos-link-btn:hover { color: var(--color-action-hover); }

.pos-chip { padding: 5px 12px; border-radius: 999px; border: 1px solid var(--color-border); background: var(--color-surface); font-size: 12px; font-weight: 600; color: #475569; cursor: pointer; }
.pos-chip:hover { background: #f8fafc; }
.pos-chip.active { border-color: var(--color-action); background: var(--color-surface-teal); color: var(--color-action); font-weight: 700; }

.pos-seg-tabs { display: inline-flex; background: #f1f5f9; border-radius: 9px; padding: 3px; gap: 2px; border: 0; margin-bottom: 6px; }
.pos-seg-tabs .nav-link { border: 0; border-radius: 7px; padding: 6px 16px; font-size: 13px; font-weight: 600; color: var(--color-muted-text); }
.pos-seg-tabs .nav-link.active { background: var(--color-surface); color: var(--color-text); box-shadow: 0 1px 2px rgba(15, 23, 42, .10); }

@media (max-width: 991.98px) {
    .pos-split { grid-template-columns: 1fr; }
    .pos-summary { border-left: 0; border-top: 1px solid var(--color-border); }
}

/* Hộp cảnh báo hủy trong modal sửa booking */
.pos-danger-box { background: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; padding: 14px 16px; }
.pos-danger-box legend, .pos-danger-box h6 { color: #b91c1c; }

/* Thẻ chọn cách áp giá (dời lịch) — viền teal khi chọn */
.pos-choice { border: 1px solid var(--color-border); border-radius: 11px; padding: 10px 14px 10px 40px; cursor: pointer; }
.pos-choice:hover { background: #f8fafc; }
.pos-choice:has(input:checked) { border-color: var(--color-action); background: var(--color-surface-teal); }
.pos-choice .form-check-input:checked { background-color: var(--color-action); border-color: var(--color-action); }

/* Bảng dòng hóa đơn trong modal (checkout, đoàn) — header uppercase nhạt */
.pos-line-table thead th { background: var(--color-surface); color: #94a3b8; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; border-bottom: 1px solid var(--color-border); }
.pos-line-table tbody td { border-top: 1px solid #f1f5f9; border-bottom: 0; font-size: 13.5px; vertical-align: middle; }
.pos-line-table tfoot td { border-top: 1px solid var(--color-border); background: var(--color-surface); }

/* Box tổng kết thanh toán */
.pos-total-box { background: var(--color-background); border: 1px solid var(--color-border); border-radius: 12px; padding: 16px; }
.pos-grand-due { font-size: 30px; font-weight: 700; letter-spacing: -.03em; color: var(--color-action); }

/* Nút chọn phương thức thanh toán */
.pos-method-btn { flex: 1; height: 40px; border-radius: 9px; border: 1px solid var(--color-border); background: var(--color-surface); color: #475569; font-size: 13.5px; font-weight: 600; cursor: pointer; }
.pos-method-btn:hover { background: #f8fafc; }
.pos-method-btn.active { background: #0f172a; border-color: #0f172a; color: #fff; }

/* Card chọn phòng trống (đặt đoàn) — teal khi chọn, hổ phách ngày đặc biệt */
.pos-room-card { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 2px; width: 100%; height: 100%; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-surface); cursor: pointer; transition: border-color .12s ease, background .12s ease; }
.pos-room-card:hover { border-color: #cbd5e1; background: #f8fafc; }
.pos-room-card__price { color: #94a3b8; font-weight: 600; }
.btn-check:checked + .pos-room-card { border-color: var(--color-action); background: var(--color-surface-teal); }
.btn-check:checked + .pos-room-card__price,
.btn-check:checked + .pos-room-card .pos-room-card__price { color: var(--color-action); }
.btn-check:focus-visible + .pos-room-card { outline: 3px solid var(--color-focus-ring); outline-offset: 1px; }
.pos-room-card--special { border-color: #fde68a; background: var(--color-warning-surface); }

/* Nút tối (Tìm phòng trong đặt đoàn) */
.pos-dark-btn { background: #0f172a; border: 1px solid #0f172a; color: #fff; }
.pos-dark-btn:hover { background: #1e293b; border-color: #1e293b; color: #fff; }

.pos-chip.flex-none { flex: none; }

/* --- Gợi ý khách cũ khi gõ số điện thoại --- */
/* Lớp phủ PHẢI thả nổi: chèn vào dòng chảy thì mỗi lần danh sách hiện ra rồi
   mất, các ô Tên / CCCD / Địa chỉ bị đẩy xuống rồi nhảy lên — form giật đúng
   lúc người dùng đang gõ. */
.pos-suggest-anchor { position: relative; }
.pos-suggest {
    /* `fixed` chứ KHÔNG `absolute`: `.workflow-modal--wide .modal-body` có
       `max-height` + `overflow-y: auto`, tức là một vùng cuộn, và nó cắt mọi
       phần tử absolute bên trong bất kể z-index. Toạ độ do JS tính từ
       getBoundingClientRect của ô nhập — xem positionSuggestPanel. */
    position: fixed;
    z-index: 1080;                 /* trên .modal (1055) của Bootstrap */
    background: #fff;
    border: 1px solid var(--color-border, #d1d5db);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .12);
    /* Phải cuộn được, không `overflow: hidden`: cùng phần tử này còn chứa bảng
       "Chọn khách dùng chung SĐT" của lỗi 409, và danh sách đó KHÔNG bị cắt còn
       5 dòng — cắt cụt là mất một khách mà không có gì báo, trong khi đây là
       đường duy nhất để đi tiếp. */
    max-height: 44vh;
    overflow-y: auto;
}
.pos-suggest__heading {
    padding: 8px 12px 4px;
    font-size: 12px; font-weight: 600; color: #64748b;
}
.pos-suggest__item {
    display: block; width: 100%; text-align: left;
    padding: 8px 12px; border: 0; background: none;
    font-size: 13px; color: #1f2937; cursor: pointer;
}

/* --- Bảng gợi ý khách cũ: 5 cột ------------------------------------------
   Một dòng chữ "Tên · SĐT · CCCD" đọc được khi có một kết quả, nhưng lúc cần
   nhất — hai khách trùng số điện thoại — thì năm dòng gần giống hệt nhau và
   mắt không biết bắt đầu từ đâu. Tách cột để quét dọc.
   Lưới dùng chung giữa hàng tiêu đề và các dòng, nên hai chỗ phải cùng một
   `grid-template-columns`; đổi một chỗ mà quên chỗ kia là cột lệch nhau. */
.pos-suggest__head {
    padding: 9px 14px;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    background: #f8fafc;
    font-size: 11.5px; font-weight: 600; letter-spacing: .3px;
    color: #64748b; text-transform: uppercase;
}
.pos-suggest__cols,
.pos-suggest__row {
    display: grid;
    grid-template-columns: 1.4fr 1.15fr 1.2fr 1.3fr .95fr;
    gap: 14px;
    align-items: center;
}
.pos-suggest__cols {
    padding: 8px 14px;
    background: #f1f5f9;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
}
.pos-suggest__col {
    font-size: 11px; font-weight: 600; letter-spacing: .3px;
    color: #94a3b8; text-transform: uppercase;
}
.pos-suggest__col:last-child { text-align: right; }
.pos-suggest__row {
    width: 100%;
    padding: 10px 14px;
    border: 0; border-bottom: 1px solid #f1f5f9;
    background: none; text-align: left; cursor: pointer;
}
.pos-suggest__row:last-child { border-bottom: 0; }
/* Chủ yếu dùng chuột, nên cả dòng phải sáng lên rõ — không chỉ đổi con trỏ. */
.pos-suggest__row:hover,
.pos-suggest__row:focus-visible {
    background: #eef2ff; outline: none;
}

/* Mọi ô đều cắt bằng ellipsis: địa chỉ dài làm vỡ lưới và đẩy cột Lưu trú ra
   ngoài panel. `min-width: 0` bắt buộc — ô lưới mặc định không co dưới nội
   dung, nên thiếu nó thì `text-overflow` không bao giờ có tác dụng. */
.pos-suggest__who,
.pos-suggest__phone,
.pos-suggest__muted,
.pos-suggest__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pos-suggest__who { display: flex; align-items: center; gap: 9px; }
.pos-suggest__avatar {
    flex-shrink: 0;
    display: grid; place-items: center;
    width: 30px; height: 30px; border-radius: 9px;
    font-size: 13px; font-weight: 700;
}
/* Năm tông nhạt cùng họ navy/xanh xám của app, xoay vòng theo thứ tự dòng —
   đủ để mắt tách các dòng ra, không đủ đậm để tranh chú ý với chữ. */
.pos-suggest__avatar--a0 { background: #e0e7ff; color: #4338ca; }
.pos-suggest__avatar--a1 { background: #dbeafe; color: #1d4ed8; }
.pos-suggest__avatar--a2 { background: #e0f2fe; color: #0369a1; }
.pos-suggest__avatar--a3 { background: #ede9fe; color: #6d28d9; }
.pos-suggest__avatar--a4 { background: #e2e8f0; color: #475569; }

.pos-suggest__name { font-size: 14px; font-weight: 600; color: #111827; }
.pos-suggest__phone { font-size: 14px; color: #374151; font-variant-numeric: tabular-nums; }
/* Đoạn số vừa gõ. Đây là chỗ duy nhất trong bảng dùng màu nhấn — để mắt bám
   vào nó chứ không vào thứ khác. */
.pos-suggest__hit {
    font-weight: 700; color: var(--color-primary, #1e293b);
    background: #e0e7ff; border-radius: 3px; padding: 0 2px;
}
.pos-suggest__muted { font-size: 13px; color: #6b7280; font-variant-numeric: tabular-nums; }
.pos-suggest__stay { min-width: 0; text-align: right; }
.pos-suggest__stay-count { display: block; font-size: 13px; font-weight: 600; color: var(--color-primary, #1e293b); }
.pos-suggest__stay-last { display: block; margin-top: 1px; font-size: 11px; color: #94a3b8; white-space: nowrap; }

/* Màn hẹp: lưới 5 cột không còn nghĩa, xếp lại thành hai dòng cho mỗi khách.
   Ẩn hàng tiêu đề cột vì nó không còn ăn khớp với gì cả. */
@media (max-width: 820px) {
    .pos-suggest__cols { display: none; }
    .pos-suggest__row {
        grid-template-columns: 1fr auto;
        row-gap: 2px;
    }
    .pos-suggest__muted { grid-column: 1 / -1; }
}
.pos-suggest__item + .pos-suggest__item { border-top: 1px solid #f1f5f9; }
.pos-suggest__item:hover,
.pos-suggest__item:focus-visible { background: #f1f5f9; outline: none; }


/* Hàng "ghi nhớ" và lối vào quên mật khẩu đứng hai đầu cùng một dòng. */
.login-remember-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.login-forgot-link {
    /* Không để trình duyệt tự tô: mặc định là tím "đã ghé", nằm ngay trên một
       thẻ toàn tông xanh thì đọc ra như một liên kết lạc từ trang khác vào. */
    color: var(--color-action);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
}

.login-forgot-link:hover {
    text-decoration: underline;
}


/* Lối quay lại dưới form. KHÔNG tái dùng .login-form-status: class đó có
   margin-top ÂM để nép sát nút submit, nên một liên kết đặt vào đó sẽ nằm đè
   lên chính cái nút. */
.login-back-link {
    margin: 16px 0 0;
    text-align: center;
    font-size: 13px;
}

.login-back-link a {
    color: var(--color-action);
    font-weight: 600;
    text-decoration: none;
}

.login-back-link a:hover {
    text-decoration: underline;
}


/* ==========================================================================
   Thông báo trượt — thay cho alert() gốc.
   Góc dưới phải: không che thanh điều hướng trên, không che nút xác nhận ở
   chân modal (chỗ tay người dùng đang ở).
   ========================================================================== */
.app-notify {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 2000;          /* trên modal Bootstrap (1055) */
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(380px, calc(100vw - 40px));
    pointer-events: none;   /* nền không chặn thao tác; từng thẻ tự bật lại */
}

.app-notify__card {
    pointer-events: auto;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: 12px;
    padding: 13px 14px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-muted-text);
    border-radius: 10px;
    box-shadow: 0 2px 4px rgba(15, 23, 42, .06), 0 12px 28px -12px rgba(15, 23, 42, .3);
    animation: app-notify-in .18s ease-out;
}

.app-notify__card--success { border-left-color: var(--color-success); }
.app-notify__card--error   { border-left-color: var(--color-danger); }
.app-notify__card--warning { border-left-color: var(--color-warning); }
.app-notify__card--info    { border-left-color: var(--color-info); }

.app-notify__icon { font-size: 15px; line-height: 1.5; }
.app-notify__card--success .app-notify__icon { color: var(--color-success); }
.app-notify__card--error   .app-notify__icon { color: var(--color-danger); }
.app-notify__card--warning .app-notify__icon { color: var(--color-warning); }
.app-notify__card--info    .app-notify__icon { color: var(--color-info); }

.app-notify__text {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--color-text);
    /* Câu từ máy chủ có thể dài và không có dấu cách (mã đơn, đường dẫn) —
       không ngắt thì thẻ tràn ra ngoài màn hình. */
    overflow-wrap: anywhere;
}

.app-notify__close {
    border: 0;
    background: none;
    padding: 0 2px;
    font-size: 19px;
    line-height: 1;
    color: var(--color-muted-text);
    cursor: pointer;
}
.app-notify__close:hover { color: var(--color-text); }
.app-notify__close:focus-visible {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
    border-radius: 4px;
}

@keyframes app-notify-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
@keyframes app-notify-out {
    to { opacity: 0; transform: translateY(6px); }
}
.app-notify__card.is-leaving { animation: app-notify-out .16s ease-in forwards; }

@media (prefers-reduced-motion: reduce) {
    .app-notify__card,
    .app-notify__card.is-leaving { animation: none; }
    .app-notify__card.is-leaving { opacity: 0; }
}

@media (max-width: 480px) {
    .app-notify { right: 12px; left: 12px; bottom: 12px; width: auto; }
}

/* Hộp xác nhận — thay cho confirm() gốc. */
.app-ask__box { border: 0; border-radius: 12px; overflow: hidden; }
.app-ask__body {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 13px;
    align-items: start;
    padding: 22px 22px 6px;
}
.app-ask__icon { font-size: 19px; color: var(--color-info); line-height: 1.4; }
.app-ask__icon--danger { color: var(--color-danger); }
.app-ask__text {
    margin: 0;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--color-text);
    overflow-wrap: anywhere;
}
.app-ask__foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 16px 22px 20px;
}
.app-ask__foot .btn { font-size: 14px; font-weight: 600; }

/* Lỗi gắn với ĐÚNG ô sai — đỏ ngay dưới ô, thay vì một câu chung ở đầu thẻ.
   Người dùng nhìn thẳng vào chỗ phải sửa, không phải dò xem câu đó nói về ô nào. */
.field-error {
    display: block;
    margin: 6px 0 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--color-danger);
}

.input-wrapper.has-error input,
input.has-error {
    border-color: var(--color-danger);
}
.input-wrapper.has-error input:focus,
input.has-error:focus {
    outline-color: var(--color-danger);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .16);
}

/* Cụm tăng/giảm số lượng trên hoá đơn trả phòng.
   
   Trước đây mượn `.input-group` của Bootstrap, mà lớp đó `flex-wrap: wrap`:
   hẹp một chút là nút "+" rơi xuống dòng, chồng chéo lên số ngay trên nó. Ba
   phần tử luôn phải nằm CÙNG MỘT HÀNG — đó là điều kiện để đọc được, nên nó
   viết thành `nowrap` chứ không phó mặc cho bề rộng cột.
   
   Không mượn `.input-group` nữa: lớp đó dùng chung khắp các màn lọc, và đã
   một lần bị chỉnh vì lý do khác làm lệch chỗ này. */
.qty-stepper {
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: stretch;
    border: 1px solid var(--color-border, #dbe2e8);
    border-radius: 8px;
    overflow: hidden;
    background: #fff;
}

.qty-stepper__btn {
    border: 0;
    background: transparent;
    padding: 0 10px;
    min-width: 34px;
    line-height: 1;
    cursor: pointer;
    color: var(--color-muted, #6b7c8f);
    transition: background-color .15s ease, color .15s ease;
}
.qty-stepper__btn--down:hover { background: #fdecea; color: #c0392b; }
.qty-stepper__btn--up:hover   { background: #e8f6ee; color: #1e8449; }
.qty-stepper__btn:focus-visible {
    outline: 2px solid var(--color-primary, #2d6cdf);
    outline-offset: -2px;
}

.qty-stepper__value {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 42px;
    padding: 6px 4px;
    font-weight: 700;
    /* Số xếp cột thì phải cùng bề ngang, nếu không 1 và 2 làm cụm nút nhảy. */
    font-variant-numeric: tabular-nums;
    border-left: 1px solid var(--color-border, #dbe2e8);
    border-right: 1px solid var(--color-border, #dbe2e8);
    color: var(--color-text, #22303f);
}

/* Hai lựa chọn cho khoản cọc còn thiếu: thu đủ, hay ghi nợ.
   
   Trước đây chỉ có một ô tiền điền sẵn nguyên số cần thu, và cách duy nhất để
   ghi nợ là tự xoá nó về 0 — một ý định quan trọng như "cho khách nợ" nằm ẩn
   trong việc xoá một con số. Hai thẻ chọn nói ý định ra thành lời.
   
   Theo UI-UX-PROMAX: vùng bấm tối thiểu 44px, cách nhau 8px, focus ring luôn
   nhìn thấy, transition 150–300ms và tôn trọng prefers-reduced-motion. */
.deposit-choice {
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 8px);
    margin-bottom: 12px;
}

.deposit-choice__option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    /* 44px là sàn, không phải chiều cao cố định: câu gợi ý xuống dòng ở màn
       hẹp thì thẻ cao lên theo, không bị cắt chữ. */
    min-height: 44px;
    margin: 0;
    /* Nhịp 4/8: 12px thay vì 10px. */
    padding: 12px;
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: 10px;
    background: var(--color-surface, #fff);
    cursor: pointer;
    transition: border-color 180ms ease, background-color 180ms ease;
}

.deposit-choice__option input[type="radio"] {
    /* Căn theo dòng chữ đầu, không theo giữa thẻ: thẻ cao lên khi chữ xuống
       dòng thì nút tròn vẫn nằm cạnh tiêu đề. */
    margin-top: 2px;
    flex: none;
    width: 18px;
    height: 18px;
    accent-color: var(--color-primary, #1e293b);
}

.deposit-choice__body { display: flex; flex-direction: column; gap: 2px; }
.deposit-choice__title { font-weight: 600; line-height: 1.35; }
.deposit-choice__hint {
    font-size: 12.5px;
    line-height: 1.4;
    /* KHÔNG dùng --color-muted-text (#64748b): trên nền thẻ đang chọn
       (#eff6ff) nó chỉ đạt 4.37:1, dưới ngưỡng 4.5:1. Màu này đạt 5.45:1
       trên trắng và 5.01:1 trên nền đã chọn — đủ ở CẢ HAI trạng thái, vì
       một màu chỉ đúng ở trạng thái mặc định là một màu chưa được kiểm. */
    color: #5b6b7f;
}

.deposit-choice { border: 0; padding: 0; margin: 0 0 12px; min-width: 0; }
.deposit-choice__legend {
    float: none;
    width: auto;
    margin-bottom: var(--space-2, 8px);
    font-size: inherit;
}

/* Ô tiền bị khoá phải NHÌN RA là khoá, không chỉ là không gõ được. Một ô
   trông gõ được mà không gõ được làm người ta tưởng bàn phím hỏng. */
#extend-stay-deposit-amount[readonly],
#transfer-room-deposit-amount[readonly] {
    background: var(--color-surface-muted, #f1f5f9);
    cursor: not-allowed;
}

.deposit-choice__option:hover {
    /* Chỉ đổi màu, không đổi kích thước: hover làm dịch layout khiến con trỏ
       trượt khỏi thứ người ta định bấm. */
    border-color: var(--color-primary, #1e293b);
}

.deposit-choice__option:has(input:checked) {
    border-color: var(--color-primary, #1e293b);
    background: var(--color-surface-blue, #eff6ff);
}

.deposit-choice__option:has(input:focus-visible) {
    outline: 2px solid var(--color-primary, #1e293b);
    outline-offset: 2px;
}

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

@media (max-width: 480px) {
    /* Trình duyệt di động tự phóng to trang khi ô nhập nhỏ hơn 16px. */
    .deposit-choice__title { font-size: 16px; }
}


/* Nút dọn nhanh ở đầu ô phòng.
   
   Chỉ có biểu tượng: chân ô không còn chỗ (154px dùng được, nút chính + nhãn
   đã 161px), còn chữ "CẦN DỌN" thì thân ô đã nói rồi. Tên đọc được nằm ở
   aria-label và title — theo ui-ux-pro-max, nút chỉ có biểu tượng phải có tên
   truy cập được, và đó là điều kiện để nó được phép không có chữ. */
.room-card__tools { display: flex; align-items: center; gap: 6px; }

.room-card__clean {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px là vùng bấm, không phải cỡ nhìn: nút trông nhỏ nhưng ngón tay vẫn
       bắt được. Viền trong suốt giữ chỗ để lúc hover không nảy layout. */
    width: 44px;
    height: 44px;
    padding: 0;
    font-size: 15px;
    color: var(--color-muted-text, #64748b);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 10px;
    cursor: pointer;
    transition: color 180ms ease, border-color 180ms ease, background-color 180ms ease;
}
/* Dấu báo trên chính cái nút làm việc đó.
   
   Thay cho dòng chữ "CẦN DỌN" ở thân ô: nhìn là thấy, mà không tốn một dòng.
   Dấu là HÌNH (một chấm ở góc), không phải màu đơn thuần — và tên đọc được
   của nút nói ra trạng thái cho trình đọc màn hình. */
.room-card__clean--alert { position: relative; }
.room-card__clean-dot {
    position: absolute;
    /* Đẩy ra sát góc: bản trước chấm ĐÈ LÊN cái chổi, hai hình chồng nhau
       thành một vệt khó đọc. */
    top: 4px;
    right: 4px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    /* #d97706 chỉ đạt 2.93:1 trên nền thẻ xanh — dưới ngưỡng 3:1 cho phần tử
       phi-văn-bản. Màu này đạt tối thiểu 3.80:1 trên CẢ NĂM nền thẻ, vì một
       màu chỉ đúng trên một nền là màu chưa được kiểm. */
    background: #c2620a;
}
.room-card__clean--alert { color: #b45309; }

.room-card__clean:hover {
    color: #1e8449;
    border-color: #1e8449;
    background: #f0fdf4;
}
.room-card__clean:focus-visible {
    outline: 2px solid var(--color-primary, #1e293b);
    outline-offset: 2px;
}

/* Phòng sắp có khách MÀ vẫn bẩn: nhãn lớn nói "SẮP NHẬN PHÒNG", dấu này nói
   nốt vế còn lại. Không chọn một trong hai, vì cả hai đều là việc phải làm. */
.room-card__dirty-mark {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .04em;
    color: #92400e;
    background: #fef3c7;
    border-radius: 99px;
    vertical-align: middle;
}

/* Nhãn chân ô bị cắt cụt TỪ TRƯỚC: "Sẵn sàng" hiện thành "Sẵn sàn". Nút chính
   co được, nhãn trạng thái thì không — theo ui-ux-pro-max: dùng nowrap với một
   nhãn co được, và vẫn để người dùng đọc được đủ chữ (ở đây là `title`). */
/* Đo ra rồi mới chọn: chân ô rộng 186px, nút chính 111 + nhãn 50 = 161, mà
   padding 16px hai bên chỉ chừa 154. Thiếu 7px — nên "Sẵn sàng" hiện thành
   "Sẵn sàn" suốt từ trước.
   
   Cắt bên nào cũng dở: cắt nhãn thì mất trạng thái, cắt nút thì "Xem thôn…".
   Nên KHÔNG cắt bên nào — thu padding và khoảng cách để đủ chỗ cho cả hai. */
.room-card__footer {
    padding-left: 10px;
    padding-right: 10px;
    gap: 6px;
}
/* Nút chính KHÔNG co: nó là việc phải làm, cắt cụt là mất nghĩa.
   
   Nhãn trạng thái co được, và khi hẹp quá thì cắt có dấu ba chấm kèm `title` —
   theo compact-label-overflow: cắt thì được, nhưng phải NÓI RA là đã cắt.
   Bản trước để cả hai không co, và ô hẹp lại (178px thay vì 188px ở màn 1024)
   thì nhãn tràn hẳn ra NGOÀI ô — tràn im lặng tệ hơn cắt có báo. */
/* Nhãn chân ô bị KHUẤT, không phải bị cắt gọn: "Sẵn sàng" hiện thành "Sẵn
   sàn" và mất luôn chữ cuối.
   
   Đo ra ca chật nhất thiếu 19px: ô co còn 178px ở màn 1024, chân ô chứa được
   156px mà nút + nhãn cần 175px. Gom lại từ ba chỗ, mỗi chỗ một ít, thay vì
   cắt cụt một bên:
     padding chân ô 10 -> 4  (+12px)
     gap             6 -> 4  (+2px)
     padding nút    10 -> 6  (+8px)
   Tổng +22px, dư 3px so với mức thiếu.
   
   Vẫn giữ ellipsis + `title` làm lưới đỡ: nếu sau này có nhãn dài hơn thì nó
   cắt CÓ BÁO thay vì lại khuất đi lần nữa. */
.room-card__footer { padding-left: 4px; padding-right: 4px; gap: 4px; }
.room-card__action { flex: none; white-space: nowrap; padding-left: 6px; padding-right: 6px; }
.room-card__footer .status-badge {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    /* Khai lại sau khi dời khối nút dọn lên đầu ô — lần dời trước làm mất nó,
       và một transition không tôn trọng cài đặt này là một luật CRITICAL bị bỏ. */
    .room-card__clean { transition: none; }
}

/* ── Màn Chuyển phòng: hai chặng của một chuyến ở ─────────────────────────
   Đọc từ trên xuống theo đúng thứ tự khách đi qua, mũi tên ở giữa nói mốc
   chuyển. Gom thành fieldset chứ không rải thành hàng ô nhập — luật
   field-grouping: những thứ thuộc về nhau phải nhìn ra là thuộc về nhau. */
.transfer-leg {
    border: 1px solid var(--pos-border, #dfe5ec);
    border-radius: .5rem;
    padding: .75rem .9rem;
    margin: 0;
}

.transfer-leg__room {
    font-weight: 700;
    font-size: 15px;
}

.transfer-leg__dates {
    font-size: 13px;
    color: #5b6b7f;          /* 4.9:1 trên nền trắng */
}

.transfer-leg__line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .75rem;
    font-size: 13px;
}

/* Số tiền không được xuống dòng theo câu chữ bên trái. */
.transfer-leg__line > strong {
    white-space: nowrap;
}

.transfer-arrow {
    margin: .4rem 0;
    padding-left: .9rem;
    font-size: 13px;
    font-weight: 600;
    color: #3f5a78;          /* 7.2:1 trên nền trắng */
}

/* Chặng khách đã chuyển đi — đã đóng sổ nên nhạt hơn, và gạch chéo để phân
   biệt bằng HÌNH chứ không chỉ bằng độ đậm: người mù màu vẫn phải thấy khác. */
.tlg-bar--past-segment {
    opacity: .88;
    background-image: repeating-linear-gradient(
        135deg, transparent 0 6px, rgba(255, 255, 255, .38) 6px 12px);
}

/* Nhãn nối hai chặng của cùng một chuyến ở. */
.tlg-bar__move {
    margin-left: .35rem;
    padding: 0 .3rem;
    border-radius: .25rem;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;          /* nhãn ngắn không được rơi xuống dòng hai */
    background: rgba(255, 255, 255, .85);
    color: #3f5a78;               /* 7.2:1 trên nền trắng */
}

/* Khối trạng thái của chặng đã chuyển đi: xám trung tính, không phải xanh
   "Đặt trước". `timelineStatusKey` xếp nó vào nhánh 'booked' vì trạng thái nó
   mang là `checked_out` — để nguyên thì một chặng đã xong đọc thành một đơn
   sắp tới. */
/* Chặng khách ĐÃ CHUYỂN ĐI mang màu TRẠNG THÁI HIỆN TẠI của khách, không phải
   xám "đã xong". Khách chưa rời khách sạn — `is_past_segment` chỉ đúng khi đơn
   còn sống — nên xám ở đây kể sai một chuyến vẫn đang diễn ra, và kể sai ngay
   tại ô mà lễ tân nhìn để biết ai còn trong nhà.

   Phân biệt với chặng đang ở bằng GẠCH CHÉO trên thân thanh, không bằng màu:
   hai chặng của cùng một khách nên trông cùng một màu, vì đó là cùng một khách. */
.tlg-bar--past-segment .tlg-bar__stripe { background: var(--color-action); }

/* KỲ Ở ĐÃ XONG — khách đã trả phòng và trả tiền.

   Mờ đi vì nó là quá khứ, gạch chéo vì mờ thôi chưa đủ: người mù màu và màn
   hình chói phải phân biệt được bằng HÌNH. Cùng lối gạch với chặng đã chuyển
   đi, nhưng khối trạng thái xám chứ không xanh — chuyến này thật sự đã đóng,
   khác hẳn chặng kia vốn vẫn đang chạy. */
.tlg-bar--done {
    opacity: .62;
    background-image: repeating-linear-gradient(
        135deg, transparent 0 6px, rgba(255, 255, 255, .45) 6px 12px);
}
.tlg-bar--done .tlg-bar__stripe { background: #94a3b8; }
.tlg-dot--done { background: #94a3b8; }

/* THANH HẸP — chỉ còn chỗ cho khối icon. Tên khách và số đêm ở bề ngang này
   chỉ là mấy chấm lửng, bỏ đi thì icon nằm giữa và đọc được. */
.tlg-bar--tiny { padding: 0; min-width: 28px; }
.tlg-bar--tiny .tlg-bar__name,
.tlg-bar--tiny .tlg-bar__meta { display: none; }
.tlg-bar--tiny .tlg-bar__stripe { width: 100%; border-radius: 7px; }

/* THANH RẤT HẸP — một gạch dài ĐÚNG TỈ LỆ kỳ ở, không icon.
   Sàn 3px để còn bấm được và còn nhìn thấy; dưới mức đó thì nó không còn là
   một vệt nữa. Quan trọng hơn: không ép rộng, vì ép rộng là nói dối về độ dài
   kỳ ở và làm hai chuyến nối đuôi nhau trông như chồng nhau. */
.tlg-bar--tick {
    padding: 0; min-width: 3px; border-radius: 2px;
    box-shadow: none;
}
.tlg-bar--tick .tlg-bar__name,
.tlg-bar--tick .tlg-bar__meta,
.tlg-bar--tick .tlg-bar__icon,
.tlg-bar--tick .tlg-bar__move { display: none; }
.tlg-bar--tick .tlg-bar__stripe { width: 100%; border-radius: 2px; }

/* Đặt trước mà đã quá giờ hẹn nhận — khách chưa tới.
   VÀNG chứ không đỏ: đỏ nói "hỏng rồi", vàng nói "nhìn cái này đi". Khách đến
   muộn vẫn là khách, lễ tân chỉ việc nhận phòng cho họ. Màu này có tên trong
   phần chú thích ngay trên lưới, nên trạng thái không nằm ở mỗi màu. */
.tlg-bar--late .tlg-bar__stripe { background: var(--color-warning); }
.tlg-dot--late { background: var(--color-warning); }

/* Phòng có đơn ĐÃ QUÁ GIỜ NHẬN mà khách chưa tới. Vàng chứ không đỏ, cùng lối
   với thanh "Chưa nhận" trên Timeline: khách đến muộn vẫn là khách, lễ tân chỉ
   việc nhận phòng cho họ. Màu này nói "nhìn cái này đi", không phán quyết. */
.room-card--late { --room-accent: #d97706; --room-tint: #fffbeb; }

/* Dòng "có khách chờ" trên thẻ phòng ĐANG CÓ NGƯỜI.
   Thân thẻ đã chật, nên đây là một dải mảnh nằm dưới tên khách đang ở, không
   phải một nút đầy đủ — nhưng vùng bấm vẫn phải đủ cao cho ngón tay. */
.room-card__waiting {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    margin-top: 6px;
    padding: 6px 8px;
    min-height: 32px;
    border: 1px solid rgba(180, 83, 9, .35);
    border-radius: 8px;
    background: rgba(251, 191, 36, .16);
    color: #92400e;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    text-align: left;
    cursor: pointer;
}
.room-card__waiting span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.room-card__waiting:hover { background: rgba(251, 191, 36, .28); }
.room-card__waiting:focus-visible { outline: 2px solid #b45309; outline-offset: 2px; }

/* Nút hoàn tác nhận phòng, nằm cạnh biểu tượng trạng thái trên thẻ phòng đang
   có khách. Kín tiếng như một lối thoát hiểm: không mời gọi, nhưng ở đúng chỗ
   người vừa bấm nhầm đang nhìn, và vùng bấm đủ rộng cho ngón tay. */
.room-card__undo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-right: 4px;
    border: 1px solid rgba(15, 23, 42, .16);
    border-radius: 8px;
    background: rgba(255, 255, 255, .78);
    color: #475569;
    font-size: 12px;
    cursor: pointer;
}
.room-card__undo:hover { background: #fff; color: #0f172a; border-color: rgba(15, 23, 42, .34); }
.room-card__undo:focus-visible { outline: 2px solid #0f172a; outline-offset: 2px; }

/* Đường nối hai chặng của một lần chuyển phòng trên Timeline.
   Một lớp SVG phủ lên lưới, dựng bằng JS sau khi lưới đã có kích thước thật —
   xem drawTransferLinks. */
#visualization { position: relative; }

.tlg-links {
    position: absolute;
    inset: 0;
    /* Không nhận chuột: lớp này phủ kín lưới, mà mọi ô dưới nó đều bấm được để
       tạo đặt phòng. */
    pointer-events: none;
    z-index: 3;
}

/* NÉT ĐỨT, không nét liền: đường này không phải một cạnh của thanh nào cả, nó
   là mối quan hệ giữa hai thanh. Nét liền đọc như một đường kẻ của lưới. */
.tlg-link {
    fill: none;
    stroke: #7c3aed;
    stroke-width: 2;
    stroke-dasharray: 5 4;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .9;
}

/* Mũi tên liền nét: nó là một hình, không phải một đoạn của đường kẻ. Để nó
   cũng đứt thì đầu mũi vỡ vụn ở cỡ này. */
.tlg-link__arrow {
    fill: #7c3aed;
    stroke: none;
}
