/* ================================================================
   DESIGN TOKENS — single source of truth for the whole app.
   Brand colours, theme surfaces, radius, and layout widths all live
   here and NOWHERE else — change the look of the entire app from
   this block. Two themes: dark (default) and light, toggled via the
   [data-theme] attribute on <html> (see js/theme.js).
   ================================================================ */
:root {
  /* Brand — Tech2Go (identical in both themes) */
  --accent: #4caf50;          /* Tech2Go green */
  --accent-rgb: 76, 175, 80;  /* same, for rgba() tints */
  --accent-2: #f97316;        /* Tech2Go orange */
  --accent-2-rgb: 249, 115, 22;
  --on-accent: #ffffff;       /* text/icons on a brand-filled surface */

  /* Status colours (shared across themes) */
  --ok: #22c55e;
  --warn: #f59e0b;
  --danger: #ef4444;

  --radius: 10px;

  /* Theme surfaces — DARK (default) */
  --bg: #0f172a;
  --surface: #1e293b;
  --surface-2: #273549;
  --border: #334155;
  --text: #e2e8f0;
  --text-dim: #94a3b8;

  /* Mobile-first content width/padding scale — one place to tune so the topbar, nav, and
     main content edges always line up and the layout never leaves large dead gutters on
     wide screens. Bump these at each breakpoint instead of hand-tuning individual pages. */
  --content-max-width: 100%;
  --content-padding: 14px;
}

/* Theme surfaces — LIGHT (brand + status tokens above are inherited) */
:root[data-theme="light"] {
  --bg: #f4f6f8;
  --surface: #ffffff;
  --surface-2: #eef1f4;
  --border: #d7dde3;
  --text: #17202e;
  --text-dim: #5b6673;
}
@media (min-width: 640px) {
  :root { --content-max-width: 720px; --content-padding: 20px; }
}
@media (min-width: 900px) {
  :root { --content-max-width: 1100px; --content-padding: 28px; }
}
@media (min-width: 1280px) {
  :root { --content-max-width: 1440px; --content-padding: 36px; }
}
@media (min-width: 1680px) {
  :root { --content-max-width: 1680px; --content-padding: 48px; }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-tap-highlight-color: transparent;
}

#app { height: 100vh; display: flex; flex-direction: column; overflow: hidden; }

header.topbar {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  padding: 12px var(--content-padding); background: var(--surface); border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 10;
}
header.topbar h1 { font-size: 16px; margin: 0; font-weight: 600; }
header.topbar .user { font-size: 12px; color: var(--text-dim); display: flex; align-items: center; flex-wrap: wrap; }
.topbar-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text); border: none; cursor: pointer;
  font-size: 22px; line-height: 1; padding: 2px 6px;
}

/* App shell: fixed topbar + a left sidebar rail, with the page content scrolling
   independently between them. On phones the sidebar collapses to a slide-in drawer
   (toggled by the ☰ button) with a dimming overlay; ≥900px it's a permanent rail.
   RTL flips the drawer to the right automatically via the [dir="rtl"] transforms. */
.shell { flex: 1; display: flex; min-height: 0; }

.sidebar {
  position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 40;
  width: 264px; max-width: 82vw; background: var(--surface);
  border-inline-end: 1px solid var(--border); overflow-y: auto;
  padding: 10px 0; transform: translateX(-100%); transition: transform .22s ease;
}
[dir="rtl"] .sidebar { transform: translateX(100%); }
.sidebar.open { transform: none; }
.sidebar-brand {
  display: flex; align-items: center; justify-content: center;
  padding: 14px 20px 16px; margin-bottom: 6px; border-bottom: 1px solid var(--border);
}
.sidebar-brand img {
  width: 84px; height: 84px; object-fit: contain;
  background: #fff; border: 1px solid var(--border); border-radius: 14px; padding: 6px;
}
.sidebar nav { display: flex; flex-direction: column; }
.sidebar a {
  display: flex; align-items: center; gap: 12px; padding: 11px 20px;
  color: var(--text-dim); text-decoration: none; font-size: 14px;
  border-inline-start: 3px solid transparent; white-space: nowrap;
}
.sidebar a:hover { background: var(--surface-2); color: var(--text); }
.sidebar a.active {
  color: var(--text); background: var(--surface-2);
  border-inline-start-color: var(--accent); font-weight: 600;
}
.sidebar a .nav-icon { font-size: 17px; width: 22px; text-align: center; flex-shrink: 0; }

