:root {
  --navy: #12283f;
  --teal: #1a7a6e;
  --teal-light: #e3f2ef;
  --sand: #f4efe6;
  --ink: #1f2a33;
  --muted: #647380;
  --border: #dfe4e8;
  --danger: #b3432b;
  --white: #ffffff;
  --caribbean: #1a7a6e;
  --usa: #2f5fa8;
  --southamerica: #b3822b;
  --other: #7a7a7a;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--sand);
}

.topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 14px 24px;
  background: var(--navy);
  color: var(--white);
}

.brand {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
}
.brand span { color: #8fd6c9; }

/* The topbar's brand also doubles as the Dashboard button — reset the
   default <button> chrome so it still reads as a logo, with a subtle
   hover/active affordance instead of the full tab-pill treatment. */
.brand-home {
  border: none;
  cursor: pointer;
  color: var(--white);
  font-family: inherit;
  padding: 6px 10px;
  border-radius: 6px;
}
.brand-home:hover { background: rgba(255,255,255,0.08); }
.brand-home.active { background: rgba(255,255,255,0.16); }

.tabs { display: flex; gap: 6px; flex: 1; align-items: center; flex-wrap: wrap; }

.tab-btn {
  background: transparent;
  border: none;
  color: #c9d6e0;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.95rem;
  white-space: nowrap;
}
.tab-btn:hover { background: rgba(255,255,255,0.08); }
.tab-btn.active { background: var(--teal); color: var(--white); }

/* "More" overflow menu — holds tabs pushed out of the top bar (Activity
   Log today, room for more later) behind a single toggle. */
.tab-dropdown { position: relative; display: flex; align-items: center; }
.tab-dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 4px;
  background: var(--navy);
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: 8px;
  padding: 4px;
  min-width: 170px;
  box-shadow: 0 10px 24px rgba(0,0,0,0.35);
  z-index: 50;
}
.tab-dropdown.open .tab-dropdown-menu { display: block; }
.tab-dropdown-item {
  display: block;
  width: 100%;
  text-align: left;
  white-space: nowrap;
}

