/* NextHop FSS — design system. Dark/tech, matching the capabilities document. */
:root {
  --ink: #0B0F1A;
  --shell: #0A0D16;
  --panel: #121A2B;
  --panel-2: #0F1626;
  --slate: #1B2436;
  --line: #243049;
  --cyan: #22D3EE;
  --cyan-dk: #0E7490;
  --teal: #2DD4BF;
  --violet: #8B5CF6;
  --amber: #F59E0B;
  --green: #34D399;
  --red: #F87171;
  --txt: #E8EDF5;
  --mute: #8497B0;
  --mute-2: #5C6E8A;
  --radius: 12px;
  --sidebar-w: 230px;
  --font: "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --mono: "JetBrains Mono", "Consolas", monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--shell);
  color: var(--txt);
  font-size: 14px;
  line-height: 1.5;
}
a { color: var(--cyan); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- App shell ---- */
.app { display: flex; min-height: 100vh; }
.sidebar {
  width: var(--sidebar-w);
  background: var(--ink);
  border-right: 1px solid var(--line);
  padding: 22px 0;
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  flex-shrink: 0;
}
.brand { padding: 0 24px 14px; border-bottom: 1px solid var(--line); }
.brand h1 { font-size: 20px; font-weight: 700; letter-spacing: -.3px; }
.brand h1 span { color: var(--cyan); }
.brand .tag { font-size: 10px; letter-spacing: 1.5px; color: var(--mute); margin-top: 2px; }

/* `flex: 1` lets nav grow to fill the sidebar height. `min-height: 0` is
   the magic that lets a flex child actually shrink below its content size,
   which is the prerequisite for `overflow-y: auto` to take effect — without
   it, the nav grows to fit ALL its links and the bottom (userchip + sign
   out) gets pushed off-screen with no scroll. */
.nav { padding: 14px 12px; flex: 1; min-height: 0; overflow-y: auto; }
.nav a {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-radius: 9px;
  color: var(--mute); font-weight: 500;
  text-decoration: none; margin-bottom: 2px;
}
.nav a .ic { width: 18px; text-align: center; opacity: .9; }
.nav a:hover { background: var(--panel); color: var(--txt); text-decoration: none; }
.nav a.active { background: var(--panel); color: var(--txt); position: relative; }
.nav a.active::before {
  content: ""; position: absolute; left: 0; top: 7px; bottom: 7px;
  width: 3px; border-radius: 2px; background: var(--cyan);
}

.userchip { padding: 14px 20px 0; border-top: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--violet);
  display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #fff; }
.userchip .meta b { display: block; font-size: 12.5px; }
.userchip .meta small { color: var(--mute); font-size: 11px; }

/* ---- Main ---- */
.main { flex: 1; min-width: 0; }
.topbar {
  height: 64px; background: var(--ink); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 28px; position: sticky; top: 0; z-index: 10;
}
.topbar .title h2 { font-size: 17px; }
.topbar .title p { font-size: 12px; color: var(--mute); }
.topbar .actions { display: flex; align-items: center; gap: 14px; }
.search { background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 7px 16px; color: var(--mute); font-size: 12px; width: 210px; }
.logout-form { margin: 0; }
.btn {
  background: var(--cyan); color: var(--ink); border: none;
  border-radius: 16px; padding: 8px 16px; font-weight: 700; font-size: 12.5px;
  cursor: pointer;
}
.btn:hover { background: #38dcf0; }
.btn-ghost { background: transparent; border: 1px solid var(--line); color: var(--txt); }

.content { padding: 26px 28px; }

/* ---- Cards ---- */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; }
.card h3 { font-size: 13.5px; margin-bottom: 14px; }
.grid { display: grid; gap: 16px; }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3-1 { grid-template-columns: 3fr 1fr; }

/* KPI */
.kpi { position: relative; padding-left: 22px; }
/* KPI cards rendered as <a> (clickable drill-down): kill link styling and
   add a subtle hover affordance so they read as tappable. */
a.kpi { display: block; color: inherit; text-decoration: none; cursor: pointer; transition: border-color .15s ease, transform .05s ease; }
a.kpi:hover { text-decoration: none; border-color: var(--cyan); }
a.kpi:active { transform: translateY(1px); }
a.kpi .delta { text-decoration: none; }
.kpi::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; border-radius: 2px; background: var(--cyan); }
.kpi.green::before { background: var(--green); }
.kpi.amber::before { background: var(--amber); }
.kpi.teal::before { background: var(--teal); }
.kpi .label { font-size: 11px; letter-spacing: .5px; color: var(--mute); text-transform: uppercase; }
.kpi .value { font-size: 30px; font-weight: 700; margin: 6px 0 2px; }
.kpi .delta { font-size: 11.5px; color: var(--cyan); }
.kpi.green .delta { color: var(--green); }
.kpi.amber .delta { color: var(--amber); }
.kpi.teal .delta { color: var(--teal); }

