@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');

:root {
  --bg: #03073dfa;          /* body background — deep navy */
  --surface: #041c49;      /* sidebar / cards — slightly lighter dark navy */
  --surface-hover: #16233d;
  --border: #1e2c47;
  --text: #e8edf7;
  --text-muted: #8b9ab5;
  --text-faint: #5a6b8a;
  --accent: #3b82f6;
  --accent-2: #06b6d4;
  --accent-hover: #2563eb;
  --success: #34d399;
  --warning: #fbbf24;
  --danger: #f87171;
  --danger-bg: rgba(248, 113, 113, 0.12);
  --success-bg: rgba(52, 211, 153, 0.12);
  --warning-bg: rgba(251, 191, 36, 0.12);
  --accent-bg: rgba(59, 130, 246, 0.12);
  --radius: 12px;
  --shadow: 0 4px 24px rgba(0,0,0,0.3);
}

* { box-sizing: border-box; }

body {
  font-family: 'Inter', -apple-system, "Segoe UI", Roboto, sans-serif;
  background:
    radial-gradient(circle at 15% 0%, rgba(59,130,246,0.08), transparent 40%),
    radial-gradient(circle at 85% 10%, rgba(6,182,212,0.06), transparent 40%),
    var(--bg);
  color: var(--text);
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
}

.page {
  max-width: 1120px;
  margin: 0 auto;
  padding: 36px 40px 60px;
}

/* Navbar */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 40px;
  border-bottom: 1px solid var(--border);
  background: rgba(18, 20, 27, 0.75);
  backdrop-filter: blur(10px);
  position: sticky;
  top: 0;
  z-index: 10;
}
.navbar .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text);
  text-decoration: none;
}
.navbar .brand img {
  display: block;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.06), 0 4px 12px rgba(59,130,246,0.25);
}
.navbar .nav-right {
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: 14px;
  color: var(--text-muted);
}
.navbar .nav-right a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s;
}
.navbar .nav-right a:hover { color: var(--text); }
.navbar .nav-right .username {
  color: var(--text);
  font-weight: 600;
  padding: 5px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  font-size: 13px;
}

/* Back link */
.back-link {
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 24px;
  transition: color 0.15s;
}
.back-link:hover { color: var(--accent); }

h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; margin: 0 0 8px 0; }
h2 { font-size: 17px; font-weight: 700; margin: 0 0 16px 0; }
p.subtitle { color: var(--text-muted); font-size: 14px; margin: 0 0 24px 0; line-height: 1.5; }

/* Card grid */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  margin-bottom: 44px;
}
.card {
  background: linear-gradient(180deg, var(--surface) 0%, rgba(19,26,43,0.6) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  text-decoration: none;
  color: var(--text);
  display: flex;
  align-items: flex-start;
  gap: 14px;
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
  position: relative;
  overflow: hidden;
}
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(59,130,246,0.06), transparent 60%);
  opacity: 0;
  transition: opacity 0.18s;
}
.card:hover {
  border-color: rgba(59,130,246,0.4);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.card:hover::before { opacity: 1; }
.card .icon {
  font-size: 18px;
  line-height: 1;
  width: 36px; height: 36px;
  min-width: 36px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(2, 22, 54, 0.137);
  border-radius: 8px;
}
.card .title { font-size: 15px; font-weight: 700; margin-bottom: 4px; position: relative; }
.card .desc { font-size: 13px; color: var(--text-muted); line-height: 1.4; position: relative; }
.card.warn { border-color: rgba(251,191,36,0.25); }
.card.warn .icon { background: rgba(251,191,36,0.1); }
.card.warn .desc { color: var(--warning); }

/* Section titles */
.section-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: 14px;
  font-weight: 700;
}

