/* ==========================================================================
   crews.css — unified dark theme (black + orange)
   Applies to BOTH Job Board and Job Detail pages.
   ========================================================================== */

:root{
  --bg: #0b0b0c;            /* page background (near-black) */
  --surface: #141518;       /* cards/panels */
  --surface-2: #1a1c20;     /* slightly lighter surface */
  --border: #23252b;        /* subtle borders */
  --muted: #9aa3ae;         /* secondary text */
  --text: #e9edf1;          /* primary text */
  --accent: var(--brand-primary,#ff7a00);        /* orange */
  --accent-2: var(--brand-primary-hover,#ffa24a);      /* hover/soft orange */
  --shadow: rgba(0,0,0,.35);

  /* Role badge colors (kept as requested) */
  --role-super: var(--brand-primary,#ff7a00);    /* orange */
  --role-gf: #ffd54a;       /* yellow */
  --role-foreman: #ff5c5c;  /* strong red (consolidated effective) */
  --role-journeyman: #6c8cff; /* indigo-ish (consistent with blue family) */
  --role-lv: #8ecbff;       /* light blue */
  --role-apprentice: #4caf50;/* green */
  --role-qaqc: #d500f9;     /* magenta */
  --role-operator: #c19a6b; /* light brown */
  --role-safety: #dc2626;   /* red */
  --role-estimator: #1b5e20;          /* dark green */
  --role-project_controls_manager: #5d3a1a; /* dark brown */
  --role-project_coordinator: #00bcd4; /* cyan */
  --role-admin: #ec4899;              /* pink */
}

/* Base ---------------------------------------------------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
/* No sideways drift, ever: stray fixed widgets or wide rows must not widen
   the mobile layout viewport (which also skews fixed-position elements). */
html, body { overflow-x: hidden; overflow-x: clip; }
body{
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-2); }

h1,h2,h3,h4,h5,h6 { color: var(--text); }
.text-muted, .muted, small, .form-text { color: var(--muted) !important; }

/* Cards / containers -------------------------------------- */
.card,
.job-card,
.list-card{
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 6px 20px var(--shadow);
}

.card .card-header{
  background: var(--surface-2);
  color: var(--text);
  border-bottom: 1px solid var(--border);
}
.card .card-header strong,
.card .card-header h1, .card .card-header h2,
.card .card-header h3, .card .card-header h4,
.card .card-header h5, .card .card-header h6 { color: var(--text); }

/* Buttons ------------------------------------------------- */
.btn,
button{
  color: var(--text);
}

.btn-primary{
  background: var(--accent);
  border-color: var(--accent);
  color: #101214;
}
.btn-primary:hover,
.btn-primary:focus{
  background: var(--accent-2);
  border-color: var(--accent-2);
  color: #0b0b0c;
}

.btn-outline-secondary{
  color: var(--accent);
  border-color: var(--accent);
  background: transparent;
}
.btn-outline-secondary:hover{
  color: #0b0b0c;
  background: var(--accent);
  border-color: var(--accent);
}

.btn-outline-danger{
  color: #ff6b6b;
  border-color: #ff6b6b;
  background: transparent;
}
.btn-outline-danger:hover{
  color: #0b0b0c;
  background: #ff6b6b;
  border-color: #ff6b6b;
}

/* Forms --------------------------------------------------- */
.form-control,
.form-select{
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
}
.form-control::placeholder{ color: #8b939c; }
.form-control:focus,
.form-select:focus{
  border-color: var(--accent);
  box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--brand-primary,#ff7a00) 15%, transparent);
}

/* Badges / counters -------------------------------------- */
.badge{
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}
.badge.bg-secondary{
  background: var(--surface-2) !important;
  border-color: var(--border);
  color: var(--text) !important;
}
.count b,
.badge b{
  color: var(--accent);
  font-weight: 700;
}

/* Navbar (minimal tweaks only) ---------------------------- */
.navbar,
.navbar-dark{
  background: #111214 !important;
  border-bottom: 1px solid var(--accent); /* CHANGED: make divider orange */
}
.navbar .nav-link{ color: var(--text) !important; }
.navbar .nav-link:hover{ color: var(--accent) !important; }

/* brand to orange */
.navbar .navbar-brand,
.navbar-dark .navbar-brand{
  color: var(--accent) !important;   /* NEW */
}
.navbar .navbar-brand:hover,
.navbar-dark .navbar-brand:hover{
  color: var(--accent-2) !important; /* NEW */
}

/* make specifically the Logout link orange (keeps other links as-is) */
.navbar a.nav-link[href$="logout/"],
.navbar a.nav-link[href*="/logout"]{
  color: var(--accent) !important;   /* NEW */
}
.navbar a.nav-link[href$="logout/"]:hover,
.navbar a.nav-link[href*="/logout"]:hover{
  color: var(--accent-2) !important; /* NEW */
}

/* Logout: round brand-orange icon button (all screen sizes) */
.nav-logout {
  display: inline-flex !important; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid var(--accent); border-radius: 50%;
  padding: 0 !important;
  transition: background .12s ease, transform .08s ease;
}
.nav-logout:hover { background: var(--accent); transform: translateY(-1px); }
.nav-logout:hover .logout-ic { color: #0b0b0c; }

/* =========================================================
   JOB BOARD
   ========================================================= */
.job-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}

.job-card{
  display: block;
  padding: 14px 14px 12px;
  transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.job-card:hover{
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 10px 28px var(--shadow);
}
.job-card-title{
  font-weight: 600;
  font-size: 1.05rem;
  margin-bottom: 4px;
  color: var(--text);
}
.job-card-address{
  color: var(--muted);
  font-size: .9rem;
  margin-bottom: 8px;
}
.job-card-stats{
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  font-size: .88rem;
  color: #cfd6dd;
}
.job-card-stats span b{ color: var(--accent); }

/* =========================================================
   JOB BOARD — polished card (v2)
   ========================================================= */
.jc-section{
  display: flex; align-items: center; gap: 10px;
  margin: 26px 0 12px;
}
.jc-section-label{
  text-transform: uppercase; letter-spacing: .18em;
  font-weight: 800; font-size: .8rem; color: var(--text);
}
.jc-section-count{
  font-size: .72rem; font-weight: 700; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 9px;
}
.jc-section-rule{ flex: 1; height: 1px; background: var(--border); }

.job-card--v2{
  padding: 0;
  overflow: hidden;
  border-left: 4px solid var(--accent);
}
.job-card--v2 .jc-body{
  display: flex; flex-direction: column; gap: 12px;
  height: 100%;
  padding: 16px 18px 14px;
}

/* Header: title/address/union on the left, hero headcount on the right */
.jc-head{ display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.jc-head-main{ min-width: 0; flex: 1 1 auto; }   /* long names wrap, hero stays put */
.jc-title{
  font-size: 1.15rem; font-weight: 700; color: var(--text);
  line-height: 1.2;
}
.jc-address{
  display: flex; gap: 6px; align-items: flex-start;
  color: var(--muted); font-size: .86rem; margin-top: 5px;
}
.jc-pin{
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); margin-top: 6px; flex: 0 0 auto;
}
.jc-union{ font-size: .8rem; color: var(--muted); margin-top: 5px; }
.jc-union strong{ color: var(--text); font-weight: 700; }

.jc-hero{ text-align: right; flex: 0 0 auto; }
.jc-hero-num{ font-size: 2rem; font-weight: 800; color: var(--accent); line-height: 1; }
.jc-hero-label{
  font-size: .6rem; font-weight: 700; letter-spacing: .12em;
  color: var(--muted); margin-top: 3px;
}

/* Crew composition bar + legend (colors reuse the .role-<position> classes) */
.jc-bar{
  display: flex; width: 100%; height: 8px;
  border-radius: 999px; overflow: hidden; background: #23262c;
}
.jc-seg{ height: 100%; }
.jc-legend{
  display: flex; flex-wrap: nowrap; justify-content: space-between;
  gap: 6px; font-size: .72rem; color: var(--text);
}
.jc-leg{ display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.jc-dot{ width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }

/* Job board: a touch wider than the stock container so the 4-metric
   footer isn't smooshed, but well short of full-bleed — the cards keep
   side breathing room and a sane width. Doubled selector: this must
   outrank crews_consolidated.css's later ".container-fluid{max-width:98vw}",
   which otherwise re-stretches the board on wide monitors. */
.container-fluid.jobs-board-wrap,
.jobs-board-wrap{ padding-left: 2.5rem; padding-right: 2.5rem; max-width: 1520px; margin: 0 auto; }
@media (max-width: 768px){ .jobs-board-wrap{ padding-left: 1rem; padding-right: 1rem; } }

/* Footer metrics: Field | Office | Safety | Trucks. Each column takes
   only the room its number/label needs (centered as a group) rather
   than stretching to fill the card. */
.jc-foot{
  margin-top: auto; display: flex; justify-content: center;
  border-top: 1px solid var(--border); padding-top: 10px;
}
.jc-metric{ flex: 0 1 auto; text-align: center; position: relative; padding: 0 16px; min-width: 70px; }
.jc-metric + .jc-metric::before{
  content: ""; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%); height: 62%; width: 1px; background: var(--border);
}
.jc-metric-num{ display: block; font-size: 1.25rem; font-weight: 800; color: var(--text); }
.jc-metric-num--accent{ color: var(--accent); }
.jc-metric-label{
  display: block; font-size: .62rem; font-weight: 700; letter-spacing: .1em;
  color: var(--muted); margin-top: 2px;
}


/* “Create Job” button on board sits nicely */
.create-job-wrap{
  display:flex; align-items:center; justify-content:flex-end; gap:8px;
}

/* =========================================================
   JOB DETAIL (Crews page)
   ========================================================= */
.list-title{ color: var(--text); }
.people-list{
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 36px;
}

.empty-hint{
  color: var(--muted);
  font-style: italic;
}

.person{
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
  cursor: grab;
  transition: border-color .12s ease, transform .08s ease;
}
.person:active{ cursor: grabbing; }
.person:hover{ border-color: var(--accent); }

.person .person-top{
  display:flex; align-items:center;
  gap: 5px;
}
.person .name{ color: var(--text); font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.person .person-bottom{
  margin-top: 4px; display:flex; gap:10px; flex-wrap:wrap; align-items:center;
  color: #cfd6dd;
}
.person .phone{ color: #dfe6ee; opacity: .9; }
.person .truck{ color: var(--accent); }

/* Role badges — keep the specified colors */
.role-badge{
  padding: 2px 8px;
  font-size: .75rem;
  font-weight: 700;
  border-radius: 999px;
  color: #0b0b0c;
}
.role-superintendent{ background: var(--role-super); }
.role-gf{ background: var(--role-gf); color: #121212; }
.role-foreman{ background: var(--role-foreman); }
.role-journeyman{ background: var(--role-journeyman); }
.role-lv_tech{ background: var(--role-lv); color: #102030; }
.role-apprentice{ background: var(--role-apprentice); }
.role-project_manager{ background: var(--role-project_manager, #805ad5); color: #f2eaff; }
.role-qaqc{ background: var(--role-qaqc); color: #000; }
.role-operator{ background: var(--role-operator); color: #1a1208; }
.role-safety{ background: var(--role-safety); color: #fff; }
.role-estimator{ background: var(--role-estimator); color: #fff; }
.role-project_controls_manager{ background: var(--role-project_controls_manager); color: #fff; }
.role-project_coordinator{ background: var(--role-project_coordinator); color: #001218; }
.role-admin{ background: var(--role-admin); color: #fff; }

/* Senior crown — shown next to the role badge for top PM / Super on a project */
.senior-crown{
  display: inline-block;
  margin-left: 4px;
  font-size: .95rem;
  line-height: 1;
  vertical-align: middle;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.6));
}

/* ============================================================
   Dynamic count strip — plain text "S: 5 · GF: 2 · F: 3 · 🚚 2"
   followed by an accent-bordered "Total N" chip. When a crew card
   has multiple shift zones, a second .count-shifts line shows
   "Shift 1: N · Shift 2: N · Shift 3: N" beneath.
   ============================================================ */
.dynamic-counts,
.job-card-stats,
#job-totals {
  font-size: .82rem;
  color: var(--text);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.dynamic-counts .count-breakdown,
#job-totals .count-breakdown {
  color: var(--muted);
  white-space: normal;
}
.dynamic-counts .count-chips,
#job-totals .count-chips,
.job-card-stats .count-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
}
/* Per-shift Field/Trailer/Total rows on crew cards: one line per shift,
   each led by its "Shift N" pill. */
.dynamic-counts .count-shifts {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
}
.dynamic-counts .count-shift-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
/* Field / Trailer chips — orange accent pills so the subtotals stand out
   from the muted count breakdown text (which stays as-is). */
.count--field,
.count--trailer {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 999px;
  border: 1px solid var(--accent);
  color: var(--accent);
  font-weight: 700;
  white-space: nowrap;
}
/* Named non-field positions in a crew (Safety, PM, …): boots on the ground,
   counted by name so they never inflate the Field number. Neutral pill so
   the orange Field chip stays the headline. */
.count--pos {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 999px;
  border: 1px solid #5c6470;
  color: #cfd6df;
  font-weight: 700;
  white-space: nowrap;
}
/* Job Totals on the job detail page — Field pill + per-position color-dot
   key (office staff included). No composition bar: the dots are the
   breakdown. */
#job-totals { flex: 1 1 320px; min-width: 280px; }
.jt-legend {
  flex-wrap: wrap; justify-content: flex-start;
  align-items: center; gap: 3px 12px;
}
/* Total pill on Job Totals — full headcount, field + non-field, white. */
.count--total {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 999px;
  border: 1px solid #e8eaee;
  color: #f3f5f7;
  font-weight: 700;
  white-space: nowrap;
}
/* Project GC pill on crew cards — Field-chip format, always white. */
.count--gc {
  display: inline-block;
  padding: 0 8px;
  border-radius: 999px;
  border: 1px solid #e8eaee;
  color: #f3f5f7;
  font-size: .72rem;
  font-weight: 700;
  white-space: nowrap;
}
/* Crew card titles: a touch bigger than the stock h5. */
.list-card .list-title { font-size: 1.4rem; }

/* Side rails (Management/Office + Unassigned bench): sit beside the crew
   grid; collapse to a slim vertical tab so the crew columns get the width
   back. The two rails share one mechanic. */
.crew-board-flex { display: flex; gap: 1rem; align-items: flex-start; width: 100%; }
.crew-board-flex > .board-grid { flex: 1 1 auto; min-width: 0; }
.unassigned-rail, .mgmt-rail {
  flex: 0 0 330px; min-width: 0; position: relative; overflow: hidden;
  transition: flex-basis .28s ease;
}
.unassigned-rail .list-card, .mgmt-rail > .card { transition: opacity .18s ease; min-width: 300px; }
.unassigned-rail.collapsed, .mgmt-rail.collapsed { flex-basis: 36px; }
.unassigned-rail.collapsed .list-card, .mgmt-rail.collapsed > .card { opacity: 0; visibility: hidden; }
/* Collapsed bar: one smooth continuous strip, full column height, with the
   label in upright (unrotated) letters reading downward. */
.bench-tab {
  position: absolute; inset: 0;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 14px 0; border: 1px solid var(--border, #2d2d32);
  border-radius: 10px; background: #15171b; color: #f3f5f7;
  cursor: pointer; opacity: 0; pointer-events: none;
  transition: opacity .18s ease .12s, border-color .12s ease;
}
.unassigned-rail.collapsed .bench-tab, .mgmt-rail.collapsed .bench-tab { opacity: 1; pointer-events: auto; }
.bench-tab:hover { border-color: var(--accent, #ff7a00); }
.bench-tab-text {
  writing-mode: vertical-rl;   /* rotated 90° — letters read sideways */
  font-size: .82rem; font-weight: 700; letter-spacing: .08em;
  white-space: nowrap; user-select: none;
}
@media (max-width: 900px) {
  .crew-board-flex { flex-direction: column; }
  /* Stacked layout: the rails are normal blocks; flex-basis would become
     HEIGHT here, so neutralize it (incl. the collapsed 36px) or a
     collapsed rail leaves a tall empty box behind. */
  .unassigned-rail, .unassigned-rail.collapsed,
  .mgmt-rail, .mgmt-rail.collapsed {
    flex: 0 0 auto; width: 100%; height: auto; min-height: 0;
    transition: none; overflow: visible;
  }
  .unassigned-rail .list-card, .mgmt-rail > .card { min-width: 0; }
  /* !important: must outgun "#pane-crews .list-card { display:flex }" */
  .unassigned-rail.collapsed .list-card,
  .mgmt-rail.collapsed > .card { display: none !important; }
  /* Collapsed rail = one full-width slim bar, horizontal label. */
  .bench-tab {
    position: static; display: none; width: 100%;
    align-items: center; justify-content: center; padding: 9px 0;
    opacity: 1; pointer-events: auto; transition: border-color .12s ease;
  }
  .unassigned-rail.collapsed .bench-tab,
  .mgmt-rail.collapsed .bench-tab { display: flex; }
  .bench-tab-text { writing-mode: horizontal-tb; text-orientation: mixed; }
}

/* Keep the Unassigned/Management collapse (skinny) behavior, but make the
   collapsed rail span the FULL height of the crew columns beside it so the
   skinny bar matches the column length instead of sitting short at the top.
   align-self overrides the row's flex-start just for the collapsed rails. */
.crew-board-flex > .unassigned-rail.collapsed,
.crew-board-flex > .mgmt-rail.collapsed { align-self: stretch; }
@media (max-width: 900px) {
  /* Stacked layout: cross-axis is width; stretch would do nothing useful and
     the rails are already full width — keep natural height. */
  .crew-board-flex > .unassigned-rail.collapsed,
  .crew-board-flex > .mgmt-rail.collapsed { align-self: auto; }
}

/* Crew cards take their natural height: the column grows to fit its people so
   a tall display shows a longer list instead of an internal scrollbar. Lists
   only scroll internally as a last resort on small screens (see the media
   query override below). */
.list-card[data-list-type="crew"] {
  display: flex;
  flex-direction: column;
  max-height: none;
}
.list-card[data-list-type="crew"] > .card-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: visible;
}
.list-card[data-list-type="crew"] .shift-segment {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 0 1 auto;
}
.shift-dropzone,
.shift-segment .people-list.dropzone {
  flex: 0 1 auto;
  min-height: 40px;                  /* always a usable drop target */
  max-height: none;                  /* grow with content — no internal scroll */
  overflow-y: visible;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.shift-dropzone::-webkit-scrollbar,
.shift-segment .people-list.dropzone::-webkit-scrollbar { width: 6px; }
.shift-dropzone::-webkit-scrollbar-thumb,
.shift-segment .people-list.dropzone::-webkit-scrollbar-thumb {
  background: #3a3f47; border-radius: 4px;
}
/* Category labels ("Shift 1:", "Totals:") — headings for the row's pills,
   not totals themselves, so plain muted text rather than a pill. */
.dynamic-counts .count-cat {
  color: var(--muted);
  font-weight: 600;
  white-space: nowrap;
  margin-right: 2px;
}

/* ============================================================
   Union-book highlight rings for employee cards on the job board.
   Applied via {{ employee|book_class:job }} (crews/templatetags/book_tags.py).
   - book-1: same local as the job (green)
   - book-2: traveler from another local (blue)
   - book-4: outside-union permit hire (orange)
   - (empty class for salary employees / job without a local set)
   ============================================================ */
.person.book-1 {
  box-shadow: inset 0 0 0 2px var(--book-1,#21c55d), 0 0 8px rgba(33,197,93,.35);
  border-radius: 10px;
}
.person.book-2 {
  box-shadow: inset 0 0 0 2px var(--book-2,#3b82f6), 0 0 8px rgba(59,130,246,.35);
  border-radius: 10px;
}
.person.book-4 {
  box-shadow: inset 0 0 0 2px var(--book-4,#f97316), 0 0 8px rgba(249,115,22,.35);
  border-radius: 10px;
}

/* Legend pills (used in the job board header to explain the rings) */
.book-legend {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-left: 8px;
}
.book-legend .legend-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: .72rem;
  font-weight: 600;
  color: #cfd6dd;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px;
}
.book-legend .legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}
.book-legend .legend-dot.book-1 { background: var(--book-1,#21c55d); box-shadow: 0 0 6px rgba(33,197,93,.6); }
.book-legend .legend-dot.book-2 { background: var(--book-2,#3b82f6); box-shadow: 0 0 6px rgba(59,130,246,.6); }
.book-legend .legend-dot.book-4 { background: var(--book-4,#f97316); box-shadow: 0 0 6px rgba(249,115,22,.6); }

/* Counts row inside crew/unassigned cards */
.list-card .counts{
  display:flex; gap: 10px; flex-wrap: wrap; color: #cfd6dd;
}
.list-card .counts .count b{ color: var(--accent); }

/* Drag & drop affordances */
.list-card.drag-over{
  outline: 2px dashed var(--accent);
  outline-offset: -6px;
}
.person.dragging{
  opacity: .75;
  transform: scale(.98);
}

/* Tables (if any) ---------------------------------------- */
.table{
  --bs-table-bg: var(--surface);
  --bs-table-color: var(--text);
  --bs-table-border-color: var(--border);
  color: var(--text);
  border-color: var(--border);
}
.table thead th{
  color: var(--text);
  border-bottom-color: var(--border);
}
.table tbody td{
  border-top-color: var(--border);
}

/* Toasts / alerts (Bootstrap) ---------------------------- */
.alert{
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
}
.alert-primary{
  background: color-mix(in srgb, var(--brand-primary,#ff7a00) 10%, transparent);
  border-color: color-mix(in srgb, var(--brand-primary,#ff7a00) 40%, transparent);
  color: var(--text);
}

/* Footer / minor UI -------------------------------------- */
hr{ border-color: var(--border); opacity: 1; }
code, pre{ color: #ffe0c2; }

/* Small helpers ------------------------------------------ */
.bg-accent{ background: var(--accent) !important; color: #0b0b0c !important; }
.text-accent{ color: var(--accent) !important; }
.border-accent{ border-color: var(--accent) !important; }

/* Make cards breathe a bit on small screens */
@media (max-width: 480px){
  .job-grid{ grid-template-columns: 1fr; }
  .job-card{ padding: 12px; }
}

/* === Layout for job page: left sidebar + right board === */
.job-layout{
  display:grid;
  grid-template-columns: 320px 1fr;
  gap:16px;
}
@media (max-width: 991.98px){
  .job-layout{ grid-template-columns: 1fr; }
  #leftSidebar{ order: 2; }
}

/* Make entire crew card feel like a drop zone */
.drop-host { position: relative; }
.drop-host.drag-over,
.people-list.dropzone.drag-over{
  outline: 2px dashed var(--accent);
  outline-offset: -6px;
}
.people-list.dropzone{
  min-height: 56px;           /* bigger target */
  padding-bottom: 4px;
}

/* Slight spacing for the counts row */
.list-card .counts { margin-top: 2px; }

/* ======================================================================
   APPENDED: Tools & Rentals item cards + Tabs (kept dark theme)
   ====================================================================== */
.item-card{
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
  cursor: grab;
  transition: border-color .12s ease, transform .08s ease, box-shadow .08s ease;
}
.item-card:hover{ border-color: var(--accent); }
.item-card.dragging{
  opacity: .8;
  transform: scale(.98);
  box-shadow: 0 8px 18px var(--shadow);
}
.item-card .top{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.item-card .top .fw-semibold{ color: var(--text); }
.item-card .top .text-muted{ color: var(--muted) !important; }

/* ToolVault-style tool cards on the Job Board live in crews_job_detail.css
   (single canonical definition). The duplicate block that used to be here was
   removed to end the override conflict. */

/* Tabs */
.nav-tabs{
  border-bottom: 1px solid var(--border);
}
.nav-tabs .nav-link{
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
}
.nav-tabs .nav-link:hover{
  color: var(--accent);
  border-color: transparent;
}
.nav-tabs .nav-link.active{
  color: var(--text);
  background: var(--surface);
  border-color: var(--border) var(--border) var(--surface);
}



/* ======================================================================
   APPENDED: Responsive full-width grid for Crews pane (TV-friendly)
   ====================================================================== */
:root{
  /* Adjust this to control min tile width (more columns if smaller) */
  --crew-col-min: 320px;
}

/* Make the crews page span nearly the full viewport width */
#pane-crews .container,
#pane-crews .container-fluid{
  max-width: 98vw !important;
  width: 100% !important;
  padding-left: 8px;
  padding-right: 8px;
}

/* Turn the crews row into a CSS Grid that auto-fills horizontally */
#pane-crews .row.g-3{
  display: grid !important; /* override Bootstrap's flex row */
  grid-template-columns: repeat(auto-fill, minmax(var(--crew-col-min), 1fr)) !important;
  gap: 12px !important;     /* mirrors Bootstrap g-3 spacing */
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
}

/* Let grid handle sizing instead of Bootstrap's col classes */
#pane-crews .row.g-3 > [class*="col-"]{
  width: 100% !important;
  max-width: none !important;
  flex: 0 0 auto !important;
}

/* Ensure each crew card stretches within its grid cell */
#pane-crews .list-card{
  height: 100%;
  display: flex;
  flex-direction: column;
}
#pane-crews .list-card .card-body{ padding: .75rem; }
#pane-crews .people-list{ min-height: 2.25rem; }

/* Optional: scale tile minimum width on very large displays */
@media (min-width: 1600px){
  :root{ --crew-col-min: 360px; }
}



/* ======================================================================
   OVERRIDES — Responsive, clean expansion for Crew cards (TV-friendly)
   ----------------------------------------------------------------------
   Goals:
   - Cards **expand** as the window grows; never squished.
   - Auto-fit columns with a comfortable minimum width.
   - Use available horizontal space cleanly, with even breathing room.
   - No JS changes; DnD unaffected.
   - Scoped to the Crews pane only.
   ====================================================================== */

/* Use nearly the full viewport width on the crews pane */
#pane-crews .container,
#pane-crews .container-fluid{
  max-width: 100vw !important;
  width: 100% !important;
  padding-left: 8px;
  padding-right: 8px;
}

/* Turn the Bootstrap row into a CSS Grid that expands gracefully.
   - auto-fit chooses how many columns fit without squishing.
   - min 360px keeps each tile comfortable.
   - 1fr lets tiles *grow* to fill negative space (no awkward gaps). */
#pane-crews .row.g-3{
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)) !important;
  gap: 16px !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
}

/* Let the grid handle sizing instead of Bootstrap column widths */
#pane-crews .row.g-3 > [class*="col-"]{
  width: 100% !important;
  max-width: none !important;
  flex: 0 0 auto !important;
}

/* Make each crew card stretch and breathe */
#pane-crews .list-card{
  min-height: 120px;
  height: 100%;
  display: flex;
  flex-direction: column;
}
#pane-crews .list-card .card-body{ padding: .9rem; }
#pane-crews .people-list{ min-height: 2.4rem; }

/* On ultra-wide displays, gently increase spacing */
@media (min-width: 1920px){
  #pane-crews .row.g-3{ gap: 20px !important; }
}



/* ======================================================================
   FULL-BLEED CREWS BOARD (use entire viewport width cleanly)
   - #crew-page wrapper breaks out of any parent .container max-width
   - Uses CSS Grid on the crews row to expand cards naturally
   - Keeps DnD intact (layout-only)
   ====================================================================== */

/* Make the page wrapper go full-bleed across the viewport */
#crew-page{
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-left: 12px;
  padding-right: 12px;
}

/* If any ancestor .container tries to clamp width, squash it under our scope */
#crew-page .container,
#crew-page .container-sm,
#crew-page .container-md,
#crew-page .container-lg,
#crew-page .container-xl,
#crew-page .container-xxl{
  max-width: 100% !important;
  width: 100% !important;
  padding-left: 0;
  padding-right: 0;
}

/* Tabs/content should also stretch */
#crew-page .tab-content,
#crew-page .nav-tabs{
  max-width: 100% !important;
  width: 100% !important;
}

/* Turn the crews row into an expanding grid */
#crew-page #pane-crews .row.g-3{
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)) !important;
  gap: 16px !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
}

/* Let the grid own sizing of columns */
#crew-page #pane-crews .row.g-3 > [class*="col-"]{
  width: 100% !important;
  max-width: none !important;
  flex: 0 0 auto !important;
}

/* Make crew cards fill their grid cells and breathe */
#crew-page #pane-crews .list-card{
  height: 100%;
  display: flex;
  flex-direction: column;
}
#crew-page #pane-crews .list-card .card-body{ padding: .9rem; }
#crew-page #pane-crews .people-list{ min-height: 2.25rem; }

/* Slightly larger gap on very wide displays for a clean look */
@media (min-width: 1920px){
  #crew-page #pane-crews .row.g-3{ gap: 20px !important; }
}


/* === Apply same responsive grid to Bus Plugs & Materials panes === */
#pane-busplugs .row.g-3,
#pane-materials .row.g-3,
#pane-tools .row.g-3,
#pane-rentals .row.g-3{
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)) !important;
  gap: 16px !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  width: 100% !important;
}
#pane-busplugs .row.g-3 > [class*="col-"],
#pane-materials .row.g-3 > [class*="col-"],
#pane-tools .row.g-3 > [class*="col-"],
#pane-rentals .row.g-3 > [class*="col-"]{
  width: 100% !important;
  max-width: none !important;
  flex: 0 0 auto !important;
}

/* Make board cards stretch and keep internals tidy */
.list-card.card {
  display: flex;
  flex-direction: column;
}
.list-card .card-body {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

/* Reduce extra padding on dense boards (optional) */
.list-card .card-body {
  padding: .75rem .9rem;
}

/* Keep titles from wrapping too wildly */
.list-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Tighten “counts” line on small screens */
@media (max-width: 576px) {
  .counts {
    flex-wrap: wrap;
    gap: .5rem !important;
  }
}
/* Viewport that fills the screen (no scroll). Adjust offset if your header is taller/shorter. */
.fit-wrapper {
  --header-offset: 148px;              /* tweak to match your header area */
  width: 100%;
  height: calc(100vh - var(--header-offset));
  overflow: hidden;                    /* we will scale the strip to avoid scroll */
  position: relative;
}

/* One long horizontal row of fixed-width columns */
.crews-strip {
  display: flex;
  gap: 1rem;
  align-items: stretch;
  flex-wrap: nowrap;                   /* <-- critical: single row, no wrap */
  transform-origin: 0 0;               /* scale from top-left in JS */
  will-change: transform;
}

/* Each column gets a fixed base width; change if you want larger/smaller tiles */
.crew-col {
  flex: 0 0 280px;                     /* width per column; change 280 to taste */
}

/* Make cards fill their column */
.list-card.card { height: 100%; display: flex; flex-direction: column; }
.list-card .card-body { display: flex; flex-direction: column; gap: .5rem; }

/* Keep titles neat */
.list-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.board-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  width: 100%;
}

/* Make Bootstrap .col-* work as grid items even without a .row */
.board-grid > [class*="col-"]{
  width: 100% !important;
  max-width: none !important;
  flex: 0 0 auto; /* stop Bootstrap's flex rules */
}

/* Make sure tab panes themselves don’t constrain width */
.tab-content, 
#pane-tools, #pane-rentals, #pane-busplugs, #pane-materials {
  width: 100%;
}

.tab-pane .list-card{
  height: 100%;
  display: flex;
  flex-direction: column;
}

/* Put counts under the crew title without changing HTML structure */
#pane-crews .card-body > .d-flex.align-items-center.justify-content-between.mb-2 {
  flex-wrap: wrap;
  gap: 4px 8px;
}
#pane-crews .card-body > .d-flex.align-items-center.justify-content-between.mb-2 .list-title {
  flex: 1 1 auto;
}
#pane-crews .card-body > .d-flex.align-items-center.justify-content-between.mb-2 .counts {
  width: 100%;
  order: 2;
  margin-top: 2px;
}

/* Let crew names wrap fully (fixes truncated titles only on Crews tab) */
#pane-crews .list-title {
  white-space: normal;
  overflow: visible;
  text-overflow: initial;
}

/* Transfers: subtle timeline + green completion badge (UI-only) */
.tr-timeline {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 12px;
  color: var(--muted);
}
@media (max-width: 480px) {
  .tr-timeline { grid-template-columns: 1fr; }
}

/* Card outline + checkmark when fully received (status=received) */
.tr-complete {
  box-shadow: 0 0 0 1px #2ecc71 inset;
  border-color: #2ecc71 !important;
}
.tr-complete-badge {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #2ecc71;
  color: #0b0b0c;
  display: grid;
  place-items: center;
  font-weight: 900;
  line-height: 1;
}

/* Transfers cards with status styling */
.tr-card{
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: .75rem .9rem;
  box-shadow: 0 6px 20px var(--shadow);
}
.tr-title { font-weight: 600; color: var(--text); }
.tr-meta  { font-size: .875rem; color: var(--muted); }

/* Pending: yellow outline + hourglass */
.tr-card.pending{
  border-color: #f7c948;
  box-shadow: 0 0 0 .15rem rgba(247,201,72,.25);
}
.tr-card.pending::after{
  content: "⌛";
  position: absolute; top: .4rem; right: .5rem;
  font-size: 1rem; opacity: .9;
}

/* Completed: subtle check mark */
.tr-card.completed::after{
  content: "✓";
  position: absolute; top: .4rem; right: .5rem;
  font-weight: 700; opacity: .85;
}

/* Denied: red border + X */
.tr-card.denied{
  border-color: #dc3545;
  box-shadow: 0 0 0 .15rem rgba(220,53,69,.2);
  background: color-mix(in srgb, #dc3545 6%, var(--surface));
}
.tr-card.denied::after{
  content: "✕";
  position: absolute; top: .4rem; right: .5rem;
  font-weight: 700; color: #dc3545; opacity: .9;
}

/* Completed: green outline + ✓ */
.tr-card.completed,
.tr-card.tr-complete,           /* back-compat if old class still present */
.tr-card.border-success {       /* back-compat if Bootstrap class was used */
  border-color: #198754;        /* Bootstrap "success" green */
  box-shadow: 0 0 0 .15rem rgba(25,135,84,.25);
  /* Optional subtle tint; remove if you want pure background */
  background: color-mix(in srgb, #198754 6%, var(--bs-body-bg));
}
.tr-card.completed::after,
.tr-card.tr-complete::after,
.tr-card.border-success::after {
  content: "✓";
  position: absolute;
  top: .4rem;
  right: .5rem;
  font-weight: 700;
  opacity: .85;
}

/* NOTE: PreFab status card visuals now live in crews_job_detail.css (to avoid duplication) */
#jobTabsContent > .tab-pane { display: none !important; }
#jobTabsContent > .tab-pane.active.show { display: block !important; }

/* Search form cleanup */
.mv-search-form .form-label {
  font-weight: 500;
  color: var(--bs-secondary-color, #888);
}
.mv-search-form input, .mv-search-form select {
  height: 36px;
  font-size: 0.9rem;
}
.mv-search-form .btn {
  height: 36px;
  font-weight: 600;
}

.ring-focus { outline: 3px solid var(--brand-primary,#ff7a00); outline-offset: 2px; border-radius: 8px; }

/* crewhierarchy/static/crewhierarchy/tree.css */

/* Container width and breathing room */
.ch-wrap { padding: 0.75rem; }

/* Rail above the tree for PM (parallel) */
.ch-rail {
  margin-bottom: 1rem;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: .6rem;
  background: rgba(255,255,255,.02);
}
.ch-rail-title {
  font-size: .85rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  opacity: .75;
  padding: .5rem .75rem .25rem;
}
.ch-rail-row {
  padding: .25rem .75rem .75rem;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

/* Generic tree rows */
.ch-row { margin-bottom: 1.25rem; }
.ch-row-title {
  font-size: .85rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  opacity: .75;
  margin: 0 .5rem .25rem;
}
.ch-row-nodes {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  justify-content: center;   /* center like the screenshot */
}

/* Gold-ish connectors between rows, subtle */
.ch-row-connector {
  height: 14px;
  position: relative;
  margin: .25rem auto 0;
  width: clamp(200px, 50%, 540px);
}
.ch-row-connector::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 6px;
  height: 2px;
  background: linear-gradient(90deg, rgba(255,193,7,.15), rgba(255,193,7,.45), rgba(255,193,7,.15));
  border-radius: 2px;
}

/* Crew grid (cards on bottom row) */
.ch-crew-grid {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}
.ch-crew-card {
  border: 1px solid rgba(255,255,255,.08);
  border-radius: .75rem;
  background: rgba(255,255,255,.02);
  padding: .5rem .6rem .65rem;
  position: relative;
}
.ch-crew-head {
  padding-bottom: .35rem;
  border-bottom: 1px dashed rgba(255,255,255,.12);
  margin-bottom: .35rem;
  display: flex;
  align-items: baseline;
  gap: .25rem;
}
.ch-crew-name { font-weight: 600; }
.ch-crew-loc { opacity: .75; }

.ch-crew-rail {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  padding-top: .25rem;
}
.ch-crew-rail--foremen {
  /* light underline separator to echo screenshot “pill rows” */
  padding-bottom: .25rem;
  border-bottom: 1px dashed rgba(255,255,255,.08);
  margin-bottom: .25rem;
}

/* Node wrapper so your employee badge can drop in */
.ch-node {
  display: inline-flex;
  align-items: stretch;
}

/* Optional: small polish if your badge does not span full height */
.ch-node > * {
  border-radius: .75rem; /* soften corners like the screenshot pills */
}

/* Responsive helpers */
@media (max-width: 720px) {
  .ch-row-connector { width: 70%; }
}

/* universal "Previous page" link */
.back-link {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px;                       /* gloved-thumb touch floor */
  margin: 4px 0 12px; padding: 6px 14px 6px 10px;
  border-radius: 999px;
  border: 1px solid var(--border, #23252b);
  color: var(--muted, #9aa3ae);
  font-size: .85rem; font-weight: 600;
  transition: color .12s ease, border-color .12s ease, transform .12s ease;
}
.back-link svg { width: 16px; height: 16px; }
.back-link:hover {
  color: var(--brand-primary, #ff7a00);
  border-color: var(--brand-primary, #ff7a00);
  transform: translateY(-1px);
}

/* Weekend availability toggle ------------------------------------------------ */
.wk-toggle-wrap {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: auto;
  flex-shrink: 0;
  vertical-align: middle;
}
.wk-toggle-wrap .wk-label {
  font-size: 0.6rem;
  font-weight: 700;
  color: var(--muted);
  user-select: none;
}
.wk-toggle {
  display: inline-block;
  position: relative;
  width: 30px;
  height: 16px;
  border-radius: 8px;
  cursor: pointer;
  background: #3a3d44;
  border: none;
  user-select: none;
  vertical-align: middle;
  transition: background .2s;
  flex-shrink: 0;
}
.wk-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #888;
  transition: transform .2s, background .2s;
}
.wk-toggle:hover {
  background: #4a4d54;
}
.wk-toggle.wk-on {
  background: #2e7d32;
}
.wk-toggle.wk-on::after {
  transform: translateX(14px);
  background: #81c784;
}

/* Weekend shift badges (weekend board) ---------------------------------------- */
.wk-shift-badge {
  display: inline-block;
  font-size: 0.55rem;
  font-weight: 700;
  padding: 0 4px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--brand-primary,#ff7a00) 20%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--brand-primary,#ff7a00) 35%, transparent);
  vertical-align: middle;
  margin-left: 2px;
}

/* Weekend tier labels --------------------------------------------------------- */
.wk-tier-label {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  padding: 4px 0 2px;
  margin-top: 6px;
  border-bottom: 1px solid var(--border);
}
.wk-tier-label:first-child {
  margin-top: 0;
}

/* Weekend summary panel ------------------------------------------------------- */
#wk-summary-panel .card-header {
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
#wk-summary-body .row > div {
  border-right: 1px solid var(--border);
}
#wk-summary-body .row > div:last-child {
  border-right: none;
}
/* ======================================================================
   MOBILE / SMALL-SCREEN PASS (applies app-wide via base.html)
   Desktop-size chrome reads "zoomed in" on a phone, so the root font
   steps down (everything rem-based scales with it), the navbar collapses
   to one compact row, tab strips become wrapping chips instead of
   broken half-tabs, and dropdown menus are clamped to the viewport.
   ====================================================================== */
@media (max-width: 991.98px){
  html { font-size: 14px; }

  /* --- Navbar: one tight row; dropdowns can never run off screen --- */
  .navbar { row-gap: 2px; padding-top: .35rem; padding-bottom: .35rem; }
  .navbar .navbar-brand img { height: 28px; width: 28px; }
  .navbar .ms-auto { gap: .5rem !important; }
  .navbar .dropdown-menu {
    max-width: calc(100vw - 16px);
    max-height: 70vh;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .navbar .dropdown-menu .dropdown-item { white-space: normal; }

  /* Apps menu: Bootstrap makes navbar-nav dropdowns position:static below
     the lg breakpoint, which inflates the whole header when opened. Float
     it over the page instead. */
  .navbar .navbar-nav .nav-item.dropdown { position: relative; }
  .navbar .navbar-nav .dropdown-menu {
    position: absolute;
    top: 100%; left: auto; right: 0;   /* the Apps item sits right of the brand */
    z-index: 1050;
    margin-top: .3rem;
    box-shadow: 0 14px 32px rgba(0,0,0,.55);
  }

  /* --- Tab strips (Job page, Forecasting, etc.): the stock underlined
     tabs wrap into ragged rows on a phone, so present them as a tidy
     chip cloud. Active chip = brand accent. --- */
  .nav-tabs { gap: 6px; border-bottom: 0; }
  .nav-tabs .nav-item { margin: 0; }
  .nav-tabs .nav-link {
    padding: .32rem .65rem;
    font-size: .88rem;
    border: 1px solid var(--border) !important;
    border-radius: 999px;
    color: var(--text);
    background: var(--surface-2);
    white-space: nowrap;
  }
  .nav-tabs .nav-link.active {
    background: var(--accent);
    border-color: var(--accent) !important;
    color: #0b0b0c;
    font-weight: 700;
  }

  /* --- Page chrome: reclaim padding the phone can't spare --- */
  main.py-4 { padding-top: .65rem !important; padding-bottom: .75rem !important; }
  .container, .container-fluid { padding-left: .75rem; padding-right: .75rem; }
  .back-link { margin: 2px 0 8px; padding: 4px 8px; font-size: .85rem; }

  /* Job totals header card: tighter, legend wraps below the pills */
  .book-legend { margin-left: 0 !important; width: 100%; }

  /* Crew cards may use the full viewport height on a phone */
  .list-card[data-list-type="crew"] { max-height: none; }
  .list-card .list-title { font-size: 1.2rem; }
}

@media (max-width: 480px){
  html { font-size: 13px; }
  .jc-hero-num { font-size: 1.7rem; }
  .jc-metric-num { font-size: 1.1rem; }
}

/* ======================================================================
   SAFETY — Lock Vault & Equipment card grids (ToolVault/MaterialVault
   pattern: each row is a card; the lock card is the link to the lock
   profile and lights up in brand color on hover). Long lists scroll
   inside the pane instead of stretching the page.
   ====================================================================== */
.saf-scroll {
  max-height: 68vh;
  overflow-y: auto;
  overflow-x: hidden;          /* the row's negative gutters must not scroll */
  overscroll-behavior: contain;
  scrollbar-width: thin;
  /* absorb .row.g-3's -0.5rem side margins so nothing pokes out */
  padding: 0 .5rem 0 .5rem;
}
.saf-scroll::-webkit-scrollbar { width: 6px; }
.saf-scroll::-webkit-scrollbar-thumb { background: #3a3f47; border-radius: 4px; }

.lock-card { cursor: pointer; transition: border-color .12s ease, transform .12s ease; }
.lock-card:hover { border-color: var(--accent, #ff7a00); transform: translateY(-2px); }
/* Let the text column shrink inside the flex card instead of forcing width */
.lock-card .flex-fill { min-width: 0; overflow-wrap: anywhere; }
.lock-qr-img {
  border-radius: 8px; border: 1px solid #2d2d32;
  background: #fff; padding: 4px; flex: 0 0 auto;
}
/* Obscured QR tile: shown in place of the code while the lock is applied */
.lock-qr-hidden {
  width: 96px; height: 96px; flex: 0 0 auto;
  border-radius: 8px; border: 1px dashed #3a3f47; background: #15171b;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; text-align: center; color: var(--muted); font-size: .58rem; padding: 6px;
}
.lock-qr-hidden .lqh-emoji { font-size: 1.35rem; line-height: 1; }

.eq-card { transition: border-color .12s ease; }
.eq-card:hover { border-color: #3f444c; }

/* Round icon actions on cards (view / print …): neutral grey ring that
   lights up brand-orange on hover, with a hover label pill underneath. */
.card-act {
  position: relative;
  width: 30px; height: 30px; border-radius: 50%;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border, #2d2d32);
  background: #1b1e24;
  color: var(--muted, #9aa3ae);
  text-decoration: none;
  transition: border-color .12s ease, color .12s ease, transform .12s ease;
  flex: 0 0 auto;
}
.card-act svg { width: 14px; height: 14px; }
.card-act:hover {
  border-color: var(--accent, #ff7a00);
  color: var(--accent, #ff7a00);
  transform: translateY(-1px);
}
.card-act::after {
  content: attr(data-tip);
  position: absolute; top: calc(100% + 6px); left: 50%;
  transform: translateX(-50%) translateY(-3px);
  background: #1b1e24; color: #f3f5f7;
  border: 1px solid #2d2d32; border-radius: 999px;
  padding: 2px 9px; font-size: .68rem; font-weight: 600;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .14s ease, transform .14s ease;
  z-index: 5;
}
.card-act:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Collapsible filter sections: slim pill that toggles the filter form
   (used by MaterialVault and the safety hub panes). Orange when open or
   when filters are active so applied filters are never invisible. */
.filter-toggle {
  border: 1px solid var(--border, #2d2d32);
  border-radius: 999px;
  color: var(--text, #e9edf1);
  background: var(--surface-2, #1a1c20);
  display: inline-flex;
  align-items: center;
  transition: border-color .12s ease, color .12s ease;
}
.filter-toggle:hover,
.filter-toggle.active {
  border-color: var(--accent, #ff7a00);
  color: var(--accent, #ff7a00);
}
.filter-toggle .filter-caret { transition: transform .18s ease; }
.filter-toggle[aria-expanded="true"] .filter-caret { transform: rotate(180deg); }

/* Brand-orange round icon action with a hover label pill (CrewTracker
   primary actions, e.g. New Crew). Same language as .saf-act/.card-act. */
.brand-act {
  position: relative;
  z-index: 5;
  width: 38px; height: 38px; border-radius: 50%; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--accent, #ff7a00);
  background: var(--surface-2, #1a1c20);
  color: var(--accent, #ff7a00);
  cursor: pointer;
  transition: transform .12s ease, box-shadow .18s ease, background .12s ease,
              color .12s ease;
}
.brand-act svg { width: 18px; height: 18px; }
.brand-act:hover, .brand-act:focus-visible {
  z-index: 1100;   /* the hover label bubble must ride over sibling cards */
}
.brand-act:hover {
  transform: translateY(-2px);
  background: var(--accent-2, #ffa24a);
  border-color: var(--accent-2, #ffa24a);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--brand-primary,#ff7a00) 35%, transparent);
  color: #0b0b0c;
}
.brand-act::after {
  content: attr(data-tip);
  position: absolute; top: calc(100% + 7px); left: 50%;
  transform: translateX(-50%) translateY(-3px);
  background: #1b1e24; color: #f3f5f7;
  border: 1px solid #2d2d32; border-radius: 999px;
  padding: 3px 10px; font-size: .72rem; font-weight: 600;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .14s ease, transform .14s ease;
  z-index: 1075;
}
.brand-act:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }
/* No label pill while the button's dropdown is open — on touch the tap
   leaves the button "hovered", so the pill lingered over the open sheet
   and could clip at the screen edge. */
.brand-act[aria-expanded="true"]::after { opacity: 0 !important; }

/* Create Job dropdown panel (job board) */
.job-create-menu { min-width: 340px; max-height: 80vh; overflow-y: auto; }
.job-create-menu .form-label { font-size: .78rem; font-weight: 600; }

/* Apps menu: the active (current app) item follows the brand primary instead
   of Bootstrap's blue, so it re-skins automatically when the theme/branding
   palette changes (Admin → Branding sets --brand-primary). */
.navbar .dropdown-menu .dropdown-item.active,
.navbar .dropdown-menu .dropdown-item:active {
  background-color: var(--brand-primary, #ff7a00);
  color: var(--brand-on-primary, #0b0b0c);
}

/* Segmented toggle (filters / view modes, all tabs): exactly the Labor
   Curve / Forecasting selector — compact outline group whose active segment
   fills with the brand color. One class, used everywhere. */
.seg-toggle { flex-wrap: wrap; row-gap: 4px; }
.seg-toggle .btn {
  font-size: .8rem;
  font-weight: 600;
  flex: 0 0 auto;
}
.seg-toggle .btn.active {
  background: var(--brand-primary, #ff7a00) !important;
  border-color: var(--brand-primary, #ff7a00) !important;
  color: var(--brand-on-primary, #0b0b0c) !important;
  font-weight: 700;
}

/* Dropdown form panels (Add Reel / Add Stock Material / New Crew / Create
   Job): sized for phones — never wider than the screen, scrolls if tall. */
.form-drop {
  min-width: min(92vw, 340px);
  max-width: 96vw;
  max-height: 75vh;
  overflow-y: auto;
  margin-inline-end: 16px;   /* air off the screen edge — native select
                                popups inside don't get clipped */
}
.form-drop .form-select { text-overflow: ellipsis; }
.form-drop--wide { min-width: min(96vw, 560px); }

/* In-panel catalog picker (cat_picker.js): the option list renders inside
   the form-drop panel instead of a native <select> popup, so it can never
   hang off the viewport; long entries wrap, the list scrolls. */
.cat-picker-list {
  max-height: 240px;
  overflow-y: auto;
  margin-top: 6px;
  border: 1px solid var(--border, #2d2d32);
  border-radius: 8px;
  background: var(--surface-2, #1a1c20);
}
.cat-picker-item {
  display: block; width: 100%; text-align: left;
  background: none; border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border, #2d2d32) 60%, transparent);
  color: var(--text, #e9edf1);
  font-size: .85rem; padding: 6px 10px; cursor: pointer;
  white-space: normal; overflow-wrap: anywhere;  /* nothing gets cut off */
}
.cat-picker-item:last-child { border-bottom: 0; }
.cat-picker-item:hover {
  background: color-mix(in srgb, var(--brand-primary, #ff7a00) 14%, transparent);
}
.cat-picker-item.active {
  background: var(--brand-primary, #ff7a00);
  color: var(--brand-on-primary, #0b0b0c);
  font-weight: 600;
}
.cat-picker-empty { padding: 6px 10px; }

/* Filter toggles use the shared .filter-toggle + Bootstrap collapse
   pattern (see MaterialVault). Area chips keep .reel-chip below. */
.reel-filter-toggle .tog-caret {
  display: inline-block; transition: transform .15s ease;
  transform: rotate(-90deg);
}
.reel-filter-toggle[aria-expanded="true"] .tog-caret { transform: rotate(0deg); }
.reel-search { max-width: 280px; }

/* Reel card feed lists: bold FED FROM / FED TO labels with the equipment
   names stacked beneath — long tags wrap inside the card instead of
   overflowing, lists stay clean, and blocks cap at three names (+N more)
   so every card keeps a professional, bounded size. */
/* Reel card typography (ReelVault board + Materials tab share these):
   big title for fast navigation, a hero "live length", small single-line
   wire type. */
/* Procurement status pill on reel cards (Pending grey / Ordered amber /
   On Site green) — small, no extra card height. */
.reel-proc {
  display: inline-block; padding: 0 7px; border-radius: 999px;
  font-size: .6rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .03em; line-height: 1.5; white-space: nowrap;
}
.reel-proc--pending { background: #6b7280; color: #fff; }
.reel-proc--ordered { background: #f59e0b; color: #0b0b0c; }
.reel-proc--shipped { background: #3b82f6; color: #fff; }
.reel-proc--on_site { background: #22c55e; color: #0b0b0c; }
.reel-no { font-size: 1.2rem; font-weight: 800; line-height: 1.12; letter-spacing: .01em; }
.reel-len { line-height: 1.05; margin-top: .1rem; }
.reel-len-num { font-size: 1.5rem; font-weight: 800; }
.reel-len-unit { font-size: .8rem; font-weight: 700; }
.reel-len-sub { font-size: .62rem; color: var(--muted, #9aa3ae); }
.reel-type { font-size: .66rem; color: var(--muted, #9aa3ae); text-transform: uppercase; letter-spacing: .03em; }

.feed-label {
  font-size: .58rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted, #9aa3ae);
  margin-top: .25rem; line-height: 1.15;
}
.feed-label + .feed-name { margin-top: 0; }
.feed-name {
  font-size: .68rem; color: #cfd6dd; line-height: 1.15;
  overflow-wrap: anywhere;
}
.feed-more { font-size: .62rem; color: var(--muted, #9aa3ae); font-style: italic; line-height: 1.15; }

/* --------------------------------------------------------------------------
   Permit cards — same visual language as the reel cards above (coloured left
   edge by stage, compact body, big identifier, labelled detail rows). Lives in
   crews.css (loaded in <head>) so the Job Board Permits tab — injected via HTMX
   — always gets these styles, not just the server-rendered Manpower tab.
   -------------------------------------------------------------------------- */
.permit-card { border-radius: .6rem; transition: transform .15s ease, box-shadow .15s ease; }
.permit-card .card-body { padding: .6rem .7rem; }
.permit-card:hover { transform: translateY(-1px); box-shadow: 0 .45rem 1rem rgba(0,0,0,.35); }
.permit-stage-card { border-left: 6px solid var(--stage, #6c757d) !important; }
.permit-clickable { cursor: pointer; }
.permit-clickable:hover { border-color: var(--stage, #6c757d); }

.permit-no { font-size: 1.05rem; font-weight: 800; line-height: 1.12; }
.permit-for { font-size: .9rem; font-weight: 700; color: var(--text, #e9edf1); line-height: 1.2; margin-top: .1rem; }
.permit-sub { font-size: .72rem; color: var(--muted, #9aa3ae); line-height: 1.2; }
.permit-label {
  font-size: .58rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted, #9aa3ae);
  margin-top: .35rem; line-height: 1.15;
}
.permit-val { font-size: .72rem; color: #cfd6dd; line-height: 1.25; overflow-wrap: anywhere; }
.stage-badge {
  background: var(--stage, #6c757d); color: #0b0b0c;
  font-weight: 700; white-space: nowrap; font-size: .62rem; padding: .3em .55em;
}
.permit-doc-chip { font-size: .62rem; }
.reel-chip {
  --chip: #9aa3ae;
  border: 1px solid color-mix(in srgb, var(--chip) 55%, transparent);
  color: var(--chip); background: none; border-radius: 999px;
  font-size: .72rem; font-weight: 700; padding: 2px 10px; line-height: 1.4;
  text-transform: uppercase; letter-spacing: .03em; cursor: pointer;
}
.reel-chip.active { background: var(--chip); color: #0b0b0c; }
.reel-chip[data-area="all"] { --chip: var(--brand-primary, #ff7a00); }

/* Desktop: form dropdowns drop inline anchored to their trigger, and stay on
   screen via Popper's flip/shift (the trigger sets data-bs-boundary="viewport").
   They overlay other content (high z-index) and scroll if tall. */
.dropdown-menu.form-drop {
  max-height: 80vh;
  overflow-y: auto;
  z-index: 1085;
}
/* Phones/tablets: become a centered sheet so a finger-sized panel never hangs
   off the edge and native <select> popups stay clear of the screen edge. */
@media (max-width: 991.98px) {
  .dropdown-menu.form-drop.show {
    position: fixed !important;
    left: 50% !important; right: auto !important;
    top: 10vh !important; bottom: auto !important;
    transform: translateX(-50%) !important;
    width: min(92vw, 360px);
    max-height: 78vh;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .6);
    z-index: 1080;
  }
}


/* ==========================================================================
   UI continuity contracts (Phase 1)
   ========================================================================== */
/* Heading contract: every page opens with .page-title; section headers use
   .section-label — one size/weight everywhere regardless of the h-tag. */
.page-title { font-size: 1.4rem; font-weight: 700; letter-spacing: .01em; margin-bottom: 0; }
.section-label {
  font-size: 1.05rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em;
}

/* iOS zooms any focused field under 16px — global rule, not per-page. */
@media (max-width: 991.98px) {
  input, select, textarea { font-size: 16px !important; }
}

/* Keyboard focus: a visible brand ring app-wide. */
:focus-visible { outline: 2px solid var(--brand-primary, #ff7a00); outline-offset: 2px; }

/* Buttons: one modern pill shape product-wide (groups keep their fused
   inner edges via Bootstrap's own group rules). */
.btn { border-radius: 999px; font-weight: 600; }

/* Tables: one dark skin + a scroll container so phones pan instead of
   stretching the layout. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 10px; }
.table { color: var(--text, #e9edf1); --bs-table-bg: transparent; }
.table thead th {
  background: var(--surface-2, #1a1c20); color: var(--muted, #9aa3ae);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  border-color: var(--border, #23252b) !important;
}
.table td, .table th { border-color: var(--border, #23252b) !important; }
.table tbody tr:hover td { background: color-mix(in srgb, var(--brand-primary, #ff7a00) 7%, transparent); }

/* Pagination: pill chips in the filter-chip language. */
.pagination { gap: 6px; }
.pagination .page-link {
  border-radius: 999px !important; background: transparent;
  border: 1px solid var(--border, #23252b); color: var(--text, #e9edf1);
  font-size: .8rem; padding: 4px 12px;
}
.pagination .page-item.active .page-link,
.pagination .page-link:hover {
  background: var(--brand-primary, #ff7a00);
  border-color: var(--brand-primary, #ff7a00);
  color: var(--brand-on-primary, #0b0b0c);
}


/* Scanner icon buttons (Tool Scan / Material Scan / Safety Scan) — one
   definition shared by all three scanner pages. */
.qr-icon-btn {
  width: 44px; height: 44px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border, #2d2d32);
  background: var(--surface, #141518);
  color: var(--text, #e9edf1); font-size: 1.05rem;
  cursor: pointer; text-decoration: none;
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.qr-icon-btn:hover { background: var(--surface-2, #1a1c20); border-color: var(--brand-primary, #ff7a00); }
.qr-icon-btn.is-off { opacity: .45; }
.qr-icon-btn[aria-pressed="true"] { border-color: var(--brand-primary, #ff7a00); color: var(--brand-primary, #ff7a00); }


/* Tab bars with many tabs: one horizontally-scrollable row on phones
   instead of wrapping to 3-4 rows and shoving content down the screen. */
@media (max-width: 991.98px) {
  .nav-tabs-scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .nav-tabs-scroll::-webkit-scrollbar { display: none; }
  .nav-tabs-scroll .nav-item { flex: 0 0 auto; }
  .nav-tabs-scroll .nav-link { white-space: nowrap; }
}

/* ── Reel label multi-select (Materials tab + ReelVault board) ───────── */
.reel-item { position: relative; }
.reel-pick { display: none; position: absolute; top: 8px; left: 8px; z-index: 3;
  width: 22px; height: 22px; border-radius: 6px; border: 2px solid var(--accent, #ff7a00);
  background: rgba(0,0,0,.55); }
body.reel-pick-mode .reel-pick { display: block; }
body.reel-pick-mode .reel-mat-card, body.reel-pick-mode .reel-card { cursor: pointer; }
.reel-item.picked .reel-pick { background: var(--accent, #ff7a00); }
.reel-item.picked .reel-pick::after { content: "✓"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; color: #0b0b0c;
  font-weight: 900; font-size: 14px; }
.reel-item.picked .reel-mat-card, .reel-item.picked .reel-card {
  outline: 3px solid var(--accent, #ff7a00); outline-offset: 1px; }
#reelPrintBar { position: fixed; left: 50%; transform: translateX(-50%); bottom: 18px;
  z-index: 1080; display: none; gap: 10px; align-items: center; background: #15171b;
  border: 1px solid #2d2d32; border-radius: 999px; padding: 8px 14px;
  box-shadow: 0 8px 24px rgba(0,0,0,.45); }
#reelPrintBar.show { display: flex; }