.sidebar-overlay {
  position: fixed; inset: 0; z-index: 39; background: rgba(0,0,0,.5);
  opacity: 0; pointer-events: none; transition: opacity .22s ease;
}
.sidebar-overlay.open { opacity: 1; pointer-events: auto; }

@media (min-width: 900px) {
  .nav-toggle { display: none; }
  .sidebar {
    position: static; transform: none; width: 240px; max-width: none; z-index: auto;
  }
  [dir="rtl"] .sidebar { transform: none; }
  .sidebar-overlay { display: none; }
}

main {
  flex: 1; min-width: 0; overflow-y: auto; width: 100%; margin: 0 auto;
  max-width: var(--content-max-width); padding: var(--content-padding);
}

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px; margin-bottom: 12px;
}

.grid { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid.cols-2 { grid-template-columns: 1fr 1fr; } .grid.cols-3 { grid-template-columns: repeat(3,1fr); } }

/* Card collections (suppliers, and anything else listing an open-ended number of cards)
   use a fluid auto-fill grid instead of a fixed column count — it naturally shows 1 column
   on a phone and however many 280px+ cards fit on a wider screen, with no breakpoint tuning
   needed as the catalog grows or the viewport changes. */
.grid.cards { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

.stat { text-align: center; }
.stat .value { font-size: 28px; font-weight: 700; }
.stat .label { font-size: 12px; color: var(--text-dim); margin-top: 4px; }

.badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;
  background: var(--surface-2); color: var(--text-dim);
}
.badge.ok { background: rgba(34,197,94,.15); color: var(--ok); }
.badge.warn { background: rgba(245,158,11,.15); color: var(--warn); }
.badge.danger { background: rgba(239,68,68,.15); color: var(--danger); }
.badge.info { background: rgba(var(--accent-rgb),.15); color: var(--accent); }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--border); }
th { color: var(--text-dim); font-weight: 500; font-size: 12px; }

button, .btn {
  background: var(--accent); color: var(--on-accent); border: none; border-radius: 8px;
  padding: 10px 16px; font-size: 14px; font-weight: 600; cursor: pointer;
}
button:disabled { opacity: .5; cursor: not-allowed; }
button.secondary { background: var(--surface-2); color: var(--text); }
button.danger { background: var(--danger); }

input, select, textarea {
  width: 100%; padding: 10px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text); font-size: 14px; margin-bottom: 10px;
}
label { font-size: 12px; color: var(--text-dim); display: block; margin-bottom: 4px; }

.error-banner {
  background: rgba(239,68,68,.15); color: var(--danger); border: 1px solid var(--danger);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; font-size: 13px;
}
.success-banner {
  background: rgba(34,197,94,.15); color: var(--ok); border: 1px solid var(--ok);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; font-size: 13px;
}

.sync-badge {
  position: fixed; bottom: 16px; right: 16px; background: var(--warn); color: #1a1a1a;
  padding: 8px 14px; border-radius: 999px; font-size: 12px; font-weight: 700;
  box-shadow: 0 2px 8px rgba(0,0,0,.4); z-index: 20; cursor: pointer;
}
.sync-badge.synced { background: var(--ok); }

.checklist-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.checklist-item .label { flex: 1; font-size: 14px; }
.result-buttons { display: flex; gap: 6px; }
.result-buttons button { padding: 6px 10px; font-size: 12px; background: var(--surface-2); color: var(--text-dim); }
.result-buttons button.selected.pass { background: var(--ok); color: #fff; }
.result-buttons button.selected.fail { background: var(--danger); color: #fff; }
.result-buttons button.selected.na { background: var(--text-dim); color: #fff; }

.photo-thumb { width: 64px; height: 64px; object-fit: cover; border-radius: 6px; margin: 4px; }
.photo-row { display: flex; flex-wrap: wrap; }
.file-chip {
  width: 64px; height: 64px; margin: 4px; border-radius: 6px; background: var(--surface-2);
  border: 1px solid var(--border); display: flex; flex-direction: column; align-items: center;
  justify-content: center; padding: 4px; overflow: hidden;
}
.file-chip .file-icon { font-size: 20px; line-height: 1; }
.file-chip .file-name {
  font-size: 9px; color: var(--text-dim); text-align: center; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}

.muted { color: var(--text-dim); font-size: 12px; }
.section-title { font-size: 14px; font-weight: 600; margin: 18px 0 8px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; }

.spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid var(--text-dim);
  border-top-color: var(--accent); border-radius: 50%; animation: spin .6s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

a.link { color: var(--accent); text-decoration: none; }

/* Contract cards on the dashboard. Two things make cards in the same row drift out of
   alignment: (1) a title that wraps to 2 lines in one card but 1 line in the other pushes
   everything below it down by a line — fixed by reserving 2 lines of height on the title
   always, so short and long titles occupy identical space; (2) a shorter content block
   leaving the footer floating mid-card instead of at the bottom — fixed by pinning it with
   margin-top:auto in a flex column. Together every row of stats/badges/footer lines up
   across cards regardless of how much text is above them. */
.contract-card { display: flex; flex-direction: column; }
.contract-card .card-title {
  margin: 0 0 12px; font-size: 16px; line-height: 1.35; font-weight: 600;
  min-height: calc(1.35em * 2); display: flex; align-items: flex-start;
}
.contract-card .card-footer { margin-top: auto; padding-top: 10px; }

.lang-toggle {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 12px; font-size: 12px; font-weight: 600; cursor: pointer;
  margin-inline-start: 10px;
}

/* Supplier directory — every card renders the same fixed slots in the same style
   regardless of how much is known about that supplier, so cards read as one consistent
   system rather than drifting in tone/size card to card:
   header -> location -> equipment badges -> what-they-supply -> verification callout
   (only if present) -> a uniform small facts footer (address / website / contact). */
.supplier-card { cursor: pointer; }
.supplier-card:hover { border-color: var(--accent); }
.supplier-logo { width: 48px; height: 48px; object-fit: contain; border-radius: 6px; background: var(--surface-2); flex-shrink: 0; }
.supplier-header { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.supplier-name { font-size: 16px; font-weight: 700; margin: 0; line-height: 1.3; }
.supplier-location { font-size: 12px; color: var(--text-dim); margin: 0 0 8px; }
.supplier-badges { margin-bottom: 8px; }
.supplier-desc { font-size: 13px; color: var(--text); margin: 0 0 8px; line-height: 1.5; }
.supplier-verify {
  font-size: 12px; color: var(--warn); background: rgba(245,158,11,.08);
  border-inline-start: 3px solid var(--warn); padding: 8px 10px; border-radius: 6px;
  margin: 0 0 8px; line-height: 1.5;
}
.supplier-facts { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.supplier-facts .fact { font-size: 12px; color: var(--text-dim); margin-bottom: 4px; }
.supplier-facts .fact:last-child { margin-bottom: 0; }
.supplier-facts .fact-label { color: var(--text-dim); }

/* Help page */
.glossary-term { font-weight: 700; color: var(--text); }
.glossary-row { padding: 8px 0; border-bottom: 1px solid var(--border); }

.pagination { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:10px; }

/* GIS client portal — executive presentation surface (money-blind). All colours come from
   design tokens, so it themes light/dark and mirrors RTL automatically. */
.client-program-head {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px solid var(--border);
}
.client-logo {
  width: 56px; height: 56px; object-fit: contain; flex-shrink: 0;
  background: #fff; border: 1px solid var(--border); border-radius: 12px; padding: 5px;
}
.client-program-titles { flex: 1; min-width: 0; }
.client-program-titles h2 { margin: 0; font-size: 20px; line-height: 1.3; }
.client-confidential {
  font-size: 11px; font-weight: 700; letter-spacing: .03em; white-space: nowrap;
  color: var(--danger); border: 1px solid var(--danger); border-radius: 999px;
  padding: 3px 10px; background: rgba(239,68,68,.08);
}

.client-summary { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-bottom: 8px; }
.client-pct { text-align: center; flex-shrink: 0; }
.client-pct .value { font-size: 40px; font-weight: 800; line-height: 1; color: var(--accent); }
.client-pct .label { font-size: 12px; color: var(--text-dim); margin-top: 4px; }
.client-summary-side { flex: 1; min-width: 240px; }
.client-sites-line { margin-top: 8px; font-size: 13px; }

/* Phase stepper — six macro delivery phases, current highlighted. */
.phase-stepper { display: flex; align-items: flex-start; overflow-x: auto; }
.phase-stepper .step {
  flex: 1; min-width: 66px; display: flex; flex-direction: column; align-items: center;
  gap: 6px; position: relative; text-align: center;
}
.phase-stepper .step::before {
  content: ""; position: absolute; top: 13px; height: 2px; background: var(--border);
  inset-inline-start: -50%; width: 100%; z-index: 0;
}
.phase-stepper .step:first-child::before { display: none; }
.phase-stepper .step-dot {
  position: relative; z-index: 1; width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700;
  background: var(--surface-2); color: var(--text-dim); border: 2px solid var(--border);
}
.phase-stepper .step-label { font-size: 11px; color: var(--text-dim); line-height: 1.25; }
.phase-stepper .step.done .step-dot,
.phase-stepper .step.done::before { background: var(--accent); }
.phase-stepper .step.done .step-dot { color: var(--on-accent); border-color: var(--accent); }
.phase-stepper .step.active::before { background: var(--accent); }
.phase-stepper .step.active .step-dot { background: var(--surface); color: var(--accent); border-color: var(--accent); }
.phase-stepper .step.active .step-label,
.phase-stepper .step.done .step-label { color: var(--text); }
.phase-stepper .step.active .step-label { font-weight: 700; }

/* Site register — one pill per site with its install status (colour by status). */
.site-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.site-pill {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border); border-inline-start: 3px solid var(--border);
  font-size: 13px; font-weight: 600;
}
.site-pill em { font-style: normal; font-size: 11px; font-weight: 500; color: var(--text-dim); }
.site-pill.ok { border-inline-start-color: var(--ok); }
.site-pill.info { border-inline-start-color: var(--accent); }
.site-pill.warn { border-inline-start-color: var(--warn); }

/* Progress-photo gallery (client portal) + fullscreen lightbox. */
.client-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.gallery-item {
  padding: 0; margin: 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  cursor: pointer; background: var(--surface-2); aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-video { text-decoration: none; }
.gallery-play {
  width: 46px; height: 46px; border-radius: 50%; background: var(--accent); color: var(--on-accent);
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.gallery-lightbox {
  position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,.85);
  display: flex; align-items: center; justify-content: center; padding: 20px; cursor: zoom-out;
}
.gallery-lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; }

/* "Show to client" curation toggle in the internal document lists. */
.doc-vis {
  padding: 4px 10px; font-size: 11px; font-weight: 600; border-radius: 999px;
  background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--border); cursor: pointer;
}
.doc-vis.on { background: rgba(var(--accent-rgb),.15); color: var(--accent); border-color: var(--accent); }

/* Submittal print transmittal — letterhead header hidden on screen, shown only when printing.
   The rest of the print stylesheet strips app chrome and interactive controls so what prints
   is a clean transmittal sheet: logo/title header, submittal facts, and status history. */
.print-header, .print-signature-block { display: none; }

@media print {
  #app { height: auto; overflow: visible; display: block; }
  .shell { display: block; }
  main { overflow: visible; }
  header.topbar, .sidebar, .nav-toggle, .sidebar-overlay, .no-print, .sync-badge { display: none !important; }
  body, .card { background: #fff !important; color: #000 !important; border-color: #ccc !important; }
  .print-header {
    display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
    border-bottom: 2px solid #000; padding-bottom: 10px;
  }
  .print-logo { width: 64px; height: auto; }
  .print-company { font-size: 18px; font-weight: 700; }
  .print-doc-title { font-size: 12px; color: #444; }
  .badge { border: 1px solid #000; color: #000 !important; background: transparent !important; }
  a.link { color: #000; text-decoration: underline; }
  .print-signature-block { display: block; margin-top: 40px; }
  .sig-line {
    display: inline-block; width: 45%; margin-inline-end: 5%; padding-top: 30px;
    border-top: 1px solid #000; font-size: 12px;
  }
}

/* RTL overrides — logical properties handle most of this automatically via [dir="rtl"],
   these are the few spots with a hardcoded physical left/right that need flipping */
[dir="rtl"] th, [dir="rtl"] td { text-align: right; }
[dir="rtl"] .sync-badge { right: auto; left: 16px; }
[dir="rtl"] .checklist-item { direction: rtl; }
[dir="rtl"] .photo-row, [dir="rtl"] .result-buttons { direction: rtl; }

/* Program schedule timeline (Gantt-lite) — pure CSS/HTML percentage positioning, no charting
   library. Inline inset-inline-start/top/width styles are set from JS in week-percentage terms;
   these classes only handle appearance, so RTL mirrors automatically via logical properties. */
.gantt-track { position: relative; background: var(--surface-2); border-radius: var(--radius); padding: 10px 0 26px 0; margin-top: 10px; }
.gantt-bands { position: relative; }
.gantt-band {
  position: absolute; height: 22px; border-radius: 4px; background: rgba(var(--accent-rgb),.25);
  border: 1px solid var(--accent); color: var(--text); font-size: 10px; padding: 3px 6px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.gantt-markers { position: absolute; inset-inline-start: 0; width: 100%; height: 0; }
.gantt-marker {
  position: absolute; top: -8px; display: flex; flex-direction: column; align-items: center;
  transform: translateX(-50%);
}
[dir="rtl"] .gantt-marker { transform: translateX(50%); }
.gantt-marker::before { content: ""; display: block; width: 2px; height: 16px; background: var(--text-dim); }
.gantt-marker-ok::before { background: var(--ok); }
.gantt-marker-warn::before { background: var(--warn); }
.gantt-marker-danger::before { background: var(--danger); }
.gantt-marker-info::before { background: var(--accent); }
.gantt-marker-label { font-size: 10px; font-weight: 700; margin-top: 2px; white-space: nowrap; }
.gantt-today {
  position: absolute; top: -8px; height: calc(100% + 8px); border-inline-start: 2px dashed var(--danger);
  transform: translateX(-50%);
}
[dir="rtl"] .gantt-today { transform: translateX(50%); }
.gantt-today-label { position: absolute; top: -16px; font-size: 10px; color: var(--danger); font-weight: 700; white-space: nowrap; }
.gantt-week-ruler { position: absolute; bottom: 0; inset-inline-start: 0; inset-inline-end: 0; height: 20px; }
.gantt-week-ruler span { position: absolute; font-size: 9px; color: var(--text-dim); transform: translateX(-50%); }
[dir="rtl"] .gantt-week-ruler span { transform: translateX(50%); }
