/* =============================================================================
   DISPATCH — bảng điều khiển forward Zalo
   Token system
   Color   : nền than-xanh (#0C1016), panel #141A23/#1B222D, accent hổ phách
             tín hiệu #FFB020 (đèn "on-air"), phụ #3FC1C9 (waveform), success
             #34D399, danger #F0555F, idle #64748B
   Type    : Space Grotesk (display) + Inter (body) + JetBrains Mono (data/log)
   Layout  : topbar -> dải chỉ số (instrument tiles) -> toolbar -> lưới card
   Signature: mỗi card là 1 "kênh dispatch" (CH·01, CH·02…) với dải màu dọc bên
             trái + đèn LIVE dạng equalizer, log hiện dạng terminal mono.
============================================================================= */

:root {
    --bg: #F3F5F8;
    --bg-grid: #EEF1F5;
    --panel: #FFFFFF;
    --panel-2: #F4F6F9;
    --border: #E1E6ED;
    --border-soft: #EAEDF2;

    --text: #1C2430;
    --text-muted: #5B6B7C;
    --text-faint: #8996A6;

    --accent: #D9880C;
    --accent-dim: #F6E0B4;
    --accent-2: #0E8C93;

    --success: #16A374;
    --warning: #D9880C;
    --danger: #DC3545;
    --idle: #64748B;
    --unknown: #9AA6B6;

    --overlay-soft: rgba(15,23,42,0.04);

    --font-display: 'Space Grotesk', 'Inter', sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;
    --font-mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;

    --radius-lg: 14px;
    --radius-md: 10px;
    --radius-sm: 6px;

    --shadow-card: 0 1px 0 rgba(255,255,255,0.6) inset, 0 10px 22px -16px rgba(15,23,42,0.18);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background:
        radial-gradient(1200px 500px at 15% -10%, rgba(217,136,12,0.07), transparent 60%),
        radial-gradient(900px 500px at 100% 0%, rgba(14,140,147,0.06), transparent 55%),
        var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent); color: #fff; }

a { color: inherit; }

