2026-03-07 23:27:25 -06:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" / >
< title > CPAS Tracker — Demo Preview< / title >
< link rel = "preconnect" href = "https://fonts.googleapis.com" >
< link href = "https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Syne:wght@700;800&family=Inter:wght@300;400;500;600;700&display=swap" rel = "stylesheet" >
< style >
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
2026-03-08 00:19:59 -06:00
--gold: #d4af37;
--gold-lt: #ffdf8a;
--gold-dk: #a88520;
--bg: #050608;
--bg-nav: #000000;
--bg-card: #111217;
--bg-section: #181924;
--border: #222;
--border-lt: #2a2b3a;
--text: #f8f9fa;
--text-muted: #9ca0b8;
--text-dim: #d1d3e0;
--green: #28a745;
--green-bg: #d4edda;
--yellow: #856404;
--yellow-bg: #fff3cd;
--red: #d9534f;
--red-bg: #f8d7da;
--red-dk: #721c24;
--red-dk-bg: #f5c6cb;
--sep: #721c24;
2026-03-07 23:27:25 -06:00
}
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--text);
font-family: 'Inter', sans-serif;
min-height: 100vh;
overflow-x: hidden;
}
/* ── DEMO BANNER ── */
.demo-banner {
background: linear-gradient(90deg, #1a1200 0%, #2a1f00 50%, #1a1200 100%);
border-bottom: 1px solid var(--gold-dk);
padding: 8px 40px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
font-family: 'DM Mono', monospace;
font-size: 11px;
color: var(--gold-lt);
letter-spacing: 0.8px;
position: sticky;
top: 0;
z-index: 1000;
}
.demo-banner .dot {
width: 6px; height: 6px; border-radius: 50%;
background: var(--gold);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.4; transform: scale(0.7); }
}
/* ── NAV ── */
nav {
background: var(--bg-nav);
padding: 0 40px;
display: flex;
align-items: center;
gap: 0;
border-bottom: 1px solid #333;
position: sticky;
top: 33px;
z-index: 999;
}
.logo-wrap {
display: flex; align-items: center;
margin-right: 32px; padding: 14px 0;
gap: 10px;
}
.logo-icon {
width: 28px; height: 28px;
background: linear-gradient(135deg, var(--gold), var(--gold-lt));
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 14px; font-weight: 900; color: #000;
font-family: 'Syne', sans-serif;
flex-shrink: 0;
}
.logo-text {
color: var(--text);
font-weight: 800;
font-size: 18px;
letter-spacing: 0.5px;
font-family: 'Syne', sans-serif;
}
.nav-tab {
padding: 18px 22px;
color: rgba(248,249,250,0.55);
border-bottom: 3px solid transparent;
cursor: pointer;
font-weight: 400;
font-size: 14px;
background: none;
border-top: none; border-left: none; border-right: none;
transition: color 0.2s;
text-decoration: none;
display: inline-block;
}
.nav-tab.active {
color: var(--text);
border-bottom-color: var(--gold);
font-weight: 700;
}
.nav-tab:hover { color: var(--text); }
.nav-docs {
margin-left: auto;
background: none;
border: 1px solid var(--border-lt);
color: var(--text-muted);
border-radius: 6px;
padding: 6px 14px;
font-size: 12px;
cursor: pointer;
font-weight: 600;
}
/* ── MAIN LAYOUT ── */
.main {
max-width: 1100px;
margin: 30px auto;
padding: 0 20px 60px;
}
/* ── HERO ── */
.hero {
background: var(--bg-card);
border-radius: 10px;
border: 1px solid var(--border);
padding: 48px 48px 40px;
margin-bottom: 24px;
position: relative;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: linear-gradient(90deg, transparent, var(--gold), var(--gold-lt), var(--gold), transparent);
}
.hero::after {
content: 'DEMO';
position: absolute;
top: 20px; right: 24px;
font-family: 'DM Mono', monospace;
font-size: 10px;
letter-spacing: 2px;
color: var(--gold-dk);
border: 1px solid var(--gold-dk);
padding: 2px 8px;
border-radius: 3px;
}
.hero-eyebrow {
font-family: 'DM Mono', monospace;
font-size: 11px;
letter-spacing: 2px;
color: var(--gold);
text-transform: uppercase;
margin-bottom: 14px;
}
.hero h1 {
font-family: 'Syne', sans-serif;
font-size: 36px;
font-weight: 800;
color: var(--text);
line-height: 1.1;
margin-bottom: 14px;
}
.hero h1 span { color: var(--gold); }
.hero p {
font-size: 15px;
color: var(--text-dim);
max-width: 580px;
line-height: 1.7;
margin-bottom: 28px;
}
.hero-stats {
display: flex;
gap: 32px;
flex-wrap: wrap;
}
.hero-stat {
display: flex; flex-direction: column; gap: 3px;
}
.hero-stat .val {
font-family: 'Syne', sans-serif;
font-size: 28px;
font-weight: 800;
color: var(--gold-lt);
line-height: 1;
}
.hero-stat .lbl {
font-size: 11px;
color: var(--text-muted);
letter-spacing: 0.5px;
text-transform: uppercase;
font-family: 'DM Mono', monospace;
}
.hero-stat-divider {
width: 1px; background: var(--border-lt);
align-self: stretch; margin: 4px 0;
}
/* ── SECTION TITLE ── */
.section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
}
.section-title {
font-family: 'Syne', sans-serif;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1.5px;
color: var(--text-muted);
display: flex;
align-items: center;
gap: 8px;
}
.section-title::before {
content: '';
display: block;
width: 3px; height: 14px;
background: var(--gold);
border-radius: 2px;
}
/* ── KPI CARDS ROW ── */
.kpi-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
margin-bottom: 24px;
}
.kpi-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 20px 22px;
position: relative;
overflow: hidden;
transition: border-color 0.2s, transform 0.15s;
}
.kpi-card:hover { border-color: var(--border-lt); transform: translateY(-1px); }
.kpi-card .kpi-label {
font-size: 11px;
font-family: 'DM Mono', monospace;
letter-spacing: 0.8px;
color: var(--text-muted);
text-transform: uppercase;
margin-bottom: 10px;
}
.kpi-card .kpi-val {
font-family: 'Syne', sans-serif;
font-size: 32px;
font-weight: 800;
color: var(--text);
line-height: 1;
margin-bottom: 6px;
}
.kpi-card .kpi-sub { font-size: 11px; color: var(--text-muted); }
.kpi-card .kpi-accent { position: absolute; bottom: 0; left: 0; right: 0; height: 3px; }
.kpi-accent-gold { background: linear-gradient(90deg, var(--gold-dk), var(--gold)); }
.kpi-accent-red { background: linear-gradient(90deg, #a02020, #e74c3c); }
.kpi-accent-blue { background: linear-gradient(90deg, #1a3a6a, #3b82f6); }
.kpi-accent-green{ background: linear-gradient(90deg, #0a3d20, #28a745); }
/* ── TWO COLUMNS ── */
.two-col {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 24px;
}
.panel {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
.panel-head {
background: var(--bg-section);
border-bottom: 1px solid var(--border);
padding: 14px 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.panel-title {
font-size: 13px; font-weight: 700;
color: var(--text); font-family: 'Syne', sans-serif;
}
/* ── EMPLOYEE TABLE ── */
.emp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.emp-table th {
padding: 10px 16px; text-align: left;
font-size: 10px; font-family: 'DM Mono', monospace;
letter-spacing: 1px; text-transform: uppercase;
color: var(--text-muted); border-bottom: 1px solid var(--border);
background: var(--bg-section);
}
.emp-table td { padding: 11px 16px; border-bottom: 1px solid #18191f; vertical-align: middle; }
.emp-table tr:last-child td { border-bottom: none; }
.emp-table tr:hover td { background: rgba(255,255,255,0.02); }
.emp-name { font-weight: 600; color: var(--text); }
/* ── TIER BADGES ── */
.tier-badge {
display: inline-block; padding: 3px 9px; border-radius: 10px;
font-size: 11px; font-weight: 700; white-space: nowrap; border: 1px solid;
}
.tier-0 { color: #28a745; background: #d4edda; border-color: #28a745; }
.tier-1 { color: #856404; background: #fff3cd; border-color: #c9a000; }
.tier-2 { color: #d9534f; background: #f8d7da; border-color: #d9534f; }
.tier-3 { color: #d9534f; background: #f8d7da; border-color: #d9534f; }
.tier-4 { color: #721c24; background: #f5c6cb; border-color: #c0392b; }
.tier-5 { color: #721c24; background: #f5c6cb; border-color: #c0392b; }
.tier-6 { color: #fff; background: #721c24; border-color: #5a1520; }
/* ── VIOLATION FEED ── */
.viol-item {
padding: 13px 18px; border-bottom: 1px solid #18191f;
display: flex; align-items: flex-start; gap: 12px;
}
.viol-item:last-child { border-bottom: none; }
.viol-dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex-shrink: 0; }
.viol-dot-red { background: #e74c3c; box-shadow: 0 0 6px rgba(231,76,60,0.5); }
.viol-dot-yellow { background: var(--gold); box-shadow: 0 0 6px rgba(212,175,55,0.5); }
.viol-dot-green { background: #28a745; }
.viol-info { flex: 1; min-width: 0; }
.viol-name { font-size: 13px; font-weight: 600; color: var(--text); }
.viol-type { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.viol-meta { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: 11px; color: var(--text-muted); font-family: 'DM Mono', monospace; }
.viol-pts { font-family: 'Syne', sans-serif; font-size: 18px; font-weight: 800; color: var(--gold-lt); flex-shrink: 0; }
.repeat-tag { display: inline-block; padding: 1px 6px; border-radius: 8px; font-size: 10px; font-weight: 700; background: #3b2e00; color: #ffd666; border: 1px solid var(--gold-dk); margin-left: 4px; }
/* ── DEPT BREAKDOWN ── */
.dept-row { padding: 12px 18px; border-bottom: 1px solid #18191f; display: flex; align-items: center; gap: 12px; }
.dept-row:last-child { border-bottom: none; }
.dept-name { font-size: 13px; color: var(--text-dim); min-width: 160px; }
.dept-bar-track { flex: 1; height: 6px; background: var(--border-lt); border-radius: 3px; overflow: hidden; }
.dept-bar-fill { height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--gold-dk), var(--gold)); }
.dept-count { font-family: 'DM Mono', monospace; font-size: 12px; color: var(--text-muted); min-width: 28px; text-align: right; }
/* ── FORM PREVIEW ── */
.form-preview { background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; margin-bottom: 24px; overflow: hidden; }
.form-section { background: var(--bg-section); border-left: 4px solid var(--gold); padding: 20px 24px; margin: 20px; border-radius: 4px; border-top: 1px solid var(--border-lt); border-right: 1px solid var(--border-lt); border-bottom: 1px solid var(--border-lt); }
.form-section-title { font-family: 'Syne', sans-serif; font-size: 18px; font-weight: 700; color: var(--text); margin-bottom: 14px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }
.form-item { display: flex; flex-direction: column; gap: 5px; }
.form-label { font-size: 12px; font-weight: 600; color: #e5e7f1; }
.form-input { padding: 9px 12px; border: 1px solid var(--border-lt); border-radius: 4px; font-size: 13px; background: #050608; color: var(--text-muted); font-family: 'Inter', sans-serif; pointer-events: none; }
.form-input.filled { color: var(--text); border-color: #3a3d52; }
.point-val { font-family: 'Syne', sans-serif; font-size: 28px; font-weight: 800; color: var(--gold-lt); }
/* ── TIER SCALE ── */
.tier-timeline { display: flex; align-items: stretch; border-radius: 8px; border: 1px solid var(--border); overflow: hidden; }
.tier-seg { flex: 1; padding: 12px 8px 10px; text-align: center; border-right: 1px solid rgba(255,255,255,0.05); }
.tier-seg:last-child { border-right: none; }
.tier-seg .ts-pts { font-family: 'Syne', sans-serif; font-size: 15px; font-weight: 800; margin-bottom: 3px; }
.tier-seg .ts-label { font-size: 9px; font-family: 'DM Mono', monospace; letter-spacing: 0.5px; opacity: 0.8; line-height: 1.3; }
.ts-0 { background: rgba(40,167,69,0.12); color: #28a745; }
.ts-1 { background: rgba(133,100,4,0.15); color: #c9a000; }
.ts-2 { background: rgba(217,83,79,0.15); color: #d9534f; }
.ts-3 { background: rgba(217,83,79,0.18); color: #d9534f; }
.ts-4 { background: rgba(114,28,36,0.20); color: #e87070; }
.ts-5 { background: rgba(114,28,36,0.25); color: #e87070; }
.ts-6 { background: rgba(114,28,36,0.50); color: #ff9999; }
/* ── AUDIT LOG ── */
.audit-item { padding: 11px 18px; border-bottom: 1px solid #18191f; display: flex; align-items: center; gap: 12px; font-size: 12px; }
.audit-item:last-child { border-bottom: none; }
.audit-time { font-family: 'DM Mono', monospace; color: var(--text-muted); font-size: 11px; min-width: 80px; }
.audit-action { flex: 1; color: var(--text-dim); }
.audit-action strong { color: var(--text); font-weight: 600; }
.audit-pts { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--gold); font-weight: 700; }
/* ── FEATURES ── */
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 24px; }
.feature-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; padding: 22px; transition: border-color 0.2s, transform 0.15s; }
.feature-card:hover { border-color: var(--border-lt); transform: translateY(-2px); }
.feature-icon { font-size: 22px; margin-bottom: 12px; display: block; }
.feature-title { font-family: 'Syne', sans-serif; font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.feature-desc { font-size: 12px; color: var(--text-muted); line-height: 1.6; }
/* ── FOOTER ── */
2026-03-08 00:19:59 -06:00
footer {
border-top: 1px solid var(--border);
padding: 20px 40px;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 12px;
font-size: 11px;
color: var(--text-muted);
font-family: 'DM Mono', monospace;
background: var(--bg-nav);
}
.footer-left {
display: flex;
align-items: center;
gap: 18px;
}
.footer-brand {
font-family: 'Syne', sans-serif;
font-size: 13px;
font-weight: 700;
color: var(--text-dim);
}
.footer-copy {
color: var(--text-muted);
font-size: 11px;
}
.footer-gitea {
display: flex;
align-items: center;
gap: 6px;
color: var(--text-muted);
text-decoration: none;
padding: 4px 10px;
border: 1px solid var(--border-lt);
border-radius: 5px;
transition: border-color 0.2s, color 0.2s;
font-size: 11px;
}
.footer-gitea:hover {
border-color: var(--gold-dk);
color: var(--gold-lt);
}
.footer-gitea svg {
width: 14px;
height: 14px;
fill: currentColor;
flex-shrink: 0;
}
.footer-right {
display: flex;
align-items: center;
gap: 18px;
}
.footer-ticker {
display: flex;
align-items: center;
gap: 8px;
background: rgba(212,175,55,0.06);
border: 1px solid rgba(212,175,55,0.2);
border-radius: 5px;
padding: 4px 12px;
}
.footer-ticker-label {
font-size: 10px;
color: var(--text-muted);
letter-spacing: 0.5px;
text-transform: uppercase;
}
.footer-ticker-time {
font-family: 'DM Mono', monospace;
font-size: 12px;
color: var(--gold);
font-weight: 500;
letter-spacing: 1px;
}
.footer-ticker-dot {
width: 5px; height: 5px; border-radius: 50%;
background: var(--gold);
animation: pulse 2s infinite;
flex-shrink: 0;
}
.footer-divider {
width: 1px;
height: 16px;
background: var(--border-lt);
}
2026-03-07 23:27:25 -06:00
/* ── ANIMATIONS ── */
.fade-in { opacity: 0; transform: translateY(16px); animation: fadeUp 0.5s ease forwards; }
@keyframes fadeUp { to { opacity: 1; transform: translateY(0); } }
.fade-in:nth-child(1) { animation-delay: 0.05s; }
.fade-in:nth-child(2) { animation-delay: 0.10s; }
.fade-in:nth-child(3) { animation-delay: 0.15s; }
.fade-in:nth-child(4) { animation-delay: 0.20s; }
.tab-pane { display: none; }
.tab-pane.active { display: block; }
@media (max-width: 768px) {
.kpi-row { grid-template-columns: repeat(2, 1fr); }
.two-col { grid-template-columns: 1fr; }
.features-grid { grid-template-columns: 1fr 1fr; }
.hero { padding: 30px 24px; }
.hero h1 { font-size: 26px; }
nav { padding: 0 16px; }
.main { padding: 0 12px 60px; }
2026-03-08 00:19:59 -06:00
footer { padding: 16px 20px; flex-direction: column; align-items: flex-start; }
.footer-right { flex-wrap: wrap; }
2026-03-07 23:27:25 -06:00
}
< / style >
< / head >
< body >
<!-- Demo Banner -->
< div class = "demo-banner" >
< div class = "dot" > < / div >
DEMO ENVIRONMENT — Simulated data for stakeholder preview only — Not connected to live database
< div class = "dot" > < / div >
< / div >
<!-- Navigation -->
< nav >
< div class = "logo-wrap" >
< div class = "logo-icon" > C< / div >
< div class = "logo-text" > CPAS Tracker< / div >
< / div >
< a class = "nav-tab active" href = "#" onclick = "switchTab('dashboard', this); return false;" > 📊 Dashboard< / a >
< a class = "nav-tab" href = "#" onclick = "switchTab('violations', this); return false;" > + New Violation< / a >
< button class = "nav-docs" > ? Docs< / button >
< / nav >
< div class = "main" >
<!-- ── DASHBOARD TAB ── -->
< div id = "tab-dashboard" class = "tab-pane active" >
< div class = "hero fade-in" >
< div class = "hero-eyebrow" > Corrective Performance Action System< / div >
< h1 > Employee < span > Compliance< / span > Dashboard< / h1 >
< p > Real-time visibility into workforce disciplinary standing. Track violations, monitor tier escalations, and generate signed documentation — all in one place.< / p >
< div class = "hero-stats" >
< div class = "hero-stat" > < div class = "val" > 47< / div > < div class = "lbl" > Total Employees< / div > < / div >
< div class = "hero-stat-divider" > < / div >
< div class = "hero-stat" > < div class = "val" > 23< / div > < div class = "lbl" > Active Violations (90d)< / div > < / div >
< div class = "hero-stat-divider" > < / div >
< div class = "hero-stat" > < div class = "val" > 3< / div > < div class = "lbl" > At-Risk (Tier 3+)< / div > < / div >
< div class = "hero-stat-divider" > < / div >
< div class = "hero-stat" > < div class = "val" > 91%< / div > < div class = "lbl" > In Good Standing< / div > < / div >
< / div >
< / div >
< div class = "kpi-row" >
< div class = "kpi-card fade-in" >
< div class = "kpi-label" > New This Week< / div >
< div class = "kpi-val" > 6< / div >
< div class = "kpi-sub" > +2 vs prior week< / div >
< div class = "kpi-accent kpi-accent-gold" > < / div >
< / div >
< div class = "kpi-card fade-in" >
< div class = "kpi-label" > Tier 3+ Employees< / div >
< div class = "kpi-val" > 3< / div >
< div class = "kpi-sub" > Requires attention< / div >
< div class = "kpi-accent kpi-accent-red" > < / div >
< / div >
< div class = "kpi-card fade-in" >
< div class = "kpi-label" > PDFs Generated< / div >
< div class = "kpi-val" > 18< / div >
< div class = "kpi-sub" > This month< / div >
< div class = "kpi-accent kpi-accent-blue" > < / div >
< / div >
< div class = "kpi-card fade-in" >
< div class = "kpi-label" > Expiring (30d)< / div >
< div class = "kpi-val" > 9< / div >
< div class = "kpi-sub" > Points rolling off< / div >
< div class = "kpi-accent kpi-accent-green" > < / div >
< / div >
< / div >
< div class = "two-col" >
<!-- Employee Roster -->
< div class = "panel" >
< div class = "panel-head" >
< span class = "panel-title" > Employee Roster< / span >
< span style = "font-size:11px;color:var(--text-muted);font-family:'DM Mono',monospace;" > 47 total< / span >
< / div >
< table class = "emp-table" >
< thead > < tr > < th > Employee< / th > < th > Dept< / th > < th > Standing< / th > < / tr > < / thead >
< tbody >
< tr > < td > < div class = "emp-name" > Marcus T.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Operations< / div > < / td > < td > < span class = "tier-badge tier-4" > 22 pts — Tier 4< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Janelle R.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Production< / div > < / td > < td > < span class = "tier-badge tier-3" > 17 pts — Tier 3< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Devon H.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Operations< / div > < / td > < td > < span class = "tier-badge tier-3" > 15 pts — Tier 3< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Priya S.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Impl & Support< / div > < / td > < td > < span class = "tier-badge tier-2" > 12 pts — Tier 2< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Carlos M.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Production< / div > < / td > < td > < span class = "tier-badge tier-1" > 7 pts — Tier 1< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Aisha W.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Administrative< / div > < / td > < td > < span class = "tier-badge tier-1" > 5 pts — Tier 1< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Tom B.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Design & Content< / div > < / td > < td > < span class = "tier-badge tier-0" > 2 pts — Elite< / span > < / td > < / tr >
< tr > < td > < div class = "emp-name" > Sandra K.< / div > < / td > < td > < div style = "font-size:11px;color:var(--text-muted);" > Business Dev< / div > < / td > < td > < span class = "tier-badge tier-0" > 0 pts — Elite< / span > < / td > < / tr >
< / tbody >
< / table >
< / div >
<!-- Recent Violations -->
< div class = "panel" >
< div class = "panel-head" >
< span class = "panel-title" > Recent Violations< / span >
< span style = "font-size:11px;color:var(--text-muted);font-family:'DM Mono',monospace;" > Last 7 days< / span >
< / div >
< div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-red" > < / div >
< div class = "viol-info" >
2026-03-08 00:19:59 -06:00
< div class = "viol-name" > Marcus T. < span class = "repeat-tag" > ☆ REPEAT< / span > < / div >
2026-03-07 23:27:25 -06:00
< div class = "viol-type" > Unauthorized Absence — Operations< / div >
< div class = "viol-meta" > < span > Mar 6< / span > < span > ·< / span > < span > D. Williams< / span > < / div >
< / div >
< div class = "viol-pts" > +5< / div >
< / div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-red" > < / div >
< div class = "viol-info" >
< div class = "viol-name" > Janelle R.< / div >
< div class = "viol-type" > Insubordination — Production< / div >
< div class = "viol-meta" > < span > Mar 5< / span > < span > ·< / span > < span > K. Thompson< / span > < / div >
< / div >
< div class = "viol-pts" > +4< / div >
< / div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-yellow" > < / div >
< div class = "viol-info" >
< div class = "viol-name" > Devon H.< / div >
< div class = "viol-type" > Tardiness (3× ) — Operations< / div >
< div class = "viol-meta" > < span > Mar 4< / span > < span > ·< / span > < span > D. Williams< / span > < / div >
< / div >
< div class = "viol-pts" > +3< / div >
< / div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-yellow" > < / div >
< div class = "viol-info" >
< div class = "viol-name" > Carlos M.< / div >
< div class = "viol-type" > Cell Phone Policy — Production< / div >
< div class = "viol-meta" > < span > Mar 3< / span > < span > ·< / span > < span > K. Thompson< / span > < / div >
< / div >
< div class = "viol-pts" > +2< / div >
< / div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-yellow" > < / div >
< div class = "viol-info" >
< div class = "viol-name" > Priya S.< / div >
< div class = "viol-type" > Dress Code Violation — Impl & Support< / div >
< div class = "viol-meta" > < span > Mar 2< / span > < span > ·< / span > < span > M. Johnson< / span > < / div >
< / div >
< div class = "viol-pts" > +1< / div >
< / div >
< div class = "viol-item" >
< div class = "viol-dot viol-dot-green" > < / div >
< div class = "viol-info" >
< div class = "viol-name" > Aisha W.< / div >
< div class = "viol-type" > Late Return from Break — Administrative< / div >
< div class = "viol-meta" > < span > Mar 1< / span > < span > ·< / span > < span > S. Martinez< / span > < / div >
< / div >
< div class = "viol-pts" > +1< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "two-col" >
<!-- Dept Breakdown -->
< div class = "panel" >
< div class = "panel-head" >
< span class = "panel-title" > Violations by Department< / span >
< span style = "font-size:11px;color:var(--text-muted);font-family:'DM Mono',monospace;" > 90-day window< / span >
< / div >
< div style = "padding:8px 0;" >
< div class = "dept-row" > < div class = "dept-name" > Operations< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:88%" > < / div > < / div > < div class = "dept-count" > 8< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Production< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:66%" > < / div > < / div > < div class = "dept-count" > 6< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Impl & Support< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:44%" > < / div > < / div > < div class = "dept-count" > 4< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Administrative< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:22%" > < / div > < / div > < div class = "dept-count" > 2< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Business Dev< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:11%" > < / div > < / div > < div class = "dept-count" > 1< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Design & Content< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:11%" > < / div > < / div > < div class = "dept-count" > 1< / div > < / div >
< div class = "dept-row" > < div class = "dept-name" > Executive< / div > < div class = "dept-bar-track" > < div class = "dept-bar-fill" style = "width:0%" > < / div > < / div > < div class = "dept-count" > 0< / div > < / div >
< / div >
< / div >
<!-- Audit Log -->
< div class = "panel" >
< div class = "panel-head" >
< span class = "panel-title" > Audit Log< / span >
< span style = "font-size:11px;color:var(--text-muted);font-family:'DM Mono',monospace;" > System activity< / span >
< / div >
< div >
< div class = "audit-item" > < div class = "audit-time" > 03/06 2:14p< / div > < div class = "audit-action" > < strong > Violation #41< / strong > created — Marcus T.< / div > < div class = "audit-pts" > +5 pts< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/06 2:15p< / div > < div class = "audit-action" > PDF generated for < strong > Violation #41< / strong > < / div > < div class = "audit-pts" > —< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/05 9:40a< / div > < div class = "audit-action" > < strong > Violation #40< / strong > created — Janelle R.< / div > < div class = "audit-pts" > +4 pts< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/04 11:20a< / div > < div class = "audit-action" > Employee < strong > Devon H.< / strong > record updated< / div > < div class = "audit-pts" > —< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/04 8:55a< / div > < div class = "audit-action" > < strong > Violation #39< / strong > created — Devon H.< / div > < div class = "audit-pts" > +3 pts< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/03 3:30p< / div > < div class = "audit-action" > < strong > Violation #38< / strong > amended — Carlos M.< / div > < div class = "audit-pts" > − 1 pt< / div > < / div >
< div class = "audit-item" > < div class = "audit-time" > 03/02 1:05p< / div > < div class = "audit-action" > < strong > Duplicate record< / strong > merged — R. Johnson< / div > < div class = "audit-pts" > —< / div > < / div >
< / div >
< / div >
< / div >
<!-- CPAS Tier Scale -->
< div style = "margin-bottom:24px;" >
< div class = "section-header" >
< div class = "section-title" > CPAS Tier Scale< / div >
< / div >
< div class = "tier-timeline" >
< div class = "tier-seg ts-0" > < div class = "ts-pts" > 0– 4< / div > < div class = "ts-label" > Elite< br / > Standing< / div > < / div >
< div class = "tier-seg ts-1" > < div class = "ts-pts" > 5– 9< / div > < div class = "ts-label" > Tier 1< br / > Realignment< / div > < / div >
< div class = "tier-seg ts-2" > < div class = "ts-pts" > 10– 14< / div > < div class = "ts-label" > Tier 2< br / > Admin Lockdown< / div > < / div >
< div class = "tier-seg ts-3" > < div class = "ts-pts" > 15– 19< / div > < div class = "ts-label" > Tier 3< br / > Verification< / div > < / div >
< div class = "tier-seg ts-4" > < div class = "ts-pts" > 20– 24< / div > < div class = "ts-label" > Tier 4< br / > Risk Mitigation< / div > < / div >
< div class = "tier-seg ts-5" > < div class = "ts-pts" > 25– 29< / div > < div class = "ts-label" > Tier 5< br / > Final Decision< / div > < / div >
< div class = "tier-seg ts-6" > < div class = "ts-pts" > 30+< / div > < div class = "ts-label" > Tier 6< br / > Separation< / div > < / div >
< / div >
< / div >
<!-- System Capabilities -->
< div class = "section-header" > < div class = "section-title" > System Capabilities< / div > < / div >
< div class = "features-grid" >
< div class = "feature-card fade-in" > < span class = "feature-icon" > ⚡< / span > < div class = "feature-title" > Repeat Offense Detection< / div > < div class = "feature-desc" > Automatically flags prior violations for the same type and escalates point recommendations per recidivist policy.< / div > < / div >
< div class = "feature-card fade-in" > < span class = "feature-icon" > 📄< / span > < div class = "feature-title" > One-Click PDF Generation< / div > < div class = "feature-desc" > Generates signed, professional violation documents instantly — with or without employee acknowledgment signatures.< / div > < / div >
2026-03-08 00:19:59 -06:00
< div class = "feature-card fade-in" > < span class = "feature-icon" > 📀< / span > < div class = "feature-title" > Duplicate Record Merge< / div > < div class = "feature-desc" > Consolidate duplicate employee records while preserving full violation history under the canonical profile.< / div > < / div >
< div class = "feature-card fade-in" > < span class = "feature-icon" > 🕊< / span > < div class = "feature-title" > 90-Day Rolling Window< / div > < div class = "feature-desc" > Points automatically expire after 90 days. Active standing reflects only the current compliance window.< / div > < / div >
2026-03-07 23:27:25 -06:00
< div class = "feature-card fade-in" > < span class = "feature-icon" > 🏷️< / span > < div class = "feature-title" > Tier Escalation Warnings< / div > < div class = "feature-desc" > Real-time alerts when a new violation would push an employee across a tier boundary before you submit.< / div > < / div >
< div class = "feature-card fade-in" > < span class = "feature-icon" > 🗂️< / span > < div class = "feature-title" > Full Audit Trail< / div > < div class = "feature-desc" > Every create, amendment, merge, and PDF generation is logged with timestamp and operator attribution.< / div > < / div >
< / div >
< / div > <!-- /tab - dashboard -->
<!-- ── VIOLATION FORM TAB ── -->
< div id = "tab-violations" class = "tab-pane" >
< div style = "margin-bottom:20px;" >
< div style = "background:#181200;border:1px solid var(--gold-dk);border-radius:8px;padding:12px 18px;font-size:12px;color:var(--gold-lt);font-family:'DM Mono',monospace;letter-spacing:0.4px;" >
2026-03-08 00:19:59 -06:00
⚡ DEMO VIEW — Form fields shown with sample data. Submission is disabled in demo mode.
2026-03-07 23:27:25 -06:00
< / div >
< / div >
< div class = "form-preview" >
< div class = "form-section" >
< div class = "form-section-title" > Employee Information< / div >
< div style = "margin-bottom:16px;" >
< div class = "form-label" style = "margin-bottom:6px;" > Quick-Select Existing Employee:< / div >
< div class = "form-input filled" style = "display:flex;align-items:center;justify-content:space-between;" >
< span > Marcus Thompson — Operations< / span > < span style = "color:var(--text-muted);font-size:11px;" > ▼< / span >
< / div >
< div style = "margin-top:8px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;" >
< span style = "font-size:12px;color:var(--text-dim);font-weight:600;" > Current Standing:< / span >
< span class = "tier-badge tier-4" > 22 pts — Tier 4 · Risk Mitigation< / span >
< span style = "font-size:11px;color:var(--text-muted);" > 4 violations in last 90 days< / span >
< / div >
< / div >
< div class = "form-grid" >
< div class = "form-item" > < div class = "form-label" > Employee Name:< / div > < div class = "form-input filled" > Marcus Thompson< / div > < / div >
< div class = "form-item" > < div class = "form-label" > Department:< / div > < div class = "form-input filled" style = "display:flex;align-items:center;justify-content:space-between;" > < span > Operations< / span > < span style = "color:var(--text-muted);font-size:11px;" > ▼< / span > < / div > < / div >
< div class = "form-item" > < div class = "form-label" > Supervisor Name:< / div > < div class = "form-input filled" > D. Williams< / div > < / div >
< div class = "form-item" > < div class = "form-label" > Witness Name (Officer):< / div > < div class = "form-input" > Officer Name< / div > < / div >
< / div >
< / div >
< div class = "form-section" >
< div class = "form-section-title" > Violation Details< / div >
< div class = "form-grid" >
< div class = "form-item" style = "grid-column:1 / -1;" >
< div class = "form-label" > Violation Type:< / div >
< div class = "form-input filled" style = "display:flex;align-items:center;justify-content:space-between;" >
2026-03-08 00:19:59 -06:00
< span > Unauthorized Absence ☆ 2x in 90 days< / span > < span style = "color:var(--text-muted);font-size:11px;" > ▼< / span >
2026-03-07 23:27:25 -06:00
< / div >
< div style = "background:#141623;border:1px solid var(--border-lt);border-radius:4px;padding:10px;font-size:12px;color:var(--text-dim);margin-top:6px;" >
2026-03-08 00:19:59 -06:00
< strong > Unauthorized Absence< / strong > < span class = "repeat-tag" > ☆ Repeat — 2x prior< / span > < br / >
2026-03-07 23:27:25 -06:00
Absence from scheduled work without prior approval or acceptable documentation.< br / >
< span style = "font-size:10px;color:#a0a3ba;" > Chapter 4, Section 4.1 — Attendance & Punctuality< / span >
< / div >
< div style = "background:#3b2e00;border:1px solid var(--gold-dk);border-radius:4px;padding:8px 12px;margin-top:6px;font-size:12px;color:#ffdf8a;" >
< strong > Repeat offense detected.< / strong > Point slider set to maximum (5 pts) per recidivist policy. Adjust if needed.
< / div >
< / div >
< div class = "form-item" > < div class = "form-label" > Incident Date:< / div > < div class = "form-input filled" > 2026-03-06< / div > < / div >
< / div >
< div style = "background:#2d1a00;border:1px solid #a06000;border-radius:6px;padding:12px 16px;margin-top:16px;font-size:13px;color:#ffc107;" >
2026-03-08 00:19:59 -06:00
⚡ < strong > Tier escalation warning:< / strong > Adding 5 pts will bring Marcus to < strong > 27 pts (Tier 5 — Final Decision)< / strong > . This is one tier below Separation. Review carefully.
2026-03-07 23:27:25 -06:00
< / div >
< div style = "background:#181200;border:2px solid var(--gold);padding:14px;border-radius:6px;margin:16px 0 0;text-align:center;" >
< div style = "color:#ffdf8a;font-weight:700;margin-bottom:8px;" > CPAS Point Assessment< / div >
< div style = "font-size:13px;color:var(--text-dim);" > Unauthorized Absence: 3– 5 Points< / div >
< div style = "width:100%;height:6px;background:var(--border-lt);border-radius:3px;margin:12px 0 4px;overflow:hidden;" > < div style = "width:100%;height:100%;background:linear-gradient(90deg,var(--gold-dk),var(--gold));border-radius:3px;" > < / div > < / div >
< div class = "point-val" > 5 Points< / div >
< div style = "font-size:12px;color:var(--text-dim);margin-top:4px;" > Adjust to reflect severity and context< / div >
< / div >
< / div >
< div style = "background:var(--bg-section);border-left:4px solid #2196F3;padding:20px 24px;margin:20px;border-radius:4px;border:1px solid var(--border-lt);" >
< div style = "font-family:'Syne',sans-serif;font-size:16px;font-weight:700;margin-bottom:8px;" > Employee Acknowledgment< / div >
< div style = "font-size:12px;color:var(--text-muted);margin-bottom:14px;line-height:1.6;" > If the employee is present and acknowledges receipt of this violation, enter their name and the date below.< / div >
< div class = "form-grid" >
< div class = "form-item" > < div class = "form-label" > Acknowledged By:< / div > < div class = "form-input" > Employee's printed name< / div > < / div >
< div class = "form-item" > < div class = "form-label" > Acknowledgment Date:< / div > < div class = "form-input" > yyyy-mm-dd< / div > < / div >
< / div >
< / div >
< div style = "display:flex;gap:14px;justify-content:center;padding:20px 20px 28px;" >
< button style = "padding:14px 36px;font-size:15px;font-weight:700;border:none;border-radius:6px;cursor:not-allowed;background:linear-gradient(135deg,#d4af37,#ffdf8a);color:#000;text-transform:uppercase;opacity:0.5;" > Submit Violation< / button >
< button style = "padding:14px 36px;font-size:15px;font-weight:700;border:1px solid var(--border-lt);border-radius:6px;cursor:not-allowed;background:#050608;color:var(--text);text-transform:uppercase;opacity:0.5;" > Clear Form< / button >
< / div >
< / div >
< / div > <!-- /tab - violations -->
< / div > <!-- /main -->
< footer >
2026-03-08 00:19:59 -06:00
< div class = "footer-left" >
< div class = "footer-brand" > CPAS Tracker< / div >
< div class = "footer-divider" > < / div >
< div class = "footer-copy" > © 2026 Jason Stedwell< / div >
< div class = "footer-divider" > < / div >
< div style = "font-size:11px;color:var(--text-muted);" > DEMO BUILD — All data synthetic< / div >
< / div >
< div class = "footer-right" >
< a class = "footer-gitea" href = "https://git.alwisp.com/jason/cpas" target = "_blank" rel = "noopener" >
<!-- Gitea logo SVG -->
< svg viewBox = "0 0 640 640" xmlns = "http://www.w3.org/2000/svg" >
< path d = "M321.6 3.2C146.4 3.2 3.2 146.4 3.2 321.6c0 141.6 91.8 261.9 219.7 304.1 16.1 3 22-7 22-15.5 0-7.6-.3-32.8-.4-59.5-89.5 19.4-108.4-38.4-108.4-38.4-14.6-37.2-35.7-47.1-35.7-47.1-29.2-20 2.2-19.6 2.2-19.6 32.3 2.3 49.3 33.1 49.3 33.1 28.7 49.2 75.3 35 93.7 26.7 2.9-20.8 11.2-35 20.4-43-71.4-8.1-146.5-35.7-146.5-158.9 0-35.1 12.5-63.8 33.1-86.3-3.3-8.1-14.4-40.8 3.1-85.1 0 0 27-8.7 88.4 32.9 25.6-7.1 53.1-10.7 80.4-10.8 27.3.1 54.8 3.7 80.5 10.8 61.3-41.6 88.3-32.9 88.3-32.9 17.6 44.3 6.5 77 3.2 85.1 20.6 22.5 33 51.2 33 86.3 0 123.5-75.2 150.7-146.8 158.7 11.5 10 21.8 29.7 21.8 59.8 0 43.2-.4 78-0.4 88.6 0 8.6 5.8 18.6 22.1 15.5C524.8 583.2 616.8 463.1 616.8 321.6 616.8 146.4 473.6 3.2 298.4 3.2z" / >
< / svg >
jason/cpas
< / a >
< div class = "footer-divider" > < / div >
< div class = "footer-ticker" >
< div class = "footer-ticker-dot" > < / div >
< div class = "footer-ticker-label" > Dev Time< / div >
< div class = "footer-ticker-time" id = "dev-ticker" > —< / div >
< / div >
< / div >
2026-03-07 23:27:25 -06:00
< / footer >
< script >
function switchTab(name, el) {
document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-tab').forEach(t => t.classList.remove('active'));
document.getElementById('tab-' + name).classList.add('active');
el.classList.add('active');
}
2026-03-08 00:19:59 -06:00
// ── DEV TIME TICKER ──────────────────────────────────────────────────────────
// Base dev time calculated from real commit sessions (30-min gap = new session).
// Each session timed as (last_commit - first_commit) + 15min overhead.
//
// Session 1: 2026-03-06 11:33 → 12:05 = 32min + 15 = 47min
// Session 2: 2026-03-06 12:19 → 18:00 = 341min + 15 = 356min
// Session 3: 2026-03-06 23:18 → 23:41 = 23min + 15 = 38min
// Session 4: 2026-03-07 09:22 → 09:53 = 31min + 15 = 46min
// Session 5: 2026-03-07 18:31 → 19:02 = 31min + 15 = 46min
// Session 6: 2026-03-07 21:28 → 22:02 = 34min + 15 = 49min
// Session 7: 2026-03-07 23:13 → 23:59 = 46min + 15 = 61min
// Session 8: 2026-03-08 00:11 → 00:12 = 1min + 15 = 16min
// Total: 659min = 39,540 seconds
//
// Anchor: last commit timestamp 2026-03-08T06:12:11Z (UTC)
// Ticker ticks up every second from that base.
const BASE_SECONDS = 39540;
const ANCHOR_UTC = new Date('2026-03-08T06:12:11Z').getTime();
function formatDevTime(totalSec) {
const h = Math.floor(totalSec / 3600);
const m = Math.floor((totalSec % 3600) / 60);
const s = totalSec % 60;
return `${String(h).padStart(2,'0')}h ${String(m).padStart(2,'0')}m ${String(s).padStart(2,'0')}s`;
}
function updateTicker() {
const elapsed = Math.floor((Date.now() - ANCHOR_UTC) / 1000);
const total = BASE_SECONDS + Math.max(0, elapsed);
document.getElementById('dev-ticker').textContent = formatDevTime(total);
}
updateTicker();
setInterval(updateTicker, 1000);
2026-03-07 23:27:25 -06:00
< / script >
< / body >
< / html >