/* assets/css/app.css
 *
 * Flattened 2026-08-23: this file previously contained the entire stylesheet
 * twice, and the later (older, flatter) copy won, so the newer "visible
 * elevation" pass was dead code. It is now one rule per selector.
 *
 * 2026-08-23: that newer pass is now ACTIVE — 1.5px borders, tinted card
 * headers, heavier type, and --surface-* / --text-primary / --border-strong
 * tokens in place of hardcoded greys. The :root palette below was always
 * written for it (see the "stepped for visible depth" comments); the rules
 * that consumed it simply never took effect until now.
 */

:root {
  /* ── Brand palette ──────────────────────────────────────────── */
  --brand:       #0033A0;
  --brand-dark:  #002280;
  --brand-light: #dbeafe;

  /* ── Semantic colours ───────────────────────────────────────── */
  --success:  #15803d;
  --warning:  #b45309;
  --danger:   #b91c1c;

  /* ── Surfaces — stepped for visible depth ───────────────────── */
  --surface-0:  #e8eaed;   /* page background — darker than before */
  --surface-1:  #f1f3f5;   /* in-flow card / subtle section */
  --surface-2:  #ffffff;   /* raised card / panel */
  --surface-3:  #ffffff;   /* popover / floating */
  --bg:         var(--surface-0);
  --white:      #ffffff;

  /* ── Text — higher contrast hierarchy ──────────────────────── */
  --text:            #111827;   /* primary — near black */
  --text-primary:    #111827;
  --text-secondary:  #374151;   /* strong enough to read on white */
  --text-muted:      #6b7280;   /* labels, hints */
  --text-disabled:   #9ca3af;
  --text-accent:     #1d4ed8;
  --text-success:    #15803d;
  --text-danger:     #b91c1c;
  --text-warning:    #92400e;

  /* ── Borders — more visible ──────────────────────────────────── */
  --border:        #c4c9d4;   /* was #d1d5db — more visible */
  --border-strong: #9ca3b0;   /* hover / emphasis */
  --border-stronger: #6b7280;
  --border-accent: #3b82f6;

  /* ── Role fills (for mobile dropdowns, buttons etc.) ─────────── */
  --fill-accent:         #0033A0;
  --fill-accent-hover:   #002280;
  --bg-accent:           #dbeafe;
  --on-accent:           #ffffff;
  --bg-success:          #dcfce7;
  --bg-danger:           #fee2e2;
  --bg-warning:          #fef3c7;

  /* ── Legacy aliases ──────────────────────────────────────────── */
  --accent:     #0033A0;

  /* -- Development instance (sidebar only) --------------------- */
  /* Applied via .sidebar--dev when APP_ENV !== 'production'.
     Light grey so a dev instance is obvious at a glance. The whole
     sidebar palette has to flip, not just the background: the normal
     sidebar is brand blue with white text, which would be unreadable
     on grey. */
  --dev-sidebar-bg:         #d5d8dd;
  --dev-sidebar-text:       #1f2937;
  --dev-sidebar-text-muted: #4b5563;
  --dev-sidebar-hover:      rgba(0,0,0,.07);
  --dev-sidebar-active:     rgba(0,0,0,.11);
  --dev-sidebar-border:     rgba(0,0,0,.16);

  /* -- Values that were repeated as inline hex in app pages ----- */
  /* Named so they can be referenced instead of hardcoded. Each is the
     EXACT value that was already in use, so naming them changed nothing
     visually. */
  --brand-tint:          #e8edf8;   /* pale brand wash, matches BRAND_LIGHT in config.php */
  --surface-tint:        #eef0f4;   /* slightly cooler than --surface-1 */
  --text-warning-strong: #78350f;   /* deeper than --text-warning, for small text on amber */
  --bg-warning-subtle:   #fffbeb;   /* lighter than --bg-warning */
  --bg-success-subtle:   #f0fdf4;   /* lighter than --bg-success */
  --text-success-strong: #166534;   /* deeper than --success */
  --surface-inverse:     #1e1e2e;   /* dark panel (code/preview blocks) */
  --border-success:      #86efac;   /* green rule on success panels */
  --border-warning:      #fcd34d;   /* amber rule on warning panels */
  --bg-overdue:          #fff5f5;   /* row tint for overdue activities */
  --text-success-deep:   #14532d;   /* darkest green, small text on pale green */
  /* ── Misc ────────────────────────────────────────────────────── */
  --radius:    6px;
  --shadow:    0 1px 3px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.08);
  --shadow-md: 0 4px 8px rgba(0,0,0,.12), 0 2px 4px rgba(0,0,0,.08);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.08);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--bg);
  min-height: 100vh;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── Layout ──────────────────────────────────────────────────── */