button, input, textarea, select {
    font-family: inherit;
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

code {
    font-family: var(--font-mono);
    background: var(--overlay-soft);
    padding: 0 4px;
    border-radius: 4px;
    font-size: 0.9em;
}

/* ---------------------------------- Topbar --------------------------------- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 28px;
    background: rgba(255,255,255,0.85);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border-soft);
}

.topbar__brand {
    display: flex;
    align-items: center;
    gap: 12px;
}

.topbar__mark {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: linear-gradient(155deg, var(--accent) 0%, #B9750E 100%);
    position: relative;
    flex-shrink: 0;
}
.topbar__mark::after {
    content: "";
    position: absolute;
    inset: 8px;
    border-radius: 3px;
    background: var(--bg);
    opacity: 0.85;
}

.topbar__title {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}
.topbar__title strong {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 17px;
    letter-spacing: 0.01em;
}
.topbar__title span {
    font-size: 12px;
    color: var(--text-muted);
}

.topbar__meta {
    display: flex;
    align-items: center;
    gap: 14px;
}

.service-pill {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--text-muted);
}
.service-pill .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--danger);
    box-shadow: 0 0 0 3px rgba(240,85,95,0.15);
}
.service-pill[data-ok="1"] .dot {
    background: var(--success);
    box-shadow: 0 0 0 3px rgba(52,211,153,0.15);
}

.clock {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-muted);
    min-width: 74px;
    text-align: right;
}

.help-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--border);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
}
.help-btn:hover { border-color: var(--accent); color: var(--accent); }

/* ------------------------------------ Shell --------------------------------- */

.shell {
    max-width: 1360px;
    margin: 0 auto;
    padding: 28px 28px 60px;
}

/* ------------------------------------ Stats ---------------------------------- */

.stats {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 12px;
    margin-bottom: 22px;
}

.stat-tile {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.stat-tile__label {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-faint);
}
.stat-tile__value {
    font-family: var(--font-display);
    font-size: 26px;
    font-weight: 600;
}
.stat-tile--online .stat-tile__value { color: var(--success); }
.stat-tile--idle .stat-tile__value { color: var(--idle); }
.stat-tile--error .stat-tile__value { color: var(--danger); }
.stat-tile--offline .stat-tile__value { color: var(--text-faint); }

/* Tài nguyên máy chủ (CPU/RAM/Disk/OS) */
.stats--sys { grid-template-columns: repeat(4, 1fr); }

.stat-tile__sub {
    font-size: 11.5px;
    color: var(--text-faint);
    margin-top: -4px;
}
.stat-tile__bar {
    height: 4px;
    border-radius: 999px;
    background: var(--panel-2);
    overflow: hidden;
    margin-top: 2px;
}
.stat-tile__bar span {
    display: block;
    height: 100%;
    width: 0%;
    background: var(--accent-2);
    border-radius: 999px;
    transition: width 0.4s ease;
}
.stat-tile--os .stat-tile__value--text,
.stat-tile--pkg .stat-tile__value--text {
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.stat-tile--pkg[data-level="warn"] .stat-tile__value--text { color: var(--warning); }
.stat-tile--pkg[data-level="warn"] .stat-tile__sub { color: var(--warning); }
.stat-tile--pkg[data-level="expired"] .stat-tile__value--text { color: var(--danger); }
.stat-tile--pkg[data-level="expired"] .stat-tile__sub { color: var(--danger); }

/* --- CPU + RAM gộp chung 1 card --- */
.stat-tile--cpuram {
    gap: 10px;
    justify-content: center;
}
.cpuram-row {
    display: grid;
    grid-template-columns: 40px 1fr auto;
    align-items: center;
    column-gap: 10px;
    row-gap: 2px;
}
.cpuram-row .stat-tile__label {
    grid-row: 1;
}
.cpuram-row .stat-tile__value--sm {
    grid-row: 1;
    grid-column: 3;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
}
.cpuram-row .stat-tile__bar {
    grid-column: 1 / -1;
    margin-top: 0;
}
/* Màu số CPU/RAM theo mức tải: <60% ổn định, 60-84% cần chú ý, >=85% quá tải */
.cpuram-row[data-level="ok"] .stat-tile__value--sm { color: var(--success); }
.cpuram-row[data-level="warn"] .stat-tile__value--sm { color: var(--warning); }
.cpuram-row[data-level="danger"] .stat-tile__value--sm { color: var(--danger); }
.cpuram-row[data-level="ok"] .stat-tile__bar span { background: var(--success); }
.cpuram-row[data-level="warn"] .stat-tile__bar span { background: var(--warning); }
.cpuram-row[data-level="danger"] .stat-tile__bar span { background: var(--danger); }

/* --- Card "Tin nhắn xử lý hôm nay" --- */
.stat-tile--msg { gap: 8px; }
.msg-stat__row {
    display: flex;
    align-items: baseline;
    gap: 18px;
}
.msg-stat__item {
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.msg-stat__num {
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 600;
}
.msg-stat__unit {
    font-size: 11.5px;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.msg-stat__num--text { color: var(--accent-2); }
.msg-stat__num--image { color: var(--accent); }
.msg-stat__total {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-top: 0;
    font-size: 12px;
}
.msg-stat__total .msg-stat__num {
    font-size: 15px;
}
.msg-stat__num--total { color: var(--success); }
.msg-stat__num--week { color: var(--idle); }

/* ----------------------------------- Toolbar --------------------------------- */

.toolbar {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.toolbar__search {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 9px 12px;
    flex: 1 1 280px;
    min-width: 220px;
    color: var(--text-faint);
}
.toolbar__search input {
    background: transparent;
    border: none;
    color: var(--text);
    font-size: 13.5px;
    width: 100%;
}
.toolbar__search input::placeholder { color: var(--text-faint); }
.toolbar__search input:focus { outline: none; }

.toolbar__filters {
    display: flex;
    gap: 6px;
}
.filter-btn {
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 12.5px;
    padding: 8px 13px;
    border-radius: 999px;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.filter-btn:hover { color: var(--text); border-color: #3A4657; }
.filter-btn.is-active {
    color: #fff;
    background: var(--accent);
    border-color: var(--accent);
    font-weight: 600;
}

.toolbar__pause {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text-muted);
    cursor: pointer;
    user-select: none;
    margin-left: auto;
}
.toolbar__pause input { accent-color: var(--accent); }

/* ------------------------------------- Grid ----------------------------------- */

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 16px;
}

.empty-state, .no-results {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
    border: 1px dashed var(--border);
    border-radius: var(--radius-lg);
}
.empty-state h2 { font-family: var(--font-display); color: var(--text); margin-bottom: 8px; }

/* -------------------------------------- Card ------------------------------------ */

.card {
    display: flex;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    transition: border-color .2s ease, transform .2s ease;
}
.card:hover { border-color: #333F4F; }

.card__strip {
    width: 5px;
    flex-shrink: 0;
    background: var(--unknown);
}
.card[data-state="online"]  .card__strip { background: var(--success); }
.card[data-state="idle"]    .card__strip { background: var(--idle); }
.card[data-state="error"]   .card__strip { background: var(--danger); }
.card[data-state="offline"] .card__strip { background: var(--text-faint); }

.card__body {
    flex: 1;
    padding: 16px 18px 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.card__head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}
.card__chno {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-faint);
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    padding: 3px 7px;
    border-radius: 5px;
    letter-spacing: 0.04em;
    margin-top: 2px;
    flex-shrink: 0;
}
.card__titles { flex: 1; min-width: 0; }
.card__titles h3 {
    font-family: var(--font-display);
    font-size: 14.5px;
    font-weight: 600;
    margin: 0 0 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.card__titles p {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
}

.card__status {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: var(--text-muted);
    flex-shrink: 0;
    padding-top: 3px;
}
.pulse-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--unknown);
    position: relative;
}
.pulse-dot::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    background: inherit;
    opacity: 0.35;
}
.card[data-state="online"] .pulse-dot { background: var(--success); animation: pulse 1.8s ease-in-out infinite; }
.card[data-state="error"] .pulse-dot { background: var(--danger); animation: pulse 1.2s ease-in-out infinite; }
.card[data-state="idle"] .pulse-dot { background: var(--idle); }
.card[data-state="offline"] .pulse-dot { background: var(--text-faint); }

@keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(52,211,153,0.35); }
    50% { box-shadow: 0 0 0 5px rgba(52,211,153,0); }
}
.card[data-state="error"] .pulse-dot { animation-name: pulse-danger; }
@keyframes pulse-danger {
    0%, 100% { box-shadow: 0 0 0 0 rgba(240,85,95,0.4); }
    50% { box-shadow: 0 0 0 5px rgba(240,85,95,0); }
}

/* Route: nguồn -> đích */

.card__route {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    padding: 10px 12px;
}
.route__group {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.route__label {
    display: block;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-faint);
    margin-bottom: 5px;
}
.route__ids {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
}
.id-chip {
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: 1.4;
    max-width: 100%;
    background: var(--overlay-soft);
    border: 1px solid var(--border-soft);
    padding: 2px 6px;
    border-radius: 4px;
    color: var(--text-muted);
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.route__arrow {
    color: var(--text-faint);
    flex-shrink: 0;
    margin-top: 22px;
}
@media (max-width: 460px) {
    .card__route {
        flex-direction: column;
        align-items: stretch;
    }
    .route__arrow {
        margin: 2px 0;
        transform: rotate(90deg);
    }
}

/* Rule chips (giá / prepend / append) */

.card__rules {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.rule-chip {
    font-size: 11px;
    padding: 4px 9px;
    border-radius: 999px;
    background: rgba(14,140,147,0.08);
    border: 1px solid rgba(14,140,147,0.25);
    color: var(--accent-2);
}
.rule-chip--price {
    background: rgba(217,136,12,0.1);
    border-color: rgba(217,136,12,0.3);
    color: var(--accent);
    font-weight: 600;
}

/* Card cảnh báo thiếu dữ liệu (account/config chưa điền đủ) */
.card__warning {
    font-size: 11.5px;
    line-height: 1.5;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    background: rgba(217,136,12,0.1);
    border: 1px solid rgba(217,136,12,0.3);
    color: #8A5A05;
}
.card[data-state="incomplete"] .card__strip { background: var(--warning); }
.card[data-state="incomplete"] .pulse-dot { background: var(--warning); }
.card[data-state="incomplete"] .card__status { color: var(--warning); }

/* Console (log realtime) */

.card__console {
    /* Bảng màu riêng cho log — nền terminal tối nên cần tông sáng/bão hoà hơn
       theme sáng chung của trang, chỉ áp dụng trong phạm vi .card__console. */
    --log-source: #7DD3E8;      /* nhóm nguồn */
    --log-target: #6EE7B7;      /* nhóm đích */
    --log-arrow: #4B5768;       /* mũi tên/nối => */
    --log-media: #C4B5FD;       /* [N ảnh] */
    --log-link: #93C5FD;        /* link/search(...) */
    --log-content: #C7D0DC;     /* nội dung tin nhắn thường */
    --log-tag-regex: #FBBF24;   /* [Regex:xxx] */
    --log-price-old: #F87171;   /* giá trước khi Regex chỉnh */
    --log-price-new: #34D399;   /* giá sau khi Regex chỉnh */
    --log-tag-ai: #C792EA;      /* [AI] */
    --log-tag-reload: #60A5FA;  /* 🔄 [tên cấu hình] */
    --log-price-rule: #FBBF24;  /* giá: ... trong dòng nạp cấu hình */
    --log-system: #FCD34D;      /* === Bot khởi động/dừng === */
    --log-success: #34D399;     /* ✅ Đăng nhập thành công */
    --log-uid: #8996A6;         /* UID: ... */
    --log-tag-imgproc: #F0ABFC; /* [imgproc] — cổng xử lý ảnh (OCR + watermark) */
    --log-img-index: #A5B4FC;   /* "ảnh #5" / "ảnh #5 vùng 1" */
    --log-badge-count: #FDBA74; /* "2 vùng badge" */

    background: #0A0D12;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    max-height: 420px; /* chặn card giãn vô hạn khi log tích luỹ nhiều theo thời gian; log dư sẽ tự cuộn */
}

.console__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border-soft);
    background: rgba(255,255,255,0.015);
}

.live-tag {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.08em;
    color: var(--text-faint);
    flex-shrink: 0;
}
.live-tag .eq {
    display: inline-flex;
    align-items: flex-end;
    gap: 2px;
    height: 10px;
}
.live-tag .eq i {
    width: 2px;
    background: var(--text-faint);
    border-radius: 1px;
    height: 3px;
    display: block;
}
.card[data-state="online"] .live-tag { color: var(--success); }
.card[data-state="online"] .live-tag .eq i { background: var(--success); animation: eq 1s ease-in-out infinite; }
.card[data-state="online"] .live-tag .eq i:nth-child(1) { animation-delay: 0s; }
.card[data-state="online"] .live-tag .eq i:nth-child(2) { animation-delay: .15s; }
.card[data-state="online"] .live-tag .eq i:nth-child(3) { animation-delay: .3s; }
.card[data-state="online"] .live-tag .eq i:nth-child(4) { animation-delay: .45s; }

@keyframes eq {
    0%, 100% { height: 3px; }
    50% { height: 10px; }
}

.console__meta {
    font-size: 11px;
    color: var(--text-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

.console__clear {
    background: none;
    border: 1px solid var(--border-soft);
    color: var(--text-faint);
    font-size: 10.5px;
    padding: 3px 8px;
    border-radius: 5px;
    cursor: pointer;
    flex-shrink: 0;
}
.console__clear:hover { color: var(--text); border-color: #3A4657; }

.console__body {
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.65;
    padding: 10px 12px;
    flex: 1;
    min-height: 120px;
    overflow-y: auto;
    color: #C7D0DC;
}

.console__placeholder { color: var(--text-faint); margin: 0; }

.log-line {
    display: flex;
    gap: 8px;
    white-space: pre-wrap;
    word-break: break-word;
    padding: 1px 0;
    animation: fadein .25s ease;
}
@keyframes fadein {
    from { opacity: 0; transform: translateY(-2px); }
    to { opacity: 1; transform: translateY(0); }
}
.log-line__ts { color: var(--text-faint); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.log-line__msg { flex: 1; }
.log-line[data-level="ERROR"] .log-line__msg { color: var(--danger); }
.log-line[data-level="WARNING"] .log-line__msg { color: var(--warning); }
.log-line[data-level="SUCCESS"] .log-line__msg { color: var(--success); }
.log-line[data-level="INFO"] .log-line__msg { color: #C7D0DC; }

/* Tô màu từng phần riêng biệt trong 1 dòng log (nguồn / nội dung / đích / tag...) */
.log-seg--source      { color: var(--log-source); font-weight: 600; }
.log-seg--target      { color: var(--log-target); font-weight: 600; }
.log-seg--arrow        { color: var(--log-arrow); }
.log-seg--media        { color: var(--log-media); font-style: italic; }
.log-seg--link          { color: var(--log-link); text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; }
.log-seg--content      { color: var(--log-content); }
.log-seg--text          { color: var(--log-content); }

.log-seg--tag-regex   { color: var(--log-tag-regex); font-weight: 700; }
.log-seg--price-old   { color: var(--log-price-old); text-decoration: line-through; opacity: .75; }
.log-seg--price-new   { color: var(--log-price-new); font-weight: 700; }

.log-seg--tag-ai        { color: var(--log-tag-ai); font-weight: 700; }

.log-seg--tag-reload  { color: var(--log-tag-reload); font-weight: 600; }
.log-seg--price-rule   { color: var(--log-price-rule); font-weight: 600; }

.log-seg--system        { color: var(--log-system); font-weight: 700; }
.log-seg--success       { color: var(--log-success); font-weight: 600; }
.log-seg--uid            { color: var(--log-uid); }

/* Dòng lỗi (❌), cảnh báo (⚠️) broadcast và dòng bỏ qua tin có SĐT */
.log-seg--tag-error    { color: var(--danger); font-weight: 700; }
.log-seg--error-reason { color: var(--danger); opacity: .9; }
.log-seg--warning       { color: var(--warning); font-weight: 600; }
.log-seg--skip           { color: var(--idle); font-style: italic; }
/* Nhiều giá đổi cùng lúc trong 1 tin, gộp chung 1 khối thay vì tách cũ/mới */
.log-seg--price-change { color: var(--log-price-new); font-weight: 700; }

/* Dòng "[imgproc] ..." — cổng xử lý ảnh (OCR badge giá + watermark).
   Trước đây cả dòng rơi vào .log-seg--text nên hiển thị 1 màu xám phẳng,
   không phân biệt được nguồn / số ảnh / giá cũ / giá mới như dòng forward. */
.log-seg--tag-imgproc  { color: var(--log-tag-imgproc); font-weight: 700; }
.log-seg--img-index    { color: var(--log-img-index); font-weight: 600; }
.log-seg--badge-count  { color: var(--log-badge-count); }

/* Trên dòng LỖI/CẢNH BÁO, phần mô tả chi tiết phải theo màu của mức độ đó —
   nếu không, segment .log-seg--content tự đặt màu riêng sẽ "ăn" mất màu đỏ/
   vàng mà .log-line[data-level=...] .log-line__msg định gán cho cả dòng. */
.log-line[data-level="ERROR"] .log-seg--content,
.log-line[data-level="ERROR"] .log-seg--text     { color: var(--danger); }
.log-line[data-level="WARNING"] .log-seg--content,
.log-line[data-level="WARNING"] .log-seg--text   { color: var(--warning); }

/* Dòng hệ thống (bot dừng/khởi động) và đăng nhập thành công nổi bật hơn 1 chút,
   phân tách trực quan với log forward tin nhắn thông thường. */
.log-line:has(.log-seg--system) { padding: 3px 0; border-top: 1px dashed rgba(255,255,255,0.08); margin-top: 2px; }

.console__body::-webkit-scrollbar { width: 8px; }
.console__body::-webkit-scrollbar-track { background: transparent; }
.console__body::-webkit-scrollbar-thumb { background: #262F3B; border-radius: 8px; }

/* ------------------------------------ Add Panel (form) -------------------------------- */

.add-panel {
    margin-bottom: 20px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--panel);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

.add-panel__header {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text);
}
.add-panel__header-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font-size: 12px;
    flex-shrink: 0;
}

.add-panel__body {
    padding: 4px 18px 18px;
    border-top: 1px solid var(--border-soft);
}

.add-panel__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin-top: 14px;
}

.add-panel__section {
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    padding: 14px 16px 16px;
    background: var(--panel-2);
    min-width: 0;
}
.add-panel__section legend {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 600;
    padding: 0 6px;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.legend-help-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--border);
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
}
.legend-help-btn:hover { border-color: var(--accent); color: var(--accent); }

/* ---- Badge nổi bật: tổng số nhóm (nguồn+đích) đang dùng / giới hạn chung ---- */
.cfg-total-badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 10px 4px 12px;
    border-radius: 999px;
    background: var(--panel);
    border: 1.5px solid var(--border);
}
.cfg-total-badge__label {
    font-family: var(--font-body);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-faint);
    text-transform: uppercase;
}
.cfg-total-badge__count {
    font-family: var(--font-mono);
    font-size: 16px;
    font-weight: 700;
    line-height: 1;
    color: var(--accent);
}
.cfg-total-badge__slash { color: var(--text-faint); font-weight: 500; margin: 0 1px; }
.cfg-total-badge__remain {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    padding-left: 7px;
    border-left: 1px solid var(--border-soft);
}
.cfg-total-badge__remain #cfgTotalBadgeRemain {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 700;
}
/* Mức bình thường (còn nhiều chỗ): số màu accent như mặc định phía trên */
.cfg-total-badge[data-level="ok"] .cfg-total-badge__remain #cfgTotalBadgeRemain { color: var(--success); }
/* Sắp đầy (còn ít chỗ) */
.cfg-total-badge[data-level="warn"] { border-color: var(--warning, #D9880C); }
.cfg-total-badge[data-level="warn"] .cfg-total-badge__count { color: var(--warning, #D9880C); }
.cfg-total-badge[data-level="warn"] .cfg-total-badge__remain #cfgTotalBadgeRemain { color: var(--warning, #D9880C); }
/* Đã đầy (hết chỗ, không thêm được nhóm nào nữa) */
.cfg-total-badge[data-level="full"] { border-color: var(--danger); }
.cfg-total-badge[data-level="full"] .cfg-total-badge__count { color: var(--danger); }
.cfg-total-badge[data-level="full"] .cfg-total-badge__remain #cfgTotalBadgeRemain { color: var(--danger); }

.field {
    display: block;
    margin-bottom: 12px;
}
.field__label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 5px;
}
.field__label small {
    font-weight: 400;
    color: var(--text-faint);
}
.field__hint code {
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    border-radius: 4px;
    padding: 1px 5px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--accent-2);
}
.field__hint {
    display: block;
    font-size: 11px;
    color: var(--text-faint);
    margin-top: 4px;
}
.field__hint--total {
    margin: -6px 0 14px;
    font-weight: 600;
    color: var(--text-muted);
}
.field--split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 0;
}
.field--split .field { margin-bottom: 0; }

.field input[type="text"],
.field input[type="number"],
.field select,
.field textarea {
    width: 100%;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 10px;
    font-size: 13px;
    color: var(--text);
    resize: vertical;
    font-family: var(--font-mono);
}
.field input[type="text"]:focus,
.field input[type="number"]:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--accent);
}
.field input[type="range"] {
    width: 100%;
    accent-color: var(--accent);
    cursor: pointer;
}
.field input::placeholder,
.field textarea::placeholder {
    color: var(--text-faint);
    font-family: var(--font-body);
}