/* Tables */
table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
th, td {
  padding: 14px 18px;
  text-align: left;
  font-size: 13.5px;
  border-bottom: 1px solid var(--border);
}
tr:last-child td { border-bottom: none; }
th {
  background: rgba(255,255,255,0.02);
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
}
tbody tr { transition: background 0.15s; }
tbody tr:hover { background: var(--surface-hover); }
code {
  font-family: "SF Mono", Consolas, monospace;
  font-size: 12.5px;
  color: var(--accent-2);
  background: rgba(6,182,212,0.08);
  padding: 2px 6px;
  border-radius: 4px;
}
tbody tr:nth-child(even) {
  background: rgba(255,255,255,0.015);
}
td:last-child { max-width: 400px; }
table a { color: #60a5fa; text-decoration: none; font-weight: 600; }
table a:hover { text-decoration: underline; }

/* Findings table (scan_detail.html) — Prowler infra findings can carry
   very long "Location" resource paths (full Azure/AWS resource IDs
   with no natural break points, e.g. "/subscriptions/xxx/
   resourceGroups/xxx/providers/Microsoft.ContainerService/
   managedClusters/aks-dev") and long remediation text. Under the
   default table-layout: auto above, columns just grow to fit that
   content instead of wrapping — td:last-child's max-width is
   effectively inert there, since auto layout sizes columns from
   content first. table-layout: fixed here makes the column widths
   below authoritative, which is what actually makes wrapping happen.
   Scoped to .findings-table (not the shared `table`/`code` rules)
   so scans_list.html and the project-list tables — short, unrelated
   content — are untouched. */
.findings-table { table-layout: fixed; }
.findings-table th:nth-child(1), .findings-table td:nth-child(1) { width: 9%; }
.findings-table th:nth-child(2), .findings-table td:nth-child(2) { width: 9%; }
.findings-table th:nth-child(3), .findings-table td:nth-child(3) { width: 25%; }
.findings-table th:nth-child(4), .findings-table td:nth-child(4) { width: 15%; }
.findings-table th:nth-child(5), .findings-table td:nth-child(5) { width: 42%; }
.findings-table td { overflow-wrap: break-word; }
.findings-table td code {
  display: inline-block;
  white-space: normal;
  word-break: break-all;
  overflow-wrap: break-word;
}
.findings-table .remediation-box { overflow-wrap: break-word; }
.empty {
  color: var(--text-faint);
  font-size: 14px;
  padding: 40px 20px;
  text-align: center;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}

/* Status badges */
.status {
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 20px;
  display: inline-block;
  letter-spacing: 0.02em;
}
.status-complete { color: var(--success); background: var(--success-bg); }
.status-pending { color: var(--warning); background: var(--warning-bg); }
.status-failed { color: var(--danger); background: var(--danger-bg); }

/* Buttons */
.btn {
  display: inline-block;
  padding: 10px 22px;
  border-radius: 8px;
  border: none;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.1s, box-shadow 0.15s, background 0.15s;
}
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: white;
  box-shadow: 0 2px 12px rgba(59,130,246,0.3);
}
.btn-primary:hover { box-shadow: 0 4px 18px rgba(59,130,246,0.45); }
.btn-success { background: #16a34a; color: white; }
.btn-success:hover { background: #15803d; }
.btn-danger { background: var(--danger); color: white; }
.btn-danger:hover { background: #ef4444; }

/* Forms */
input[type=text], input[type=password], input[type=email] {
  width: 100%;
  padding: 11px 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59,130,246,0.15);
}
input::placeholder { color: var(--text-faint); }

/* Auth pages */
.auth-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background:
    radial-gradient(circle at 20% 20%, rgba(59,130,246,0.1), transparent 45%),
    radial-gradient(circle at 80% 80%, rgba(6,182,212,0.08), transparent 45%),
    var(--bg);
}
.auth-box {
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 36px 32px;
  border-radius: 16px;
  width: 360px;
  box-shadow: var(--shadow);
}
.auth-box .brand-label {
  text-align: center;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 16px;
  color: var(--text);
}
.auth-box .brand-label .vi-accent {
  background: linear-gradient(135deg, #3b82f6, #10b981);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.auth-box h1 { text-align: center; font-size: 21px; }
.auth-box form { margin-top: 22px; display: flex; flex-direction: column; gap: 14px; }
.auth-box .btn { width: 100%; text-align: center; padding: 12px; }
.auth-box .switch { text-align: center; font-size: 13px; color: var(--text-muted); margin-top: 18px; }
.auth-box .switch a { color: var(--accent-2); font-weight: 600; text-decoration: none; }
.auth-box .switch a:hover { text-decoration: underline; }

.error-box {
  background: var(--danger-bg);
  color: #fca5a5;
  padding: 11px 16px;
  border-radius: 8px;
  font-size: 13px;
  margin-bottom: 18px;
  border: 1px solid rgba(248,113,113,0.25);
}
.error-box a { color: inherit; font-weight: 600; text-decoration: underline; }

/* Compact persistent banner shown in the sidebar/user-footer area on
   every dashboard page when the logged-in user's subscription is
   past_due — see show_past_due_banner() in api.py. */
.past-due-banner {
  background: var(--danger-bg);
  color: #fca5a5;
  border: 1px solid rgba(248,113,113,0.25);
  border-radius: 8px;
  padding: 9px 12px;
  font-size: 12px;
  line-height: 1.4;
  margin: 0 0 12px;
}
.past-due-banner a { color: inherit; font-weight: 700; text-decoration: underline; }
/* A finding's "how to fix" text (findings.remediation) — shown as a
   distinct tinted block under a finding's description, not just more
   paragraph text, so it's scannable at a glance. Older findings saved
   before this column existed have remediation = NULL and simply don't
   render this block (see scan_detail.html/report.py) rather than
   showing an empty or "None" box. */
.remediation-box {
  background: var(--accent-bg);
  color: var(--text);
  padding: 8px 12px;
  border-radius: 6px;
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.5;
  border: 1px solid rgba(59, 130, 246, 0.25);
}
.remediation-label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-2);
  margin-bottom: 3px;
}
.connected {
  background: var(--success-bg);
  color: #6ee7b7;
  padding: 11px 16px;
  border-radius: 8px;
  margin-bottom: 18px;
  font-size: 13px;
  border: 1px solid rgba(52,211,153,0.25);
}
.not-connected {
  background: var(--warning-bg);
  color: #fcd34d;
  padding: 11px 16px;
  border-radius: 8px;
  margin-bottom: 18px;
  font-size: 13px;
  border: 1px solid rgba(251,191,36,0.25);
}

/* App shell: sidebar + main content */
.app-shell {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 220px;
  min-width: 220px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 20px 12px;
  position: sticky;
  top: 0;
  height: 100vh;
}
.sidebar .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 20px;
  font-size: 16px;
  font-weight: 800;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
.sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.sidebar nav a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
}
.sidebar nav a .nav-icon {
  font-size: 20px;
  width: 20px;
  text-align: center;
}
/* SVG counterpart to .nav-icon (emoji spans) — sized to match the
   emoji's rendered footprint (16px glyph in a 20px slot) so swapping
   one for the other doesn't shift row height or icon column alignment. */