.btn {
  border: 1px solid var(--border);
  background: var(--white);
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
}
.btn.primary { background: var(--teal); color: var(--white); border-color: var(--teal); }
.btn.danger { background: var(--danger); color: var(--white); border-color: var(--danger); }
.btn.small { padding: 4px 10px; font-size: 0.8rem; }
.btn.active { background: var(--navy, #0F2A33); color: var(--white); border-color: var(--navy, #0F2A33); }

/* ---------- Gantt charts (Scheduling > Gantt Charts) ---------- */
.gantt-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; background: var(--white); }
.gantt-row { display: flex; align-items: stretch; }
.gantt-row-label {
  flex: 0 0 220px; position: sticky; left: 0; background: var(--white); z-index: 2;
  padding: 8px 10px; border-right: 1px solid var(--border); border-bottom: 1px solid #eee2;
  font-size: 0.83rem; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center;
}
.gantt-row-label .gantt-row-sublabel { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }
.gantt-group-label { font-weight: 700; background: #f7f5ef; }
.gantt-header-row .gantt-row-label { border-bottom: 2px solid var(--border); }
.gantt-header-track { display: flex; border-bottom: 2px solid var(--border); flex: 0 0 auto; }
.gantt-header-cell {
  flex: 0 0 auto; font-size: 0.66rem; color: var(--muted); text-align: center;
  padding: 4px 0; box-sizing: border-box; border-right: 1px solid #f2f0e8;
}
.gantt-track {
  position: relative; border-bottom: 1px solid #eee2; flex: 0 0 auto; min-height: 42px;
}
.gantt-bar {
  position: absolute; top: 6px; bottom: 6px; border-radius: 5px; font-size: 0.7rem; color: #fff;
  display: flex; align-items: center; padding: 0 6px; overflow: hidden; white-space: nowrap; cursor: default;
}
.gantt-bar-NotStarted { background: #8a8f93; }
.gantt-bar-InProgress { background: #2f6fb0; }
.gantt-bar-Delayed { background: #c0392b; }
.gantt-bar-Complete { background: #2f8f5b; }
.gantt-today-line { position: absolute; top: 0; bottom: 0; width: 2px; background: #e8623d; z-index: 1; }
.gantt-empty-note { padding: 10px; color: var(--muted); font-size: 0.85rem; }

/* Sport sub-heading row — a full-width divider, no track/bars underneath it. */
.gantt-sport-heading-row { background: #0F2A33; }
.gantt-sport-heading-label {
  flex: 1 1 auto !important; position: static !important; background: transparent !important;
  color: #fff; font-weight: 700; font-size: 0.78rem; letter-spacing: 0.03em; text-transform: uppercase;
  border-right: none !important;
}
/* Court sub-rows nested under a sport heading get a slight indent so the
   hierarchy (Sport -> Court -> Phase) reads visually, without a 3rd column. */
.gantt-row-indent .gantt-row-label { padding-left: 22px; }

.gantt-bar-draggable { cursor: grab; }
.gantt-bar-draggable:active { cursor: grabbing; }
.gantt-bar-dragging { opacity: 0.75; box-shadow: 0 2px 8px rgba(0,0,0,0.35); z-index: 3; }
.gantt-bar-locked { cursor: not-allowed; }

/* Resize handles on the left/right edge of a resizable bar — extend or
   shorten a phase without moving the other end. Hidden until hover so they
   don't clutter a chart full of short bars. */
.gantt-resize-handle {
  position: absolute; top: 0; bottom: 0; width: 7px; cursor: ew-resize;
  z-index: 4; opacity: 0; background: rgba(255,255,255,0.55);
}
.gantt-bar:hover .gantt-resize-handle { opacity: 1; }
.gantt-resize-handle.left { left: 0; border-radius: 5px 0 0 5px; }
.gantt-resize-handle.right { right: 0; border-radius: 0 5px 5px 0; }
.gantt-bar-resizing { z-index: 5; box-shadow: 0 2px 8px rgba(0,0,0,0.35); }

/* Ghost bar shown while click-dragging on empty chart space to create a
   new phase directly on the timeline. */
.gantt-bar-ghost {
  position: absolute; top: 6px; bottom: 6px; border-radius: 5px;
  background: rgba(47, 111, 176, 0.35); border: 1px dashed #2f6fb0; pointer-events: none; z-index: 2;
}
.gantt-track { cursor: crosshair; }
.gantt-bar, .gantt-today-line { cursor: default; }
.gantt-bar-draggable { cursor: grab; }

/* Company-wide overview: one clickable bar per project. */
.gantt-bar-project { cursor: pointer; font-weight: 600; }
.gantt-bar-project:hover { filter: brightness(1.12); }

/* Read-only rendering (the public customer schedule page, and anywhere else
   a Gantt is shown without edit rights) — no grab/resize/crosshair cursors
   since nothing here is actually draggable. */
.gantt-readonly .gantt-track { cursor: default; }
.gantt-readonly .gantt-bar { cursor: default; }
.gantt-readonly .gantt-resize-handle { display: none; }

@media print {
  /* module 46: .gantt-wrap normally scrolls horizontally (overflow-x:auto)
     so a wide "Whole Job" or "Quarter" chart fits the screen — but a
     scrollable div doesn't paginate for print, it just SILENTLY CLIPS
     everything past one page width. Landscape + overflow:visible here
     means the browser's print/PDF engine lays the full width out (wrapping
     across pages as needed) instead of losing the tail end of the chart. */
  @page { size: landscape; margin: 12mm; }
  body.printing-gantt > *:not(main) { visibility: hidden; }
  body.printing-gantt main > *:not(#scheduling-view) { visibility: hidden; }
  body.printing-gantt #scheduling-view > *:not(#sched-gantt) { visibility: hidden; }
  body.printing-gantt #sched-gantt > *:not(#ganttPrintArea) { visibility: hidden; }
  body.printing-gantt #ganttPrintArea, body.printing-gantt #ganttPrintArea * { visibility: visible; }
  body.printing-gantt #ganttPrintArea { position: absolute; top: 0; left: 0; width: 100%; }
  body.printing-gantt .gantt-row-label { position: static; }
  body.printing-gantt .gantt-wrap { overflow: visible; border: none; }

  /* Public customer schedule page (public/schedule.html) — same overflow
     fix, plus hide the zoom/navigation/print controls since none of them
     mean anything on a printed page. */
  #schedToolbar, #schedPrevBtn, #schedNextBtn { display: none !important; }
  #schedGanttRoot .gantt-wrap { overflow: visible; border: none; }
}

main { padding: 20px 24px; max-width: 1400px; margin: 0 auto; }

/* Legal Terms (module 21) needs real width for its "page layout" contract
   column -- the shared 1400px content cap and the Proposal editor's normal
   900px .editor-pane cap (below) both squeezed it down to a fraction of
   the screen. Widen just this view rather than touching every other page
   that relies on the narrower, form-like .editor-pane width. */
body:has(#proposal-terms-view.active) main { max-width: none; }
#proposalTermsRoot.editor-pane { max-width: none; }

.view { display: none; }
.view.active { display: block; }

.toolbar { display: flex; gap: 10px; margin-bottom: 14px; }
.toolbar input, .toolbar select {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
}
#searchInput { flex: 1; max-width: 420px; }

.split { display: grid; grid-template-columns: 1.1fr 1.4fr; gap: 18px; align-items: start; }

.list-pane, .detail-pane {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
thead th {
  text-align: left;
  background: var(--teal-light);
  padding: 10px 12px;
  font-weight: 600;
  color: var(--navy);
  border-bottom: 1px solid var(--border);
}
tbody td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
tbody tr { cursor: pointer; }
tbody tr:hover { background: var(--teal-light); }
tbody tr.selected { background: #d6ede8; }

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
}
.badge.Lead { background: #fdf0d5; color: #8a5a00; }
.badge.Active { background: #dff0ea; color: #14634f; }
.badge.Past.Client, .badge.PastClient { background: #eee; color: #666; }

.detail-pane { padding: 18px 22px; min-height: 300px; }
.empty-state { color: var(--muted); text-align: center; padding: 60px 20px; }

.detail-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 6px; }
.detail-header h2 { margin: 0 0 2px 0; }
.detail-meta { color: var(--muted); font-size: 0.88rem; margin-bottom: 14px; }

.property-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: #fbfbfa;
}
.property-card h4 { margin: 0 0 4px 0; }
.property-card .sub { color: var(--muted); font-size: 0.85rem; margin-bottom: 8px; }

.subsection-title {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 10px 0 4px;
}

.mini-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--border);
  font-size: 0.86rem;
}
.mini-row:last-child { border-bottom: none; }

.stage-pill {
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
}
.stage-New { background: #e6eef8; color: #2f5fa8; }
.stage-Pre-Sale { background: #eaeafb; color: #4b4fc4; }
.stage-Quoted { background: #fdf0d5; color: #8a5a00; }
.stage-Proposal.Sent, .stage-ProposalSent { background: #efe1f7; color: #6b3fa0; }
.stage-Won { background: #dff0ea; color: #14634f; }
.stage-Lost { background: #f6e2df; color: #a13a26; }

.card-actions { display: flex; gap: 8px; margin-top: 8px; }

/* Map */
#map { height: 620px; border-radius: 10px; border: 1px solid var(--border); }
.map-legend { display: flex; gap: 18px; margin-bottom: 10px; font-size: 0.85rem; color: var(--muted); align-items: center; flex-wrap: wrap; }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; }
.dot.caribbean { background: var(--caribbean); }
.dot.usa { background: var(--usa); }
.dot.southamerica { background: var(--southamerica); }
.dot.other { background: var(--other); }

/* Emoji-based markers (ships, crew) — no image assets needed */
.emoji-marker { background: transparent; border: none; }
.emoji-marker-inner { font-size: 20px; line-height: 1; text-align: center; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.45)); }
.ship-route-line { stroke-dasharray: 2, 8; }

.map-refresh-controls { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.map-refresh-controls label { display: flex; align-items: center; gap: 4px; cursor: pointer; }

#propertyMiniMap, #locationMiniMap, #clientMiniMap { height: 220px; border-radius: 8px; margin-bottom: 10px; border: 1px solid var(--border); }

/* Pipeline */
.pipeline-board { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.pipeline-col { background: var(--white); border: 1px solid var(--border); border-radius: 10px; padding: 10px; min-height: 200px; }
.pipeline-col h4 { margin: 4px 6px 10px; font-size: 0.85rem; color: var(--navy); }
.pipeline-card {
  background: #fbfbfa;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 8px;
  font-size: 0.82rem;
  cursor: pointer;
}
.pipeline-card .co { font-weight: 600; margin-bottom: 2px; }
.pipeline-card .val { color: var(--teal); font-weight: 600; margin-top: 6px; }

/* Modals */
.modal-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(18,40,63,0.45);
  align-items: center;
  justify-content: center;
  z-index: 50;
}
.modal-backdrop.active { display: flex; }
.modal {
  background: var(--white);
  border-radius: 10px;
  padding: 22px 26px;
  width: 460px;
  max-height: 88vh;
  overflow-y: auto;
}
.modal h3 { margin-top: 0; }
.modal form label { display: block; font-size: 0.82rem; color: var(--muted); margin: 10px 0 4px; }
.modal form input, .modal form select, .modal form textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
}
.hint { font-size: 0.78rem; color: var(--muted); margin: 4px 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.checkbox-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 8px 0 2px;
}
.checkbox-list label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.85rem;
  color: var(--ink, #222);
  margin: 0;
  width: auto;
}
.checkbox-list input[type="checkbox"] { width: auto; }
.specialty-badge {
  display: inline-block;
  background: #eef2fb;
  color: #2f4b8f;
  font-size: 0.72rem;
  font-weight: 600;
  border-radius: 4px;
  padding: 2px 7px;
  margin: 2px 4px 2px 0;
  white-space: nowrap;
}

/* Proposal editor */
.editor-pane {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 22px 26px;
  margin-top: 14px;
  max-width: 900px;
}
.editor-pane h2 { margin-top: 0; }
.editor-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.editor-row label { display: block; font-size: 0.8rem; color: var(--muted); margin-bottom: 4px; }
.editor-row input, .editor-row select { width: 100%; padding: 7px 9px; border: 1px solid var(--border); border-radius: 6px; }

.line-items-table { width: 100%; border-collapse: collapse; font-size: 0.86rem; margin-bottom: 10px; }
.line-items-table th { text-align: left; padding: 6px 8px; background: var(--teal-light); font-size: 0.75rem; text-transform: uppercase; color: var(--navy); }
.line-items-table td { padding: 5px 8px; border-bottom: 1px solid var(--border); }
.line-items-table input, .line-items-table select { width: 100%; padding: 5px 6px; border: 1px solid var(--border); border-radius: 5px; font-size: 0.85rem; }
.line-items-table .num-col { width: 70px; }
.line-items-table .price-col { width: 100px; }
.line-items-table .total-col { width: 100px; text-align: right; white-space: nowrap; }

.add-row-form { display: grid; grid-template-columns: 100px 110px 200px 110px 1fr 60px 60px 90px 32px; gap: 6px; align-items: center; margin-top: 6px; }
/* module 23 follow-up: the "linked to Cost Catalogue" note under a line
   item's description, plus its "refresh price" link (Draft proposals only). */
.li-cost-link { font-size: 0.74rem; color: var(--muted); margin-top: 2px; }
.li-cost-link a { color: var(--teal); }

/* Job Costing Budget (module 18) */
.jb-summary { display: flex; gap: 28px; padding: 14px 18px; background: var(--sand); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 18px; }
.jb-summary > div { flex: 1; }
.jb-group-header { font-weight: 700; color: var(--navy); background: var(--teal-light); padding: 6px 10px; margin-top: 14px; border-radius: 6px 6px 0 0; }
.jb-pos { color: var(--teal); }
.jb-neg { color: var(--danger); }
.jb-link-picker { padding: 8px 10px; background: var(--sand); border-radius: 6px; }
.jb-link-picker .mini-row { padding: 4px 0; }
.add-row-form input, .add-row-form select { padding: 6px 7px; border: 1px solid var(--border); border-radius: 5px; font-size: 0.85rem; }

.payments-editor .row { display: flex; gap: 10px; align-items: center; margin-bottom: 6px; }
.payments-editor input[type=text] { flex: 1; padding: 6px 8px; border: 1px solid var(--border); border-radius: 5px; }
.payments-editor input[type=number] { width: 130px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 5px; }

.editor-terms textarea { width: 100%; min-height: 220px; font-family: inherit; font-size: 0.82rem; padding: 12px; border: 1px solid var(--border); border-radius: 8px; }

.totals-box { margin-top: 10px; margin-left: auto; width: 260px; font-size: 0.9rem; }
.totals-box .row { display: flex; justify-content: space-between; padding: 3px 0; }
.totals-box .row.grand { font-weight: 700; border-top: 2px solid var(--navy); margin-top: 4px; padding-top: 6px; }

.editor-actions { display: flex; gap: 10px; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
.share-link-box { margin-top: 14px; padding: 12px 14px; background: var(--teal-light); border-radius: 8px; font-size: 0.85rem; }
.share-link-box a { word-break: break-all; }

/* Login screen */
.login-backdrop {
  position: fixed; inset: 0;
  background: var(--navy);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
}
.login-backdrop.hidden { display: none; }
.login-box {
  background: var(--white);
  border-radius: 12px;
  padding: 34px 38px;
  width: 340px;
}
.login-box label { display: block; font-size: 0.82rem; color: var(--muted); margin: 12px 0 4px; }
.login-box input { width: 100%; padding: 9px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.95rem; }

body.app-hidden main, body.app-hidden .topbar { display: none; }

/* User chip */
.user-chip { display: flex; align-items: center; gap: 10px; color: #dbe7ef; font-size: 0.85rem; }
.user-chip button { background: transparent; color: #dbe7ef; border-color: rgba(255,255,255,0.3); }

/* The one notification bell (module 35 — Yvanna's shipping notes, point 1:
   Procurement approval-pool alerts; backed by /api/notifications, module
   26's notifications table, which already existed server-side but had no
   web front end yet). Originally a second, separate bell existed for
   shipment stale/overdue alerts (shippingCategory1.js) — merged into this
   one dropdown as a second section (2026-08-29, Evan: "There should only
   be 1 notification bell"). See refreshGnotifBell()/renderGnotifDropdown()
   in app.js. */
.gnotif-wrap { position: relative; }
.gnotif-bell {
  background: transparent; border: 1px solid rgba(255,255,255,0.28);
  color: #fff; cursor: pointer; border-radius: 8px; padding: 5px 9px;
  font-size: 1rem; line-height: 1; position: relative;
}
.gnotif-bell:hover { background: rgba(255,255,255,0.10); }
.gnotif-badge {
  position: absolute; top: -7px; right: -7px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: #b3432b; color: #fff;
  font-size: 0.7rem; font-weight: 700; line-height: 18px; text-align: center;
}
.gnotif-dropdown {
  display: none; position: absolute; top: calc(100% + 8px); right: 0;
  width: 360px; max-height: 460px; overflow-y: auto; background: #fff;
  color: var(--ink, #1f2a33); border: 1px solid var(--border, #dfe4e8);
  border-radius: 10px; box-shadow: 0 12px 30px rgba(18,40,63,0.28); z-index: 60;
}
.gnotif-dropdown.open { display: block; }
.gnotif-head {
  padding: 10px 14px; border-bottom: 1px solid var(--border, #dfe4e8);
  font-weight: 700; font-size: 0.88rem; color: var(--navy, #12283f);
  display: flex; justify-content: space-between; align-items: center;
  position: sticky; top: 0; background: #fff;
}
.gnotif-head a { font-size: 0.78rem; font-weight: 400; }
.gnotif-empty { padding: 22px 16px; text-align: center; color: var(--muted, #647380); font-size: 0.88rem; }
.gnotif-item {
  display: block; padding: 10px 12px; border-bottom: 1px dashed var(--border, #dfe4e8);
  cursor: pointer;
}
.gnotif-item:last-child { border-bottom: none; }
.gnotif-item:hover { background: var(--teal-light, #e3f2ef); }
.gnotif-item.unread { background: #f4f9f8; }
.gnotif-title { font-size: 0.84rem; font-weight: 600; line-height: 1.3; }
.gnotif-body-text { font-size: 0.78rem; color: var(--muted, #647380); margin-top: 2px; }
.gnotif-time { font-size: 0.72rem; color: var(--muted, #647380); margin-top: 3px; }

/* Shipment Alerts section (stale / overdue checklist) within the same
   dropdown — these rows carry a Dismiss action general notifications don't
   have, so they get their own flex layout + tag color, everything else
   (.gnotif-item hover/border, .gnotif-title/.gnotif-body-text) is shared. */
.gnotif-item.gnotif-shipalert { display: flex; gap: 8px; align-items: flex-start; }
.gnotif-shipalert-body { flex: 1; min-width: 0; }
.gnotif-tag { flex-shrink: 0; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.03em; padding: 2px 6px; border-radius: 6px; margin-top: 1px; }
.gnotif-tag-stale { background: #fdf0d5; color: #8a5a00; }
.gnotif-tag-overdue_checklist { background: #f6e2df; color: #a13a26; }
.gnotif-dismiss { flex-shrink: 0; background: transparent; border: none; color: var(--muted, #647380); font-size: 1.1rem; line-height: 1; cursor: pointer; padding: 0 2px; }
.gnotif-dismiss:hover { color: #b3432b; }

/* Open Jobs (module 35 follow-up) — a collapsible job list next to a
   "Project Overview" stat panel, modeled on the Buildertrend screenshot
   Evan shared: pick a job on the left, see its at-a-glance status on the
   right, without opening a modal for the quick-glance case. The deeper
   detail (linked shipments/POs, ground team update, notes, edit) stays in
   the existing Project Detail modal, reachable via "View Full Details". */
.oj-workspace { display: flex; gap: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--white); min-height: 360px; }
.oj-sidebar { width: 300px; flex-shrink: 0; border-right: 1px solid var(--border); display: flex; flex-direction: column; transition: width 0.15s ease; background: #fbfbfa; }
.oj-sidebar.collapsed { width: 44px; }
.oj-sidebar.collapsed .oj-sidebar-body { display: none; }
.oj-sidebar-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--border); gap: 8px; }
.oj-sidebar.collapsed .oj-sidebar-head { justify-content: center; padding: 10px 4px; }
.oj-sidebar.collapsed .oj-sidebar-head-label { display: none; }
.oj-collapse-btn { background: var(--white); border: 1px solid var(--border); border-radius: 50%; width: 26px; height: 26px; line-height: 1; cursor: pointer; color: var(--navy, #12283f); flex-shrink: 0; }
.oj-collapse-btn:hover { background: var(--teal-light, #e3f2ef); }
.oj-sidebar-body { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.oj-sidebar-filters { padding: 8px 12px; display: flex; flex-direction: column; gap: 6px; border-bottom: 1px solid var(--border); }
.oj-sidebar-filters input, .oj-sidebar-filters select { width: 100%; }
.oj-sidebar-count { padding: 6px 12px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.03em; color: var(--muted); text-transform: uppercase; }
.oj-list { flex: 1; overflow-y: auto; }
.oj-list-item { display: block; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--border); padding: 10px 12px; cursor: pointer; font: inherit; }
.oj-list-item:hover { background: var(--teal-light, #e3f2ef); }
.oj-list-item.active { background: var(--teal-light, #e3f2ef); border-left: 3px solid var(--teal, #1f8a70); }
.oj-list-item-name { font-size: 0.86rem; font-weight: 600; color: var(--navy, #12283f); }
.oj-list-item-sub { font-size: 0.76rem; color: var(--muted); margin-top: 2px; }
.oj-list-empty { padding: 20px 12px; color: var(--muted); font-size: 0.85rem; }
.oj-overview { flex: 1; min-width: 0; padding: 18px 22px; overflow-y: auto; }
.oj-overview-placeholder { color: var(--muted); padding: 40px 20px; text-align: center; }
.oj-overview-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 14px; }
.oj-overview-header h3 { margin: 0; }
.oj-overview-header .sub { color: var(--muted); font-size: 0.85rem; margin-top: 2px; }
.oj-list-country-header { padding: 8px 12px 4px; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--teal, #1f8a70); background: #fbfbfa; position: sticky; top: 0; }

/* Project Overview quick-glance row (2026-08-29 follow-up) — one wrapping
   horizontal line of small chips instead of the old stacked stat-card grid,
   so a single job's overview stays scannable and compact even though the
   panel gets reused 20 times a day flipping between jobs. */
.oj-quickrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.oj-chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px; font-size: 0.78rem; background: #fbfbfa; color: var(--navy, #12283f); white-space: nowrap; }
.oj-chip-group { display: inline-flex; align-items: center; gap: 4px; }
.oj-chip-static { cursor: default; }
.oj-chip-toggle { border: none; cursor: pointer; font-weight: 600; }
.oj-chip-toggle.yes { background: #1f8a70; color: #fff; }
.oj-chip-toggle.no { background: #efe4e0; color: #8a3a24; }
.oj-chip-link { cursor: pointer; color: var(--teal, #1f8a70); font-weight: 600; border-style: dashed; background: none; }
.oj-chip-link:hover { background: var(--teal-light, #e3f2ef); }
.oj-chip-field { padding: 3px 10px 3px 12px; gap: 6px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; color: var(--muted); }
.oj-chip-field select, .oj-chip-field input[type="date"] { border: none; background: none; font: inherit; font-weight: 600; text-transform: none; color: var(--navy, #12283f); padding: 0; }
.oj-chip-details { cursor: pointer; position: relative; }
.oj-chip-details summary { list-style: none; cursor: pointer; }
.oj-chip-details summary::-webkit-details-marker { display: none; }
.oj-chip-details[open] { background: var(--teal-light, #e3f2ef); }
.oj-ship-dropdown { position: absolute; top: calc(100% + 6px); left: 0; z-index: 20; background: var(--white); border: 1px solid var(--border); border-radius: 8px; padding: 10px; width: 300px; box-shadow: 0 6px 18px rgba(0,0,0,0.12); white-space: normal; }
.oj-ship-drop-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--border); font-size: 0.78rem; }
.oj-ship-drop-row:last-of-type { border-bottom: none; }
.oj-ship-drop-desc { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.oj-ship-drop-date { color: var(--muted); font-size: 0.72rem; flex-shrink: 0; }
.oj-ship-drop-empty { color: var(--muted); font-size: 0.8rem; padding: 4px 0; }
.oj-ship-drop-expected { display: flex; flex-direction: column; gap: 3px; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: var(--muted); margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.oj-ship-drop-expected input { font: inherit; text-transform: none; font-weight: 600; color: var(--navy, #12283f); }
.oj-ship-drop-link { margin-top: 8px; width: 100%; border: none; background: var(--teal, #1f8a70); color: #fff; border-radius: 6px; padding: 6px 0; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.oj-ship-drop-link:hover { background: #176a56; }

/* Shipping view's "filtered to one job" chip (module 35 follow-up) */
.ship-project-filter-chip { display: flex; align-items: center; gap: 8px; background: var(--teal-light, #e3f2ef); border: 1px solid var(--teal, #1f8a70); border-radius: 8px; padding: 6px 12px; margin: 10px 0; font-size: 0.85rem; color: var(--navy, #12283f); width: fit-content; }
.ship-project-filter-chip button { border: none; background: none; cursor: pointer; font-size: 1rem; line-height: 1; color: var(--muted); }
.ship-project-filter-chip button:hover { color: var(--navy, #12283f); }

/* Cost field masking hint */
.cost-field.masked { opacity: 0.5; }
.cost-hidden-note { font-size: 0.78rem; color: var(--muted); font-style: italic; }

/* Warehouse subtabs */
.subtabs { display: flex; gap: 6px; margin-bottom: 16px; border-bottom: 2px solid var(--border); }
.subtab-btn { background: transparent; border: none; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -2px; }
.subtab-btn.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); }
.subview { display: none; }
.subview.active { display: block; }

/* Cost Catalogue's inner Cost Items / Assemblies toggle — nested one level
   inside the Sales Pipeline "Cost Catalogue" sub-tab. Styled to look the
   same as .subtabs/.subtab-btn but kept as distinct classes so it doesn't
   get caught by the generic .subtab-btn click handler (see app.js). */
.cc-subtabs { display: flex; gap: 6px; margin: 4px 0 16px; border-bottom: 2px solid var(--border); }
.cc-tab-btn { background: transparent; border: none; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -2px; }
.cc-tab-btn.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); }
.cc-subview { display: none; }
.cc-subview.active { display: block; }

/* module 23: the single admin-only "Standard Materials markup %" setting,
   sitting above the Cost Items/Assemblies sub-tabs. */
.material-markup-box {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: #fafaf8;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 14px;
}
.material-markup-box label { font-weight: 600; font-size: 0.88rem; color: var(--navy); }

/* Project Management tab's top-level Scheduling/Job Costing toggle --
   same pattern as Cost Catalogue's .cc-* pair above, kept separate from
   the generic .subtabs/.subview classes so it doesn't collide with
   Scheduling's own nested sub-tabs (Calendar/Jobs & Phases/etc). */
.pm-subtabs { display: flex; gap: 6px; margin: 4px 0 16px; border-bottom: 2px solid var(--border); }
.pm-tab-btn { background: transparent; border: none; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -2px; }
.pm-tab-btn.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); }
.pm-subview { display: none; }
.pm-subview.active { display: block; }

/* WhatsApp inbox (module 17) */
.wa-nav-badge {
  display: inline-block;
  margin-left: 6px;
  background: var(--danger);
  color: var(--white);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 10px;
  vertical-align: middle;
}
.wa-thread-list { max-height: 70vh; overflow-y: auto; }
.wa-thread-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: var(--white);
  cursor: pointer;
  font: inherit;
}
.wa-thread-item:hover { background: var(--teal-light); }
.wa-thread-item.selected { background: #d6ede8; }
.wa-thread-item .wa-thread-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.wa-thread-item .wa-thread-name { font-weight: 600; color: var(--navy); }
.wa-thread-item .wa-thread-time { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.wa-thread-item .wa-thread-preview {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wa-thread-item .wa-thread-meta { margin-top: 4px; font-size: 0.75rem; color: var(--muted); }
.wa-unread-dot {
  display: inline-block;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--teal);
  color: var(--white);
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  line-height: 18px;
}
.wa-empty { color: var(--muted); text-align: center; padding: 40px 16px; }

.wa-chat-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.wa-chat-header h3 { margin: 0 0 2px 0; }
.wa-messages { max-height: 46vh; overflow-y: auto; padding: 4px 2px; display: flex; flex-direction: column; gap: 8px; }
.wa-msg { max-width: 78%; padding: 8px 12px; border-radius: 12px; font-size: 0.88rem; line-height: 1.4; }
.wa-msg.inbound { align-self: flex-start; background: var(--teal-light); color: var(--ink); border-bottom-left-radius: 3px; }
.wa-msg.outbound { align-self: flex-end; background: var(--navy); color: var(--white); border-bottom-right-radius: 3px; }
.wa-msg.outbound.failed { background: #f4d9d0; color: var(--danger); border: 1px dashed var(--danger); }
.wa-msg-time { display: block; font-size: 0.68rem; opacity: 0.75; margin-top: 4px; }
.wa-composer { display: flex; gap: 8px; margin-top: 14px; }
.wa-composer textarea {
  flex: 1;
  resize: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-family: inherit;
  font-size: 0.88rem;
  min-height: 44px;
}
.wa-window-note {
  font-size: 0.8rem;
  color: var(--danger);
  background: #f4d9d0;
  border-radius: 8px;
  padding: 8px 10px;
  margin-top: 10px;
}

.wh-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }

.wh-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.wh-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  position: relative;
}
.wh-card img.wh-photo { width: 100%; height: 120px; object-fit: cover; border-radius: 6px; margin-bottom: 8px; background: #eee; }
.wh-card h4 { margin: 0 0 2px; }
.wh-card .sub { color: var(--muted); font-size: 0.82rem; margin-bottom: 8px; }
.wh-card .qty-row, .ship-card .qty-row { display: flex; justify-content: space-between; font-size: 0.85rem; padding: 3px 0; border-bottom: 1px dashed var(--border); }
.wh-card .low-stock { color: #a13a26; font-weight: 700; }
.wh-card .card-actions { margin-top: 10px; }

.reorder-table, .location-table, .movements-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.reorder-table th, .location-table th, .movements-table th { text-align: left; background: var(--teal-light); padding: 8px 10px; }
.reorder-table td, .location-table td, .movements-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); }
.reorder-table tr.critical { background: #fdecea; }
.location-table tr.group-header td { background: var(--teal-light); font-weight: 700; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; padding: 6px 10px; border-bottom: none; }

.status-chip { padding: 2px 9px; border-radius: 10px; font-size: 0.72rem; font-weight: 600; }
.status-Active { background: #dff0ea; color: #14634f; }
.status-Needs.Service, .status-NeedsService { background: #fdf0d5; color: #8a5a00; }
.status-Out.of.Service, .status-OutofService { background: #f6e2df; color: #a13a26; }
.status-Retired { background: #eee; color: #666; }

/* Shipping */
.ship-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.ship-card { background: var(--white); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; }
.ship-card .kind-badge { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); }
.ship-card h4 { margin: 4px 0 2px; }
.ship-card .sub { color: var(--muted); font-size: 0.82rem; margin-bottom: 10px; }
.ship-stage-pill { padding: 3px 10px; border-radius: 10px; font-size: 0.75rem; font-weight: 600; display: inline-block; }
.ship-stage-pill.stage-early { background: #f6e9d7; color: #8a5a00; }
.ship-stage-pill.stage-mid { background: #dbe7f6; color: #2f5fa8; }
.ship-stage-pill.stage-final { background: #dff0ea; color: #14634f; }
.ship-stage-pill.stage-cancelled { background: #f6e2df; color: #a13a26; }
.ship-timeline { list-style: none; padding: 0; margin: 10px 0; }
.ship-timeline li { border-left: 2px solid var(--teal); padding: 4px 0 14px 16px; position: relative; }
.ship-timeline li::before { content: ''; position: absolute; left: -5px; top: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--teal); }
.ship-timeline .stage-name { font-weight: 700; }
.ship-timeline .stage-meta { color: var(--muted); font-size: 0.8rem; }
.ship-doc-thumbs { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.ship-doc-thumbs img { width: 64px; height: 64px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); }
/* D20: typed shipment documents — badge on image thumbs, chip for files */
.ship-doc-type-badge { position: absolute; bottom: 2px; left: 2px; right: 2px; font-size: 0.58rem; line-height: 1.1; padding: 1px 3px; border-radius: 4px; background: rgba(0,0,0,0.65); color: #fff; text-align: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ship-doc-file-chip { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.78rem; background: var(--panel-2, var(--panel)); text-decoration: none; color: inherit; max-width: 240px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ship-doc-file-chip:hover { border-color: var(--accent); }
.ship-line-items-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; margin: 8px 0; }
.ship-line-items-table th { text-align: left; background: var(--teal-light); padding: 6px 8px; }
.ship-line-items-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
.ship-add-row-form { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; align-items: center; }
.ship-add-row-form input, .ship-add-row-form select { flex: 1; min-width: 90px; }

/* Schedule Templates */
.template-item-row {
  display: flex; align-items: center; gap: 6px; margin-bottom: 6px; flex-wrap: wrap;
  border: 1px solid var(--border); border-radius: 6px; padding: 6px 8px; background: #fbfbfa;
}
.template-item-row input[type="text"] { flex: 2 1 140px; min-width: 120px; }
.template-item-row select { flex: 1 1 100px; min-width: 90px; }
.template-item-row input[type="number"] { flex: 0 0 64px; width: 64px; }
.template-item-track { flex: 0 0 56px; width: 56px; }
.template-item-suggested { flex: 0 0 auto; font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.template-item-suggested.has-suggestion { cursor: pointer; text-decoration: underline dotted; color: var(--teal); }
.template-item-remove { flex: 0 0 auto; }
.template-card {
  border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; margin-bottom: 10px; background: #fbfbfa;
}
.template-card-header { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.template-sport-chip {
  display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 0.68rem; font-weight: 600;
  background: var(--teal-light); color: var(--navy, #0F2A33); margin-right: 4px;
}
.template-items-preview { font-size: 0.8rem; color: var(--muted); margin-top: 4px; }
.apply-template-preview-row { display: flex; justify-content: space-between; gap: 10px; font-size: 0.83rem; padding: 3px 0; border-bottom: 1px solid #eee2; }

/* Activity Log — company-wide feed and per-record history modal share this */
.activity-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px dashed var(--border);
  font-size: 0.87rem;
}
.activity-row:last-child { border-bottom: none; }
.activity-main { flex: 1; min-width: 0; }
.activity-action-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--teal);
  margin-right: 6px;
}
.activity-time { color: var(--muted); font-size: 0.78rem; white-space: nowrap; flex-shrink: 0; }
.activity-history-list { max-height: 320px; overflow-y: auto; }
#activityLogList { background: var(--white); border: 1px solid var(--border); border-radius: 10px; padding: 6px 16px; }

/* Dashboard — per-user tasks + upcoming crew jobs, tailored by role */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 20px;
  align-items: start;
}
.dash-col { min-width: 0; }
#taskList, #myJobsList {
  background: var(--white); border: 1px solid var(--border); border-radius: 10px; padding: 6px 16px;
}
.task-row { align-items: flex-start; }
.task-row .card-actions { flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; margin-top: 0; }

.status-Scheduled { background: #e4edf7; color: #2f5fa8; }
.status-InProgress { background: #fdf0d5; color: #8a5a00; }
.status-Completed { background: #dff0ea; color: #14634f; }
.status-Cancelled { background: #eee; color: #666; }
.status-Inactive { background: #eee; color: #666; }
.status-Open { background: #e4edf7; color: #2f5fa8; }
.status-Done { background: #dff0ea; color: #14634f; }
.status-NotStarted { background: #eee; color: #666; }
.status-Delayed { background: #f6e2df; color: #a13a26; }
.status-Complete { background: #dff0ea; color: #14634f; }

/* Scheduling — calendar */
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.cal-daylabel {
  background: var(--teal-light);
  color: var(--navy);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 6px 8px;
  text-align: center;
}
.cal-cell {
  background: var(--white);
  min-height: 96px;
  padding: 4px 5px;
  overflow: hidden;
}
.cal-cell.cal-outside { background: #f7f6f2; color: var(--muted); }
.cal-cell.cal-outside .cal-daynum { color: var(--muted); }
.cal-cell.cal-today { background: #fbf8ee; box-shadow: inset 0 0 0 2px var(--teal); }
.cal-daynum { font-size: 0.78rem; font-weight: 600; margin-bottom: 3px; }
.cal-event {
  color: #fff;
  font-size: 0.68rem;
  line-height: 1.3;
  padding: 1px 4px;
  border-radius: 4px;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cal-more { font-size: 0.68rem; color: var(--muted); padding: 1px 4px; }
.cal-event-phase { cursor: pointer; border: 1px dashed rgba(255,255,255,0.7); }
.cal-event-phase:hover { filter: brightness(1.15); }

/* Scheduling — jobs & phases */
.phase-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  margin-bottom: 6px;
  background: #fbfbfa;
}
.phase-detail { margin-top: 6px; display: none; }
.phase-card.expanded .phase-detail { display: block; }

/* Compressed one-line phase row (Jobs & Phases pane + Gantt tab list).
   Name/status/sport-court/dates/crew count all on one line; clicking it
   (anywhere but an action button) expands the phase-detail block below. */
.phase-row {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: 0.83rem; white-space: nowrap; overflow: hidden;
}
.phase-row-name { overflow: hidden; text-overflow: ellipsis; max-width: 220px; flex: 0 1 auto; }
.phase-row-meta { color: var(--muted); font-size: 0.78rem; flex: 0 0 auto; }
.phase-row-spacer { flex: 1 1 auto; }
.phase-color-dot {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  flex: 0 0 auto; border: 1px solid rgba(0,0,0,0.15);
}
.phase-row-actions { display: flex; gap: 4px; flex: 0 0 auto; }
.phase-row-actions .btn.small { padding: 2px 7px; font-size: 0.72rem; }
.phase-row-caret { flex: 0 0 auto; color: var(--muted); font-size: 0.75rem; width: 12px; text-align: center; }
.phase-card.expanded .phase-row-caret { transform: rotate(90deg); }

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .pipeline-board { grid-template-columns: 1fr 1fr; }
  .dashboard-grid { grid-template-columns: 1fr; }
  .cal-cell { min-height: 60px; }
}

/* ===== Module 20 — top-nav dropdown redesign =====
   The three views with more than one page (Sales Pipeline, Project
   Management, Warehouse) now navigate through a dropdown menu off the top
   tab, Buildertrend-style, instead of an inline pill-bar of sub-tabs on the
   page itself. The pill-bars are still in the DOM exactly as before (see
   app.js — the dropdown items proxy-click them rather than duplicating
   their logic); they're just hidden here so they don't show twice. Nested
   one-level-deeper toggles (Cost Catalogue's Cost Items/Assemblies pair,
   Scheduling's own 5 internal sub-tabs) are DELIBERATELY left visible on
   their page — those are genuine same-page content toggles, not
   section-level navigation, and hiding them would just force a trip back
   up to the top dropdown to do something that used to be one click away. */
#sales-view > nav.subtabs,
#projectmanagement-view > nav.pm-subtabs,
#warehouse-view > nav.subtabs {
  display: none;
}

/* The caret is a separate button from the .tab-btn label it sits beside —
   see app.js's module 20 comment block for why. Slim, low-emphasis, just
   enough of a hit target to be clickable next to the tab label. */
.tab-dropdown-caret {
  background: transparent;
  border: none;
  color: #c9d6e0;
  cursor: pointer;
  font-size: 0.75rem;
  padding: 8px 6px 8px 0;
  margin-left: -8px;
  border-radius: 6px;
  opacity: 0.85;
}
.tab-dropdown-caret:hover { background: rgba(255,255,255,0.08); opacity: 1; }
.tab-dropdown.open .tab-dropdown-caret { opacity: 1; }

.tab-dropdown-menu {
  min-width: 210px;
  max-height: 70vh;
  overflow-y: auto;
}

/* Override the plain block/no-icon .tab-dropdown-item rule from the old
   "More" menu (still used for its layout basics) with the icon+label
   treatment every dropdown item now needs. */
.tab-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 6px;
  background: transparent;
  border: none;
  color: #dbe6ee;
  font-family: inherit;
  font-size: 0.88rem;
  cursor: pointer;
  white-space: nowrap;
}
.tab-dropdown-item:hover { background: rgba(255,255,255,0.12); color: var(--white); }

.nav-icon {
  width: 16px;
  height: 16px;
  flex: none;
  stroke: currentColor;
  fill: none;
}

.nav-dd-divider {
  border-top: 1px solid rgba(255,255,255,0.15);
  margin-top: 4px;
  padding-top: 4px;
}

/* WhatsApp unread badge, duplicated next to its dropdown item (the original
   #waNavBadge lives on the now-hidden pill-bar button and still updates
   normally — see app.js — this one is just its visible twin). */
.tab-dropdown-item .wa-nav-badge { margin-left: auto; }

/* ===== Module 21 — Legal Terms clause library ===== */
.terms-summary-box { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 10px 14px; background: var(--teal-light); border-radius: 8px; }

.pt-subtabs { display: flex; gap: 6px; margin: 4px 0 16px; border-bottom: 2px solid var(--border); }
.pt-tab-btn { background: transparent; border: none; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -2px; }
.pt-tab-btn.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); }
.pt-tab-btn:disabled { cursor: not-allowed; opacity: 0.5; }
.pt-subview { display: none; }
.pt-subview.active { display: block; }

/* Two working columns: page OPTIONS on the left, a fixed comfortable width
   since it's just a checklist of clauses, and the page LAYOUT on the right
   -- the assembled document itself -- taking every pixel left over, now
   that the page as a whole (see the body:has() rule above) is no longer
   capped at 900px/1400px. Both share one scroll height so they read as one
   clean working page with no separate "Preview" click and no PDF export
   needed to read the actual contract text. */
.pt-layout { display: grid; grid-template-columns: 420px minmax(0, 1fr); gap: 24px; align-items: start; }
@media (max-width: 1150px) { .pt-layout { grid-template-columns: 1fr; } }

.pt-col-scroll { max-height: 760px; overflow-y: auto; }

.pt-options-col #ptClauseSearch { width: 100%; margin: 10px 0; padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; }
.pt-options-list { border: 1px solid var(--border); border-radius: 8px; }
.pt-clause-group-title { background: var(--teal-light); color: var(--navy); font-weight: 700; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.03em; padding: 6px 10px; position: sticky; top: 0; }

/* Include checkbox sits at the far left of every row -- the primary
   include/exclude control for building this proposal's contract. */
.pt-clause-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px; border-bottom: 1px solid var(--border); }
.pt-clause-checkbox { flex: none; padding-top: 2px; }
.pt-clause-checkbox input[type="checkbox"] { width: 17px; height: 17px; cursor: pointer; }
.pt-clause-checkbox input[disabled] { cursor: not-allowed; }
.pt-clause-body { flex: 1; min-width: 0; }
.pt-clause-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pt-clause-title { font-weight: 600; font-size: 0.88rem; }
.pt-clause-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.pt-clause-actions a { color: var(--muted); text-decoration: none; font-size: 0.9rem; }
.pt-clause-actions a:hover { color: var(--navy); }
.pt-clause-actions a.pt-disabled { opacity: 0.25; pointer-events: none; }
.pt-clause-actions button { flex: none; white-space: nowrap; }

/* Full clause text, not just a truncated first line -- clamped to a
   readable handful of lines via CSS rather than cut to one line in JS, so
   longer clauses are actually legible before you check them in. Greyed out
   while the box is unchecked (library text, not yet part of this contract). */
.pt-clause-preview {
  color: var(--muted);
  font-size: 0.83rem;
  line-height: 1.5;
  margin-top: 4px;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pt-clause-preview.muted { opacity: 0.75; }

/* The "Edit box" option -- opened per-row via the Edit button, only for a
   clause that's actually checked in. Editing here never touches the shared
   library, only this proposal's own copy. */
.pt-clause-editbox { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; }
.pt-clause-editbox input[type="text"] { font-weight: 600; padding: 6px 8px; border: 1px solid var(--border); border-radius: 5px; }
.pt-clause-editbox textarea { font-family: inherit; font-size: 0.85rem; line-height: 1.5; padding: 8px; border: 1px solid var(--border); border-radius: 5px; resize: vertical; min-height: 130px; }

/* The full contract, formatted like an actual document (not a plain
   scrolling textarea) and kept live -- every checkbox, edit, and reorder
   on the left re-renders this immediately. */
.pt-preview-col .subsection-title { display: flex; align-items: center; gap: 8px; }
.pt-preview {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 0.86rem;
  color: #2b2b2b;
  line-height: 1.65;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 28px 30px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.08);
}
.pt-preview-clause { margin-bottom: 18px; }
.pt-preview-clause:last-child { margin-bottom: 0; }
.pt-preview-clause h4 {
  margin: 0 0 6px;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--navy);
}

/* Daily Logs feed + Weekly Reports history (module 37) — one card style
   shared by both lists, since they're the same "one entry, one job, one
   date range" shape. */
.dlog-card {
  background: #fff;
  border: 1px solid var(--border, #dfe4e8);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.dlog-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 3px;
}
.dlog-card-head strong { font-size: 0.92rem; color: var(--navy, #12283f); }
.dlog-date { font-size: 0.78rem; color: var(--muted, #647380); white-space: nowrap; }
.dlog-card p { margin: 6px 0 0; font-size: 0.86rem; }
.dlog-flag { color: #a13a26; }

/* Open Job command-center status strip (module 37) — four at-a-glance
   cards (Schedule / Budget / Shipping / Crew) at the top of the Project
   Detail modal. Color is purely a semantic hint (good/neutral/bad), never
   the only signal — the label text always states the actual status. */
.cc-status-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin: 12px 0 16px;
}
.cc-status-card {
  border-radius: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border, #dfe4e8);
  background: #f7f9fa;
}
.cc-status-card.cc-card-good { background: #eaf7f1; border-color: #bfe6d1; }
.cc-status-card.cc-card-bad { background: #fcecea; border-color: #f0c2ba; }
.cc-status-card.cc-card-neutral { background: #f7f9fa; }
.cc-status-label {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted, #647380); font-weight: 700;
}
.cc-status-value { font-size: 0.98rem; font-weight: 700; color: var(--navy, #12283f); margin: 2px 0; }
.cc-status-detail { font-size: 0.76rem; color: var(--muted, #647380); line-height: 1.3; }
@media (max-width: 720px) {
  .cc-status-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Project Detail modal, below the command-center strip (module 42) — was a
   flat stack of uppercase labels and bare content with no visual
   separation, and #projectDetailBody has no <form> ancestor (every other
   modal in the app wraps its content in one), so its select/textarea/
   text-input never picked up .modal form input's styling and rendered as
   plain unstyled browser controls. Restyled those two things directly
   rather than adding a <form> tag, to avoid any risk of accidental
   submit-on-Enter behavior in a text field. */
#projectDetailBody select,
#projectDetailBody textarea,
#projectDetailBody input[type="text"] {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
}
#projectDetailBody label.pd-label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin: 10px 0 4px;
}
.pd-section {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 14px 0;
}
.pd-section-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 700;
  margin: 0 0 10px;
}
.pd-section-title a { font-weight: 600; text-transform: none; letter-spacing: normal; font-size: 0.78rem; }
/* .mini-row already gives a spaced flex row elsewhere in the app (gap:10px
   fixes the bug below); just make the link side truncate instead of
   pushing the status pill off — a real supplier name + PO number is often
   wider than the modal. */
.pd-section .mini-row a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-section .mini-row .ship-stage-pill { flex-shrink: 0; }
.pt-preview-clause p { margin: 0; }

/* ===== Phone nav toggle =====
   No narrow-viewport styling existed anywhere in this stylesheet before the
   Mobile section gave people a page they'd actually open on a phone (same
   gap module 25h's write-up records against the other working copy). Every
   rule below is scoped to the media queries, so above 900px the topbar is
   pixel-identical to before: toggle stays hidden, tab row and user chip stay
   visible, module 20's dropdowns stay absolutely positioned. This is shared
   chrome (.topbar is visible in every section), so per the org's two-changed-
   categories rule it rides in as part of this Mobile module only with Evan's
   own go-ahead as Admin to build the field-crew UI end-to-end. */
.nav-toggle {
  display: none;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.3);
  color: var(--white);
  font-size: 1.1rem;
  line-height: 1;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
}
@media (max-width: 900px) {
  .nav-toggle { display: inline-block; }
  .topbar { flex-wrap: wrap; }
  .topbar .tabs,
  .topbar .user-chip,
  .topbar #newCustomerBtn {
    display: none;
    flex-basis: 100%;
  }
  .topbar.nav-open .tabs,
  .topbar.nav-open .user-chip,
  .topbar.nav-open #newCustomerBtn {
    display: flex;
  }
  .topbar.nav-open .tabs { flex-direction: column; align-items: stretch; gap: 2px; }
  .topbar .tab-btn, .topbar .tab-dropdown-caret { min-height: 44px; }
  /* Module 20's dropdown menus are position:absolute, which would float off
     the stacked column here — render them inline in the flow instead. The
     caret still just toggles .tab-dropdown.open; nothing in app.js changes. */
  .topbar.nav-open .tab-dropdown-menu { position: static; box-shadow: none; }
  .topbar.nav-open .tab-dropdown:not(.open) .tab-dropdown-menu { display: none; }
  .gnotif-wrap { order: -1; margin-left: auto; }
}
@media (max-width: 420px) {
  .modal { width: 94vw !important; max-width: 94vw !important; }
  .modal input, .modal select, .modal textarea { font-size: 16px; } /* stop iOS zoom-on-focus */
}

/* ===== Field-crew nav lockdown (module 25i) =====
   One class on <body>, set in onLoggedIn — the topbar markup is untouched
   and nothing is reordered. `.tabs > *` covers both plain .tab-btn buttons
   and .tab-dropdown wrappers, and only the Mobile button carries data-view
   at that level (the dropdowns use data-group-view instead), so this hides
   every section except Mobile without naming any of them and without
   needing an update when a new office tab is added later — a new tab is
   hidden from crew by default, the safe direction for that mistake to fall.
   `.topbar` is in the selector so this out-specifies the phone-nav-open rule
   above ((1,2,1) vs (1,1,1)) without any !important. */
body.role-fieldcrew .topbar .tabs > *:not([data-view="mobile"]) { display: none; }
body.role-fieldcrew .topbar #newCustomerBtn { display: none; }

/* ===== Mobile / field-crew section (module 25/30) ===== */
.mob-tabs { display: flex; gap: 6px; margin: 4px 0 16px; border-bottom: 2px solid var(--border); flex-wrap: wrap; }
.mob-tab-btn, .mob-seg-btn {
  background: transparent; border: none; padding: 10px 16px; cursor: pointer;
  font-size: 0.9rem; color: var(--muted); border-bottom: 3px solid transparent;
  margin-bottom: -2px; min-height: 44px;
}
.mob-tab-btn.active, .mob-seg-btn.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); }
.mob-tabpane, .mob-pane { display: none; }
.mob-tabpane.active, .mob-pane.active { display: block; }

.mob-job-card {
  border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
  margin-bottom: 10px; cursor: pointer; background: var(--white);
}
.mob-job-card:hover { background: var(--teal-light); }
.mob-job-card .mob-job-name { font-weight: 700; color: var(--navy); font-size: 0.95rem; }
.mob-job-card .mob-job-sub { color: var(--muted); font-size: 0.8rem; margin-top: 2px; }
.mob-job-card .mob-job-dates { color: var(--muted); font-size: 0.78rem; margin-top: 4px; }

.mob-phase-row { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin-bottom: 8px; }
.mob-phase-row .mob-phase-name { font-weight: 600; color: var(--navy); }
.mob-phase-row .mob-phase-dates { font-size: 0.78rem; color: var(--muted); margin-top: 3px; }
.mob-phase-row .mob-phase-dates .mob-actual { color: var(--teal); font-weight: 600; }
.mob-delay-pill { display: inline-block; background: #fcecea; color: #a13a26; border-radius: 999px; padding: 2px 9px; font-size: 0.72rem; margin: 4px 4px 0 0; }

.mob-weather-box { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin: 8px 0; background: #f7f9fa; }
.mob-weather-box .mob-weather-row { display: flex; justify-content: space-between; font-size: 0.85rem; margin-bottom: 4px; }
.mob-weather-box .mob-weather-row:last-child { margin-bottom: 0; }

.mob-media-grid { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.mob-media-thumb { width: 84px; height: 84px; border-radius: 8px; overflow: hidden; position: relative; border: 1px solid var(--border); background: #eef1f3; }
.mob-media-thumb img, .mob-media-thumb video { width: 100%; height: 100%; object-fit: cover; }
.mob-media-thumb .mob-media-video-badge { position: absolute; bottom: 2px; right: 4px; background: rgba(0,0,0,0.6); color: #fff; font-size: 0.62rem; padding: 1px 4px; border-radius: 4px; }
.mob-media-thumb .mob-media-del { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,0.55); color: #fff; border: none; border-radius: 50%; width: 18px; height: 18px; line-height: 1; cursor: pointer; font-size: 0.7rem; }

@media (max-width: 900px) {
  .mob-job-card, .mob-phase-row { padding: 12px; }
  #mob-jobs input, #mob-jobs select, #mobile-view select { min-height: 40px; }
}

/* ---- Module 58b: Agile Chat floating widget (web + mobile) ---- */
/* Minimised state = the Agile Man in a Forest Green circle (2026 Brand
   Standards: Forest Green #1E3D2B, Island Ivory #F6F2E8). */
#agileChatFab {
  position: fixed; right: 18px; bottom: 18px; z-index: 4000;
  width: 64px; height: 64px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid rgba(246,242,232,0.55); border-radius: 50%; cursor: pointer;
  background: #1E3D2B;
  box-shadow: 0 6px 18px rgba(0,0,0,0.3);
}
#agileChatFab:hover { transform: translateY(-1px) scale(1.04); box-shadow: 0 8px 22px rgba(0,0,0,0.35); }
#agileChatFab .fab-logo { width: 46px; height: 46px; object-fit: contain; pointer-events: none; }
#agileChatPanel {
  position: fixed; right: 18px; bottom: 84px; z-index: 4001;
  width: 400px; max-width: calc(100vw - 24px);
  height: 540px; max-height: calc(100vh - 110px);
  display: flex; flex-direction: column;
  background: var(--panel, #fff); color: inherit;
  border: 1px solid var(--border, #d8dcdf); border-radius: 14px;
  box-shadow: 0 12px 34px rgba(0,0,0,0.3); overflow: hidden;
}
/* The hidden attribute must beat the display:flex above, or the panel can
   never minimise. */
#agileChatPanel[hidden] { display: none !important; }
#agileChatPanel .ac-head { display: flex; align-items: center; gap: 6px; padding: 10px 12px; border-bottom: 1px solid var(--border, #d8dcdf); background: #1E3D2B; color: #F6F2E8; }
#agileChatPanel .ac-head .hint { color: #cdd6d9; font-size: 0.72rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
#agileChatPanel .ac-jobrow { display: flex; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border, #d8dcdf); align-items: center; }
#agileChatPanel .ac-jobrow select { flex: 1; min-width: 0; }
#agileChatMessages { flex: 1; overflow-y: auto; padding: 10px 12px; }
#agileChatPanel .ac-inputrow { display: flex; gap: 6px; padding: 10px; border-top: 1px solid var(--border, #d8dcdf); }
#agileChatPanel .ac-inputrow input { flex: 1; min-width: 0; }
@media (max-width: 640px) {
  #agileChatPanel { right: 8px; left: 8px; width: auto; bottom: 78px; height: 70vh; }
  #agileChatFab { right: 12px; bottom: 12px; width: 56px; height: 56px; }
  #agileChatFab .fab-logo { width: 40px; height: 40px; }
}

/* Module 62 — people on the map (Dani's ask). A filled green badge means the
   foreman recorded them present on that day's site report; an outline means
   it is still the plan. Offset from the job pin so neither hides the other. */
.crew-marker { background: none; border: none; }
.crew-marker-inner {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px 2px 4px; border-radius: 13px;
  background: var(--white); border: 1.5px dashed var(--teal);
  font-size: 14px; line-height: 1; white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
}
.crew-marker-inner.observed { border-style: solid; background: var(--teal); }
.crew-marker-inner.observed .crew-count { color: var(--white); }
.crew-marker-inner .crew-count { font-size: 11px; font-weight: 700; color: var(--teal); }
.map-crew-date { display: inline-flex; align-items: center; gap: 6px; }
.map-crew-date label { font-size: 0.8rem; color: var(--muted); }
.map-crew-date input[type=date] { padding: 3px 6px; font-size: 0.8rem; }

/* Modules 63/64 — the job-document generator and the team profile.
   Both are form-heavy dialogs that live outside a <form>, so the .modal form
   selectors above don't reach them; these give them the same field styling. */
.modal-wide { width: 660px; }
.jd-label, .tp-label {
  display: block; font-size: 0.72rem; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted); margin: 12px 0 4px;
}
.jd-label input, .jd-label textarea,
.tp-label input, .tp-label select, .tp-label textarea {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: 6px; font-size: 0.92rem;
  font-family: inherit; text-transform: none; letter-spacing: normal; color: var(--ink);
}
.panel-note {
  background: var(--teal-light); border: 1px solid var(--border);
  border-radius: 6px; padding: 9px 12px; margin: 10px 0 4px; font-size: 0.82rem;
}
.tp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
@media (max-width: 620px) { .tp-grid { grid-template-columns: 1fr; } .modal-wide { width: auto; } }
.tp-doc-row {
  display: flex; align-items: center; gap: 8px; padding: 7px 0;
  border-bottom: 1px solid var(--border); font-size: 0.86rem;
}
.tp-doc-row .tp-doc-main { flex: 1; min-width: 0; }
.tp-expiry { font-size: 0.72rem; padding: 2px 8px; border-radius: 10px; white-space: nowrap; }
.tp-expiry.valid { background: #dff0ea; color: #14634f; }
.tp-expiry.expiring { background: #f5f1e6; color: #6f5a2a; }
.tp-expiry.expired { background: #f6e2df; color: #a13a26; font-weight: 600; }

/* Module 66 — the client running log. Deliberately quiet: it is read in bulk,
   scanning down dates before a call, so the note text carries and the
   metadata recedes. */
.comm-row { align-items: flex-start; padding: 9px 0; }
.comm-when { font-weight: 600; font-size: 0.8rem; }
.comm-chan { font-size: 0.74rem; color: var(--muted); margin-left: 8px; }
.comm-job {
  font-size: 0.7rem; margin-left: 8px; padding: 1px 7px; border-radius: 9px;
  background: var(--teal-light); color: var(--navy);
}
.comm-internal {
  font-size: 0.68rem; margin-left: 8px; padding: 1px 7px; border-radius: 9px;
  background: #f1efe9; color: #6f5a2a; text-transform: uppercase; letter-spacing: 0.06em;
}
.comm-note { margin: 3px 0 0; font-size: 0.88rem; line-height: 1.5; white-space: pre-wrap; }
.comm-follow {
  margin-top: 3px; font-size: 0.8rem; color: var(--navy);
  border-left: 2px solid var(--teal); padding-left: 8px;
}

/* Module 67 — the supplier directory. Collapsed rows scan; open one and you
   get the judgement: who to write to, who has left, what to watch. */
.sup-card { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; background: var(--white); }
.sup-card > summary {
  cursor: pointer; padding: 9px 12px; display: flex; align-items: center;
  gap: 10px; flex-wrap: wrap; font-size: 0.88rem;
}
.sup-card > summary::-webkit-details-marker { color: var(--muted); }
.sup-name { font-weight: 600; }
.sup-status { font-size: 0.68rem; padding: 2px 8px; border-radius: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
.sup-primary { margin-left: auto; }
.sup-body { padding: 4px 14px 14px; border-top: 1px solid var(--border); font-size: 0.86rem; }
.sup-body p { margin: 4px 0; }
.sup-subtitle {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); margin: 12px 0 4px;
}
.sup-contact { padding: 4px 0; border-bottom: 1px dashed var(--border); }
.sup-gone { opacity: 0.75; text-decoration-color: var(--danger); }
.sup-gone strong { text-decoration: line-through; }
.sup-notes { white-space: pre-wrap; line-height: 1.55; background: var(--sand); padding: 9px 12px; border-radius: 6px; }

/* 67b — the party tabs. Suppliers first and selected by default; shippers,
   brokers, subcontractors and personal accounts keep their records without
   cluttering the list someone buys fence from. */
.sup-tabs { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin: 0 0 10px; border-bottom: 1px solid var(--border); }
.sup-tab {
  appearance: none; background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 7px 12px; margin-bottom: -1px; cursor: pointer; font: inherit;
  font-size: 0.84rem; color: var(--muted); border-radius: 4px 4px 0 0;
}
.sup-tab:hover { color: var(--navy); background: var(--sand); }
.sup-tab.active { color: var(--navy); font-weight: 600; border-bottom-color: var(--teal); background: none; }
.sup-tab-n { font-size: 0.72rem; color: var(--muted); font-weight: 400; }
.sup-tab.active .sup-tab-n { color: var(--teal); }
.sup-tab-blurb { flex-basis: 100%; margin: 2px 0 8px; font-size: 0.78rem; }