.field__row {
    min-height: 16px;
    margin: -4px 0 10px;
}
.resolve-status {
    font-size: 11.5px;
    color: var(--text-faint);
}

.add-panel__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 14px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border-soft);
}
.add-panel__msg {
    font-size: 12.5px;
    white-space: pre-line;
    text-align: right;
    color: var(--text-muted);
}
.add-panel__msg.is-success { color: var(--success); }
.add-panel__msg.is-error { color: var(--danger); }

.btn-save {
    background: var(--accent);
    color: #fff;
    border: none;
    padding: 10px 20px;
    border-radius: var(--radius-md);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
    transition: filter .15s ease;
}
.btn-save:hover { filter: brightness(1.08); }
.btn-save:disabled { opacity: 0.6; cursor: not-allowed; }

/* ---- Nhóm nguồn/đích: 1 hàng 2 cột ---- */
.field-group-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-bottom: 14px;
}
/* min-width: 0 là BẮT BUỘC — ô của grid mặc định là min-width:auto nên KHÔNG
   co lại được dưới bề rộng nội dung, khiến bảng nhóm đẩy cả lưới tràn ra ngoài
   màn hình điện thoại (không chạm được các nút ▲▼✕). */
.field-group-row .field-group { margin-bottom: 0; min-width: 0; }