.layout { display: flex; min-height: 100vh; }

.sidebar {
  width: 240px;
  background: var(--brand);
  color: #fff;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 100;
  overflow-y: auto;
}

.sidebar-logo {
  padding: 20px 20px 16px;
  border-bottom: 1px solid rgba(255,255,255,.2);
}
.sidebar-logo .company { font-size: 18px; font-weight: 700; letter-spacing: -.3px; }
.sidebar-logo .app-name { font-size: 11px; opacity: .75; margin-top: 2px; }

.sidebar-nav { flex: 1; padding: 12px 0; }
.sidebar-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 20px;
  color: rgba(255,255,255,.85);
  font-size: 13px;
  transition: background .15s, color .15s;
  border-left: 3px solid transparent;
}
.sidebar-nav a:hover, .sidebar-nav a.active {
  background: rgba(255,255,255,.15);
  color: #fff;
  border-left-color: #fff;
  text-decoration: none;
}
.sidebar-nav .nav-section {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .55;
  padding: 16px 20px 4px;
}

.sidebar-user {
  padding: 14px 20px;
  border-top: 1px solid rgba(255,255,255,.2);
  font-size: 12px;
}
.sidebar-user .user-name { font-weight: 600; }
.sidebar-user .user-role { opacity: .65; font-size: 11px; }

.main {
  margin-left: 240px;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  /* A flex item defaults to min-width:auto, so it cannot shrink below its
     content's intrinsic width. A table wider than the viewport therefore
     stretched .main past the window and scrolled the WHOLE PAGE sideways —
     and it also defeated .table-wrap's overflow-x:auto, because the wrapper
     was being stretched rather than constrained. min-width:0 lets .main
     shrink to the available width so the table scrolls inside its own card
     instead. */
  min-width: 0;
}

.topbar {
  background: var(--white);
  border-bottom: 2px solid var(--border);
  padding: 0 28px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* FIXED, not sticky. `position: sticky` only pins vertically — the bar still
     scrolls horizontally with the page, so the stream switcher and account menu
     on the right slid out of view whenever content was wider than the window:
     off to the right when scrolled left, off to the left when scrolled right.
     A sticky child could not fix it either, because a sticky element is clamped
     to its containing block and the containing block is the bar itself.
     Fixed positions it against the viewport, so those controls stay put on both
     axes — matching the sidebar, which is already fixed. */
  position: fixed;
  top: 0;
  left: 240px;      /* clears the fixed sidebar; kept in step with it below */
  right: 0;
  z-index: 50;
  box-shadow: var(--shadow);
}
.topbar-title { font-size: 16px; font-weight: 600; }
.topbar-actions { display: flex; align-items: center; gap: 12px; }

/* The fixed topbar no longer takes up space in the flow, so reserve its
   56px height here. Without this the first card slides under the bar. */
.content { padding: 84px 28px 28px; flex: 1; min-width: 0; }

