/*!
 * Dispatch Board
 * Copyright (c) 2026 Virtuoso Technologies Ltd. All rights reserved.
 *
 * Proprietary. Unauthorized copying, duplicating, modifying or
 * distributing this file, in whole or in part, by any means, without
 * written permission from Virtuoso Technologies Ltd. is prohibited and is
 * a violation of copyright law. See the LICENSE file.
 */
/* Real-data hardening (v10.46). Loaded last. Long names, long addresses, two currencies, many KPI tiles and many tabs
   must never spill out of a box, overlap another element, or leave a lone tab on a second row. Every rule here is about
   fit, not looks: themes and looks keep their colours and type. */

/* ---------- KPI tiles ---------- */
/* The value scales with its tile (container query units), wraps between amounts, and never leaves the card. */
.kpi-card, .credit-kpi { min-width: 0; container-type: inline-size; }
.kpi-card .kpi-value, .credit-kpi strong {
  min-width: 0; max-width: 100%; line-height: 1.15;
  font-size: clamp(16px, 18cqi, 22px);
  white-space: normal; overflow-wrap: anywhere; word-break: normal;
}
.kpi-card .kpi-value.long { font-size: clamp(14px, 12cqi, 19px); }
.kpi-card .kpi-value.multi { display: flex; flex-direction: column; gap: 1px; font-size: clamp(13px, 11cqi, 17px); }
.kpi-card .kpi-value .kpi-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-card .kpi-value .kpi-unit { font-size: 12px; font-weight: 600; letter-spacing: 0; font-family: inherit; opacity: .85; white-space: nowrap; }
.kpi-card .kpi-label { overflow-wrap: anywhere; }
.kpi-card .kpi-sub { overflow-wrap: anywhere; }
.rep-kpis .kpi-card .kpi-value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The board strip stays one even row on a computer however many tiles a company has (the values scale with the tile);
   phones keep the wrapping grid from mobile.css. */
@media (min-width: 900px) { #kpiStrip { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); } }

/* ---------- Top-level tabs ---------- */
/* One row always. Tighter padding on laptop widths; when they still do not fit, the row scrolls sideways with a soft
   fade at the edge instead of dropping one tab onto a second row. */
.tabbar .tabs { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain; }
.tabbar .tabs::-webkit-scrollbar { display: none; }
.tabbar .tab { flex: none; white-space: nowrap; }
@media (max-width: 1500px) { .tabbar .tab { padding-left: 10px; padding-right: 10px; } }
@media (max-width: 1320px) { .tabbar .tab { padding-left: 8px; padding-right: 8px; font-size: 12.5px; } }
.tabbar .tabs.scroll-r { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent); }
.tabbar .tabs.scroll-l { -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px); mask-image: linear-gradient(90deg, transparent, #000 36px); }
.tabbar .tabs.scroll-l.scroll-r { -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent); }