/* ---- Prepend / Append / Price: 1 hàng 3 cột ---- */
.field-row-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 12px;
}
.field-row-3 .field { margin-bottom: 12px; min-width: 0; }

/* ---- Chạy song song nhiều cấu hình: toggle + cảnh báo ---- */
.toggle-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}
.warning-banner {
    margin-top: 10px;
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    background: rgba(217, 136, 12, 0.1);
    border: 1px solid rgba(217, 136, 12, 0.35);
    color: var(--accent);
    font-size: 12px;
    line-height: 1.5;
    font-weight: 600;
}

/* ---- Toggle switch (bật/tắt chạy song song) ---- */
.switch {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    width: 40px;
    height: 22px;
    margin-top: 4px;
    cursor: pointer;
}
.switch input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
    z-index: 1;
}
.switch__track {
    position: absolute;
    inset: 0;
    background: var(--border);
    border-radius: 999px;
    transition: background .15s ease;
}
.switch__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(15,23,42,0.25);
    transition: transform .15s ease;
}
.switch input:checked ~ .switch__track { background: var(--accent); }
.switch input:checked ~ .switch__track .switch__thumb { transform: translateX(18px); }
.switch input:focus-visible ~ .switch__track { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- Radio inline: OCR/Watermark - chọn kiểu chữ/logo ---- */
.radio-row { display: flex; gap: 18px; flex-wrap: wrap; }
.radio-inline { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 13.5px; }
.radio-inline input[type="radio"] { width: auto; accent-color: var(--accent); cursor: pointer; }

/* ---- Input color (badge watermark) ---- */
.field input[type="color"] {
    padding: 2px;
    height: 36px;
    cursor: pointer;
}

@media (max-width: 800px) {
    .add-panel__grid { grid-template-columns: 1fr; }
    .field-group-row { grid-template-columns: 1fr; gap: 0; }
    .field-row-3 { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
    .toggle-row { flex-direction: column; align-items: stretch; }
    .switch { align-self: flex-end; }
    .field-group__head { flex-wrap: wrap; }
    .login-card { padding: 22px 18px; }
}

/* ------------------------------------ Responsive -------------------------------- */

@media (max-width: 960px) {
    .stats { grid-template-columns: repeat(3, 1fr); }
    .stats--sys { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
    html, body { overflow-x: hidden; }

    .cfg-select__trigger { flex-wrap: wrap; row-gap: 6px; }
    .cfg-select__badges { flex-wrap: wrap; }
    .cfg-select__option { flex-wrap: wrap; row-gap: 6px; }
    /* Nhóm nguồn / nhóm đích xếp DỌC trên điện thoại — 2 cột cạnh nhau chỉ
       còn ~150px mỗi bên, không đủ chỗ cho tên nhóm lẫn 3 nút thao tác. */
    .field-group-row { grid-template-columns: 1fr; }
    .group-table__id { display: none; }
    /* Thu nhỏ khoảng cách + số thứ tự để dành tối đa chỗ cho tên nhóm */
    .group-table__row { gap: 6px; padding: 6px 8px; }
    .group-table__order { min-width: 16px; height: 16px; font-size: 9.5px; }
    .group-table__actions { gap: 2px; }
    .modal-tabs { flex-wrap: wrap; }
    .modal-tab { flex: 1 1 45%; }
    .group-tag { max-width: 160px; }

    .topbar {
        flex-wrap: wrap;
        row-gap: 10px;
        padding: 12px 14px;
    }
    .topbar__brand {
        min-width: 0;
        flex: 1 1 auto;
    }
    .topbar__title {
        min-width: 0;
    }
    .topbar__title strong,
    .topbar__title span {
        display: block;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .topbar__meta {
        width: 100%;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: flex-start;
    }
    .help-btn,
    .bot-pill,
    .service-pill,
    .clock {
        font-size: 11.5px;
        padding: 5px 10px;
    }
    .bot-pill { max-width: 46vw; }
    .service-pill { max-width: 46vw; }
    .clock { min-width: 0; padding: 5px 8px; }

    .shell { padding: 18px 14px 40px; }
    .stats { grid-template-columns: repeat(2, 1fr); }
    .stats--sys { grid-template-columns: repeat(2, 1fr); }
    .grid { grid-template-columns: 1fr; }
    .toolbar__pause { margin-left: 0; }
}

@media (max-width: 400px) {
    .help-btn {
        padding: 5px 8px;
    }
    .bot-pill,
    .service-pill {
        max-width: 42vw;
    }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

/* =============================================================================
   BỔ SUNG: tài khoản QR, cấu hình dạng "quét nhóm", popup, danh sách nhóm
   ============================================================================= */

/* ---- Bot pill (topbar) — trạng thái tổng của zalo_forward_bot ---- */
.bot-pill {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--text-muted);
    max-width: 220px;
}
.bot-pill span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bot-pill .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--idle);
    box-shadow: 0 0 0 3px rgba(100,116,139,0.15);
    flex-shrink: 0;
}
.bot-pill[data-state="online"] .dot {
    background: var(--success);
    box-shadow: 0 0 0 3px rgba(52,211,153,0.15);
}
.bot-pill[data-state="idle"] .dot {
    background: var(--idle);
    box-shadow: 0 0 0 3px rgba(100,116,139,0.15);
}
.bot-pill[data-state="error"] .dot {
    background: var(--danger);
    box-shadow: 0 0 0 3px rgba(220,53,69,0.15);
    animation: pulse 1.2s ease-in-out infinite;
}
.bot-pill[data-state="offline"] .dot,
.bot-pill[data-state="unknown"] .dot {
    background: var(--text-faint);
    box-shadow: 0 0 0 3px rgba(100,116,139,0.1);
}

/* ---- Account box (add panel): layout linh hoạt — trái identity, phải settings ---- */
.add-panel__section--account { margin-bottom: 18px; }

.account-layout {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-items: stretch;
}
.account-layout__col { min-width: 0; }
.account-layout__col--identity {
    flex: 1 1 260px;
    max-width: 320px;
}

.account-layout__col--settings {
    flex: 2 1 260px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 14px;
    padding-left: 20px;
    border-left: 1px solid var(--border-soft);
}
.account-layout__col--settings .field { margin-bottom: 0; }

/* Khi cột "identity" wrap xuống hàng riêng (màn hẹp), cột settings cũng nên
   chiếm trọn chiều rộng và đổi viền trái -> viền trên cho hợp lý. Đặt NGAY
   SAU rule gốc ở trên để tránh bị các rule .account-layout khai báo sau đè
   mất (bug cũ: media query khai báo sớm trong file bị 1 rule không-media
   khai báo muộn hơn ghi đè do cùng độ đặc hiệu + đứng sau trong cascade). */
@media (max-width: 640px) {
    .account-layout__col--identity { max-width: none; flex-basis: 100%; }
    .account-layout__col--settings {
        flex-basis: 100%;
        padding-left: 0;
        padding-top: 16px;
        border-left: none;
        border-top: 1px solid var(--border-soft);
    }
}

.account-box {
    display: flex;
    flex-direction: column;
    gap: 14px;
    height: 100%;
    padding: 16px;
    border-radius: var(--radius-md);
    background: var(--panel);
    border: 1px solid var(--border);
}
.account-box__top {
    display: flex;
    align-items: center;
    gap: 12px;
}
.account-box__info { min-width: 0; }
.account-box__name {
    font-weight: 600;
    font-size: 13.5px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.account-box__phone {
    font-size: 12px;
    color: var(--text-muted);
    font-family: var(--font-mono);
    margin-top: 1px;
}
.account-box__empty {
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-faint);
}
.account-box__actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px solid var(--border-soft);
}
.account-box__actions .btn-outline {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    white-space: nowrap;
}

.btn-outline {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 7px 14px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
.btn-outline:hover { border-color: var(--accent); color: var(--accent); }
.btn-outline:disabled { opacity: 0.6; cursor: not-allowed; }

.btn-outline--danger { margin-right: auto; }
.btn-outline--danger:hover { border-color: var(--danger); color: var(--danger); }

/* ---- Field group: nguồn/đích dạng bảng + nút thêm ---- */
.field-group { margin-bottom: 14px; }
.field-group__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 5px;
}
.field-group__head .field__label { margin-bottom: 0; }
.field-group__count {
    display: inline-flex;
    align-items: baseline;
    font-family: var(--font-mono);
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--panel-2);
    border: 1.5px solid var(--border-soft);
    flex-shrink: 0;
}
.field-group__count-used {
    font-size: 15px;
    font-weight: 800;
    line-height: 1;
    color: var(--accent);
}
.field-group__count-slash { font-size: 11px; color: var(--text-faint); margin: 0 1px; }
.field-group__count-max { font-size: 11px; font-weight: 600; color: var(--text-muted); }

