Add roadmap API and mock dashboard

This commit is contained in:
2025-11-13 15:05:34 -05:00
parent e21301cffb
commit 4455640afa
29 changed files with 3717 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200" role="img" aria-label="GooseStrike mark">
<defs>
<style>
.goose-fill { fill: #0b0c0d; }
.accent-red { fill: #d90429; }
.leaf-fill { fill: #d90429; }
.type { font-family: 'Oswald', 'Arial Black', sans-serif; font-size: 32px; font-weight: 700; letter-spacing: 2px; fill: #0b0c0d; }
</style>
</defs>
<rect width="300" height="200" fill="none" />
<path class="goose-fill" d="M206 33c-32.7-14.7-78-16.4-104.1 8.4-12.9 12.4-19.7 29.6-16.5 48.5 2.7 16 11.8 29.6 24.8 38.8-11.9 6.4-19.4 17.5-19.4 29.6 0 22 21.5 39.1 56.7 39.1 20.6 0 37.6-4.8 50.7-13.7l-9.5-15c-8.9 6.3-22 10.6-37.5 10.6-19.6 0-32.8-8.2-32.8-20 0-7.7 8.1-15.5 22.8-17.7l26.6-4c36.4-5.5 63.3-28.2 63.3-66.1-.1-28.4-17.1-51.7-45.1-62.5zm-12.6 101.8-24.9 3.7c-15.5-9.4-26-25.8-26-43.4 0-32.7 34.2-52 68.5-43.9 23.3 5.5 36.7 22.5 36.7 43.6 0 27.3-21.3 34.4-54.3 40z"/>
<path class="goose-fill" d="M210.7 48.4c9.9 2.7 19.1 8.3 25.6 16.1 4.6-6.5 5.2-14.8 1.2-20.8-5.3-7.8-17.5-11.9-30-10.4-5.7.7-10.5 2.5-14 5 6.9 1.2 12.8 3.4 17.2 6.1z"/>
<path class="accent-red" d="M227.4 60.4c-2.9 3.8-7.5 6.7-13.2 8.2 4 4 9.2 6.6 14.1 7.3 6.3.9 12.5-1 16.4-5.3 1.9-2.1 3.1-4.6 3.3-7.2-6.2 1.6-13.1 1.2-20.6-3z"/>
<polygon class="leaf-fill" points="122 88 132 88 135 72 142 88 152 88 144 101 154 112 140 113 135 128 128 112 116 114 125 101"/>
<text class="type" x="40" y="182">GOOSE STRIKE</text>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

368
web/static/styles.css Normal file
View File

@@ -0,0 +1,368 @@
:root {
--black: #0b0c0d;
--grey: #4b4f58;
--white: #f5f5f5;
--red: #d90429;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: var(--black);
color: var(--white);
min-height: 100vh;
display: flex;
flex-direction: column;
}
header {
display: flex;
align-items: center;
gap: 1rem;
padding: 1.5rem;
background: linear-gradient(135deg, var(--black), var(--grey));
border-bottom: 4px solid var(--red);
}
section.hero-panel {
background: linear-gradient(120deg, rgba(0, 0, 0, 0.95), rgba(11, 12, 13, 0.85), rgba(75, 79, 88, 0.85));
border: 1px solid rgba(255, 255, 255, 0.2);
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 2rem;
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.55);
}
.hero-text h2 {
margin-top: 0;
font-size: 1.6rem;
}
.hero-list {
list-style: none;
padding-left: 0;
margin: 0 0 1.5rem 0;
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.hero-list li {
font-size: 1rem;
letter-spacing: 0.02em;
}
.hero-meta h3 {
margin-bottom: 0.5rem;
color: var(--white);
}
.hero-meta table {
width: 100%;
border-collapse: collapse;
font-size: 0.95rem;
}
.hero-meta th,
.hero-meta td {
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 0.45rem 0.6rem;
text-align: left;
}
.hero-meta th {
background: rgba(255, 255, 255, 0.08);
}
.hero-visual {
display: flex;
align-items: center;
justify-content: center;
}
.hero-visual-inner {
width: min(320px, 100%);
border-radius: 18px;
background: radial-gradient(circle at top, rgba(255, 255, 255, 0.12), rgba(0, 0, 0, 0.75));
padding: 1.5rem;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.65);
}
.hero-visual img {
width: 100%;
height: auto;
display: block;
}
.canadian-flag {
width: 80px;
height: 48px;
border: 2px solid var(--white);
border-radius: 4px;
background: linear-gradient(90deg, var(--red) 0 25%, var(--white) 25% 75%, var(--red) 75% 100%);
box-shadow: 0 0 12px rgba(0, 0, 0, 0.45);
}
.goose-logo {
margin-left: auto;
width: 120px;
height: 120px;
border-radius: 12px;
border: 2px solid rgba(255, 255, 255, 0.85);
background: linear-gradient(145deg, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.45));
padding: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.65);
}
.goose-logo img {
width: 100%;
height: 100%;
object-fit: contain;
filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.75));
}
main {
flex: 1;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
padding: 1.5rem;
}
section {
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--grey);
border-radius: 8px;
padding: 1rem;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.35);
}
.wide {
grid-column: span 2;
}
#assets article {
border: 1px solid var(--grey);
border-radius: 6px;
padding: 0.75rem;
margin-bottom: 0.75rem;
background: rgba(0, 0, 0, 0.3);
}
#assets .meta {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.7);
margin-bottom: 0.35rem;
}
#scans,
#mitre {
max-height: 60vh;
overflow-y: auto;
}
#scans article,
#mitre article {
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 6px;
padding: 0.75rem;
margin-bottom: 0.75rem;
background: rgba(255, 255, 255, 0.03);
}
#mitre h3,
#scans h3 {
margin-top: 0;
color: var(--red);
}
.service-line {
display: flex;
justify-content: space-between;
align-items: center;
}
.vuln-list {
margin-top: 0.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.35rem;
}
.badge {
display: inline-block;
padding: 0.2rem 0.45rem;
border-radius: 4px;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.severity-critical {
background: var(--red);
color: var(--white);
}
.severity-high {
background: #ff6b6b;
color: var(--black);
}
.severity-medium {
background: #ffba08;
color: var(--black);
}
.severity-low,
.severity-info,
.severity-unknown {
background: rgba(255, 255, 255, 0.2);
color: var(--white);
}
.scan-card .meta,
#mitre .meta {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.75);
}
#assets h3 {
margin: 0 0 0.5rem 0;
color: var(--red);
}
#assets ul {
list-style: none;
padding: 0;
margin: 0;
}
#assets li {
display: flex;
flex-direction: column;
margin-bottom: 0.5rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
#assets li strong {
font-size: 1.1rem;
}
footer {
text-align: center;
padding: 1rem;
background: var(--grey);
color: var(--white);
}
form.card-form {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 0.75rem;
}
label {
font-size: 0.9rem;
display: flex;
flex-direction: column;
gap: 0.35rem;
}
input,
textarea,
select {
background: rgba(0, 0, 0, 0.6);
border: 1px solid rgba(255, 255, 255, 0.2);
color: var(--white);
padding: 0.5rem;
border-radius: 4px;
font-size: 1rem;
}
textarea {
resize: vertical;
}
.form-actions {
display: flex;
align-items: center;
gap: 1rem;
}
button {
background: var(--red);
color: var(--white);
border: none;
padding: 0.6rem 1.25rem;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
}
button:hover {
background: #ff4d4d;
}
.helper {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.7);
}
.helper.error {
color: #ff8c8c;
}
#tasks {
max-height: 60vh;
overflow-y: auto;
}
.task-card {
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
padding: 0.75rem;
margin-bottom: 0.75rem;
background: rgba(0, 0, 0, 0.3);
}
.task-line {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.35rem;
}
.status-pill {
background: rgba(255, 255, 255, 0.2);
color: var(--white);
}
.status-running {
background: #ffba08;
color: var(--black);
}
.status-completed {
background: #06d6a0;
color: var(--black);
}
.status-failed,
.status-error {
background: #ef476f;
color: var(--white);
}