/* Sub-tabs (Billing, Reports, Settlements, Equipment, Settings sections): same single-row rule. */
.bill-nav, .int-nav { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.bill-nav::-webkit-scrollbar, .int-nav::-webkit-scrollbar { display: none; }
.bill-nav .tab, .int-nav .fleet-chip { flex: none; white-space: nowrap; }

/* ---------- Timeline ---------- */
.driver-id { min-width: 0; }
.driver-id .name { overflow-wrap: anywhere; line-height: 1.25; }
.driver-id .truck { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Long compliance notes ("Port / terminal access permit expired 44d ago") wrap inside the driver column. */
.driver-id .pill-row > * { max-width: 100%; }
.driver-id .lfd { white-space: normal; overflow-wrap: anywhere; line-height: 1.3; }
.driver-id .daysum { overflow-wrap: anywhere; }
/* Load bars: the route text gives way first, then the badges; a bar too short for text shows only its colour. */
.load-block { container-type: inline-size; min-width: 14px; }
.load-block .route { min-width: 0; flex: 0 1 auto; }
@container (max-width: 150px) { .load-block .inline-badge:not(:first-of-type) { display: none; } }
@container (max-width: 96px) { .load-block .inline-badge, .load-block .hot { display: none; } }
@container (max-width: 34px) { .load-block .route { display: none; } }
/* "Free 3:30p" sits under the end of the bar, not on top of the next bar or the now line. */
.free-tag { bottom: auto; top: calc(100% + 3px); transform: translateX(-100%); padding-right: 2px; z-index: 1; }
/* One NOW label per board, on the first row; the line itself still runs through every row. */
.driver-row + .driver-row .now-line::before { display: none; }

/* ---------- Kanban ---------- */
/* Columns share the width (min 236px) so all five fit on a laptop; narrower screens scroll sideways. */
.kanban-col { width: auto; min-width: 236px; flex: 1 1 0; }
.kanban-col h3 { display: flex; align-items: center; gap: 8px; font-size: 12px; letter-spacing: .04em; }
.kanban-card { min-width: 0; }
.kanban-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kanban-card.hot { border-left: 3px solid var(--status-critical); }
.k-head { gap: 8px; margin-bottom: 4px; }
.k-num { display: inline-flex; align-items: center; gap: 4px; font-family: "IBM Plex Mono", monospace; font-size: 13px; }
.k-cust { font-size: 13px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 4px; }
.k-cont { font-size: 12px; color: var(--ink-muted); margin-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-cont span { color: var(--ink-faint); }
.k-moves { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.k-driver { margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-driver.none { background: var(--status-risk-soft); color: var(--status-risk); }
.k-rate { font-size: 12px; color: var(--ink-muted); flex: none; }

/* ---------- Tables ---------- */
/* Row buttons stay on one line; the table scrolls sideways inside its card when a screen is too narrow. */
table.loads td .row-actions { flex-wrap: nowrap; }
table.loads td .row-actions > * { flex: none; }
.table-wrap { overflow-x: auto; }
table.loads td { overflow-wrap: break-word; } /* not "anywhere": that shrinks columns and splits pills */
table.loads td :is(.status-pill, .lfd, .move-tag, .req-chip, .flag-tag, .bill-flag, .inline-badge, .conflict-pill) { white-space: nowrap; overflow-wrap: normal; }
table.loads td.mono, table.loads td .mono, table.loads td .rate, table.loads td .money { overflow-wrap: normal; white-space: nowrap; }

/* ---------- Needs attention / banners ---------- */
.attention li, .attention .att-row { min-width: 0; }

/* ---------- Version pill ---------- */
/* In the header next to the product name, not floating over the page (it used to cover the Edit buttons at the right
   edge of tables). Quiet until you point at it. m.html keeps its floating one, hidden on phones below. */
.version-badge.in-head { position: relative; right: auto; bottom: auto; vertical-align: 3px; margin-left: 6px; box-shadow: none; }
.version-badge { color: var(--ink-faint); background: var(--surface); border-color: var(--border); box-shadow: var(--shadow); opacity: .72; padding: 2px 8px; font-size: 10.5px; }
.version-badge:hover, .version-badge:focus-visible, .version-badge.has-new { opacity: 1; color: var(--accent); border-color: var(--accent); filter: none; }

/* Phones: the version pill would sit on top of a card; the version is in the menu (☰ › Show the version number). */
@media (max-width: 600px) { .version-badge, .m-page .version-badge { display: none !important; } }

/* ---------- Form checks ---------- */
input.needs-value, select.needs-value, textarea.needs-value { border-color: var(--status-critical) !important; box-shadow: 0 0 0 3px var(--status-critical-soft) !important; }

/* KPI values line up along the bottom of the row even when a label ("Units needing repair") takes two lines. */
.kpi-card { justify-content: space-between; }
.free-tag.at-start { transform: none; }
.track { transition: height .15s ease; }