/* Sắp đầy: cả badge lẫn số dùng chuyển sang màu cam cảnh báo */
.field-group__count[data-level="warn"] { border-color: var(--warning); background: rgba(217,136,12,0.08); }
.field-group__count[data-level="warn"] .field-group__count-used { color: var(--warning); }
/* Đã đầy / vượt hạn mức: chuyển sang màu đỏ */
.field-group__count[data-level="full"],
.field-group__count.is-over {
    border-color: rgba(220,53,69,0.5);
    background: rgba(220,53,69,0.08);
}
.field-group__count[data-level="full"] .field-group__count-used,
.field-group__count.is-over .field-group__count-used {
    color: var(--danger);
}

.group-table {
    max-height: 180px;
    overflow-y: auto;
    /* Chặn tràn NGANG: tên nhóm dài phải bị cắt bằng "…" chứ không được đẩy
       rộng bảng ra ngoài khung. min-width:0 để bảng co được khi nằm trong grid. */
    overflow-x: hidden;
    min-width: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
}
.group-table__empty {
    margin: 0;
    padding: 14px 10px;
    text-align: center;
    font-size: 12px;
    color: var(--text-faint);
}
.group-table__row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-bottom: 1px solid var(--border-soft);
    font-size: 12.5px;
    /* Không cho dòng tự nới rộng theo nội dung — phần thừa dồn hết vào tên
       nhóm (đã có ellipsis), nhờ đó các nút ▲▼✕ luôn còn chỗ hiển thị. */
    min-width: 0;
    max-width: 100%;
}
.group-table__row:last-child { border-bottom: none; }
.group-table__name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
}
.group-table__id {
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-faint);
    flex-shrink: 0;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Số thứ tự ưu tiên: nhóm số 1 được bot xử lý/gửi trước (xem _source_priority
   trong worker/zalo_forward_bot.py). */
.group-table__order {
    flex-shrink: 0;
    min-width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text-faint);
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 1;
}
.group-table__actions {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.group-table__move {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--panel);
    color: var(--text-muted);
    font-size: 9px;
    line-height: 1;
    cursor: pointer;
}
.group-table__move:hover:not(:disabled) {
    border-color: var(--accent);
    background: var(--accent);
    color: #fff;
}
.group-table__move:disabled {
    opacity: .3;
    cursor: default;
}
.group-table__remove {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid rgba(220,53,69,0.35);
    background: rgba(220,53,69,0.08);
    color: var(--danger);
    font-size: 11px;
    line-height: 1;
    cursor: pointer;
}
.group-table__remove:hover { background: var(--danger); color: #fff; }
.field-group__actions {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.btn-chip {
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
.btn-chip:hover { border-color: var(--accent-2); color: var(--accent-2); }

/* ---- Modal "Test xử lý tin nhắn" ---- */
#testMsgInput {
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
    min-height: 90px;
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.6;
}
.test-msg__actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 4px;
}
.test-msg__opt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
}
.test-msg__opt input[type="text"] {
    padding: 4px 8px;
    font-size: 12px;
}
.test-msg__steps {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    overflow: hidden;
}
.test-msg__step {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 7px 10px;
    border-bottom: 1px solid var(--border-soft);
    font-size: 12.5px;
    min-width: 0;
}
.test-msg__step:last-child { border-bottom: none; }
.test-msg__step-icon { flex-shrink: 0; }
.test-msg__step-name {
    flex-shrink: 0;
    min-width: 130px;
    font-weight: 600;
    color: var(--text);
}
.test-msg__step-detail {
    flex: 1;
    min-width: 0;
    color: var(--text-muted);
    word-break: break-word;
}
.test-msg__step[data-status="warn"]  .test-msg__step-detail { color: var(--warning); }
.test-msg__step[data-status="error"] .test-msg__step-detail { color: var(--danger); }
.test-msg__step[data-status="skip"]  .test-msg__step-detail { color: var(--idle); }
.test-msg__output {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.7;
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 260px;
    overflow-y: auto;
}
.test-msg__output[data-empty="1"] { color: var(--text-faint); font-style: italic; }

@media (max-width: 640px) {
    .test-msg__step { flex-wrap: wrap; row-gap: 2px; }
    .test-msg__step-name { min-width: 0; }
}

/* ---- Bảng "Cấu hình tổng đang áp dụng" (hiện cho cả admin lẫn khách hàng) ---- */
/* 6 card/hàng (admin) hoặc 4 card/hàng (khách hàng, không có 2 card cuối) đều tự
   co giãn gọn gàng nhờ auto-fit — minmax 190px vừa đủ để 6 card lọt 1 hàng ở độ
   rộng khung .shell (1360px), tự giảm cột khi màn hẹp dần mà không cần thêm
   media query riêng (auto-fit tự dồn card lại, không để trống cột thừa). */
.overview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
}
.overview-item {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 11px 13px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--border);
    border-radius: var(--radius-sm);
    min-width: 0;
}
.overview-item__label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.overview-item__value {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    word-break: break-word;
}
/* Bật = xanh, tắt = xám nhạt (chỉ tô viền trái để không rối mắt) */
.overview-item[data-on="1"] { border-left-color: var(--success); }
.overview-item[data-on="0"] { border-left-color: var(--text-faint); }
.overview-item[data-on="0"] .overview-item__value { color: var(--text-muted); }
/* Trạng thái bot dùng chung bảng màu với card */
.overview-item[data-state="online"]  { border-left-color: var(--success); }
.overview-item[data-state="idle"]    { border-left-color: var(--idle); }
.overview-item[data-state="error"]   { border-left-color: var(--danger); }
.overview-item[data-state="offline"] { border-left-color: var(--text-faint); }
.overview-item[data-state] .pulse-dot { background: var(--text-faint); }
.overview-item[data-state="online"]  .pulse-dot { background: var(--success); animation: pulse 1.8s ease-in-out infinite; }
.overview-item[data-state="idle"]    .pulse-dot { background: var(--idle); }
.overview-item[data-state="error"]   .pulse-dot { background: var(--danger); animation: pulse-danger 1.2s ease-in-out infinite; }

/* ---- Nhịp tim trong ô "Bot" ----
   Dòng phụ, cỡ nhỏ hơn giá trị chính: đây là thông tin tham chiếu (bot tự kiểm
   tra kết nối lúc nào), không phải trạng thái chính. Trước đây thông tin này bị
   ghi lặp vào log của mọi cấu hình nên rất nhiễu — xem bot_heartbeat_info(). */