View File

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="GooseStrike official crest">
<defs>
<linearGradient id="bg" x1="0%" x2="100%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#101112" />
<stop offset="55%" stop-color="#1c1e20" />
<stop offset="100%" stop-color="#2b2f36" />
</linearGradient>
<linearGradient id="beak" x1="0%" x2="100%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#e43d3d" />
<stop offset="100%" stop-color="#a10b0b" />
</linearGradient>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="12" stdDeviation="12" flood-color="#000" flood-opacity="0.65" />
</filter>
</defs>
<rect width="640" height="640" rx="64" fill="url(#bg)" />
<g filter="url(#shadow)">
<path d="M365 120c-88 0-162 78-162 174 0 73 43 122 96 138-4 18-38 58-68 76 0 0 120-18 152-142 44-1 112-44 125-112 20-106-82-134-143-134z" fill="#f7f7f2"/>
<path d="M274 178c-12 8-18 18-18 30 0 20 22 36 54 36 38 0 94-24 142-78-40 8-78-2-106-10-34-10-58-4-72 22z" fill="#050505"/>
<path d="M360 210c-18 0-32 10-32 24s14 24 32 24 32-10 32-24-14-24-32-24z" fill="#f7f7f2"/>
<path d="M418 204c48-22 90-22 122 0-6-54-58-88-128-88-42 0-92 10-142 32 42 26 82 34 148 56z" fill="#050505"/>
<path d="M468 232c-16 14-20 34-10 46 12 16 38 14 58-4 22-20 22-46 2-64-18-16-44-18-64-4-10 8-10 16-4 26 10-8 22-8 34 0 14 10 12 24-4 36-12 10-26 12-36 2 0-6 2-12 10-18z" fill="#050505"/>
<path d="M270 374c-26 62-70 104-120 126 72 10 142-12 186-66 32-40 46-94 46-124-36 26-78 44-112 64z" fill="#050505"/>
<path d="M322 330l-42 60 62-28c28-14 50-30 66-54-34 10-64 16-86 22z" fill="#050505"/>
<path d="M256 426 320 512l60-86z" fill="#050505"/>
<path d="M320 500l-80 32 20 32 88-12z" fill="#050505" opacity="0.8"/>
<path d="M320 328 208 448l116-56 100 50z" fill="#050505" opacity="0.85"/>
<path d="M326 360c-30 0-56 24-56 52s26 52 56 52 56-24 56-52-26-52-56-52z" fill="#050505" opacity="0.9"/>
<path d="M346 370c-18 0-32 12-32 28s14 28 32 28 32-12 32-28-14-28-32-28z" fill="#f5f5f5"/>
<path d="M320 260c-58 58-88 118-88 178l62-32 26-76 24 76 68 30c0-96-26-160-92-176z" fill="#d90429"/>
<path d="M320 272c-42 44-62 90-62 138l44-22 18-50 16 50 46 20c0-68-18-114-62-136z" fill="#fdf7f7"/>
<path d="M448 132c-10 0-20 4-28 12 28 0 52 10 70 24 10 8 18 18 24 28 4-4 6-10 6-18 0-26-32-46-72-46z" fill="#050505"/>
<path d="M480 188c-6 0-12 2-18 6 10 8 18 18 22 32 8-2 12-6 12-14 0-12-8-24-16-24z" fill="#050505"/>
<path d="M430 220c-10 0-18 6-18 14 0 8 8 14 18 14s18-6 18-14c0-8-8-14-18-14z" fill="#fefefe"/>
<path d="M512 248c-6 0-10 2-14 6 6 4 10 12 10 20 8-2 12-6 12-12 0-8-4-14-8-14z" fill="#fefefe"/>
<path d="M392 190c-10 0-18 4-18 10s8 10 18 10 18-4 18-10-8-10-18-10z" fill="#fefefe"/>
<path d="M360 144c-10 0-18 6-18 12s8 12 18 12 18-6 18-12-8-12-18-12z" fill="#fefefe"/>
<path d="M428 144c-6 0-12 2-16 6 12 4 22 10 30 18 2-2 2-4 2-6 0-10-8-18-16-18z" fill="#be1e2d"/>
<path d="M448 176c-6 0-12 2-16 6 10 6 18 14 22 22 4-2 6-6 6-10 0-10-6-18-12-18z" fill="url(#beak)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB