<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vulnerd — Security Report Card</title>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet" />
  <style>
    :root {
      --bg:           #0c0c1a;
      --surface:      #12122a;
      --card:         #1a1a35;
      --card-hover:   #20203e;
      --border:       #2a2a4a;
      --accent:       #7c6cf8;
      --accent-dim:   #4a3fb0;
      --text:         #e4e4f0;
      --muted:        #7070a0;
      --success:      #22c55e;
      --warning:      #f59e0b;
      --danger:       #ef4444;
      --radius:       12px;
      --transition:   0.2s ease;
    }

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

    html { scroll-behavior: smooth; }

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

    /* ── HEADER ── */
    .site-header {
      background: linear-gradient(135deg, #0f0f25 0%, #1a0a3a 100%);
      border-bottom: 1px solid var(--border);
      padding: 28px 24px 24px;
      text-align: center;
    }
    .site-header h1 {
      font-family: 'Space Mono', monospace;
      font-size: 2.6rem;
      letter-spacing: 0.18em;
      color: #fff;
      text-shadow: 0 0 40px rgba(124, 108, 248, 0.6);
    }
    .site-header h1 span { color: var(--accent); }
    .tagline {
      margin-top: 8px;
      color: var(--muted);
      font-size: 0.95rem;
    }
    .nerdy-badge {
      display: inline-block;
      margin-top: 12px;
      background: rgba(124, 108, 248, 0.15);
      border: 1px solid rgba(124, 108, 248, 0.4);
      border-radius: 999px;
      padding: 4px 16px;
      font-size: 0.8rem;
      color: #a89ff8;
    }

    /* ── LAYOUT ── */
    .container {
      max-width: 1280px;
      margin: 0 auto;
      padding: 32px 32px 64px;
    }

    /* ── CARD ── */
    .card {
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      padding: 28px;
      margin-bottom: 20px;
    }
    .card-title {
      font-size: 0.75rem;
      font-weight: 600;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 16px;
    }

    /* ── UPLOAD ZONE ── */
    #drop-zone {
      border: 2px dashed var(--border);
      border-radius: var(--radius);
      padding: 48px 24px;
      text-align: center;
      cursor: pointer;
      transition: border-color var(--transition), background var(--transition);
      position: relative;
    }
    #drop-zone:hover, #drop-zone.drag-over {
      border-color: var(--accent);
      background: rgba(124, 108, 248, 0.06);
    }
    #drop-zone input[type="file"] {
      position: absolute;
      inset: 0;
      opacity: 0;
      cursor: pointer;
      width: 100%;
      height: 100%;
    }
    .drop-icon { font-size: 3rem; margin-bottom: 12px; }
    .drop-title {
      font-size: 1.1rem;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 6px;
    }
    .drop-sub { color: var(--muted); font-size: 0.88rem; }

    /* ── FILE LIST ── */
    #file-list {
      display: none;
      margin-top: 16px;
      border: 1px solid var(--border);
      border-radius: 8px;
      overflow: hidden;
    }
    .file-item {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 14px;
      border-bottom: 1px solid var(--border);
      background: var(--surface);
      font-size: 0.88rem;
    }
    .file-item:last-child { border-bottom: none; }
    .file-item .file-icon { color: var(--accent); }
    .file-item .file-name { flex: 1; color: var(--text); font-family: 'Space Mono', monospace; font-size: 0.8rem; }
    .file-item .file-size { color: var(--muted); font-size: 0.78rem; }

    /* ── MODE SELECTOR ── */
    .mode-row {
      display: flex;
      gap: 10px;
      margin-top: 18px;
    }
    .mode-btn {
      flex: 1;
      padding: 12px;
      border-radius: 8px;
      border: 2px solid var(--border);
      background: transparent;
      color: var(--muted);
      cursor: pointer;
      font-family: inherit;
      font-size: 0.88rem;
      font-weight: 500;
      text-align: center;
      transition: all var(--transition);
    }
    .mode-btn.active {
      border-color: var(--accent);
      background: rgba(124, 108, 248, 0.12);
      color: var(--text);
    }
    .mode-btn .mode-icon { display: block; font-size: 1.3rem; margin-bottom: 4px; }

    /* ── ANALYZE BUTTON ── */
    .btn-primary {
      display: block;
      width: 100%;
      margin-top: 20px;
      padding: 16px;
      border-radius: 10px;
      border: none;
      background: var(--accent);
      color: #fff;
      font-family: inherit;
      font-size: 1rem;
      font-weight: 600;
      cursor: pointer;
      transition: background var(--transition), transform var(--transition);
      letter-spacing: 0.02em;
    }
    .btn-primary:hover:not(:disabled) { background: #6458e8; transform: translateY(-1px); }
    .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

    /* ── LOADING STATE ── */
    #loading-section { display: none; }
    .loading-card {
      text-align: center;
      padding: 60px 28px;
    }
    .spinner {
      width: 56px;
      height: 56px;
      border: 4px solid var(--border);
      border-top-color: var(--accent);
      border-radius: 50%;
      animation: spin 0.9s linear infinite;
      margin: 0 auto 24px;
    }
    @keyframes spin { to { transform: rotate(360deg); } }
    .loading-msg {
      font-size: 1rem;
      color: var(--text);
      min-height: 3.5em;
      transition: opacity 0.4s;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 6px;
      max-width: 560px;
      margin: 0 auto;
    }
    .quote-text {
      font-style: italic;
      font-size: 1.05rem;
      color: var(--text);
      line-height: 1.55;
      display: block;
    }
    .quote-attr {
      font-size: 0.8rem;
      color: var(--accent);
      letter-spacing: 0.05em;
      font-weight: 600;
      display: block;
    }
    .loading-sub {
      color: var(--muted);
      font-size: 0.85rem;
      margin-top: 8px;
    }
    .loading-progress {
      display: flex;
      gap: 6px;
      justify-content: center;
      margin-top: 20px;
    }
    .loading-dot {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: var(--border);
    }
    .loading-dot.active { background: var(--accent); }

    /* ── RESULTS ── */
    #results-section { display: none; }

    /* ── GRADE CARD ── */
    .grade-card {
      display: grid;
      grid-template-columns: auto 1fr;
      gap: 0;
      border-radius: var(--radius);
      overflow: hidden;
      border: 1px solid var(--border);
      margin-bottom: 20px;
    }
    .grade-letter-block {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 28px 32px;
      min-width: 120px;
      background: #6b8e23; /* updated by JS */
    }
    .grade-letter {
      font-family: 'Space Mono', monospace;
      font-size: 4rem;
      font-weight: 700;
      color: #fff;
      line-height: 1;
      animation: pop-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
    }
    .grade-score-sub {
      font-family: 'Space Mono', monospace;
      font-size: 1rem;
      color: rgba(255,255,255,0.85);
      margin-top: 6px;
    }
    @keyframes pop-in {
      0%   { transform: scale(0.3); opacity: 0; }
      100% { transform: scale(1);   opacity: 1; }
    }
    .grade-details {
      background: var(--surface);
      padding: 20px 24px;
    }
    .grade-details h2 {
      font-size: 0.75rem;
      font-weight: 600;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 14px;
    }
    .severity-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 0.88rem;
    }
    .severity-table th {
      text-align: left;
      color: var(--muted);
      font-weight: 600;
      padding: 4px 8px 8px 0;
      font-size: 0.78rem;
      letter-spacing: 0.06em;
      text-transform: uppercase;
    }
    .severity-table td {
      padding: 6px 8px 6px 0;
      border-top: 1px solid var(--border);
    }
    .severity-badge {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      font-weight: 500;
    }
    .severity-dot {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      flex-shrink: 0;
    }
    .sev-critical { background: #ef4444; }
    .sev-high     { background: #f97316; }
    .sev-medium   { background: #eab308; }
    .sev-low      { background: #22c55e; }
    .severity-deduction { color: var(--muted); font-size: 0.82rem; font-family: 'Space Mono', monospace; }
    .total-row td { border-top: 2px solid var(--border); font-weight: 600; }

    /* ── COMMENTARY ── */
    .commentary-box {
      background: rgba(124, 108, 248, 0.08);
      border-left: 3px solid var(--accent);
      border-radius: 0 8px 8px 0;
      padding: 16px 20px;
      margin-bottom: 20px;
      font-style: italic;
      color: #c0b8f8;
      font-size: 0.95rem;
      line-height: 1.65;
    }

    /* ── TREND HISTORY ── */
    .trend-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 0.88rem;
    }
    .trend-table th {
      text-align: left;
      color: var(--muted);
      font-weight: 600;
      padding: 8px 12px;
      border-bottom: 1px solid var(--border);
      font-size: 0.78rem;
      text-transform: uppercase;
      letter-spacing: 0.06em;
    }
    .trend-table td {
      padding: 10px 12px;
      border-bottom: 1px solid rgba(42,42,74,0.5);
    }
    .trend-table tr:last-child td { border-bottom: none; }
    .trend-grade-pill {
      display: inline-block;
      padding: 2px 10px;
      border-radius: 999px;
      font-family: 'Space Mono', monospace;
      font-size: 0.82rem;
      font-weight: 700;
      color: #fff;
    }

    /* ── SECTION CARDS ── */
    .section-card {
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      margin-bottom: 14px;
      overflow: hidden;
      transition: border-color var(--transition);
    }
    .section-card:hover { border-color: rgba(124, 108, 248, 0.4); }
    .section-card.special { border-color: rgba(124, 108, 248, 0.3); }

    .section-header {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 16px 20px;
      cursor: pointer;
      user-select: none;
    }
    .section-icon { font-size: 1.2rem; flex-shrink: 0; }
    .section-title {
      font-weight: 600;
      font-size: 0.9rem;
      flex: 1;
      letter-spacing: 0.04em;
    }
    .section-toggle {
      color: var(--muted);
      font-size: 0.9rem;
      transition: transform 0.2s;
    }
    .section-card.open .section-toggle { transform: rotate(180deg); }

    .section-body {
      padding: 0 20px 20px;
      display: none;
    }
    .section-card.open .section-body { display: block; }

    .section-body p {
      color: #c8c8e0;
      line-height: 1.75;
      font-size: 0.92rem;
      margin-bottom: 8px;
    }
    .section-body p:last-child { margin-bottom: 0; }

    /* Special styling for INSTRUCTOR'S NOTE / PROGRESS REPORT COMMENT */
    .section-card.instructors-note .section-body {
      background: rgba(124, 108, 248, 0.06);
      margin: 0 -1px;
      padding: 16px 20px 20px;
      border-top: 1px solid rgba(124, 108, 248, 0.2);
    }
    .section-card.instructors-note .section-body p {
      color: #c0b8f8;
      font-style: italic;
    }

    /* ── EMAIL SECTION ── */
    .email-row {
      display: flex;
      gap: 10px;
      margin-top: 12px;
    }
    .email-input {
      flex: 1;
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 12px 16px;
      color: var(--text);
      font-family: inherit;
      font-size: 0.95rem;
      outline: none;
      transition: border-color var(--transition);
    }
    .email-input:focus { border-color: var(--accent); }
    .email-input::placeholder { color: var(--muted); }
    .btn-send {
      padding: 12px 22px;
      border-radius: 8px;
      border: none;
      background: var(--accent);
      color: #fff;
      font-family: inherit;
      font-size: 0.92rem;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
      transition: background var(--transition);
    }
    .btn-send:hover:not(:disabled) { background: #6458e8; }
    .btn-send:disabled { opacity: 0.5; cursor: not-allowed; }

    .email-status {
      margin-top: 12px;
      font-size: 0.85rem;
      min-height: 1.4em;
      line-height: 1.5;
    }
    .email-status.sending { color: var(--muted); font-style: italic; }
    .email-status.success { color: var(--success); }
    .email-status.error   { color: var(--danger); }
    .eq-text {
      display: block;
      font-style: italic;
      color: var(--muted);
      margin-top: 4px;
    }
    .eq-attr {
      display: block;
      font-size: 0.78rem;
      color: var(--accent);
      font-weight: 600;
      letter-spacing: 0.04em;
    }

    /* ── RESET BUTTON ── */
    .btn-reset {
      display: block;
      margin: 10px auto 0;
      background: transparent;
      border: 1px solid var(--border);
      border-radius: 8px;
      color: var(--muted);
      font-family: inherit;
      font-size: 0.85rem;
      padding: 8px 20px;
      cursor: pointer;
      transition: border-color var(--transition), color var(--transition);
    }
    .btn-reset:hover {
      border-color: var(--accent);
      color: var(--text);
    }

    /* ── ERROR STATE ── */
    .error-card {
      background: rgba(239,68,68,0.1);
      border: 1px solid rgba(239,68,68,0.3);
      border-radius: var(--radius);
      padding: 20px 24px;
      color: #fca5a5;
      font-size: 0.92rem;
    }
    .error-card strong { display: block; margin-bottom: 6px; }

    /* ── FOOTER ── */
    .site-footer {
      text-align: center;
      color: var(--muted);
      font-size: 0.78rem;
      padding: 20px;
      border-top: 1px solid var(--border);
    }

    /* ── MISC ── */
    .divider { height: 1px; background: var(--border); margin: 20px 0; }
    .section-label {
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 14px;
    }
    .filename-display {
      font-family: 'Space Mono', monospace;
      font-size: 0.8rem;
      color: var(--muted);
      margin-bottom: 20px;
    }
    .filename-display strong { color: var(--accent); }

    /* ── CHAT WIDGET ── */
    #chat-toggle {
      position: fixed;
      bottom: 28px;
      right: 28px;
      width: 58px;
      height: 58px;
      border-radius: 50%;
      background: var(--accent);
      border: none;
      cursor: pointer;
      font-size: 1.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0 4px 20px rgba(124, 108, 248, 0.5);
      transition: transform var(--transition), background var(--transition);
      z-index: 1000;
    }
    #chat-toggle:hover { transform: scale(1.08); background: #6458e8; }

    #chat-panel {
      position: fixed;
      bottom: 100px;
      right: 28px;
      width: 380px;
      max-height: 520px;
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: 16px;
      display: none;
      flex-direction: column;
      box-shadow: 0 8px 40px rgba(0,0,0,0.5);
      z-index: 999;
      overflow: hidden;
    }
    #chat-panel.open { display: flex; }

    .chat-header {
      padding: 16px 18px;
      background: linear-gradient(135deg, #1a1a35, #25153a);
      border-bottom: 1px solid var(--border);
      display: flex;
      align-items: center;
      gap: 10px;
    }
    .chat-header-avatar {
      width: 36px;
      height: 36px;
      border-radius: 50%;
      background: var(--accent);
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.1rem;
      flex-shrink: 0;
    }
    .chat-header-info { flex: 1; }
    .chat-header-name {
      font-weight: 700;
      font-size: 0.9rem;
      color: var(--text);
    }
    .chat-header-status {
      font-size: 0.75rem;
      color: var(--success);
    }
    .chat-close {
      background: none;
      border: none;
      color: var(--muted);
      cursor: pointer;
      font-size: 1.1rem;
      padding: 4px;
      line-height: 1;
    }
    .chat-close:hover { color: var(--text); }

    #chat-messages {
      flex: 1;
      overflow-y: auto;
      padding: 16px;
      display: flex;
      flex-direction: column;
      gap: 12px;
      scroll-behavior: smooth;
    }
    #chat-messages::-webkit-scrollbar { width: 4px; }
    #chat-messages::-webkit-scrollbar-track { background: transparent; }
    #chat-messages::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

    .chat-bubble {
      max-width: 88%;
      padding: 10px 14px;
      border-radius: 14px;
      font-size: 0.88rem;
      line-height: 1.55;
      animation: bubble-in 0.2s ease;
    }
    @keyframes bubble-in {
      from { opacity: 0; transform: translateY(6px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    .chat-bubble.user {
      background: var(--accent);
      color: #fff;
      align-self: flex-end;
      border-bottom-right-radius: 4px;
    }
    .chat-bubble.vulnerd {
      background: var(--surface);
      color: var(--text);
      align-self: flex-start;
      border-bottom-left-radius: 4px;
      border: 1px solid var(--border);
      white-space: pre-wrap;
    }
    .chat-bubble.typing {
      background: var(--surface);
      color: var(--muted);
      align-self: flex-start;
      border: 1px solid var(--border);
      border-bottom-left-radius: 4px;
      font-style: italic;
    }
    .typing-dots span {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      background: var(--muted);
      margin: 0 2px;
      animation: dot-bounce 1.2s infinite;
    }
    .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
    .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
    @keyframes dot-bounce {
      0%, 80%, 100% { transform: translateY(0); }
      40% { transform: translateY(-5px); }
    }

    .chat-footer {
      padding: 12px;
      border-top: 1px solid var(--border);
      display: flex;
      gap: 8px;
    }
    #chat-input {
      flex: 1;
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: 20px;
      padding: 9px 14px;
      color: var(--text);
      font-family: inherit;
      font-size: 0.88rem;
      outline: none;
      resize: none;
      transition: border-color var(--transition);
    }
    #chat-input:focus { border-color: var(--accent); }
    #chat-input::placeholder { color: var(--muted); }
    #chat-send {
      width: 38px;
      height: 38px;
      border-radius: 50%;
      border: none;
      background: var(--accent);
      color: #fff;
      cursor: pointer;
      font-size: 1rem;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      transition: background var(--transition);
      align-self: flex-end;
    }
    #chat-send:hover:not(:disabled) { background: #6458e8; }
    #chat-send:disabled { opacity: 0.4; cursor: not-allowed; }

    .chat-suggestions {
      display: flex;
      flex-wrap: wrap;
      gap: 6px;
      padding: 0 16px 12px;
    }
    .suggestion-chip {
      background: rgba(124,108,248,0.12);
      border: 1px solid rgba(124,108,248,0.3);
      border-radius: 999px;
      padding: 4px 12px;
      font-size: 0.78rem;
      color: #a89ff8;
      cursor: pointer;
      transition: background var(--transition);
      white-space: nowrap;
    }
    .suggestion-chip:hover {
      background: rgba(124,108,248,0.25);
      color: #fff;
    }

    /* ── BUSINESS SELECTOR ── */
    .biz-grid {
      display: grid;
      grid-template-columns: repeat(5, 1fr);
      gap: 8px;
      margin-top: 4px;
    }
    .biz-card {
      background: transparent;
      border: 2px solid var(--border);
      border-radius: 10px;
      padding: 12px 6px;
      cursor: pointer;
      text-align: center;
      transition: all var(--transition);
      font-family: inherit;
      color: var(--muted);
    }
    .biz-card:hover { border-color: var(--accent); color: var(--text); background: rgba(124,108,248,0.06); }
    .biz-card.active { border-color: var(--accent); background: rgba(124,108,248,0.14); color: var(--text); }
    .biz-icon { display: block; font-size: 1.6rem; margin-bottom: 6px; }
    .biz-label { font-size: 0.75rem; font-weight: 600; line-height: 1.3; }
    .biz-skip {
      display: block;
      text-align: center;
      margin-top: 8px;
      font-size: 0.78rem;
      color: var(--muted);
      cursor: pointer;
      text-decoration: underline;
    }
    .biz-skip:hover { color: var(--text); }

    /* ── TWO COLUMN RESULTS ── */
    .results-grid {
      display: grid;
      grid-template-columns: 1fr 440px;
      gap: 28px;
      align-items: start;
    }
    @media (max-width: 900px) {
      .results-grid { grid-template-columns: 1fr; }
      .biz-grid { grid-template-columns: repeat(3, 1fr); }
    }

    /* ── COMPLIANCE DASHBOARD ── */
    .compliance-panel {
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      overflow: hidden;
      position: sticky;
      top: 20px;
    }
    .compliance-header {
      background: linear-gradient(135deg, #1a1a35, #25153a);
      padding: 18px 20px;
      border-bottom: 1px solid var(--border);
    }
    .compliance-framework-name {
      font-family: 'Space Mono', monospace;
      font-size: 1rem;
      font-weight: 700;
      color: var(--accent);
      letter-spacing: 0.08em;
    }
    .compliance-framework-full {
      font-size: 0.78rem;
      color: var(--muted);
      margin-top: 2px;
    }
    .compliance-body { padding: 18px 20px; }

    /* Bar charts */
    .attr-list { display: flex; flex-direction: column; gap: 14px; margin-bottom: 20px; }
    .attr-item {}
    .attr-top {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
      margin-bottom: 5px;
    }
    .attr-name { font-size: 0.82rem; font-weight: 600; color: var(--text); }
    .attr-pct  { font-family: 'Space Mono', monospace; font-size: 0.75rem; color: var(--muted); }
    .attr-track {
      height: 8px;
      background: var(--border);
      border-radius: 99px;
      overflow: hidden;
    }
    .attr-fill {
      height: 100%;
      border-radius: 99px;
      transition: width 1s cubic-bezier(0.4,0,0.2,1);
    }
    .attr-blurb { font-size: 0.78rem; color: var(--muted); margin-top: 4px; line-height: 1.4; }

    .compliance-divider { height: 1px; background: var(--border); margin: 18px 0; }

    /* Story section */
    .compliance-section-title {
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 10px;
    }
    .compliance-text {
      font-size: 0.85rem;
      color: #c8c8e0;
      line-height: 1.65;
      margin-bottom: 10px;
    }
    .story-box {
      background: rgba(239,68,68,0.08);
      border-left: 3px solid #ef4444;
      border-radius: 0 8px 8px 0;
      padding: 12px 14px;
      font-size: 0.82rem;
      color: #fca5a5;
      line-height: 1.6;
      margin-bottom: 4px;
    }

    /* Cost comparison */
    .cost-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 10px;
      margin-top: 10px;
    }
    .cost-card {
      border-radius: 10px;
      padding: 14px;
      text-align: center;
    }
    .cost-card.fix   { background: rgba(34,197,94,0.1); border: 1px solid rgba(34,197,94,0.25); }
    .cost-card.breach{ background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.25); }
    .cost-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 6px; }
    .cost-card.fix   .cost-label { color: #22c55e; }
    .cost-card.breach .cost-label { color: #ef4444; }
    .cost-amount {
      font-family: 'Space Mono', monospace;
      font-size: 0.95rem;
      font-weight: 700;
      color: var(--text);
      line-height: 1.2;
    }
    .cost-sublabel { font-size: 0.7rem; color: var(--muted); margin-top: 3px; }
    .cost-context {
      font-size: 0.8rem;
      color: var(--muted);
      line-height: 1.55;
      margin-top: 12px;
      text-align: center;
    }
  </style>
</head>
<body>

  <!-- ── HEADER ── -->
  <header class="site-header">
    <h1>VULN<span>E</span>RD</h1>
    <p class="tagline">Your network's GPA, delivered. No cramming required.</p>
    <span class="nerdy-badge">🤓 &nbsp;Drop your scan. Get your grade. I'll explain everything.</span>
  </header>

  <!-- ── MAIN ── -->
  <main class="container">

    <!-- UPLOAD SECTION -->
    <div id="upload-section">
      <div class="card">
        <div class="card-title">Step 1 — Upload your Nessus CSV export(s)</div>

        <div id="drop-zone">
          <input type="file" id="file-input" accept=".csv" multiple />
          <div class="drop-icon">📂</div>
          <div class="drop-title">Drag & drop your scan file here</div>
          <div class="drop-sub">or click to browse &nbsp;·&nbsp; accepts .csv Nessus exports &nbsp;·&nbsp; upload multiple for trend analysis</div>
        </div>

        <div id="file-list"></div>

        <!-- MODE SELECTOR (hidden until 2+ files) -->
        <div id="mode-selector" style="display:none;">
          <div class="divider"></div>
          <div class="card-title">Step 2 — Choose your analysis mode</div>
          <div class="mode-row">
            <button class="mode-btn active" data-mode="single" onclick="setMode('single')">
              <span class="mode-icon">📋</span>
              Single Scan
              <div style="font-size:0.78rem;color:var(--muted);margin-top:4px;">Grade your latest scan</div>
            </button>
            <button class="mode-btn" data-mode="trend" onclick="setMode('trend')">
              <span class="mode-icon">📈</span>
              Trend Analysis
              <div style="font-size:0.78rem;color:var(--muted);margin-top:4px;">Track progress over time</div>
            </button>
          </div>
        </div>

        <!-- BUSINESS TYPE SELECTOR -->
        <div class="divider"></div>
        <div class="card-title">Step 2 — What best describes your business? <span style="color:var(--muted);font-weight:400;">(optional)</span></div>
        <div class="biz-grid">
          <button class="biz-card" data-type="healthcare" onclick="selectBiz(this)">
            <span class="biz-icon">🏥</span>
            <span class="biz-label">Healthcare</span>
          </button>
          <button class="biz-card" data-type="retail" onclick="selectBiz(this)">
            <span class="biz-icon">💳</span>
            <span class="biz-label">Retail / Payments</span>
          </button>
          <button class="biz-card" data-type="government" onclick="selectBiz(this)">
            <span class="biz-icon">🏛️</span>
            <span class="biz-label">Government</span>
          </button>
          <button class="biz-card" data-type="education" onclick="selectBiz(this)">
            <span class="biz-icon">🎓</span>
            <span class="biz-label">Education</span>
          </button>
          <button class="biz-card" data-type="general" onclick="selectBiz(this)">
            <span class="biz-icon">🏢</span>
            <span class="biz-label">General Business</span>
          </button>
        </div>

        <button class="btn-primary" id="analyze-btn" disabled onclick="runAnalysis()">
          🎓 &nbsp;Grade My Network
        </button>
      </div>
    </div>

    <!-- LOADING SECTION -->
    <div id="loading-section">
      <div class="card loading-card">
        <div class="spinner"></div>
        <div class="loading-msg" id="loading-msg">Pulling out my textbook... 📚</div>
        <div class="loading-sub">This usually takes 30–60 seconds. Sit tight — we're doing real analysis here.</div>
        <div class="loading-progress">
          <div class="loading-dot active" id="dot0"></div>
          <div class="loading-dot" id="dot1"></div>
          <div class="loading-dot" id="dot2"></div>
          <div class="loading-dot" id="dot3"></div>
          <div class="loading-dot" id="dot4"></div>
          <div class="loading-dot" id="dot5"></div>
          <div class="loading-dot" id="dot6"></div>
        </div>
      </div>
    </div>

    <!-- RESULTS SECTION -->
    <div id="results-section">

      <div id="error-container"></div>

      <div class="results-grid">

        <!-- LEFT COLUMN — Report Card -->
        <div id="report-column">
          <div id="grade-card-container"></div>
          <div id="trend-history-container"></div>
          <div id="sections-container"></div>

          <div class="card" id="email-card">
            <div class="card-title">📬 &nbsp;Send Report Card by Email</div>
            <p style="color:var(--muted);font-size:0.9rem;margin-bottom:14px;">
              Psst — want to share this with your boss or IT team? I'll send the full PDF report card straight to their inbox. They'll thank you later. 📎
            </p>
            <div class="email-row">
              <input type="email" class="email-input" id="email-input" placeholder="stakeholder@company.com" />
              <button class="btn-send" id="send-btn" onclick="sendReport()">Send it 🚀</button>
            </div>
            <div class="email-status" id="email-status"></div>
          </div>

          <button class="btn-reset" onclick="resetUI()">↩ &nbsp;Analyze Another Scan</button>
        </div>

        <!-- RIGHT COLUMN — Compliance Dashboard -->
        <div id="compliance-column"></div>

      </div>
    </div>

  </main>

  <!-- ── CHAT WIDGET ── -->
  <button id="chat-toggle" onclick="toggleChat()" title="Ask Vulnerd anything">🤓</button>

  <div id="chat-panel">
    <div class="chat-header">
      <div class="chat-header-avatar">🤓</div>
      <div class="chat-header-info">
        <div class="chat-header-name">Ask Vulnerd</div>
        <div class="chat-header-status">● Online — ask me anything</div>
      </div>
      <button class="chat-close" onclick="toggleChat()">✕</button>
    </div>

    <div id="chat-messages">
      <div class="chat-bubble vulnerd">
        Hey! I'm Vulnerd 🤓 Got questions about your scan results, a vulnerability you saw, or just want to understand what something means? I've got you. Drop your question below!
      </div>
    </div>

    <div class="chat-suggestions" id="chat-suggestions">
      <span class="suggestion-chip" onclick="useChip(this)">What is a Critical vulnerability?</span>
      <span class="suggestion-chip" onclick="useChip(this)">How do I fix an SSL issue?</span>
      <span class="suggestion-chip" onclick="useChip(this)">What is ransomware?</span>
      <span class="suggestion-chip" onclick="useChip(this)">Why does patching matter?</span>
    </div>

    <div class="chat-footer">
      <textarea id="chat-input" placeholder="Ask me about your scan, a CVE, anything..." rows="1"
        onkeydown="handleChatKey(event)" oninput="autoResize(this)"></textarea>
      <button id="chat-send" onclick="sendChatMessage()">➤</button>
    </div>
  </div>

  <footer class="site-footer">
    Vulnerd &nbsp;·&nbsp; Built for the small businesses that can't afford a full SOC team &nbsp;·&nbsp; 🤓
  </footer>

  <script>
    // ── STATE ──────────────────────────────────────────────────────────────────
    let selectedFiles  = [];
    let currentMode    = 'single';
    let currentToken   = null;
    let businessType   = 'none';
    let msgInterval    = null;
    let dotInterval    = null;

    const LOADING_MESSAGES = [
      // Modern Wisdom / self-improvement
      { q: "You don't rise to the level of your goals, you fall to the level of your systems.", a: "James Clear" },
      { q: "Most people overestimate what they can do in a day, and underestimate what they can do in a month.", a: "Alex Hormozi" },
      { q: "The universe doesn't give you what you ask for with your thoughts; it gives you what you demand with your actions.", a: "Alex Hormozi" },
      { q: "The gap between who you are and who you want to be is only crossed by what you do.", a: "Modern Wisdom" },
      { q: "Suffering is the resistance to what is. Growth is the surrender to what could be.", a: "Dr. K — Healthy Gamer" },
      { q: "Security is not a product, but a process.", a: "Bruce Schneier" },
      { q: "You can't go back and change the beginning, but you can start where you are and change the ending.", a: "C.S. Lewis" },
      { q: "Most people die at 25 and aren't buried until 75. Don't sleepwalk through your one life.", a: "Diary of a CEO" },
      { q: "Doing the work you're afraid of is the only way to become the person you want to be.", a: "Healthy Gamer" },
      // Shakespeare
      { q: "We know what we are, but know not what we may be.", a: "Shakespeare — Hamlet" },
      { q: "Our doubts are traitors, and make us lose the good we oft might win, by fearing to attempt.", a: "Shakespeare — Measure for Measure" },
      { q: "What's past is prologue.", a: "Shakespeare — The Tempest" },
      { q: "It is not in the stars to hold our destiny, but in ourselves.", a: "Shakespeare — Julius Caesar" },
      // A Knight of the Seven Kingdoms (George R.R. Martin)
      { q: "A man who won't fight for what he believes in deserves to lose.", a: "Duncan the Tall — A Knight of the Seven Kingdoms" },
      { q: "The world was full of hardship and injustice. A true knight must fight against them, no matter the cost.", a: "A Knight of the Seven Kingdoms" },
      // Existentialists
      { q: "Man is condemned to be free; because once thrown into the world, he is responsible for everything he does.", a: "Jean-Paul Sartre" },
      { q: "The most common form of despair is not being who you are.", a: "Søren Kierkegaard" },
      { q: "In the middle of difficulty lies opportunity.", a: "Albert Camus" },
      { q: "He who has a why to live can bear almost any how.", a: "Friedrich Nietzsche" },
      { q: "Life can only be understood backwards; but it must be lived forwards.", a: "Søren Kierkegaard" },
    ];

    // Shuffle quotes once on load so every session sees a different order
    (function shuffle(arr) {
      for (let i = arr.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [arr[i], arr[j]] = [arr[j], arr[i]];
      }
    })(LOADING_MESSAGES);

    const GRADE_COLORS = {
      "A":  "#1a7a1a", "A-": "#2d8a2d",
      "B+": "#4a7c1a", "B":  "#6b8e23", "B-": "#8b9a1a",
      "C+": "#b8860b", "C":  "#cc8800", "C-": "#cc6600",
      "D+": "#cc4400", "D":  "#cc2200", "D-": "#aa0000",
      "F":  "#880000",
    };

    const SPECIAL_SECTIONS = new Set([
      "INSTRUCTOR'S NOTE", "PROGRESS REPORT COMMENT"
    ]);

    // ── FILE HANDLING ──────────────────────────────────────────────────────────
    const dropZone  = document.getElementById('drop-zone');
    const fileInput = document.getElementById('file-input');

    dropZone.addEventListener('dragover', e => {
      e.preventDefault();
      dropZone.classList.add('drag-over');
    });
    dropZone.addEventListener('dragleave', () => dropZone.classList.remove('drag-over'));
    dropZone.addEventListener('drop', e => {
      e.preventDefault();
      dropZone.classList.remove('drag-over');
      addFiles(Array.from(e.dataTransfer.files).filter(f => f.name.endsWith('.csv')));
    });
    fileInput.addEventListener('change', () => {
      addFiles(Array.from(fileInput.files));
      fileInput.value = '';
    });

    function addFiles(newFiles) {
      const names = new Set(selectedFiles.map(f => f.name));
      newFiles.forEach(f => { if (!names.has(f.name)) selectedFiles.push(f); });
      renderFileList();
    }

    function removeFile(idx) {
      selectedFiles.splice(idx, 1);
      renderFileList();
    }

    function formatBytes(b) {
      if (b < 1024)       return b + ' B';
      if (b < 1048576)    return (b/1024).toFixed(1) + ' KB';
      return (b/1048576).toFixed(1) + ' MB';
    }

    function renderFileList() {
      const list    = document.getElementById('file-list');
      const modeBox = document.getElementById('mode-selector');
      const btn     = document.getElementById('analyze-btn');

      if (selectedFiles.length === 0) {
        list.style.display    = 'none';
        modeBox.style.display = 'none';
        btn.disabled          = true;
        return;
      }

      list.style.display = 'block';
      list.innerHTML     = selectedFiles.map((f, i) => `
        <div class="file-item">
          <span class="file-icon">📄</span>
          <span class="file-name">${escHtml(f.name)}</span>
          <span class="file-size">${formatBytes(f.size)}</span>
          <span style="cursor:pointer;color:var(--muted);padding:0 4px;" onclick="removeFile(${i})" title="Remove">✕</span>
        </div>
      `).join('');

      modeBox.style.display = selectedFiles.length >= 2 ? 'block' : 'none';
      btn.disabled          = false;
    }

    function selectBiz(el) {
      document.querySelectorAll('.biz-card').forEach(b => b.classList.remove('active'));
      if (el) {
        el.classList.add('active');
        businessType = el.dataset.type;
      } else {
        businessType = 'none';
      }
    }

    function setMode(mode) {
      currentMode = mode;
      document.querySelectorAll('.mode-btn').forEach(b => {
        b.classList.toggle('active', b.dataset.mode === mode);
      });
    }

    // ── ANALYSIS ──────────────────────────────────────────────────────────────
    async function runAnalysis() {
      if (selectedFiles.length === 0) return;

      showLoading();

      const formData = new FormData();
      formData.append('mode', currentMode === 'trend' && selectedFiles.length >= 2 ? 'trend' : 'single');
      formData.append('business_type', businessType);
      selectedFiles.forEach(f => formData.append('files', f));

      try {
        const resp = await fetch('/analyze', { method: 'POST', body: formData });
        const data = await resp.json();
        stopLoading();
        if (data.error) {
          showError(data.error);
        } else {
          renderResults(data);
        }
      } catch (err) {
        stopLoading();
        showError('Something went wrong: ' + err.message);
      }
    }

    // ── LOADING ───────────────────────────────────────────────────────────────
    function showLoading() {
      document.getElementById('upload-section').style.display  = 'none';
      document.getElementById('loading-section').style.display = 'block';
      document.getElementById('results-section').style.display = 'none';

      let msgIdx = 0, dotIdx = 0;
      function setQuote(idx) {
        const q = LOADING_MESSAGES[idx];
        const el = document.getElementById('loading-msg');
        el.innerHTML = `<span class="quote-text">"${q.q}"</span><span class="quote-attr">— ${q.a}</span>`;
      }
      setQuote(0);

      msgInterval = setInterval(() => {
        msgIdx = (msgIdx + 1) % LOADING_MESSAGES.length;
        const el = document.getElementById('loading-msg');
        el.style.opacity = 0;
        setTimeout(() => {
          setQuote(msgIdx);
          el.style.opacity = 1;
        }, 300);
      }, 8000);

      dotInterval = setInterval(() => {
        document.querySelectorAll('.loading-dot').forEach((d, i) => {
          d.classList.toggle('active', i === dotIdx % 7);
        });
        dotIdx++;
      }, 700);
    }

    function stopLoading() {
      clearInterval(msgInterval);
      clearInterval(dotInterval);
      document.getElementById('loading-section').style.display = 'none';
    }

    // ── RESULTS ───────────────────────────────────────────────────────────────
    function renderResults(data) {
      currentToken = data.pdf_token;
      document.getElementById('results-section').style.display = 'block';
      document.getElementById('error-container').innerHTML     = '';

      // Grade Card
      renderGradeCard(data);

      // Trend History
      if (data.mode === 'trend' && data.trend_grades) {
        renderTrendHistory(data.trend_grades);
      } else {
        document.getElementById('trend-history-container').innerHTML = '';
      }

      // Sections
      renderSections(data.sections || []);

      // Compliance dashboard
      renderComplianceDashboard(data.compliance);

      // Scroll to results
      document.getElementById('results-section').scrollIntoView({ behavior: 'smooth', block: 'start' });
    }

    function renderGradeCard(data) {
      const container = document.getElementById('grade-card-container');

      if (data.mode === 'trend') {
        container.innerHTML = `
          <div class="card" style="padding:20px 24px;">
            <div class="filename-display">
              Trend Analysis &nbsp;·&nbsp; <strong>${escHtml(data.filename)}</strong>
            </div>
            <p style="color:var(--muted);font-size:0.9rem;">
              Showing progress across your scans. See the grade history table below for the full picture.
            </p>
          </div>`;
        return;
      }

      const color    = GRADE_COLORS[data.letter] || '#555';
      const counts   = data.counts || {};
      const total    = data.total  || 0;

      container.innerHTML = `
        <div class="grade-card">
          <div class="grade-letter-block" style="background:${color};">
            <div class="grade-letter">${escHtml(data.letter)}</div>
            <div class="grade-score-sub">${data.score}/100</div>
          </div>
          <div class="grade-details">
            <h2>Scan: ${escHtml(data.filename)}</h2>
            <table class="severity-table">
              <thead>
                <tr>
                  <th>Severity</th>
                  <th>Count</th>
                  <th>Deduction</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td><span class="severity-badge"><span class="severity-dot sev-critical"></span>Critical</span></td>
                  <td>${counts.Critical || 0}</td>
                  <td class="severity-deduction">-${(counts.Critical||0)*20} pts</td>
                </tr>
                <tr>
                  <td><span class="severity-badge"><span class="severity-dot sev-high"></span>High</span></td>
                  <td>${counts.High || 0}</td>
                  <td class="severity-deduction">-${(counts.High||0)*8} pts</td>
                </tr>
                <tr>
                  <td><span class="severity-badge"><span class="severity-dot sev-medium"></span>Medium</span></td>
                  <td>${counts.Medium || 0}</td>
                  <td class="severity-deduction">-${(counts.Medium||0)*3} pts</td>
                </tr>
                <tr>
                  <td><span class="severity-badge"><span class="severity-dot sev-low"></span>Low</span></td>
                  <td>${counts.Low || 0}</td>
                  <td class="severity-deduction">-${(counts.Low||0)*1} pts</td>
                </tr>
                <tr class="total-row">
                  <td>Total Findings</td>
                  <td>${total}</td>
                  <td class="severity-deduction" style="color:var(--text);font-weight:700;">${data.score}/100</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        ${data.commentary ? `<div class="commentary-box">"${escHtml(data.commentary)}"</div>` : ''}
      `;
    }

    function renderTrendHistory(grades) {
      const container = document.getElementById('trend-history-container');
      const rows = grades.map(g => {
        const color = GRADE_COLORS[g.letter] || '#555';
        return `
          <tr>
            <td>${escHtml(g.filename)}</td>
            <td>${escHtml(g.date)}</td>
            <td style="text-align:center;">${g.total}</td>
            <td style="text-align:center;">${g.score}/100</td>
            <td style="text-align:center;">
              <span class="trend-grade-pill" style="background:${color};">${escHtml(g.letter)}</span>
            </td>
          </tr>`;
      }).join('');

      container.innerHTML = `
        <div class="card" style="padding:20px 24px;">
          <div class="card-title">📅 &nbsp;Grade History</div>
          <table class="trend-table">
            <thead>
              <tr>
                <th>Scan File</th>
                <th>Date</th>
                <th style="text-align:center;">Findings</th>
                <th style="text-align:center;">Score</th>
                <th style="text-align:center;">Grade</th>
              </tr>
            </thead>
            <tbody>${rows}</tbody>
          </table>
        </div>`;
    }

    function renderSections(sections) {
      const container = document.getElementById('sections-container');
      if (!sections.length) { container.innerHTML = ''; return; }

      container.innerHTML = `<div class="section-label">Full Report Card</div>` +
        sections.map((s, i) => {
          const isSpecial = SPECIAL_SECTIONS.has(s.title);
          const isOpen    = i < 2 || isSpecial; // open first 2 + instructor's note
          const paragraphs = s.content
            .split('\n')
            .filter(l => l.trim())
            .map(l => `<p>${escHtml(l.trim())}</p>`)
            .join('');
          return `
            <div class="section-card ${isOpen ? 'open' : ''} ${isSpecial ? 'special instructors-note' : ''}" id="sec-${i}">
              <div class="section-header" onclick="toggleSection(${i})">
                <span class="section-icon">${s.icon}</span>
                <span class="section-title">${escHtml(s.title)}</span>
                <span class="section-toggle">▼</span>
              </div>
              <div class="section-body">${paragraphs || '<p>No content in this section.</p>'}</div>
            </div>`;
        }).join('');
    }

    function toggleSection(idx) {
      document.getElementById(`sec-${idx}`).classList.toggle('open');
    }

    // ── EMAIL ─────────────────────────────────────────────────────────────────
    async function sendReport() {
      const email  = document.getElementById('email-input').value.trim();
      const status = document.getElementById('email-status');
      const btn    = document.getElementById('send-btn');

      if (!email) {
        status.className   = 'email-status error';
        status.textContent = 'Please enter an email address first.';
        return;
      }
      if (!currentToken) {
        status.className   = 'email-status error';
        status.textContent = 'No report to send — please run analysis first.';
        return;
      }

      btn.disabled     = true;
      status.className = 'email-status sending';
      const sendQuote  = LOADING_MESSAGES[Math.floor(Math.random() * LOADING_MESSAGES.length)];
      status.innerHTML = `<span class="eq-text">"${sendQuote.q}"</span><span class="eq-attr">— ${sendQuote.a}</span>`;

      try {
        const resp = await fetch('/send-report', {
          method:  'POST',
          headers: { 'Content-Type': 'application/json' },
          body:    JSON.stringify({ email, pdf_token: currentToken }),
        });
        const data = await resp.json();
        if (data.error) {
          status.className   = 'email-status error';
          status.textContent = '⚠️ ' + data.error;
        } else {
          const doneQuote = LOADING_MESSAGES[Math.floor(Math.random() * LOADING_MESSAGES.length)];
          status.className = 'email-status success';
          status.innerHTML = `✅ Sent! Now go do something with this info.<br><span class="eq-text">"${doneQuote.q}"</span><span class="eq-attr">— ${doneQuote.a}</span>`;
        }
      } catch (err) {
        status.className   = 'email-status error';
        status.textContent = '⚠️ Network error: ' + err.message;
      } finally {
        btn.disabled = false;
      }
    }

    // ── ERROR ─────────────────────────────────────────────────────────────────
    function showError(msg) {
      document.getElementById('results-section').style.display = 'block';
      document.getElementById('error-container').innerHTML = `
        <div class="error-card">
          <strong>⚠️ Something went wrong</strong>
          ${escHtml(msg)}
          <br/><br/>
          <button class="btn-reset" onclick="resetUI()" style="margin:0;">↩ Try Again</button>
        </div>`;
      document.getElementById('grade-card-container').innerHTML  = '';
      document.getElementById('trend-history-container').innerHTML = '';
      document.getElementById('sections-container').innerHTML    = '';
      document.getElementById('email-card').style.display        = 'none';
    }

    // ── RESET ─────────────────────────────────────────────────────────────────
    function resetUI() {
      selectedFiles  = [];
      currentToken   = null;
      currentMode    = 'single';
      businessType   = 'none';

      renderFileList();
      setMode('single');
      document.querySelectorAll('.biz-card').forEach(b => b.classList.remove('active'));
      document.getElementById('compliance-column').innerHTML = '';

      document.getElementById('upload-section').style.display  = 'block';
      document.getElementById('loading-section').style.display = 'none';
      document.getElementById('results-section').style.display = 'none';
      document.getElementById('email-input').value             = '';
      document.getElementById('email-status').textContent      = '';
      document.getElementById('email-card').style.display      = 'block';

      window.scrollTo({ top: 0, behavior: 'smooth' });
    }

    // ── UTILS ─────────────────────────────────────────────────────────────────
    // ── CHAT ──────────────────────────────────────────────────────────────────
    let chatOpen    = false;
    let chatBusy    = false;
    let scanContext = '';  // populated after analysis

    function toggleChat() {
      chatOpen = !chatOpen;
      document.getElementById('chat-panel').classList.toggle('open', chatOpen);
      if (chatOpen) {
        document.getElementById('chat-input').focus();
        scrollChatToBottom();
      }
    }

    function useChip(el) {
      document.getElementById('chat-input').value = el.textContent;
      document.getElementById('chat-suggestions').style.display = 'none';
      sendChatMessage();
    }

    function handleChatKey(e) {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        sendChatMessage();
      }
    }

    function autoResize(el) {
      el.style.height = 'auto';
      el.style.height = Math.min(el.scrollHeight, 100) + 'px';
    }

    function scrollChatToBottom() {
      const msgs = document.getElementById('chat-messages');
      msgs.scrollTop = msgs.scrollHeight;
    }

    function addBubble(text, role) {
      const msgs = document.getElementById('chat-messages');
      const div  = document.createElement('div');
      div.className = `chat-bubble ${role}`;
      div.textContent = text;
      msgs.appendChild(div);
      scrollChatToBottom();
      return div;
    }

    async function sendChatMessage() {
      const input = document.getElementById('chat-input');
      const question = input.value.trim();
      if (!question || chatBusy) return;

      // Hide suggestion chips after first message
      document.getElementById('chat-suggestions').style.display = 'none';

      chatBusy = true;
      document.getElementById('chat-send').disabled = true;
      input.value = '';
      input.style.height = 'auto';

      addBubble(question, 'user');

      // Typing indicator
      const msgs     = document.getElementById('chat-messages');
      const typingEl = document.createElement('div');
      typingEl.className = 'chat-bubble typing';
      typingEl.innerHTML = '<span class="typing-dots"><span></span><span></span><span></span></span>';
      msgs.appendChild(typingEl);
      scrollChatToBottom();

      try {
        const resp = await fetch('/ask', {
          method:  'POST',
          headers: { 'Content-Type': 'application/json' },
          body:    JSON.stringify({ question, scan_context: scanContext }),
        });
        const data = await resp.json();
        typingEl.remove();

        if (data.error) {
          addBubble('Hmm, something went wrong: ' + data.error, 'vulnerd');
        } else {
          addBubble(data.answer, 'vulnerd');
        }
      } catch (err) {
        typingEl.remove();
        addBubble('Network error — make sure the Vulnerd server is running!', 'vulnerd');
      } finally {
        chatBusy = false;
        document.getElementById('chat-send').disabled = false;
        input.focus();
      }
    }

    // After analysis completes, save scan summary as context for chat
    const _origRenderResults = renderResults;
    renderResults = function(data) {
      _origRenderResults(data);
      if (data.mode === 'single' && data.letter) {
        scanContext = `Grade: ${data.letter} (${data.score}/100). ` +
          `Total findings: ${data.total}. ` +
          `Critical: ${(data.counts||{}).Critical||0}, ` +
          `High: ${(data.counts||{}).High||0}, ` +
          `Medium: ${(data.counts||{}).Medium||0}, ` +
          `Low: ${(data.counts||{}).Low||0}. ` +
          `File: ${data.filename}.`;
      } else if (data.mode === 'trend' && data.trend_grades) {
        const grades = data.trend_grades.map(g =>
          `${g.filename} (${g.date}): ${g.letter} ${g.score}/100, ${g.total} findings`
        ).join('; ');
        scanContext = `Trend analysis across ${data.trend_grades.length} scans. Results: ${grades}.`;
      }
    };

    // ── COMPLIANCE DASHBOARD ──────────────────────────────────────────────────
    function renderComplianceDashboard(data) {
      const col = document.getElementById('compliance-column');
      if (!data) { col.innerHTML = ''; return; }

      const fmt = n => '$' + Number(n).toLocaleString();

      const bars = (data.attributes || []).map(a => {
        const pct   = Math.min(100, Math.max(0, a.score));
        const color = pct >= 71 ? '#22c55e' : pct >= 41 ? '#f59e0b' : '#ef4444';
        return `
          <div class="attr-item">
            <div class="attr-top">
              <span class="attr-name">${escHtml(a.name)}</span>
              <span class="attr-pct">${pct}%</span>
            </div>
            <div class="attr-track">
              <div class="attr-fill" style="width:0%;background:${color};" data-target="${pct}%"></div>
            </div>
            <div class="attr-blurb">${escHtml(a.blurb || '')}</div>
          </div>`;
      }).join('');

      col.innerHTML = `
        <div class="compliance-panel">
          <div class="compliance-header">
            <div class="compliance-framework-name">${escHtml(data.framework_name || '')}</div>
            <div class="compliance-framework-full">${escHtml(data.framework_full || '')}</div>
          </div>
          <div class="compliance-body">

            <div class="attr-list">${bars}</div>

            <div class="compliance-divider"></div>

            <div class="compliance-section-title">What is ${escHtml(data.framework_name || 'this')}?</div>
            <p class="compliance-text">${escHtml(data.what_is_it || '')}</p>
            <p class="compliance-text">${escHtml(data.why_it_matters || '')}</p>

            <div class="compliance-section-title" style="margin-top:14px;">Real World Impact</div>
            <div class="story-box">${escHtml(data.real_story || '')}</div>

            <div class="compliance-divider"></div>

            <div class="compliance-section-title">Cost Reality Check 💰</div>
            <div class="cost-grid">
              <div class="cost-card fix">
                <div class="cost-label">Fix it now</div>
                <div class="cost-amount">${fmt(data.fix_cost_low)}–${fmt(data.fix_cost_high)}</div>
                <div class="cost-sublabel">estimated remediation</div>
              </div>
              <div class="cost-card breach">
                <div class="cost-label">If you don't</div>
                <div class="cost-amount">${fmt(data.breach_cost_low)}–${fmt(data.breach_cost_high)}</div>
                <div class="cost-sublabel">potential fines & breach costs</div>
              </div>
            </div>
            <p class="cost-context">${escHtml(data.cost_context || '')}</p>

          </div>
        </div>`;

      // Animate bars in after a short delay
      setTimeout(() => {
        col.querySelectorAll('.attr-fill').forEach(el => {
          el.style.width = el.dataset.target;
        });
      }, 200);
    }

    function escHtml(str) {
      if (!str) return '';
      return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
    }
  </script>
</body>
</html>