/* ---- Tables ---- */
table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-size: 11px; letter-spacing: .5px; text-transform: uppercase;
  color: var(--mute); padding: 10px 8px; border-bottom: 1px solid var(--line); font-weight: 600; }
td { padding: 11px 8px; border-bottom: 1px solid rgba(36,48,73,.5); font-size: 13px; }
tr:hover td { background: rgba(18,26,43,.5); }
.mono { font-family: var(--mono); }
.wo-num { color: var(--cyan); font-weight: 600; }

/* ---- Status pills ---- */
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 11px; font-size: 11px; font-weight: 600; }
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill.new { color: var(--mute); background: rgba(132,151,176,.15); }
.pill.assigned { color: var(--cyan); background: rgba(34,211,238,.15); }
.pill.in_progress { color: var(--amber); background: rgba(245,158,11,.15); }
.pill.on_hold { color: var(--violet); background: rgba(139,92,246,.15); }
.pill.completed { color: var(--green); background: rgba(52,211,153,.15); }
.pill.verified { color: var(--green); background: rgba(52,211,153,.15); }

.prio { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 8px; text-transform: uppercase; }
.prio.low { color: var(--mute); background: rgba(132,151,176,.15); }
.prio.normal { color: var(--cyan); background: rgba(34,211,238,.15); }
.prio.high { color: var(--amber); background: rgba(245,158,11,.15); }
.prio.urgent { color: var(--red); background: rgba(248,113,113,.15); }

/* ---- Dispatch board ---- */
.board { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; align-items: start; }
.column { background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; min-height: 60vh; }
.column h4 { font-size: 12px; letter-spacing: .5px; display: flex; justify-content: space-between; margin-bottom: 12px; }
.wo-card { background: var(--slate); border: 1px solid var(--line); border-left: 3px solid var(--cyan);
  border-radius: 9px; padding: 12px; margin-bottom: 10px; }
.wo-card .head { display: flex; justify-content: space-between; align-items: center; }
.wo-card .task { font-weight: 600; margin: 8px 0 4px; }
.wo-card .meta { font-size: 11px; color: var(--mute); }

/* ---- Misc ---- */
.section-label { font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--violet); font-weight: 700; margin: 18px 0 10px; }
.muted { color: var(--mute); }
.mt { margin-top: 16px; }
.flex { display: flex; gap: 14px; align-items: center; }
.between { justify-content: space-between; }
.empty { padding: 40px; text-align: center; color: var(--mute); }
.qr { width: 120px; height: 120px; background: #fff; border-radius: 8px; padding: 8px; }

/* Toast-style messages: float top-right, slide in, auto-fade. JS in base.html
   marks them with .dismissed after a delay to trigger the fade-out. */
.messages {
  position: fixed; top: 80px; right: 20px; z-index: 200;
  display: grid; gap: 8px; max-width: min(380px, calc(100vw - 28px));
  pointer-events: none;
}
.message, .alert {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 16px;
  background: var(--panel);
  color: var(--txt);
  font-size: 13px;
  box-shadow: 0 6px 24px rgba(0,0,0,.45);
  pointer-events: auto;
  animation: msg-slide-in .25s ease both;
  transition: opacity .35s ease, transform .35s ease;
  cursor: pointer;
}
.message.success { border-left: 3px solid var(--green); }
.message.error, .alert { border-left: 3px solid var(--red); }
.message.warning { border-left: 3px solid var(--amber); }
.message.dismissed { opacity: 0; transform: translateX(20px); }
@keyframes msg-slide-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Skip-to-content link for keyboard users. Visually hidden until focused. */
.skip-link {
  position: absolute; top: -100px; left: 8px; z-index: 1000;
  background: var(--cyan); color: var(--ink);
  padding: 8px 14px; border-radius: 6px; font-weight: 700; font-size: 13px;
  transition: top .15s ease;
}
.skip-link:focus { top: 8px; text-decoration: none; }

/* Branded confirm modal (replaces window.confirm()) */
.modal-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,.6);
  z-index: 500;
  align-items: center; justify-content: center;
  padding: 20px;
  animation: modal-fade-in .15s ease both;
}
.modal-backdrop.open { display: flex; }
.modal {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 24px;
  max-width: 440px; width: 100%;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  animation: modal-pop-in .18s ease both;
}
.modal h3 { font-size: 15px; margin-bottom: 8px; }
.modal p { color: var(--mute); font-size: 13px; margin-bottom: 18px; }
.modal .form-actions { justify-content: flex-end; margin-top: 0; }
@keyframes modal-fade-in { from { opacity: 0 } to { opacity: 1 } }
@keyframes modal-pop-in {
  from { opacity: 0; transform: scale(.94) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.filters {
  display: grid;
  grid-template-columns: minmax(220px, 2fr) minmax(160px, 1fr) minmax(160px, 1fr) auto;
  gap: 14px;
  align-items: end;
  margin-bottom: 16px;
}
.filter-actions, .form-actions { display: flex; justify-content: flex-end; gap: 10px; }
.form-card { max-width: 920px; }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.span-2 { grid-column: span 2; }
.field small { display: block; color: var(--mute); font-size: 11px; margin-top: 4px; }
.field-error { color: var(--red); font-size: 11px; margin-top: 5px; }
.form-actions { margin-top: 18px; }
.status-form { max-width: 520px; display: grid; gap: 14px; }
.input, .field select, .field textarea {
  width: 100%;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--txt);
  font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field textarea { resize: vertical; min-height: 92px; }
.input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(34,211,238,.18);
}
/* Visible keyboard focus on interactive elements site-wide. */
.btn:focus-visible, .nav a:focus-visible, table tr:focus-visible {
  outline: 2px solid var(--cyan); outline-offset: 2px;
}
.btn { transition: background .15s ease, transform .05s ease; }
.btn:active { transform: translateY(1px); }

/* Login */
.login-wrap { display: grid; place-items: center; min-height: 100vh; }
.login-card { width: 360px; background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 32px; }
.login-card h1 { font-size: 24px; margin-bottom: 4px; }
.login-card h1 span { color: var(--cyan); }
.login-card .tag { color: var(--mute); font-size: 11px; letter-spacing: 1.5px; margin-bottom: 22px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12px; color: var(--mute); margin-bottom: 5px; }
.field input { width: 100%; background: var(--ink); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 12px; color: var(--txt); font-size: 14px; }
.field input:focus { outline: none; border-color: var(--cyan); }

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

/* Tables: on narrow screens cards overflow horizontally instead of stretching
   page width. Tables inside cards become scrollable. */
.card { overflow-x: auto; }
.card table { min-width: 480px; }

/* Hamburger button — hidden on desktop, shown on mobile. */
.hamburger {
  display: none;
  background: transparent; border: 1px solid var(--line);
  color: var(--txt); border-radius: 8px;
  padding: 6px 10px; font-size: 18px; cursor: pointer;
}

/* Scrim that dims the page when the mobile sidebar is open. */
.scrim {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,.55); z-index: 90;
}
.scrim.open { display: block; }