/* ── Cards — visible elevation ───────────────────────────────── */
.card {
  background: var(--surface-2);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card-header {
  padding: 14px 20px;
  background: var(--surface-1);        /* tinted header distinguishes from body */
  border-bottom: 1.5px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.card-header h2 { font-size: 14px; font-weight: 700; color: var(--text-primary); text-transform: uppercase; letter-spacing: .04em; }
.card-body { padding: 20px; }

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px;
  font-size: 13px; font-weight: 600;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: all .15s;
  white-space: nowrap;
  text-decoration: none;
}
.btn-primary   { background: var(--brand); color: #fff; border-color: var(--brand); }
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); color: #fff; text-decoration: none; }
.btn-secondary { background: var(--white); color: var(--text-primary); border-color: var(--border-strong); }
.btn-secondary:hover { background: var(--surface-1); border-color: var(--border-stronger); text-decoration: none; }
.btn-success   { background: var(--success); color: #fff; border-color: var(--success); }
.btn-danger    { background: var(--danger);  color: #fff; border-color: var(--danger); }
.btn-sm        { padding: 4px 10px; font-size: 12px; }
.btn-xs        { padding: 2px 8px; font-size: 11px; }
.btn:disabled  { opacity: .45; cursor: not-allowed; }

/* ── Badges ──────────────────────────────────────────────────── */
.badge {
  display: inline-block;
  font-size: 11px; font-weight: 700;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
}
.badge-blue   { background: #dbeafe; color: #1d4ed8; border: 1px solid #bfdbfe; }
.badge-green  { background: #dcfce7; color: #15803d; border: 1px solid #bbf7d0; }
.badge-teal   { background: #ccfbf1; color: #0f766e; border: 1px solid #99f6e4; }
.badge-amber  { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
.badge-red    { background: #fee2e2; color: #991b1b; border: 1px solid #fecaca; }
.badge-gray   { background: #e5e7eb; color: #374151; border: 1px solid var(--border-strong); }
.badge-brand  { background: var(--brand-light); color: var(--brand); border: 1px solid #bfdbfe; }

/* ── Forms ───────────────────────────────────────────────────── */
.form-section-title {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-primary);
  padding: 12px 0 8px; margin-bottom: 4px;
  border-bottom: 2px solid var(--brand);
}
.form-group { margin-bottom: 16px; }
.form-label { display: block; font-size: 12px; font-weight: 700; color: var(--text-secondary); margin-bottom: 5px; text-transform: uppercase; letter-spacing: .04em; }
.form-control {
  width: 100%;
  padding: 8px 12px;
  font-size: 13px;
  border: 1.5px solid var(--border-strong);  /* was 1px #d1d5db — much more visible */
  border-radius: var(--radius);
  background: var(--white);
  color: var(--text-primary);
  transition: border-color .15s, box-shadow .15s;
}
.form-control:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0,51,160,.12); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.form-hint { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

/* ── Tables ──────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th {
  background: var(--surface-0);   /* clearly different from white card body */
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-secondary);
  padding: 10px 14px; text-align: left;
  border-bottom: 2px solid var(--border-strong);  /* stronger separator */
}
tbody td { padding: 11px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-1); }

/* ── Alerts / Flash ──────────────────────────────────────────── */
.alert { padding: 12px 16px; border-radius: var(--radius); margin-bottom: 16px; font-size: 13px; border: 1.5px solid transparent; font-weight: 500; }
.alert-success { background: #dcfce7; color: #14532d; border-color: #86efac; }
.alert-error   { background: #fee2e2; color: #7f1d1d; border-color: #fca5a5; }
.alert-info    { background: var(--brand-light); color: #1e3a8a; border-color: #93c5fd; }
.alert-warning { background: #fef3c7; color: #78350f; border-color: #fcd34d; }

/* ── Progress ────────────────────────────────────────────────── */
.progress { height: 8px; background: var(--surface-0); border-radius: 4px; overflow: hidden; border: 1px solid var(--border); }
.progress-bar { height: 100%; background: var(--brand); border-radius: 4px; transition: width .4s; }

/* ── Site Cards (portfolio) ──────────────────────────────────── */
.site-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.site-card { background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow); transition: box-shadow .15s, border-color .15s, transform .1s; text-decoration: none; color: var(--text-primary); display: block; }
.site-card--banner { padding: 0; overflow: hidden; }
.site-card--banner .site-card__body { padding: 14px 16px; }
.site-card:hover { box-shadow: var(--shadow-md); border-color: var(--brand); text-decoration: none; transform: translateY(-1px); }
.site-card .site-name { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
.site-card .site-meta { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
.site-card .site-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.site-card .stat { text-align: center; }
.site-card .stat-num { font-size: 20px; font-weight: 700; line-height: 1; }
.site-card .stat-lbl { font-size: 10px; color: var(--text-muted); margin-top: 2px; text-transform: uppercase; }
.site-card .stat-num.danger { color: var(--danger); }

/* ── Activity list ───────────────────────────────────────────── */
.activity-row {
  display: grid;
  /* Trigger column is 96px, not 80px: the "Send email" button measures 90px
     and was overflowing its column by 10px, spilling past the row's tinted
     background. Most visible on overdue rows, where the tint stops at the
     row edge and the button continued beyond it.
     First column is 22px rather than 16px so the status dot is centred with
     breathing room instead of sitting flush against the card edge. */
  grid-template-columns: 22px 52px 1fr 100px 100px 96px;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
/* Keep the last column's contents right-aligned so the button and the "—"
   placeholder line up with the TRIGGER header and the card's right edge. */
.activity-row > *:last-child {
  justify-self: end;
}
.activity-row:last-child { border-bottom: none; }
/* Status is differentiated by SHAPE as well as colour, so it stays readable
   without colour vision: hollow = pending, half-filled = in progress,
   solid = done. Paired with a title/aria-label in the markup for screen
   readers, since colour and shape are both invisible to those. */
.status-indicator {
  width: 11px; height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
  justify-self: center;
  box-sizing: border-box;
}
.status-pending {
  background: transparent;
  border: 2px solid var(--text-disabled);          /* hollow */
}
.status-in_progress {
  background: linear-gradient(90deg,
              var(--brand) 0 50%, transparent 50% 100%);   /* half filled */
  border: 2px solid var(--brand);
}
.status-done {
  background: var(--success);
  border: 2px solid var(--success);                /* solid */
}

.phase-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0 10px;
}
.phase-divider-label {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em;
  color: #fff;
  background: var(--brand);
  padding: 3px 12px;
  border-radius: 10px;
  white-space: nowrap;
}
.phase-divider-line { flex: 1; height: 2px; background: var(--border); }

/* ── Email template preview ──────────────────────────────────── */
.email-preview-wrap {
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.email-header-bar {
  background: var(--brand);
  color: #fff;
  padding: 16px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.email-header-bar .logo-text { font-size: 18px; font-weight: 700; }
.email-meta { background: var(--surface-1); padding: 12px 24px; border-bottom: 1.5px solid var(--border); }
.email-meta table { font-size: 12px; }
.email-meta td { padding: 2px 8px 2px 0; color: var(--text-secondary); }
.email-meta td:first-child { font-weight: 700; width: 60px; }
.email-body-wrap { padding: 24px; background: var(--white); font-size: 14px; line-height: 1.7; }
.email-footer-bar {
  background: var(--surface-1);
  border-top: 1.5px solid var(--border);
  padding: 12px 24px;
  font-size: 11px;
  color: var(--text-muted);
  text-align: center;
}
.placeholder {
  background: #fef3c7;
  color: #78350f;
  padding: 1px 5px;
  border-radius: 3px;
  font-family: monospace;
  font-size: 12px;
  border: 1px solid #fcd34d;
}

/* ── Checklist ───────────────────────────────────────────────── */
.checklist-category {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-secondary);
  margin: 16px 0 6px; padding: 6px 0 6px;
  border-bottom: 2px solid var(--border-strong);
  background: var(--surface-1);
  padding-left: 4px;
}
.check-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.check-item:last-child { border-bottom: none; }
.check-item input[type=checkbox] { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; flex-shrink: 0; }
.check-item label { font-size: 13px; cursor: pointer; color: var(--text-primary); }
.check-item.done label { text-decoration: line-through; color: var(--text-muted); }

/* ── Notifications ───────────────────────────────────────────── */
.notif-count {
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 10px;
  min-width: 18px;
  text-align: center;
}
.notif-item { padding: 10px 16px; border-bottom: 1px solid var(--border); font-size: 12px; }
.notif-item.unread { background: #eff6ff; border-left: 3px solid var(--brand); }
.notif-type { font-weight: 700; font-size: 11px; text-transform: uppercase; }
.notif-type.overdue { color: var(--danger); }
.notif-type.template_update { color: var(--warning); }
.notif-type.info { color: var(--brand); }

/* ── Audit log ───────────────────────────────────────────────── */
.audit-entry { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 12px; }
.audit-time { color: var(--text-muted); white-space: nowrap; min-width: 130px; }
.audit-user { font-weight: 600; min-width: 100px; }
.audit-detail { color: var(--text-primary); }

/* ── Modal ───────────────────────────────────────────────────── */
.modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal { background: var(--white); border-radius: var(--radius); box-shadow: var(--shadow-md); width: 100%; max-width: 640px; max-height: 90vh; overflow-y: auto; }
.modal-header { padding: 18px 24px; border-bottom: 1.5px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.modal-header h3 { font-size: 15px; font-weight: 700; }
.modal-body { padding: 24px; }
.modal-footer { padding: 16px 24px; border-top: 1.5px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }

/* ── Stat cards ──────────────────────────────────────────────── */
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat-card { background: var(--white); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 16px 20px; box-shadow: var(--shadow); }
.stat-card .num { font-size: 28px; font-weight: 700; line-height: 1; color: var(--text-primary); }
.stat-card .lbl { font-size: 12px; color: var(--text-secondary); margin-top: 4px; font-weight: 500; }
.stat-card.brand   { border-left: 4px solid var(--brand); }
.stat-card.success { border-left: 4px solid var(--success); }
.stat-card.danger  { border-left: 4px solid var(--danger); }
.stat-card.warning { border-left: 4px solid var(--warning); }

/* ── Utilities ───────────────────────────────────────────────── */
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-4 { margin-top: 16px; }
.mt-6 { margin-top: 24px; }
.mb-2 { margin-bottom: 8px; }
.mb-4 { margin-bottom: 16px; }
.mb-6 { margin-bottom: 24px; }
.text-muted    { color: var(--text-muted); }
.text-sm       { font-size: 12px; }
.text-right    { text-align: right; }
.font-bold     { font-weight: 700; }
.font-semibold { font-weight: 600; }
.w-full        { width: 100%; }

@media (max-width: 900px) {
  .sidebar { width: 200px; }
  .main { margin-left: 200px; }
  .topbar { left: 200px; }
  .form-grid, .form-grid-3 { grid-template-columns: 1fr; }
}


/* ============================================================================
   DEVELOPMENT INSTANCE
   ----------------------------------------------------------------------------
   .sidebar--dev is added by src/helpers/layout.php when APP_ENV is not
   'production'. It turns the navigation bar light grey so a development
   instance cannot be mistaken for the live site.

   These rules live at the END of the file so they win over the base .sidebar
   rules above. (This file previously contained the entire stylesheet twice,
   which made ordering treacherous; it has since been flattened to one rule
   per selector.)

   Every colour the default sidebar sets has to be re-stated here. The normal
   sidebar is brand blue (var(--brand)) with white text and rgba(255,255,255,…)
   hovers and borders; left as-is on a grey background, the nav links would be
   white on light grey and effectively invisible.
   ========================================================================== */

.sidebar.sidebar--dev {
  background: var(--dev-sidebar-bg);
  color: var(--dev-sidebar-text);
  /* Brand blue separated itself from the page background (--surface-0,
     #e8eaed) on its own. Grey does not — the two are only 1.19:1 apart, so
     without an explicit edge the sidebar bleeds into the page. box-sizing is
     border-box globally, so this does not disturb the 240px width that
     .main's margin-left depends on. */
  border-right: 1px solid var(--dev-sidebar-border);
}

.sidebar.sidebar--dev .sidebar-logo {
  border-bottom-color: var(--dev-sidebar-border);
}

.sidebar.sidebar--dev .sidebar-nav a {
  color: var(--dev-sidebar-text-muted);
}

.sidebar.sidebar--dev .sidebar-nav a:hover {
  background: var(--dev-sidebar-hover);
  color: var(--dev-sidebar-text);
  border-left-color: var(--dev-sidebar-border);
}

.sidebar.sidebar--dev .sidebar-nav a.active {
  background: var(--dev-sidebar-active);
  color: var(--dev-sidebar-text);
  /* Keep the brand colour as the active marker so the nav still reads as
     this product, just not as production. */
  border-left-color: var(--brand);
}

.sidebar.sidebar--dev .sidebar-nav .nav-section {
  color: var(--dev-sidebar-text-muted);
  opacity: .75;
}

.sidebar.sidebar--dev .sidebar-user {
  border-top-color: var(--dev-sidebar-border);
  color: var(--dev-sidebar-text);
}

/* ----------------------------------------------------------------------------
   Release version, sidebar footer
   Renders APP_VERSION on every page so the value visible on a running site
   identifies exactly which package is deployed there.
   -------------------------------------------------------------------------- */

.sidebar-user .app-version {
  margin-top: 6px;
  font-size: 10px;
  letter-spacing: .04em;
  opacity: .6;
  font-variant-numeric: tabular-nums;
}

/* On the grey dev sidebar the text is dark, so opacity would push it below
   AA. Use the muted token at full opacity instead: 5.29:1 on --dev-sidebar-bg. */
.sidebar.sidebar--dev .sidebar-user .app-version {
  color: var(--dev-sidebar-text-muted);
  opacity: 1;
  font-weight: 600;
}

/* ============================================================================
   Keyboard focus
   ----------------------------------------------------------------------------
   The stylesheet previously had exactly one :focus rule, and it set
   outline:none — so nothing showed a focus indicator and the app could not be
   navigated by keyboard. :focus-visible means these appear for keyboard users
   without putting a ring around every mouse click.
   ========================================================================== */

a:focus-visible,
button:focus-visible,
.btn:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Inside the brand-blue sidebar a blue ring would be invisible. */
.sidebar-nav a:focus-visible,
.sidebar a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -3px;
}
.sidebar.sidebar--dev .sidebar-nav a:focus-visible {
  outline-color: var(--brand);
}

/* Inputs keep their existing ring; add the outline for keyboard users only. */
.form-control:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

/* ============================================================================
   Narrow screens
   ----------------------------------------------------------------------------
   Field engineers open the PR1-EPP project page on a phone to reach the mobile
   tracker. At 390px the 200px sidebar consumed over half the screen and the
   page scrolled sideways. Below 700px the sidebar collapses to an icon rail:
   navigation is preserved (unlike hiding it), and ~145px of width is returned.
   ========================================================================== */

@media (max-width: 700px) {
  .sidebar { width: 56px; }
  .main    { margin-left: 56px; }
  .topbar  { left: 56px; padding: 0 12px; }

  .sidebar-logo,
  .sidebar-user,
  .sidebar-nav .nav-section { display: none; }

  /* font-size:0 hides the label while the icon keeps its own size. */
  .sidebar-nav a {
    justify-content: center;
    padding: 12px 0;
    font-size: 0;
    gap: 0;
    border-left-width: 2px;
  }
  .sidebar-nav a i { font-size: 17px; }

  .content { padding: 76px 12px 20px; }
  .card-body { padding: 14px; }

  /* The topbar has to fit a long stream name and the account button in ~320px.
     Let the title truncate rather than push the controls off-screen. */
  .topbar-title {
    font-size: 14px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .topbar-actions { flex-shrink: 0; gap: 6px; }
  .stream-btn { max-width: 132px; overflow: hidden; }
  .stream-btn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Tab strips scroll sideways inside themselves instead of widening the page. */
  .tab-strip {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
  }
  .tab-strip::-webkit-scrollbar { display: none; }
  .tab-strip > a { flex: 0 0 auto; }

  /* Header action buttons wrap onto a second line rather than overflowing. */
  .page-header .flex { flex-wrap: wrap; }
  .btn { white-space: nowrap; }

  /* Wide tables scroll inside their card rather than moving the page. */
  .table-wrap { -webkit-overflow-scrolling: touch; }
}

/* Jump-to-mobile banner on the PR1-EPP project page.
   Hidden entirely on desktop; on a narrow viewport it is the first thing in
   the content area, so a field engineer does not have to scroll ~850px and
   open the Tracker tab to find the mobile view. */
.mobile-jump { display: none; }

@media (max-width: 700px) {
  .mobile-jump {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 14px;
    padding: 12px 14px;
    background: var(--brand);
    color: #fff;
    border-radius: var(--radius);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: var(--shadow);
  }
  .mobile-jump:hover { background: var(--brand-dark); color: #fff; text-decoration: none; }
  .mobile-jump i { font-size: 16px; }
}

/* ============================================================================
   Application log rows
   ----------------------------------------------------------------------------
   The log is a scanning surface: the reader is looking for the one error among
   a hundred info lines. Severity used to be a small badge only, so it had to be
   read row by row. A coloured left rule plus a subtle tint makes errors and
   warnings findable at a glance, and the rows are tightened so more fit on
   screen. Info and debug are deliberately left plain — tinting everything would
   signal nothing.
   ========================================================================== */

.log-row > td { padding: 7px 10px; vertical-align: top; }

.log-row.log-error {
  background: var(--bg-danger);
  box-shadow: inset 3px 0 0 var(--danger);
}
.log-row.log-warning {
  background: var(--bg-warning-subtle);
  box-shadow: inset 3px 0 0 var(--warning);
}
.log-row.log-notice {
  box-shadow: inset 3px 0 0 var(--border-strong);
}

/* Collapsed context payload */
.log-context { margin-top: 2px; }
.log-context > summary {
  font-size: 10px;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  user-select: none;
}
.log-context > summary::-webkit-details-marker { display: none; }
.log-context > summary::before { content: '▸'; font-size: 9px; }
.log-context[open] > summary::before { content: '▾'; }
.log-context > summary:hover { color: var(--text-secondary); }
.log-context > div {
  font-size: 10px;
  color: var(--text-muted);
  font-family: monospace;
  margin-top: 3px;
  word-break: break-all;
}