.sidebar nav a .nav-icon-svg {
  width: 22px;
  height: 22px;
  flex: none;
  display: inline-block;
}
.sidebar nav a:hover { background: var(--surface-hover); color: var(--text); }
.sidebar nav a.active {
  background: rgba(9, 7, 131, 0.808);
  color: var(--text);
  font-weight: 600;
}
.sidebar nav a.active .nav-icon { filter: none; }
/* A sidebar entry for a provider that isn't built yet (currently just
   GCP infra scanning) -- same layout as a real nav link so it doesn't
   shift anything around it, but not an <a> (nothing to navigate to
   yet) and visually muted so it doesn't read as a live, clickable
   destination. The "Soon" badge is the only thing that distinguishes
   it from a disabled *active* link at a glance. */
.sidebar nav .nav-disabled {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text-faint);
  font-size: 14px;
  font-weight: 500;
  cursor: not-allowed;
}
.sidebar nav .nav-disabled .nav-badge {
  margin-left: auto;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--text-faint);
  background: var(--surface-hover);
  padding: 2px 7px;
  border-radius: 999px;
}
.sidebar .nav-section-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  padding: 16px 12px 6px;
  font-weight: 700;
}
.sidebar .user-footer {
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin-top: 12px;
}
.sidebar .user-footer .username {
  font-size: 13px;
  font-weight: 600;
  padding: 8px 12px;
  color: var(--text);
}
.sidebar .user-footer a {
  display: block;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text-muted);
  text-decoration: none;
  border-radius: 8px;
}
.sidebar .user-footer a:hover { background: var(--surface-hover); color: var(--text); }

.main {
  flex: 1;
  min-width: 0;
}
.topbar {
  padding: 20px 36px;
  border-bottom: 1px solid var(--border);
  background: rgba(10,14,26,0.5);
}
.content {
  padding: 28px 36px 60px;
}

.settings-card {
  background: linear-gradient(180deg, var(--surface) 0%, rgba(19,26,43,0.6) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
}
.settings-card h2 {
  font-size: 15px;
  margin: 0 0 10px 0;
}
.settings-card .connected,
.settings-card .not-connected {
  padding: 8px 12px;
  font-size: 12.5px;
  margin-bottom: 12px;
}
.settings-card p.subtitle {
  font-size: 13px;
  margin-bottom: 14px;
}
.settings-card input[type=text],
.settings-card input[type=password] {
  padding: 9px 12px;
  font-size: 13px;
}
.settings-card .btn {
  padding: 9px 18px;
  font-size: 13px;
}
.settings-card.danger {
  border-color: rgba(248,113,113,0.3);
}
.settings-card.danger h2 {
  color: var(--danger);
}

/* Connector list (Settings page — compact provider rows) */
.connector-list {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 16px;
}
.connector-list > *:last-child {
  border-bottom: none;
}
.connector-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
}
.connector-info {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}
/* Flex items default to min-width:auto (not 0), so the name/status
   text wrapper refused to shrink below its own content's natural
   width even though .connector-info above already opted itself into
   shrinking -- the wrapper just overflowed past its shrunk parent
   instead, visually landing on top of the icon and whatever sits next
   to it. This is what actually caused the "overlapping text" look on
   mobile, distinct from (and in addition to) .connector-row's missing
   wrap fixed below. */
.connector-info > div {
  min-width: 0;
}
.connector-icon {
  font-size: 18px;
  width: 36px;
  height: 36px;
  min-width: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.connector-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  overflow-wrap: break-word;
}
.connector-status {
  overflow-wrap: break-word;
  font-size: 12px;
  font-weight: 600;
  margin-top: 2px;
}
.connector-status.status-connected {
  color: var(--success);
}
.connector-status.status-not-connected {
  color: var(--text-muted);
}
.connector-btn {
  padding: 7px 16px;
  font-size: 12.5px;
  font-weight: 600;
  border-radius: 20px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.connector-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.connector-btn.reconnect {
  border-color: rgba(52,211,153,0.4);
  color: var(--success);
}
.connector-btn.reconnect:hover {
  border-color: var(--success);
  background: var(--success-bg);
}
.connector-btn.disconnect {
  border-color: rgba(248,113,113,0.4);
  color: var(--danger);
  margin-left: 8px;
}
.connector-btn.disconnect:hover {
  border-color: var(--danger);
  background: var(--danger-bg);
}
.connector-actions {
  display: flex;
  align-items: center;
}
.connector-form {
  padding: 0 20px 16px;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,0.015);
}
.connector-form[hidden] {
  display: none;
}
.connector-form form {
  display: flex;
  gap: 10px;
  padding-top: 4px;
}
.connector-form form.multi-field {
  flex-direction: column;
  align-items: stretch;
}
/* .multi-field's align-items:stretch above is meant for the text
   inputs (AWS/Azure infra intentionally want those full-width) -- but
   a submit button that's a DIRECT child of the same column (AWS/Azure
   infra's "Save Credentials", not nested in a .field-row the way
   Azure DevOps's "Save" is) inherited that same full-width stretch,
   ballooning it to the whole panel's width instead of matching every
   other button on the site. Opt it back out to its natural size,
   left-aligned like Save Token/Connect/Run Scan elsewhere. */
.connector-form form.multi-field > .btn {
  align-self: flex-start;
}
.connector-form form.multi-field .field-row {
  display: flex;
  gap: 10px;
}
.connector-help {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 8px 0 10px;
}
.connector-help a {
  color: var(--accent-2);
  font-weight: 600;
  text-decoration: none;
}
.connector-help a:hover {
  text-decoration: underline;
}
.connector-form input[type=text],
.connector-form input[type=password] {
  flex: 1;
  padding: 9px 12px;
  font-size: 13px;
}
.connector-form .btn {
  padding: 9px 18px;
  font-size: 13px;
  white-space: nowrap;
}
.auth-tagline {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #10b981;
  margin-top: 4px;
  margin-bottom: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.auth-tagline::before, .auth-tagline::after {
  content: "";
  height: 1px;
  width: 28px;
  background: rgba(16, 185, 129, 0.3);
}

/* Visual-audit fix: .connector-row (used on every code/infra provider
   page -- GitLab, GitHub, Azure DevOps, AWS, Azure) has no wrap at
   narrow widths, so .connector-info's icon/name/status and
   .connector-actions' Reconnect/Disconnect buttons fight for the same
   line and overlap/clip instead of fitting. Below this breakpoint,
   stack the info block above the actions instead of forcing both into
   one row -- same fix applies to the bare "Change" (regions) button
   row on aws_infra.html, which is a .connector-row too. */
@media (max-width: 600px) {
  .connector-row {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 10px;
  }
  .connector-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    row-gap: 8px;
  }
  /* Without wrap, Reconnect (~98px) and Disconnect (~109px, plus its
     own 8px left margin) stayed on one line inside .connector-actions'
     ~41px-wide box and simply overflowed in sequence -- Reconnect
     starting inside the visible panel (so its clipped label was at
     least visible), but Disconnect starting AFTER it, past the
     viewport's own right edge entirely. That's not cosmetic label
     clipping, it's the whole button rendered off-screen and
     unreachable. Wrapping puts Disconnect on its own line starting
     from the row's left edge instead, same as Reconnect -- still
     wider than the ~41px column so its label still clips, but now
     it's reachable the same way Reconnect already was. */
  .connector-btn.disconnect {
    margin-left: 0;
  }
  /* Stacking .connector-row alone isn't enough on its own: at these
     widths .connector-row's own content box (after its padding) can be
     narrower than the icon (36px) + its gap (14px) combined, so the
     name/status text next to the icon gets squeezed to a computed
     0px width and overflow:visible renders it on top of everything
     else instead of wrapping. Stacking the icon above the name/status
     too gives that text the row's full width to wrap into. */
  .connector-info {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
}