/* Tablet landscape: KPI grid drops to 2 columns, sidebar stays. */
@media (max-width: 1100px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .search { width: 140px; }
}

/* Tablet portrait + mobile: sidebar collapses into a drawer. */
@media (max-width: 820px) {
  :root { --sidebar-w: 260px; }
  .sidebar {
    position: fixed; top: 0; left: -280px;
    width: var(--sidebar-w); height: 100vh;
    z-index: 100; transition: left .2s ease;
  }
  .sidebar.open { left: 0; box-shadow: 4px 0 20px rgba(0,0,0,.4); }
  .hamburger { display: inline-flex; align-items: center; justify-content: center; }
  .topbar { padding: 0 14px; gap: 10px; }
  .topbar .title h2 { font-size: 15px; }
  .topbar .title p { display: none; }
  .search { display: none; }
  .topbar .actions { gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
  .btn { padding: 9px 14px; font-size: 13px; }
  .content { padding: 16px 14px; }
  .grid-3-1, .grid-2 { grid-template-columns: 1fr; }
  .board { grid-template-columns: 1fr; }
  .filters, .form-grid { grid-template-columns: 1fr; }
  .filter-actions, .form-actions { justify-content: stretch; flex-wrap: wrap; }
  .filter-actions .btn, .form-actions .btn { flex: 1; min-width: 120px; }
  .span-2 { grid-column: span 1; }
  /* Touch-friendly tap targets on table rows + status pills */
  td, th { padding: 12px 8px; }
  .pill, .prio { font-size: 11.5px; padding: 4px 10px; }
  /* Calendar: 7-column grid → horizontal scroll instead of cramping */
  .content > .card > div[style*="grid-template-columns:repeat(7"] {
    display: flex !important;
    overflow-x: auto;
    gap: 8px;
    scroll-snap-type: x mandatory;
  }
  .content > .card > div[style*="grid-template-columns:repeat(7"] > div {
    flex: 0 0 75vw; scroll-snap-align: start;
  }
}

/* Small phones: tighten further, KPIs single column. */
@media (max-width: 480px) {
  .grid-4 { grid-template-columns: 1fr; }
  .topbar { height: 56px; }
  .brand h1 { font-size: 18px; }
  .nav a { padding: 12px 14px; font-size: 14px; }   /* taller touch targets */
  .kpi .value { font-size: 24px; }
  .login-card { width: 92vw; padding: 22px; }
  .form-card { padding: 14px; }
}

/* ---- Mobile polish (M50) ---- */

/* iOS Safari zooms in on any input with font-size < 16px when it's focused —
   which is jarring and breaks layout. Force 16px on phones to prevent it. */
@media (max-width: 820px) {
  .input, .field select, .field textarea, .field input, .search {
    font-size: 16px;
  }
  /* Apple/Google guideline: 44x44pt minimum tap target. Buttons here are
     mostly 32-36px tall on desktop — too small for thumbs. */
  .btn { min-height: 44px; padding: 11px 18px; font-size: 14px; }
  /* M53: keep the topbar action row visible on phone — pages like WO
     Templates, Buildings, Vendors have a primary "+ New X" button there
     that's not in the bottom bar. Hiding it entirely left those pages
     with no way to trigger their main action. Wrap the topbar to two
     rows instead, and let action buttons share the second row equally.
     Search input + Sign-out form (POST) hide; sign-out is in sidebar. */
  .topbar {
    flex-direction: column; align-items: stretch;
    height: auto; padding: 10px 14px; gap: 8px;
  }
  .topbar > .hamburger { align-self: flex-start; }
  .topbar .actions {
    width: 100%; gap: 6px; flex-wrap: wrap; justify-content: stretch;
  }
  .topbar .actions form[method="post"] { display: none; }
  .topbar .actions .btn {
    flex: 1; min-width: 0; min-height: 40px;
    padding: 9px 12px; font-size: 13px;
  }
  /* Leave room below content so the bottom action bar doesn't cover the
     last row of the page (52px bar + safe-area inset). */
  .main { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}

/* Sign out link inside the sidebar — only shown on phones (desktop keeps
   the Sign out button in the topbar). Placed under the userchip so it
   reads as "this is who you are, here's how to leave". */
.sidebar-signout { display: none; padding: 12px 24px 18px; border-top: 1px solid var(--line); }
.sidebar-signout button {
  width: 100%; background: transparent; color: var(--mute);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 10px 14px; font-size: 13px; cursor: pointer;
}
.sidebar-signout button:hover { color: var(--txt); border-color: var(--mute-2); }
@media (max-width: 820px) {
  .sidebar-signout { display: block; }
}

/* Bottom action bar — visible only on small screens for internal users.
   Gives one-tap access to the field-tech essentials without opening
   the hamburger drawer. Rendered in base.html, hidden on desktop. */
.mobile-actionbar {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--ink);
  border-top: 1px solid var(--line);
  z-index: 80;
  padding: 4px 0 calc(4px + env(safe-area-inset-bottom, 0px));
}
.mobile-actionbar a {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  padding: 8px 4px;
  color: var(--mute);
  font-size: 10.5px;
  text-decoration: none;
  min-height: 52px;
}
.mobile-actionbar a .ic { font-size: 20px; line-height: 1; }
.mobile-actionbar a.active { color: var(--cyan); }
.mobile-actionbar a:hover { color: var(--txt); text-decoration: none; background: var(--panel); }
@media (max-width: 820px) {
  .mobile-actionbar { display: flex; }
}

/* Responsive-table: on narrow viewports, render rows as stacked cards
   instead of a horizontally-scrolling table. Apply by adding the
   `data-mobile="cards"` attribute to <table> and `data-label="…"` on
   each <td> with the column header text. Hot paths (WO list, asset
   list) get this; tables not annotated still scroll horizontally. */
@media (max-width: 600px) {
  table[data-mobile="cards"] { min-width: 0; }
  table[data-mobile="cards"] thead { display: none; }
  table[data-mobile="cards"] tr {
    display: block;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 12px;
    margin-bottom: 10px;
  }
  table[data-mobile="cards"] td {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 4px 0;
    border-bottom: none;
    font-size: 13px;
  }
  table[data-mobile="cards"] td::before {
    content: attr(data-label);
    color: var(--mute);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .5px;
    margin-right: 12px;
    flex-shrink: 0;
  }
  table[data-mobile="cards"] td:first-child {
    font-size: 15px;
    padding-bottom: 8px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--line);
  }
  table[data-mobile="cards"] td:first-child::before { display: none; }
  table[data-mobile="cards"] td.hide-on-mobile { display: none; }
}
.show-on-mobile { display: none; }
@media (max-width: 600px) {
  .show-on-mobile { display: inline; }
  .hide-on-mobile { display: none; }
}

/* Print: kill chrome, expand main */
@media print {
  .sidebar, .topbar, .hamburger, .scrim { display: none !important; }
  .main { width: 100%; }
  .content { padding: 0; }
  .card { border: none; padding: 0; overflow: visible; }
}
