Changed color and contrast gradients

This commit is contained in:
2026-02-10 09:54:42 -07:00
parent ba4d16396c
commit 626d0cac3a
2 changed files with 313 additions and 118 deletions

View File

@@ -4,12 +4,43 @@
font-family: 'Outfit', system-ui, sans-serif;
}
:root {
/* Base Colors */
--intel-darkest: #0A0E27;
--intel-dark: #131937;
--intel-medium: #1E2749;
--intel-accent: #00D9FF;
--intel-warning: #FFB800;
--intel-danger: #FF3366;
--intel-success: #00FF88;
--intel-grid: rgba(0, 217, 255, 0.1);
/* Text Colors with proper contrast */
--text-primary: #FFFFFF;
--text-secondary: #E4E8F1;
--text-tertiary: #B8C5D9;
--text-muted: #8A98B0;
}
body {
background-color: #0A0E27;
color: #E4E8F1;
overflow-x: hidden;
}
/* Utility Classes for Tailwind-style usage */
.bg-intel-darkest { background-color: var(--intel-darkest); }
.bg-intel-dark { background-color: var(--intel-dark); }
.bg-intel-medium { background-color: var(--intel-medium); }
.text-intel-accent { color: var(--intel-accent); }
.text-intel-warning { color: var(--intel-warning); }
.text-intel-danger { color: var(--intel-danger); }
.text-intel-success { color: var(--intel-success); }
.border-intel-accent { border-color: var(--intel-accent); }
.border-intel-warning { border-color: var(--intel-warning); }
.border-intel-danger { border-color: var(--intel-danger); }
.border-intel-grid { border-color: var(--intel-grid); }
/* Grid background effect */
.grid-bg {
background-image:
@@ -75,13 +106,17 @@ body {
}
}
/* Card hover effects */
/* Card hover effects with depth */
.intel-card {
background: linear-gradient(135deg, #131937 0%, #1E2749 100%);
border: 1px solid rgba(0, 217, 255, 0.1);
border: 1px solid rgba(0, 217, 255, 0.2);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
box-shadow:
0 4px 6px rgba(0, 0, 0, 0.3),
0 1px 3px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.intel-card::after {
@@ -93,16 +128,20 @@ body {
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(0, 217, 255, 0.05),
rgba(0, 217, 255, 0.08),
transparent
);
transition: left 0.5s;
pointer-events: none;
}
.intel-card:hover {
border-color: rgba(0, 217, 255, 0.4);
border-color: rgba(0, 217, 255, 0.5);
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 217, 255, 0.15);
box-shadow:
0 12px 28px rgba(0, 217, 255, 0.2),
0 6px 12px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.intel-card:hover::after {
@@ -177,7 +216,7 @@ body {
box-shadow: 0 0 10px #00FF88;
}
/* Button styles */
/* Button styles with depth and glow */
.intel-button {
position: relative;
font-family: 'JetBrains Mono', monospace;
@@ -190,6 +229,9 @@ body {
transition: all 0.3s;
border: 1px solid;
overflow: hidden;
box-shadow:
0 2px 6px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.intel-button::before {
@@ -200,7 +242,7 @@ body {
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.15);
transform: translate(-50%, -50%);
transition: width 0.5s, height 0.5s;
}
@@ -211,69 +253,102 @@ body {
}
.intel-button-primary {
background: rgba(0, 217, 255, 0.15);
background: linear-gradient(135deg, rgba(0, 217, 255, 0.2) 0%, rgba(0, 217, 255, 0.15) 100%);
border-color: #00D9FF;
color: #00D9FF;
text-shadow: 0 0 10px rgba(0, 217, 255, 0.3);
}
.intel-button-primary:hover {
background: rgba(0, 217, 255, 0.25);
box-shadow: 0 0 20px rgba(0, 217, 255, 0.3);
background: linear-gradient(135deg, rgba(0, 217, 255, 0.3) 0%, rgba(0, 217, 255, 0.25) 100%);
box-shadow:
0 0 25px rgba(0, 217, 255, 0.4),
0 4px 12px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
transform: translateY(-1px);
}
.intel-button-danger {
background: rgba(255, 51, 102, 0.15);
background: linear-gradient(135deg, rgba(255, 51, 102, 0.2) 0%, rgba(255, 51, 102, 0.15) 100%);
border-color: #FF3366;
color: #FF3366;
text-shadow: 0 0 10px rgba(255, 51, 102, 0.3);
}
.intel-button-danger:hover {
background: rgba(255, 51, 102, 0.25);
box-shadow: 0 0 20px rgba(255, 51, 102, 0.3);
background: linear-gradient(135deg, rgba(255, 51, 102, 0.3) 0%, rgba(255, 51, 102, 0.25) 100%);
box-shadow:
0 0 25px rgba(255, 51, 102, 0.4),
0 4px 12px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
transform: translateY(-1px);
}
.intel-button-success {
background: rgba(0, 255, 136, 0.15);
background: linear-gradient(135deg, rgba(0, 255, 136, 0.2) 0%, rgba(0, 255, 136, 0.15) 100%);
border-color: #00FF88;
color: #00FF88;
text-shadow: 0 0 10px rgba(0, 255, 136, 0.3);
}
.intel-button-success:hover {
background: rgba(0, 255, 136, 0.25);
box-shadow: 0 0 20px rgba(0, 255, 136, 0.3);
background: linear-gradient(135deg, rgba(0, 255, 136, 0.3) 0%, rgba(0, 255, 136, 0.25) 100%);
box-shadow:
0 0 25px rgba(0, 255, 136, 0.4),
0 4px 12px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
transform: translateY(-1px);
}
/* Input fields */
/* Input fields with better contrast */
.intel-input {
background: rgba(19, 25, 55, 0.5);
border: 1px solid rgba(0, 217, 255, 0.2);
color: #E4E8F1;
background: rgba(19, 25, 55, 0.7);
border: 1px solid rgba(0, 217, 255, 0.3);
color: #FFFFFF;
padding: 0.625rem 1rem;
border-radius: 0.375rem;
font-family: 'JetBrains Mono', monospace;
font-size: 0.875rem;
transition: all 0.3s;
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.3),
0 1px 0 rgba(255, 255, 255, 0.05);
}
.intel-input:focus {
outline: none;
border-color: #00D9FF;
box-shadow: 0 0 0 2px rgba(0, 217, 255, 0.1);
background: rgba(19, 25, 55, 0.8);
box-shadow:
0 0 0 2px rgba(0, 217, 255, 0.2),
inset 0 2px 4px rgba(0, 0, 0, 0.2),
0 4px 12px rgba(0, 217, 255, 0.15);
background: rgba(19, 25, 55, 0.9);
}
.intel-input::placeholder {
color: rgba(228, 232, 241, 0.3);
color: rgba(228, 232, 241, 0.4);
}
/* Stat cards */
/* Stat cards with depth and glow */
.stat-card {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.8) 0%, rgba(30, 39, 73, 0.6) 100%);
border: 1px solid rgba(0, 217, 255, 0.15);
background: linear-gradient(135deg, rgba(19, 25, 55, 0.9) 0%, rgba(30, 39, 73, 0.8) 100%);
border: 1px solid rgba(0, 217, 255, 0.25);
border-radius: 0.5rem;
padding: 1rem;
position: relative;
overflow: hidden;
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
transition: all 0.3s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow:
0 8px 20px rgba(0, 217, 255, 0.15),
0 4px 12px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.stat-card::before {
@@ -284,13 +359,22 @@ body {
right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, #00D9FF, transparent);
opacity: 0.5;
opacity: 0.7;
box-shadow: 0 0 8px rgba(0, 217, 255, 0.5);
}
/* Modal overlay */
/* Modal overlay with proper backdrop */
.modal-overlay {
background: rgba(10, 14, 39, 0.95);
backdrop-filter: blur(8px);
background: rgba(10, 14, 39, 0.97);
backdrop-filter: blur(12px);
}
/* Modal card enhancements */
.intel-card.modal-card {
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.6),
0 10px 30px rgba(0, 217, 255, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
/* Scrollbar styling */
@@ -340,13 +424,89 @@ body {
/* Data table styling */
.data-row {
border-bottom: 1px solid rgba(0, 217, 255, 0.05);
border-bottom: 1px solid rgba(0, 217, 255, 0.1);
transition: all 0.2s;
}
.data-row:hover {
background: rgba(0, 217, 255, 0.03);
border-bottom-color: rgba(0, 217, 255, 0.2);
background: rgba(0, 217, 255, 0.06);
border-bottom-color: rgba(0, 217, 255, 0.3);
box-shadow: 0 2px 8px rgba(0, 217, 255, 0.1);
}
/* Vendor entry cards - high contrast and depth */
.vendor-card {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.9) 0%, rgba(30, 39, 73, 0.8) 100%);
border: 1px solid rgba(0, 217, 255, 0.25);
border-radius: 0.5rem;
padding: 1rem;
transition: all 0.3s ease;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.vendor-card:hover {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
border-color: rgba(0, 217, 255, 0.4);
box-shadow:
0 4px 16px rgba(0, 217, 255, 0.15),
0 2px 8px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
transform: translateY(-2px);
}
/* Document list items with depth */
.document-item {
background: linear-gradient(135deg, rgba(10, 14, 39, 0.9) 0%, rgba(19, 25, 55, 0.8) 100%);
border: 1px solid rgba(0, 217, 255, 0.15);
border-radius: 0.375rem;
padding: 0.75rem;
transition: all 0.3s ease;
box-shadow:
0 2px 6px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.document-item:hover {
background: linear-gradient(135deg, rgba(10, 14, 39, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
border-color: rgba(0, 217, 255, 0.3);
box-shadow:
0 4px 12px rgba(0, 217, 255, 0.12),
0 2px 6px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.06);
transform: translateY(-1px);
}
/* JIRA ticket items with proper contrast */
.jira-ticket-item {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.85) 0%, rgba(30, 39, 73, 0.75) 100%);
border: 1px solid rgba(255, 184, 0, 0.2);
border-radius: 0.375rem;
padding: 0.75rem;
transition: all 0.3s ease;
box-shadow:
0 2px 6px rgba(0, 0, 0, 0.25),
inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.jira-ticket-item:hover {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.85) 100%);
border-color: rgba(255, 184, 0, 0.35);
box-shadow:
0 4px 12px rgba(255, 184, 0, 0.15),
0 2px 6px rgba(0, 0, 0, 0.35),
inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
/* CVE Header card with depth */
.cve-header {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
transition: all 0.3s ease;
}
.cve-header:hover {
background: linear-gradient(135deg, rgba(30, 39, 73, 0.95) 0%, rgba(42, 52, 88, 0.9) 100%);
}
/* Loading spinner */
@@ -361,7 +521,7 @@ body {
to { transform: rotate(360deg); }
}
/* Tooltip */
/* Tooltip with enhanced styling */
.tooltip {
position: relative;
}
@@ -373,8 +533,8 @@ body {
left: 50%;
transform: translateX(-50%);
padding: 0.5rem 0.75rem;
background: #1E2749;
border: 1px solid rgba(0, 217, 255, 0.3);
background: linear-gradient(135deg, #1E2749 0%, #2A3458 100%);
border: 1px solid rgba(0, 217, 255, 0.4);
border-radius: 0.25rem;
font-size: 0.75rem;
white-space: nowrap;
@@ -383,8 +543,43 @@ body {
transition: opacity 0.3s;
margin-bottom: 0.5rem;
font-family: 'JetBrains Mono', monospace;
color: #FFFFFF;
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.4),
0 0 20px rgba(0, 217, 255, 0.2);
}
.tooltip:hover::after {
opacity: 1;
}
/* Enhanced heading glow */
h1.text-intel-accent,
h2.text-intel-accent,
h3.text-intel-accent {
text-shadow:
0 0 20px rgba(0, 217, 255, 0.4),
0 0 40px rgba(0, 217, 255, 0.2);
}
/* Enhanced border glow for featured cards */
.border-intel-accent {
box-shadow: 0 0 15px rgba(0, 217, 255, 0.15);
}
.border-intel-warning {
box-shadow: 0 0 15px rgba(255, 184, 0, 0.15);
}
.border-intel-danger {
box-shadow: 0 0 15px rgba(255, 51, 102, 0.15);
}
/* Quick lookup section enhancement */
.quick-lookup-card {
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
box-shadow:
0 4px 16px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.05),
0 0 40px rgba(0, 217, 255, 0.1);
}

View File

@@ -680,7 +680,7 @@ export default function App() {
</div>
<div className="mb-4 p-3 bg-intel-medium border border-intel-accent/30 rounded">
<p className="text-sm text-gray-300">
<p className="text-sm text-white">
<strong className="text-intel-accent">Tip:</strong> You can add the same CVE-ID multiple times with different vendors.
Each vendor will have its own documents folder.
</p>
@@ -688,7 +688,7 @@ export default function App() {
<form onSubmit={handleAddCVE} className="space-y-4">
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
CVE ID *
</label>
<div className="relative">
@@ -721,7 +721,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
Vendor *
</label>
<input
@@ -736,7 +736,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
Severity *
</label>
<select
@@ -752,7 +752,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
Description *
</label>
<textarea
@@ -766,7 +766,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
Published Date *
</label>
<input
@@ -815,14 +815,14 @@ export default function App() {
</div>
<div className="mb-4 p-3 bg-intel-medium border border-intel-warning/30 rounded">
<p className="text-sm text-gray-300">
<p className="text-sm text-white">
<strong className="text-intel-warning">Note:</strong> Changing CVE ID or Vendor will move associated documents to the new path.
</p>
</div>
<form onSubmit={handleEditCVESubmit} className="space-y-4">
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">CVE ID *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">CVE ID *</label>
<div className="relative">
<input
type="text"
@@ -850,7 +850,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Vendor *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Vendor *</label>
<input
type="text"
required
@@ -861,7 +861,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Severity *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Severity *</label>
<select
value={editForm.severity}
onChange={(e) => setEditForm({...editForm, severity: e.target.value})}
@@ -875,7 +875,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Description *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Description *</label>
<textarea
required
value={editForm.description}
@@ -886,7 +886,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Published Date *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Published Date *</label>
<input
type="date"
required
@@ -897,7 +897,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status *</label>
<select
value={editForm.status}
onChange={(e) => setEditForm({...editForm, status: e.target.value})}
@@ -955,7 +955,7 @@ export default function App() {
{!addTicketContext && (
<>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">CVE ID *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">CVE ID *</label>
<input
type="text"
required
@@ -966,7 +966,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Vendor *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Vendor *</label>
<input
type="text"
required
@@ -979,12 +979,12 @@ export default function App() {
</>
)}
{addTicketContext && (
<div className="p-3 bg-intel-medium border border-intel-warning/30 rounded text-sm text-gray-300">
<div className="p-3 bg-intel-medium border border-intel-warning/30 rounded text-sm text-white">
Adding ticket for <strong className="text-intel-warning">{addTicketContext.cve_id}</strong> / <strong className="text-intel-warning">{addTicketContext.vendor}</strong>
</div>
)}
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Ticket Key *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Ticket Key *</label>
<input
type="text"
required
@@ -995,7 +995,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">JIRA URL</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">JIRA URL</label>
<input
type="url"
placeholder="https://jira.company.com/browse/VULN-1234"
@@ -1005,7 +1005,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Summary</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Summary</label>
<input
type="text"
placeholder="Brief description"
@@ -1015,7 +1015,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status</label>
<select
value={ticketForm.status}
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
@@ -1051,12 +1051,12 @@ export default function App() {
<XCircle className="w-6 h-6" />
</button>
</div>
<div className="p-3 bg-intel-medium rounded text-sm text-gray-300 mb-4 font-mono">
<div className="p-3 bg-intel-medium rounded text-sm text-white mb-4 font-mono">
{editingTicket.cve_id} / {editingTicket.vendor}
</div>
<form onSubmit={handleUpdateTicket} className="space-y-4">
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Ticket Key *</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Ticket Key *</label>
<input
type="text"
required
@@ -1066,7 +1066,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">JIRA URL</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">JIRA URL</label>
<input
type="url"
value={ticketForm.url}
@@ -1075,7 +1075,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Summary</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Summary</label>
<input
type="text"
value={ticketForm.summary}
@@ -1084,7 +1084,7 @@ export default function App() {
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status</label>
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status</label>
<select
value={ticketForm.status}
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
@@ -1137,7 +1137,7 @@ export default function App() {
<XCircle className="w-5 h-5 text-intel-danger mt-0.5" />
<div>
<p className="font-medium text-intel-danger font-mono">Error</p>
<p className="text-sm text-gray-400">{quickCheckResult.error}</p>
<p className="text-sm text-gray-300">{quickCheckResult.error}</p>
</div>
</div>
) : quickCheckResult.exists ? (
@@ -1147,12 +1147,12 @@ export default function App() {
<p className="font-medium text-intel-success font-mono"> CVE Addressed ({quickCheckResult.vendors.length} vendor{quickCheckResult.vendors.length > 1 ? 's' : ''})</p>
<div className="mt-3 space-y-3">
{quickCheckResult.vendors.map((vendorInfo, idx) => (
<div key={idx} className="p-3 bg-intel-dark/50 rounded border border-intel-accent/20">
<p className="font-semibold text-gray-200 mb-2 font-sans">{vendorInfo.vendor}</p>
<div className="grid grid-cols-2 gap-2 text-sm text-gray-400 mb-2 font-mono">
<p><strong className="text-gray-300">Severity:</strong> {vendorInfo.severity}</p>
<p><strong className="text-gray-300">Status:</strong> {vendorInfo.status}</p>
<p><strong className="text-gray-300">Documents:</strong> {vendorInfo.total_documents} attached</p>
<div key={idx} className="p-3 bg-intel-dark/70 rounded border border-intel-accent/30 shadow-lg">
<p className="font-semibold text-white mb-2 font-sans">{vendorInfo.vendor}</p>
<div className="grid grid-cols-2 gap-2 text-sm text-gray-300 mb-2 font-mono">
<p><strong className="text-white">Severity:</strong> {vendorInfo.severity}</p>
<p><strong className="text-white">Status:</strong> {vendorInfo.status}</p>
<p><strong className="text-white">Documents:</strong> {vendorInfo.total_documents} attached</p>
</div>
</div>
))}
@@ -1164,7 +1164,7 @@ export default function App() {
<AlertCircle className="w-5 h-5 text-intel-warning mt-0.5" />
<div>
<p className="font-medium text-intel-warning font-mono">Not Found</p>
<p className="text-sm text-gray-400">This CVE has not been addressed yet. No entry exists in the database.</p>
<p className="text-sm text-gray-300">This CVE has not been addressed yet. No entry exists in the database.</p>
</div>
</div>
)}
@@ -1192,7 +1192,7 @@ export default function App() {
</div>
<div className="space-y-2">
{jiraTickets.filter(t => t.status !== 'Closed').map(ticket => (
<div key={ticket.id} className="data-row flex items-center justify-between p-3 bg-intel-dark/50 rounded border border-intel-grid hover:border-intel-warning/30">
<div key={ticket.id} className="jira-ticket-item flex items-center justify-between">
<div className="flex items-center gap-4 flex-1">
<a
href={ticket.url || '#'}
@@ -1202,9 +1202,9 @@ export default function App() {
>
{ticket.ticket_key}
</a>
<span className="text-sm text-gray-300 font-mono">{ticket.cve_id}</span>
<span className="text-sm text-gray-500 font-mono">({ticket.vendor})</span>
{ticket.summary && <span className="text-sm text-gray-400 truncate max-w-xs">{ticket.summary}</span>}
<span className="text-sm text-white font-mono">{ticket.cve_id}</span>
<span className="text-sm text-gray-300 font-mono">({ticket.vendor})</span>
{ticket.summary && <span className="text-sm text-gray-300 truncate max-w-xs">{ticket.summary}</span>}
<span className={`status-badge ${
ticket.status === 'Open' ? 'status-critical' : 'status-high'
}`}>
@@ -1213,10 +1213,10 @@ export default function App() {
</div>
{canWrite() && (
<div className="flex gap-2">
<button onClick={() => handleEditTicket(ticket)} className="text-gray-500 hover:text-intel-warning transition-colors">
<button onClick={() => handleEditTicket(ticket)} className="text-gray-400 hover:text-intel-warning transition-colors">
<Edit2 className="w-4 h-4" />
</button>
<button onClick={() => handleDeleteTicket(ticket)} className="text-gray-500 hover:text-intel-danger transition-colors">
<button onClick={() => handleDeleteTicket(ticket)} className="text-gray-400 hover:text-intel-danger transition-colors">
<Trash2 className="w-4 h-4" />
</button>
</div>
@@ -1231,7 +1231,7 @@ export default function App() {
<div className="intel-card rounded-lg p-6 mb-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="md:col-span-1">
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
<Search className="inline w-4 h-4 mr-1" />
Search CVEs
</label>
@@ -1245,7 +1245,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
<Filter className="inline w-4 h-4 mr-1" />
Vendor
</label>
@@ -1261,7 +1261,7 @@ export default function App() {
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
<AlertCircle className="inline w-4 h-4 mr-1" />
Severity
</label>
@@ -1331,7 +1331,7 @@ export default function App() {
<div key={cveId} className="intel-card rounded-lg relative overflow-hidden">
{/* Clickable CVE Header */}
<div
className="p-6 cursor-pointer hover:bg-intel-medium/30 transition-all duration-200 select-none"
className="cve-header p-6 cursor-pointer transition-all duration-200 select-none"
onClick={() => toggleCVEExpand(cveId)}
>
<div className="flex items-start justify-between">
@@ -1346,17 +1346,17 @@ export default function App() {
{/* Collapsed: truncated description + summary row */}
{!isCVEExpanded && (
<div className="ml-8">
<p className="text-gray-400 text-sm truncate mb-2">{vendorEntries[0].description}</p>
<p className="text-gray-300 text-sm truncate mb-2">{vendorEntries[0].description}</p>
<div className="flex items-center gap-3 flex-wrap">
<span className={`status-badge status-${highestSeverity.toLowerCase()}`}>
{highestSeverity}
</span>
<span className="text-xs text-gray-500 font-mono">{vendorEntries.length} vendor{vendorEntries.length > 1 ? 's' : ''}</span>
<span className="text-xs text-gray-500 flex items-center gap-1 font-mono">
<span className="text-xs text-gray-300 font-mono">{vendorEntries.length} vendor{vendorEntries.length > 1 ? 's' : ''}</span>
<span className="text-xs text-gray-300 flex items-center gap-1 font-mono">
<FileText className="w-3 h-3" />
{totalDocCount} doc{totalDocCount !== 1 ? 's' : ''}
</span>
<span className="text-xs text-gray-500 font-mono">
<span className="text-xs text-gray-300 font-mono">
{overallStatuses.join(', ')}
</span>
</div>
@@ -1366,8 +1366,8 @@ export default function App() {
{/* Expanded: full description + metadata */}
{isCVEExpanded && (
<div className="ml-8">
<p className="text-gray-300 mb-3">{vendorEntries[0].description}</p>
<div className="flex items-center gap-2 text-sm text-gray-400 font-mono">
<p className="text-white mb-3">{vendorEntries[0].description}</p>
<div className="flex items-center gap-2 text-sm text-gray-300 font-mono">
<span>Published: {vendorEntries[0].published_date}</span>
<span className="text-intel-accent"></span>
<span>{vendorEntries.length} affected vendor{vendorEntries.length > 1 ? 's' : ''}</span>
@@ -1397,17 +1397,17 @@ export default function App() {
const isDocExpanded = selectedCVE === cve.cve_id && selectedVendorView === cve.vendor;
return (
<div key={cve.id} className="border border-intel-accent/20 rounded-lg p-4 bg-intel-dark/50 hover:bg-intel-dark transition-all">
<div key={cve.id} className="vendor-card">
<div className="flex justify-between items-start">
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<h4 className="text-lg font-semibold text-gray-200 font-sans">{cve.vendor}</h4>
<h4 className="text-lg font-semibold text-white font-sans">{cve.vendor}</h4>
<span className={`status-badge status-${cve.severity.toLowerCase()}`}>
{cve.severity}
</span>
</div>
<div className="flex items-center gap-4 text-sm text-gray-400 font-mono">
<span>Status: <span className="font-medium text-gray-300">{cve.status}</span></span>
<div className="flex items-center gap-4 text-sm text-gray-300 font-mono">
<span>Status: <span className="font-medium text-white">{cve.status}</span></span>
<span className="flex items-center gap-1">
<FileText className="w-4 h-4" />
{cve.document_count} doc{cve.document_count !== 1 ? 's' : ''}
@@ -1445,9 +1445,9 @@ export default function App() {
{/* Documents Section */}
{isDocExpanded && (
<div className="mt-4 pt-4 border-t border-intel-accent/20">
<h5 className="text-sm font-semibold text-gray-300 mb-3 flex items-center gap-2 font-mono uppercase tracking-wider">
<FileText className="w-4 h-4" />
<div className="mt-4 pt-4 border-t border-intel-accent/30">
<h5 className="text-sm font-semibold text-white mb-3 flex items-center gap-2 font-mono uppercase tracking-wider">
<FileText className="w-4 h-4 text-intel-accent" />
Documents ({documents.length})
</h5>
{documents.length > 0 ? (
@@ -1455,7 +1455,7 @@ export default function App() {
{documents.map(doc => (
<div
key={doc.id}
className="data-row flex items-center justify-between p-3 bg-intel-darkest/50 rounded hover:bg-intel-medium/30 transition-all border border-intel-grid"
className="document-item flex items-center justify-between"
>
<div className="flex items-center gap-3 flex-1">
<input
@@ -1464,10 +1464,10 @@ export default function App() {
onChange={() => toggleDocumentSelection(doc.id)}
className="w-4 h-4 text-intel-accent rounded focus:ring-2 focus:ring-intel-accent bg-intel-dark border-intel-accent/50"
/>
<FileText className="w-5 h-5 text-intel-accent/70" />
<FileText className="w-5 h-5 text-intel-accent" />
<div className="flex-1">
<p className="text-sm font-medium text-gray-200 font-mono">{doc.name}</p>
<p className="text-xs text-gray-500 capitalize font-mono">
<p className="text-sm font-medium text-white font-mono">{doc.name}</p>
<p className="text-xs text-gray-300 capitalize font-mono">
{doc.type} <span className="text-intel-accent"></span> {doc.file_size}
{doc.notes && <span> <span className="text-intel-accent"></span> {doc.notes}</span>}
</p>
@@ -1496,7 +1496,7 @@ export default function App() {
))}
</div>
) : (
<p className="text-sm text-gray-500 italic font-mono">No documents attached</p>
<p className="text-sm text-gray-400 italic font-mono">No documents attached</p>
)}
{canWrite() && (
<button
@@ -1515,16 +1515,16 @@ export default function App() {
{(() => {
const vendorTickets = jiraTickets.filter(t => t.cve_id === cve.cve_id && t.vendor === cve.vendor);
return vendorTickets.length > 0 || canWrite() ? (
<div className="mt-4 pt-4 border-t border-gray-300">
<div className="mt-4 pt-4 border-t border-intel-warning/30">
<div className="flex justify-between items-center mb-3">
<h5 className="text-sm font-semibold text-gray-700 flex items-center gap-2">
<AlertCircle className="w-4 h-4 text-orange-500" />
<h5 className="text-sm font-semibold text-white flex items-center gap-2 font-mono uppercase tracking-wider">
<AlertCircle className="w-4 h-4 text-intel-warning" />
JIRA Tickets ({vendorTickets.length})
</h5>
{canWrite() && (
<button
onClick={() => openAddTicketForCVE(cve.cve_id, cve.vendor)}
className="text-xs px-2 py-1 text-orange-600 hover:bg-orange-50 rounded border border-orange-300 flex items-center gap-1"
className="text-xs px-3 py-1 intel-button intel-button-primary flex items-center gap-1"
>
<Plus className="w-3 h-3" />
Add Ticket
@@ -1534,32 +1534,32 @@ export default function App() {
{vendorTickets.length > 0 ? (
<div className="space-y-2">
{vendorTickets.map(ticket => (
<div key={ticket.id} className="flex items-center justify-between p-2 bg-white rounded border border-gray-200">
<div className="flex items-center gap-3">
<div key={ticket.id} className="jira-ticket-item flex items-center justify-between">
<div className="flex items-center gap-3 flex-1">
<a
href={ticket.url || '#'}
target="_blank"
rel="noopener noreferrer"
className="font-mono text-sm font-semibold text-[#0476D9] hover:underline"
className="font-mono text-sm font-semibold text-intel-accent hover:text-intel-warning transition-colors"
>
{ticket.ticket_key}
</a>
{ticket.summary && <span className="text-sm text-gray-600 truncate max-w-xs">{ticket.summary}</span>}
<span className={`px-2 py-0.5 rounded text-xs font-medium ${
ticket.status === 'Open' ? 'bg-red-100 text-red-800' :
ticket.status === 'In Progress' ? 'bg-yellow-100 text-yellow-800' :
'bg-green-100 text-green-800'
{ticket.summary && <span className="text-sm text-gray-300 truncate max-w-xs">{ticket.summary}</span>}
<span className={`status-badge ${
ticket.status === 'Open' ? 'status-critical' :
ticket.status === 'In Progress' ? 'status-high' :
'status-low'
}`}>
{ticket.status}
</span>
</div>
{canWrite() && (
<div className="flex gap-1">
<button onClick={() => handleEditTicket(ticket)} className="p-1 text-gray-400 hover:text-orange-600">
<Edit2 className="w-3 h-3" />
<div className="flex gap-2">
<button onClick={() => handleEditTicket(ticket)} className="p-1 text-gray-400 hover:text-intel-warning transition-colors">
<Edit2 className="w-4 h-4" />
</button>
<button onClick={() => handleDeleteTicket(ticket)} className="p-1 text-gray-400 hover:text-red-600">
<Trash2 className="w-3 h-3" />
<button onClick={() => handleDeleteTicket(ticket)} className="p-1 text-gray-400 hover:text-intel-danger transition-colors">
<Trash2 className="w-4 h-4" />
</button>
</div>
)}
@@ -1567,7 +1567,7 @@ export default function App() {
))}
</div>
) : (
<p className="text-sm text-gray-500 italic">No JIRA tickets linked</p>
<p className="text-sm text-gray-400 italic font-mono">No JIRA tickets linked</p>
)}
</div>
) : null;
@@ -1585,10 +1585,10 @@ export default function App() {
)}
{Object.keys(filteredGroupedCVEs).length === 0 && !loading && (
<div className="bg-white rounded-lg shadow-md p-12 text-center">
<div className="intel-card rounded-lg p-12 text-center">
<AlertCircle className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-900 mb-2">No CVEs Found</h3>
<p className="text-gray-600">Try adjusting your search criteria or filters</p>
<h3 className="text-lg font-medium text-white mb-2 font-mono">No CVEs Found</h3>
<p className="text-gray-300">Try adjusting your search criteria or filters</p>
</div>
)}
</div>