.overview-item__sub {
    font-size: 11.5px;
    color: var(--text-muted);
    letter-spacing: .01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.overview-item__sub[data-hb="fail"] { color: var(--danger); font-weight: 600; }
.overview-item__sub[data-hb="late"] { color: var(--idle); }
.overview-item__sub[data-hb="none"] { color: var(--text-faint); }

/* ---- Ô "Nghỉ thông minh" khi ĐANG trong giờ nghỉ ----
   Đỏ thay vì xanh: đang nghỉ là trạng thái bot KHÔNG gửi tin, người xem cần
   nhận ra ngay chứ không nhầm với "đang chạy bình thường". Nhãn đếm ngược do
   tickRest() trong app.js cập nhật mỗi giây. */
.overview-item[data-rest="resting"] { border-left-color: var(--danger); }
/* ---- Màu cho bảng hàng đợi: "nhóm nguồn => tên cấu hình" ----
   Dùng ĐÚNG quy ước màu của log trong card (nguồn lam, đích xanh lá, mũi tên
   xám mờ) để nhìn quen mắt. Nhưng KHÔNG dùng lại biến --log-* được: chúng chỉ
   tồn tại trong .card__console vốn có nền terminal TỐI, nên các tông rất sáng
   (#7DD3E8 / #6EE7B7) sẽ chìm nghỉm trên nền trắng của bảng này. Ở đây lấy
   cùng họ màu nhưng đậm hơn cho đủ tương phản. */
.queue-status-table__group {
    color: #0E7490;             /* lam — cùng họ với --log-source */
    font-weight: 600;
}
.queue-status-table__separator {
    color: var(--text-faint);
}
.queue-status-table__lot {
    color: var(--accent);
    font-weight: 700;
}
.queue-status-table__state {
    display: inline-flex;
    align-items: center;
    margin-left: 7px;
    padding: 1px 7px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1.45;
    white-space: nowrap;
}
.queue-status-table__state.is-ready {
    color: #047857;
    background: rgba(16, 185, 129, 0.12);
    border-color: rgba(16, 185, 129, 0.30);
}
.queue-status-table__state.is-processing {
    color: #B45309;
    background: rgba(245, 158, 11, 0.14);
    border-color: rgba(245, 158, 11, 0.34);
}
.queue-status-table__state.is-waiting {
    color: #7C3AED;
    background: rgba(139, 92, 246, 0.12);
    border-color: rgba(139, 92, 246, 0.30);
}
.queue-status-table__state.is-unknown {
    color: var(--text-muted);
    background: rgba(148, 163, 184, 0.10);
    border-color: rgba(148, 163, 184, 0.25);
}
.queue-status-table__arrow {
    color: var(--text-faint);   /* mũi tên mờ, không tranh chỗ với hai tên */
}
.queue-status-table__config {
    color: #12946A;             /* xanh lá — cùng họ với --log-target */
    font-weight: 600;
}

.overview-item[data-rest="resting"] .overview-item__value {
    color: var(--danger);
    font-weight: 600;
}

/* ---- Bảng "Trạng thái hàng đợi" gộp chung (thay log chi tiết cho khách hàng) ---- */
.queue-status-panel .add-panel__header { position: relative; }
.queue-status__updated {
    margin-left: auto;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-faint);
}
.queue-status-table {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--panel-2);
}
.queue-status-table__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 14px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
    background: rgba(255,255,255,0.02);
    border-bottom: 1px solid var(--border-soft);
}
.queue-status-table__body { max-height: 420px; overflow-y: auto; }
.queue-status-table__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--border-soft);
    font-size: 13px;
}
.queue-status-table__row:last-child { border-bottom: none; }
.queue-status-table__name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
}
.queue-status-table__count {
    flex-shrink: 0;
    min-width: 26px;
    text-align: center;
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--text-muted);
}
.queue-status-table__count.is-pending { color: var(--accent); }
.queue-status-table__empty {
    margin: 0;
    padding: 18px 10px;
    text-align: center;
    font-size: 12.5px;
    color: var(--text-faint);
}

/* ---- Layout 2 cột: Trạng thái hàng đợi (trái) + Lịch sử chỉnh sửa (phải) ---- */
.status-history-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    align-items: start;
}
.status-history-layout .add-panel { margin-bottom: 0; }
@media (max-width: 900px) {
    .status-history-layout { grid-template-columns: 1fr; }
}

/* ---- Danh sách "Lịch sử chỉnh sửa" ---- */
.edit-history-list {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--panel-2);
    max-height: 420px;
    overflow-y: auto;
}
.edit-history-item {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
    font-size: 12.5px;
}
.edit-history-item:last-child { border-bottom: none; }
.edit-history-item__top {
    display: flex;
    align-items: center;
    gap: 8px;
}
.edit-history-item__actor {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .01em;
    text-transform: uppercase;
}
.edit-history-item[data-role="admin"] .edit-history-item__actor {
    background: rgba(217,136,12,0.14);
    color: var(--accent, #D9880C);
}
.edit-history-item[data-role="customer"] .edit-history-item__actor {
    background: rgba(14,140,147,0.14);
    color: var(--info, #0E8C93);
}
.edit-history-item__time {
    margin-left: auto;
    flex-shrink: 0;
    font-size: 10.5px;
    color: var(--text-faint);
    font-family: var(--font-mono);
}
.edit-history-item__message {
    color: var(--text);
    line-height: 1.45;
    word-break: break-word;
}
.edit-history-list .queue-status-table__empty { border: none; }


.cfg-select { position: relative; }
.cfg-select__trigger {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 9px 12px;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
}
.cfg-select__trigger:hover { border-color: var(--accent-2); }
.cfg-select__trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cfg-select__name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--text);
}
.cfg-select__badges { display: flex; gap: 6px; flex-shrink: 0; }
.cfg-select__chevron { color: var(--text-faint); flex-shrink: 0; }
.cfg-badge {
    font-size: 10.5px;
    font-weight: 700;
    font-family: var(--font-mono);
    padding: 3px 8px;
    border-radius: 999px;
    white-space: nowrap;
}
.cfg-badge--source { color: var(--accent-2); background: rgba(14,140,147,0.1); border: 1px solid rgba(14,140,147,0.28); }
.cfg-badge--target { color: var(--accent); background: rgba(217,136,12,0.1); border: 1px solid rgba(217,136,12,0.3); }

.cfg-select__list {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 14px 34px -18px rgba(15,23,42,0.35);
    display: none;
    flex-direction: column;
    gap: 2px;
}
.cfg-select__list.is-open { display: flex; }
.cfg-select__option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.cfg-select__option:hover { background: var(--panel-2); }
.cfg-select__option.is-active { background: rgba(217,136,12,0.08); }
.cfg-select__option .cfg-select__name { font-weight: 600; color: var(--text); }

.btn-save--danger { background: var(--danger); }

/* ---- Popup chọn nhóm: tab quét tài khoản / thêm link + tag các nhóm đã chọn ---- */
.modal__head--stack { flex-direction: column; align-items: stretch; gap: 10px; }
.modal__head-row { display: flex; align-items: center; justify-content: space-between; }
.modal-tabs { display: flex; gap: 6px; }
.modal-tab {
    flex: 1;
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    color: var(--text-muted);
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.modal-tab.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }

.group-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 84px;
    overflow-y: auto;
}
.group-tags__empty { font-size: 12px; color: var(--text-faint); }
.group-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 10px;
    border-radius: 999px;
    background: rgba(14,140,147,0.1);
    border: 1px solid rgba(14,140,147,0.28);
    color: var(--accent-2);
    font-size: 11.5px;
    font-weight: 600;
    max-width: 220px;
}
.group-tag__remove {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: none;
    background: rgba(14,140,147,0.18);
    color: inherit;
    font-size: 10px;
    line-height: 1;
    cursor: pointer;
}
.group-tag__remove:hover { background: var(--danger); color: #fff; }

.group-modal__total {
    margin: 10px 0 0;
    font-size: 11.5px;
    color: var(--text-faint);
    line-height: 1.5;
}

/* ---- Card: nút sửa/xoá ở console head ---- */
.console__edit,
.console__delete {
    background: none;
    border: 1px solid var(--border-soft);
    color: var(--text-faint);
    font-size: 10.5px;
    padding: 3px 8px;
    border-radius: 5px;
    cursor: pointer;
    flex-shrink: 0;
}
.console__edit:hover { color: var(--accent-2); border-color: var(--accent-2); }
.console__delete:hover { color: var(--danger); border-color: var(--danger); }
.console__delete:disabled { opacity: 0.6; cursor: not-allowed; }

/* ---- Modal (overlay chung cho QR popup & group popup) ---- */
/* BUG ĐÃ SỬA: khoá scroll trang chính khi có modal đang mở (JS thêm class
   này vào <html> trong openModal()/gỡ lại trong closeModal()) - trước đây
   lăn chuột trong modal (nhất là phần header/footer/nền mờ) bị cuộn nhầm
   sang trang chính phía sau thay vì cuộn nội dung modal (.modal__body). */
html.modal-open, html.modal-open body { overflow: hidden; }

.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(15,23,42,0.45);
    backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.modal-overlay[hidden] { display: none; }

.modal {
    background: var(--panel);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    box-shadow: 0 20px 60px -20px rgba(15,23,42,0.4);
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.modal--lg { max-width: 620px; }
.modal--sm { max-width: 360px; }

.modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-soft);
    flex-shrink: 0;
}
.modal__head h3 {
    margin: 0;
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
}
.modal__close {
    background: none;
    border: none;
    font-size: 15px;
    color: var(--text-faint);
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
}
.modal__close:hover { background: var(--overlay-soft); color: var(--text); }

.modal__body {
    padding: 18px;
    overflow-y: auto;
    flex: 1;
}
.modal__foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 18px;
    border-top: 1px solid var(--border-soft);
    flex-shrink: 0;
}
.modal__msg {
    font-size: 12px;
    color: var(--text-muted);
    margin: 8px 0 0;
}
.modal__msg.is-error { color: var(--danger); }

/* ---- Nội dung modal hướng dẫn sử dụng ---- */
.help-guide h4 {
    margin: 20px 0 8px;
    font-family: var(--font-display);
    font-size: 13.5px;
    font-weight: 700;
    color: var(--accent-2);
}
.help-guide h4:first-child { margin-top: 0; }
.help-guide ol,
.help-guide ul {
    margin: 0;
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.help-guide li {
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-muted);
}
.help-guide li ul {
    margin-top: 6px;
    padding-left: 18px;
}
.help-guide strong { color: var(--text); }
.help-guide code {
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    border-radius: 4px;
    padding: 1px 5px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text);
}
.help-guide__note {
    margin: 18px 0 0;
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--text-muted);
}

.modal__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 10px;
}
.modal__loading {
    text-align: center;
    padding: 24px 0;
    color: var(--text-faint);
    font-size: 13px;
}

/* ---- QR box ---- */
.qr-box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 240px;
    height: 240px;
    margin: 0 auto;
    border-radius: var(--radius-md);
    background: var(--panel-2);
    border: 1px solid var(--border);
    overflow: hidden;
}
.qr-box img { width: 100%; height: 100%; object-fit: contain; }
.qr-box__loading,
.qr-box__error,
.qr-box__success {
    font-size: 12.5px;
    color: var(--text-muted);
    text-align: center;
    padding: 0 16px;
}
.qr-box__success { color: var(--success); font-weight: 600; }
.qr-box__error { color: var(--danger); }
.qr-status {
    text-align: center;
    font-size: 12.5px;
    color: var(--text-muted);
    margin: 14px 0 0;
}

/* ---- Group picker popup ---- */
.group-search {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}
.group-search input {
    flex: 1 1 160px;
    min-width: 160px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 10px;
    font-size: 13px;
}
.group-search input:focus { outline: none; border-color: var(--accent); }
.group-search span {
    font-size: 11.5px;
    color: var(--text-faint);
    flex-shrink: 0;
}
.group-search__total,
#groupSelectedCount {
    padding: 4px 9px;
    border-radius: 999px;
    background: var(--panel-2);
    border: 1px solid var(--border-soft);
    white-space: nowrap;
}
#groupSelectedCount {
    color: var(--accent-2);
    font-weight: 600;
    background: rgba(14,140,147,0.08);
    border-color: rgba(14,140,147,0.25);
}

.group-list {
    max-height: 320px;
    overflow-y: auto;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
}
.group-list__empty {
    text-align: center;
    padding: 24px 0;
    color: var(--text-faint);
    font-size: 12.5px;
    margin: 0;
}

.group-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border-soft);
    cursor: pointer;
    font-size: 13px;
}
.group-row:last-child { border-bottom: none; }
.group-row:hover { background: var(--panel-2); }
.group-row input[type="checkbox"] { flex-shrink: 0; }
.group-row__name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-row__id {
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--text-faint);
    flex-shrink: 0;
}

/* ============================================================================
   BỔ SUNG: grid log tối đa 2 card/dòng, overlay loading QR, clamp card__route
   ============================================================================ */

/* ---- Grid log: mặc định tối đa 2 card/dòng; đúng 1 card thì full-width ---- */
#cardGrid.grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}
#cardGrid.grid.grid--single {
    grid-template-columns: 1fr;
}
@media (max-width: 860px) {
    #cardGrid.grid {
        grid-template-columns: 1fr;
    }
}

/* ---- QR box: làm tối ảnh cũ + spinner khi bấm "Làm mới mã QR" ---- */
.qr-box {
    position: relative;
}
.qr-box__inner {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}
.qr-box.is-loading .qr-box__inner {
    filter: brightness(0.35) blur(1px);
    transition: filter 0.2s ease;
    pointer-events: none;
}
.qr-box__spinner {
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    margin: -20px 0 0 -20px;
    border-radius: 50%;
    border: 3px solid rgba(0, 0, 0, 0.12);
    border-top-color: var(--accent);
    animation: qrSpin 0.8s linear infinite;
}
.qr-box.is-loading .qr-box__spinner {
    display: block;
}
@keyframes qrSpin {
    to { transform: rotate(360deg); }
}

/* ---- card__route: chỉ hiện 3 id-chip đầu, bấm vào chip "+n" để mở/ẩn hết ---- */
.id-chip.is-hidden {
    display: none;
}
.id-chip--toggle {
    font-weight: 600;
    background: rgba(14, 140, 147, 0.1);
    border-color: rgba(14, 140, 147, 0.3);
    color: var(--accent-2);
    cursor: pointer;
    user-select: none;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.id-chip--toggle:hover {
    background: rgba(14, 140, 147, 0.18);
    border-color: rgba(14, 140, 147, 0.45);
}
.id-chip--toggle:active {
    transform: scale(0.96);
}
.id-chip--toggle:focus-visible {
    outline: 2px solid var(--accent-2);
    outline-offset: 1px;
}
.route__ids.is-expanded {
    animation: routeIdsExpand 0.15s ease;
}
@keyframes routeIdsExpand {
    from { opacity: 0.6; }
    to { opacity: 1; }
}
.card {
    max-height: 500px;
}
.card__body {
    max-height: 500px;
    overflow: hidden;
}
