Files
forward-assist/Forward_Assist_Plan.html

1634 lines
54 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forward Assist — Project Plan</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
:root {
--od-green: #4A5D23;
--od-green-light: #6B8C3E;
--fde: #C4A265;
--fde-light: #D4B87A;
--coyote: #8B7355;
--midnight: #1A1A1A;
--dark-bg: #0D0D0D;
--dark-surface: #1E1E1E;
--dark-card: #252525;
--dark-border: #333;
--text-primary: #E8E8E8;
--text-secondary: #999;
--text-muted: #666;
--danger: #C0392B;
--danger-light: #E74C3C;
--warning: #F39C12;
--success: #27AE60;
--blue: #3498DB;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--dark-bg);
color: var(--text-primary);
font-family: 'Inter', sans-serif;
line-height: 1.6;
}
/* ===== HERO ===== */
.hero {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #0D0D0D 0%, #1A2010 50%, #0D0D0D 100%);
position: relative;
overflow: hidden;
text-align: center;
padding: 2rem;
}
.hero::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background:
repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(74,93,35,0.03) 2px, rgba(74,93,35,0.03) 4px);
pointer-events: none;
}
.hero-badge {
display: inline-block;
border: 2px solid var(--fde);
color: var(--fde);
padding: 0.4rem 1.2rem;
font-family: 'JetBrains Mono', monospace;
font-size: 0.75rem;
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: 2rem;
position: relative;
}
.hero-badge::before, .hero-badge::after {
content: '★';
margin: 0 0.5rem;
}
.hero-logo {
font-family: 'Bebas Neue', sans-serif;
font-size: clamp(4rem, 10vw, 8rem);
letter-spacing: 8px;
line-height: 0.95;
color: var(--text-primary);
text-transform: uppercase;
margin-bottom: 0.5rem;
}
.hero-logo span {
color: var(--fde);
}
.hero-tagline {
font-family: 'JetBrains Mono', monospace;
color: var(--od-green-light);
font-size: 1.1rem;
letter-spacing: 2px;
margin-bottom: 1rem;
}
.hero-sub {
color: var(--text-secondary);
font-size: 0.95rem;
max-width: 500px;
margin-bottom: 3rem;
font-style: italic;
}
.hero-nav {
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
}
.hero-nav a {
display: inline-block;
padding: 0.8rem 2rem;
font-family: 'Bebas Neue', sans-serif;
font-size: 1.1rem;
letter-spacing: 2px;
text-decoration: none;
text-transform: uppercase;
border: 2px solid var(--dark-border);
color: var(--text-primary);
transition: all 0.2s;
}
.hero-nav a:hover {
border-color: var(--fde);
color: var(--fde);
background: rgba(196,162,101,0.05);
}
.hero-nav a.primary {
background: var(--od-green);
border-color: var(--od-green);
color: white;
}
.hero-nav a.primary:hover {
background: var(--od-green-light);
border-color: var(--od-green-light);
color: white;
}
/* ===== SECTIONS ===== */
section {
max-width: 1200px;
margin: 0 auto;
padding: 5rem 2rem;
}
.section-label {
font-family: 'JetBrains Mono', monospace;
font-size: 0.7rem;
letter-spacing: 4px;
text-transform: uppercase;
color: var(--od-green-light);
margin-bottom: 0.5rem;
}
.section-title {
font-family: 'Bebas Neue', sans-serif;
font-size: clamp(2rem, 5vw, 3.5rem);
letter-spacing: 3px;
margin-bottom: 1.5rem;
color: var(--text-primary);
}
.section-title span { color: var(--fde); }
.section-intro {
color: var(--text-secondary);
max-width: 700px;
margin-bottom: 3rem;
font-size: 1.05rem;
}
.divider {
height: 1px;
background: linear-gradient(90deg, transparent, var(--dark-border), transparent);
margin: 0 auto;
max-width: 1200px;
}
/* ===== BRANDING SECTION ===== */
.brand-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.brand-card {
background: var(--dark-card);
border: 1px solid var(--dark-border);
padding: 2rem;
position: relative;
}
.brand-card h3 {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.4rem;
letter-spacing: 2px;
color: var(--fde);
margin-bottom: 1rem;
}
.brand-card p, .brand-card li {
color: var(--text-secondary);
font-size: 0.9rem;
line-height: 1.7;
}
.brand-card ul {
list-style: none;
padding: 0;
}
.brand-card ul li::before {
content: '▸ ';
color: var(--od-green-light);
}
/* Color palette */
.color-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.color-swatch {
text-align: center;
}
.color-swatch .swatch {
height: 80px;
border-radius: 4px;
margin-bottom: 0.5rem;
border: 1px solid rgba(255,255,255,0.1);
}
.color-swatch .name {
font-family: 'JetBrains Mono', monospace;
font-size: 0.7rem;
color: var(--text-secondary);
letter-spacing: 1px;
}
.color-swatch .hex {
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
color: var(--text-muted);
}
/* UI Language examples */
.ui-lang-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1px;
background: var(--dark-border);
border: 1px solid var(--dark-border);
margin: 2rem 0;
}
.ui-lang-item {
background: var(--dark-card);
padding: 1.2rem 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.ui-lang-item .boring {
color: var(--text-muted);
font-size: 0.85rem;
text-decoration: line-through;
}
.ui-lang-item .arrow {
color: var(--od-green-light);
font-size: 1.2rem;
margin: 0 1rem;
}
.ui-lang-item .cool {
font-family: 'Bebas Neue', sans-serif;
color: var(--fde);
font-size: 1.1rem;
letter-spacing: 2px;
}
/* ===== MOCK UI ===== */
.mock-window {
background: var(--dark-surface);
border: 1px solid var(--dark-border);
border-radius: 8px;
overflow: hidden;
margin: 2rem 0;
}
.mock-titlebar {
background: var(--dark-card);
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid var(--dark-border);
}
.mock-dot {
width: 12px; height: 12px; border-radius: 50%;
}
.mock-dot.red { background: var(--danger); }
.mock-dot.yellow { background: var(--warning); }
.mock-dot.green { background: var(--success); }
.mock-titlebar .title {
font-family: 'JetBrains Mono', monospace;
font-size: 0.75rem;
color: var(--text-muted);
margin-left: 0.5rem;
}
.mock-body {
padding: 0;
}
/* Dashboard mock */
.dash-layout {
display: grid;
grid-template-columns: 220px 1fr;
min-height: 500px;
}
.dash-sidebar {
background: var(--dark-card);
border-right: 1px solid var(--dark-border);
padding: 1.5rem 0;
}
.dash-sidebar .logo-area {
padding: 0 1.2rem 1.5rem;
border-bottom: 1px solid var(--dark-border);
margin-bottom: 1rem;
}
.dash-sidebar .logo-area h2 {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.3rem;
letter-spacing: 3px;
color: var(--text-primary);
}
.dash-sidebar .logo-area h2 span { color: var(--fde); }
.dash-sidebar .logo-area small {
font-family: 'JetBrains Mono', monospace;
font-size: 0.6rem;
color: var(--od-green-light);
letter-spacing: 2px;
}
.dash-nav-item {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 0.7rem 1.2rem;
color: var(--text-secondary);
font-size: 0.85rem;
cursor: pointer;
transition: all 0.15s;
}
.dash-nav-item:hover { color: var(--text-primary); background: rgba(255,255,255,0.03); }
.dash-nav-item.active {
color: var(--fde);
background: rgba(196,162,101,0.08);
border-left: 3px solid var(--fde);
}
.dash-nav-item .icon {
width: 18px;
text-align: center;
font-size: 0.9rem;
}
.dash-main {
padding: 1.5rem 2rem;
}
.dash-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
}
.dash-header h1 {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.6rem;
letter-spacing: 2px;
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1.2rem;
font-family: 'Bebas Neue', sans-serif;
font-size: 0.9rem;
letter-spacing: 2px;
border: none;
cursor: pointer;
transition: all 0.15s;
}
.btn-primary {
background: var(--od-green);
color: white;
}
.btn-fde {
background: var(--fde);
color: var(--midnight);
}
.btn-danger {
background: transparent;
border: 1px solid var(--danger);
color: var(--danger);
}
.btn-ghost {
background: transparent;
border: 1px solid var(--dark-border);
color: var(--text-secondary);
}
/* Stats row */
.stats-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
margin-bottom: 2rem;
}
.stat-card {
background: var(--dark-card);
border: 1px solid var(--dark-border);
padding: 1rem 1.2rem;
}
.stat-card .label {
font-family: 'JetBrains Mono', monospace;
font-size: 0.6rem;
letter-spacing: 2px;
color: var(--text-muted);
text-transform: uppercase;
margin-bottom: 0.3rem;
}
.stat-card .value {
font-family: 'Bebas Neue', sans-serif;
font-size: 2rem;
letter-spacing: 1px;
}
.stat-card .value.green { color: var(--success); }
.stat-card .value.fde { color: var(--fde); }
.stat-card .value.red { color: var(--danger-light); }
.stat-card .value.blue { color: var(--blue); }
/* Ticket table */
.ticket-table {
width: 100%;
border-collapse: collapse;
}
.ticket-table th {
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--text-muted);
text-align: left;
padding: 0.8rem 1rem;
border-bottom: 1px solid var(--dark-border);
}
.ticket-table td {
padding: 0.9rem 1rem;
font-size: 0.85rem;
color: var(--text-secondary);
border-bottom: 1px solid rgba(51,51,51,0.5);
}
.ticket-table tr:hover td {
background: rgba(255,255,255,0.02);
}
.ticket-id {
font-family: 'JetBrains Mono', monospace;
color: var(--od-green-light);
font-size: 0.8rem;
}
.ticket-subject { color: var(--text-primary); font-weight: 500; }
.status-badge {
display: inline-block;
padding: 0.2rem 0.6rem;
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
letter-spacing: 1px;
text-transform: uppercase;
border-radius: 2px;
}
.status-badge.hot { background: rgba(231,76,60,0.15); color: var(--danger-light); border: 1px solid rgba(231,76,60,0.3); }
.status-badge.queued { background: rgba(243,156,18,0.15); color: var(--warning); border: 1px solid rgba(243,156,18,0.3); }
.status-badge.sent { background: rgba(39,174,96,0.15); color: var(--success); border: 1px solid rgba(39,174,96,0.3); }
.status-badge.new { background: rgba(52,152,219,0.15); color: var(--blue); border: 1px solid rgba(52,152,219,0.3); }
.priority-indicator {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 0.5rem;
}
.priority-indicator.crit { background: var(--danger-light); }
.priority-indicator.high { background: var(--warning); }
.priority-indicator.med { background: var(--blue); }
.priority-indicator.low { background: var(--text-muted); }
/* ===== WORKFLOW ===== */
.workflow-container {
overflow-x: auto;
padding: 2rem 0;
}
.workflow {
display: flex;
align-items: flex-start;
gap: 0;
min-width: 900px;
justify-content: center;
}
.wf-step {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
min-width: 130px;
position: relative;
}
.wf-icon {
width: 64px;
height: 64px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
margin-bottom: 0.8rem;
border: 2px solid var(--dark-border);
background: var(--dark-card);
position: relative;
z-index: 2;
}
.wf-icon.green { border-color: var(--od-green); background: rgba(74,93,35,0.2); }
.wf-icon.fde { border-color: var(--fde); background: rgba(196,162,101,0.15); }
.wf-icon.blue { border-color: var(--blue); background: rgba(52,152,219,0.15); }
.wf-icon.red { border-color: var(--danger); background: rgba(192,57,43,0.15); }
.wf-label {
font-family: 'Bebas Neue', sans-serif;
font-size: 0.9rem;
letter-spacing: 2px;
color: var(--text-primary);
margin-bottom: 0.3rem;
}
.wf-desc {
font-size: 0.7rem;
color: var(--text-muted);
max-width: 120px;
line-height: 1.4;
}
.wf-arrow {
display: flex;
align-items: center;
color: var(--text-muted);
font-size: 1.5rem;
margin-top: 1rem;
padding: 0 0.3rem;
min-width: 40px;
justify-content: center;
}
.wf-arrow .arrow-label {
font-family: 'JetBrains Mono', monospace;
font-size: 0.55rem;
display: block;
margin-top: -1.5rem;
color: var(--od-green-light);
letter-spacing: 1px;
}
/* ===== TECH SECTION ===== */
.tech-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
margin: 2rem 0;
}
.tech-card {
background: var(--dark-card);
border: 1px solid var(--dark-border);
padding: 2rem;
}
.tech-card h3 {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.2rem;
letter-spacing: 2px;
color: var(--fde);
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.tech-card p, .tech-card li {
color: var(--text-secondary);
font-size: 0.85rem;
line-height: 1.7;
}
.tech-card ul {
list-style: none;
padding: 0;
}
.tech-card ul li {
padding: 0.3rem 0;
border-bottom: 1px solid rgba(51,51,51,0.3);
}
.tech-card ul li:last-child { border-bottom: none; }
.tech-card ul li::before {
content: ' ';
color: var(--od-green-light);
font-weight: bold;
}
.tech-card code {
font-family: 'JetBrains Mono', monospace;
font-size: 0.8rem;
background: rgba(74,93,35,0.15);
padding: 0.1rem 0.4rem;
border-radius: 2px;
color: var(--od-green-light);
}
/* Architecture diagram */
.arch-diagram {
background: var(--dark-card);
border: 1px solid var(--dark-border);
padding: 2rem;
font-family: 'JetBrains Mono', monospace;
font-size: 0.75rem;
line-height: 1.6;
color: var(--text-secondary);
overflow-x: auto;
white-space: pre;
margin: 2rem 0;
}
.arch-diagram .highlight { color: var(--fde); }
.arch-diagram .green { color: var(--od-green-light); }
.arch-diagram .blue { color: var(--blue); }
.arch-diagram .red { color: var(--danger-light); }
/* ===== APPROVAL QUEUE MOCK ===== */
.approval-card {
background: var(--dark-card);
border: 1px solid var(--dark-border);
margin: 1rem 0;
overflow: hidden;
}
.approval-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--dark-border);
background: rgba(196,162,101,0.05);
}
.approval-header .ticket-info {
display: flex;
align-items: center;
gap: 1rem;
}
.approval-body {
display: grid;
grid-template-columns: 1fr 1fr;
border-bottom: 1px solid var(--dark-border);
}
.approval-col {
padding: 1.5rem;
}
.approval-col:first-child {
border-right: 1px solid var(--dark-border);
}
.approval-col h4 {
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--text-muted);
margin-bottom: 0.8rem;
}
.approval-col p {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.7;
}
.approval-col .ai-badge {
display: inline-block;
background: rgba(74,93,35,0.2);
border: 1px solid rgba(74,93,35,0.4);
color: var(--od-green-light);
font-family: 'JetBrains Mono', monospace;
font-size: 0.6rem;
padding: 0.2rem 0.5rem;
letter-spacing: 1px;
margin-bottom: 0.8rem;
}
.approval-actions {
display: flex;
gap: 0.8rem;
padding: 1rem 1.5rem;
justify-content: flex-end;
}
/* ===== TAGLINES ===== */
.tagline-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1px;
background: var(--dark-border);
border: 1px solid var(--dark-border);
margin: 2rem 0;
}
.tagline-item {
background: var(--dark-card);
padding: 1.5rem 2rem;
}
.tagline-item .tag {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.3rem;
letter-spacing: 2px;
color: var(--fde);
margin-bottom: 0.3rem;
}
.tagline-item .context {
font-size: 0.8rem;
color: var(--text-muted);
font-style: italic;
}
/* ===== FOOTER ===== */
.footer {
text-align: center;
padding: 3rem 2rem;
color: var(--text-muted);
font-size: 0.8rem;
border-top: 1px solid var(--dark-border);
}
.footer .fa-text {
font-family: 'Bebas Neue', sans-serif;
font-size: 1rem;
letter-spacing: 3px;
color: var(--text-secondary);
margin-bottom: 0.5rem;
}
/* ===== RESPONSIVE ===== */
@media (max-width: 768px) {
.dash-layout { grid-template-columns: 1fr; }
.dash-sidebar { display: none; }
.stats-row { grid-template-columns: repeat(2, 1fr); }
.approval-body { grid-template-columns: 1fr; }
.approval-col:first-child { border-right: none; border-bottom: 1px solid var(--dark-border); }
}
/* Scroll animation */
.fade-in {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.visible {
opacity: 1;
transform: translateY(0);
}
</style>
</head>
<body>
<!-- ==================== HERO ==================== -->
<div class="hero">
<div class="hero-badge">★ Project Briefing ★</div>
<div class="hero-logo">FORWARD<br><span>ASSIST</span></div>
<div class="hero-tagline">「 WHEN YOUR TICKETS WON'T CHAMBER 」</div>
<div class="hero-sub">"The help desk that slaps. Literally."<br>AI-powered ticket management for the firearms industry.</div>
<div class="hero-nav">
<a href="#branding" class="primary">Branding</a>
<a href="#workflow">Workflow</a>
<a href="#tech">Tech Plan</a>
<a href="#mockup">App Mockup</a>
</div>
</div>
<!-- ==================== BRANDING ==================== -->
<div class="divider"></div>
<section id="branding" class="fade-in">
<div class="section-label">Section 01</div>
<div class="section-title">THE <span>BRAND</span></div>
<div class="section-intro">
Forward Assist isn't just a ticket app. It's a ticket app that knows what a forward assist actually is.
Mil-spec aesthetic. Meme-lord energy. Professional where it counts, irreverent everywhere else.
</div>
<div class="brand-grid">
<div class="brand-card">
<h3>Brand Identity</h3>
<ul>
<li>Name references AR-15/M16 forward assist button — "tap it when things won't go into battery"</li>
<li>Dark, tactical aesthetic — think armory meets SaaS dashboard</li>
<li>Stencil typography (Bebas Neue) for headers — feels stamped on a pelican case</li>
<li>Monospace (JetBrains Mono) for data — like reading a mil-spec data sheet</li>
<li>Humor is baked into the UI language, not just slapped on</li>
</ul>
</div>
<div class="brand-card">
<h3>Tone &amp; Voice</h3>
<ul>
<li>Self-aware and irreverent — Gun Slaps "your wife's boyfriend" energy</li>
<li>Inside jokes the community gets: "send it", "LARP", "just as good", "two world wars"</li>
<li>Professional in customer-facing responses — the memes stay internal</li>
<li>Never punching down — humor is for the team, not at customers' expense</li>
<li>Think: if Garand Thumb built a SaaS product</li>
</ul>
</div>
<div class="brand-card">
<h3>Target Audience</h3>
<ul>
<li>Small-to-mid firearms manufacturers and parts makers</li>
<li>Mil-spec / defense contractors with small sales teams</li>
<li>Gun shop owners who are terminally online</li>
<li>Anyone in the industry who's tired of Zendesk looking like a dentist's office</li>
</ul>
</div>
<div class="brand-card">
<h3>Competitive Edge</h3>
<ul>
<li>No other ticket system speaks this language</li>
<li>AI that actually understands firearms context (parts, specs, compliance)</li>
<li>Branding that makes the team WANT to use the tool</li>
<li>Self-hosted option — these guys don't love cloud dependencies</li>
</ul>
</div>
</div>
<!-- Color Palette -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin-bottom:0.5rem;">Color Palette — "Armory After Dark"</h3>
<p style="color:var(--text-muted); font-size:0.85rem; margin-bottom:1rem;">OD Green + FDE + midnight. If Magpul made a dashboard.</p>
<div class="color-grid">
<div class="color-swatch">
<div class="swatch" style="background:#0D0D0D;"></div>
<div class="name">Midnight</div>
<div class="hex">#0D0D0D</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#1E1E1E;"></div>
<div class="name">Cerakote Dark</div>
<div class="hex">#1E1E1E</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#4A5D23;"></div>
<div class="name">OD Green</div>
<div class="hex">#4A5D23</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#6B8C3E;"></div>
<div class="name">OD Light</div>
<div class="hex">#6B8C3E</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#C4A265;"></div>
<div class="name">FDE</div>
<div class="hex">#C4A265</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#8B7355;"></div>
<div class="name">Coyote</div>
<div class="hex">#8B7355</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#C0392B;"></div>
<div class="name">Tracer Red</div>
<div class="hex">#C0392B</div>
</div>
<div class="color-swatch">
<div class="swatch" style="background:#E8E8E8;"></div>
<div class="name">Stainless</div>
<div class="hex">#E8E8E8</div>
</div>
</div>
<!-- UI Language -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 0.5rem;">UI Language — "Boring to Based"</h3>
<p style="color:var(--text-muted); font-size:0.85rem; margin-bottom:1rem;">Every button, label, and status is an opportunity.</p>
<div class="ui-lang-grid">
<div class="ui-lang-item">
<span class="boring">Submit</span>
<span class="arrow"></span>
<span class="cool">SEND IT</span>
</div>
<div class="ui-lang-item">
<span class="boring">Approved</span>
<span class="arrow"></span>
<span class="cool">CLEARED HOT</span>
</div>
<div class="ui-lang-item">
<span class="boring">Rejected</span>
<span class="arrow"></span>
<span class="cool">MISFIRE</span>
</div>
<div class="ui-lang-item">
<span class="boring">Pending Review</span>
<span class="arrow"></span>
<span class="cool">IN THE CHAMBER</span>
</div>
<div class="ui-lang-item">
<span class="boring">Closed</span>
<span class="arrow"></span>
<span class="cool">BRASS POLICED</span>
</div>
<div class="ui-lang-item">
<span class="boring">Urgent</span>
<span class="arrow"></span>
<span class="cool">DANGER CLOSE</span>
</div>
<div class="ui-lang-item">
<span class="boring">New Ticket</span>
<span class="arrow"></span>
<span class="cool">INCOMING</span>
</div>
<div class="ui-lang-item">
<span class="boring">Assigned</span>
<span class="arrow"></span>
<span class="cool">ON TARGET</span>
</div>
<div class="ui-lang-item">
<span class="boring">Dashboard</span>
<span class="arrow"></span>
<span class="cool">THE ARMORY</span>
</div>
<div class="ui-lang-item">
<span class="boring">Settings</span>
<span class="arrow"></span>
<span class="cool">FIELD STRIP</span>
</div>
<div class="ui-lang-item">
<span class="boring">AI Draft</span>
<span class="arrow"></span>
<span class="cool">SPOTTER CALL</span>
</div>
<div class="ui-lang-item">
<span class="boring">Knowledge Base</span>
<span class="arrow"></span>
<span class="cool">THE MANUAL</span>
</div>
</div>
<!-- Taglines -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 0.5rem;">Tagline Candidates</h3>
<div class="tagline-grid">
<div class="tagline-item">
<div class="tag">"When your tickets won't chamber."</div>
<div class="context">Primary — references the literal forward assist function</div>
</div>
<div class="tagline-item">
<div class="tag">"The help desk that slaps."</div>
<div class="context">Secondary — double meaning with Gun Slaps reference</div>
</div>
<div class="tagline-item">
<div class="tag">"Customer service. Full send."</div>
<div class="context">For marketing — "send it" is universal gun meme</div>
</div>
<div class="tagline-item">
<div class="tag">"Smack that bolt home."</div>
<div class="context">Aggressive variant — for stickers/merch</div>
</div>
<div class="tagline-item">
<div class="tag">"Your AI spotter never misses."</div>
<div class="context">AI-focused — for the tech-forward pitch</div>
</div>
<div class="tagline-item">
<div class="tag">"Steal underpants → Forward Assist → Profit"</div>
<div class="context">Internal only — Eric knows what's up</div>
</div>
</div>
</section>
<!-- ==================== WORKFLOW ==================== -->
<div class="divider"></div>
<section id="workflow" class="fade-in">
<div class="section-label">Section 02</div>
<div class="section-title">THE <span>WORKFLOW</span></div>
<div class="section-intro">
Email comes in. AI drafts a response. Human approves. Response goes out. Brass policed. That's it. No LARP required.
</div>
<div class="workflow-container">
<div class="workflow">
<div class="wf-step">
<div class="wf-icon blue">📧</div>
<div class="wf-label">INCOMING</div>
<div class="wf-desc">Customer emails sales@xyz.com (Google Workspace)</div>
</div>
<div class="wf-arrow">
<div><br><span class="arrow-label">IMAP/webhook</span></div>
</div>
<div class="wf-step">
<div class="wf-icon green">🎯</div>
<div class="wf-label">TICKET CREATED</div>
<div class="wf-desc">Auto-parsed: subject, body, sender, thread ID, attachments</div>
</div>
<div class="wf-arrow">
<div><br><span class="arrow-label">immediate</span></div>
</div>
<div class="wf-step">
<div class="wf-icon fde">🤖</div>
<div class="wf-label">SPOTTER CALL</div>
<div class="wf-desc">AI reads ticket + knowledge base, drafts response</div>
</div>
<div class="wf-arrow">
<div><br><span class="arrow-label">queued</span></div>
</div>
<div class="wf-step">
<div class="wf-icon red"></div>
<div class="wf-label">IN THE CHAMBER</div>
<div class="wf-desc">Draft queued for human review. Edit, approve, or reject.</div>
</div>
<div class="wf-arrow">
<div><br><span class="arrow-label">approved</span></div>
</div>
<div class="wf-step">
<div class="wf-icon green"></div>
<div class="wf-label">CLEARED HOT</div>
<div class="wf-desc">Response sent via SMTP through Google Workspace</div>
</div>
<div class="wf-arrow">
<div><br><span class="arrow-label">auto</span></div>
</div>
<div class="wf-step">
<div class="wf-icon">🧹</div>
<div class="wf-label">BRASS POLICED</div>
<div class="wf-desc">Ticket closed or awaiting reply. Thread tracked.</div>
</div>
</div>
</div>
<!-- Detailed flow -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 1rem;">Detailed Flow</h3>
<div class="tech-grid">
<div class="tech-card">
<h3>📧 Email Ingestion</h3>
<ul>
<li>Poll Google Workspace via <code>IMAP IDLE</code> or use Google Pub/Sub push notifications</li>
<li>Parse: sender, subject, body (HTML → plaintext), attachments, Message-ID, In-Reply-To</li>
<li>Thread detection: group by In-Reply-To / References header → same ticket</li>
<li>Dedup: ignore auto-replies, out-of-office, own outbound</li>
<li>Store raw email + parsed version</li>
</ul>
</div>
<div class="tech-card">
<h3>🤖 AI Draft (Spotter Call)</h3>
<ul>
<li>Trigger: new ticket or new reply on existing ticket</li>
<li>Context window: ticket history + knowledge base articles + customer profile</li>
<li>System prompt: product-specific (parts catalog, lead times, compliance, specs)</li>
<li>AI provider: configurable — Claude API, OpenAI API, or local LLM (Ollama)</li>
<li>Output: draft response + confidence score + suggested category/priority</li>
<li>Draft is NEVER auto-sent — always queued for approval</li>
</ul>
</div>
<div class="tech-card">
<h3>⏳ Approval Queue (The Chamber)</h3>
<ul>
<li>Side-by-side view: original email | AI draft</li>
<li>Inline editing: operator can modify the draft before approving</li>
<li>Actions: <strong>Cleared Hot</strong> (send as-is), <strong>Edit & Send</strong>, <strong>Misfire</strong> (reject + write manual reply), <strong>Reassign</strong></li>
<li>Optional: auto-approve for low-risk categories (FAQ, order status) after trust is built</li>
<li>Audit trail: who approved, what was edited, when</li>
</ul>
</div>
<div class="tech-card">
<h3>📤 Outbound &amp; Tracking</h3>
<ul>
<li>Send via Google Workspace SMTP (appears from sales@xyz.com)</li>
<li>Maintain thread: set In-Reply-To and References headers correctly</li>
<li>Track: open status, follow-up replies auto-attach to ticket</li>
<li>SLA tracking: time-to-first-response, time-to-resolution</li>
<li>Notifications: Slack/email alerts for DANGER CLOSE tickets</li>
</ul>
</div>
</div>
<!-- Rejection / Edge cases -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 1rem;">Edge Cases &amp; Safety</h3>
<div class="brand-grid">
<div class="brand-card">
<h3>Misfire Handling</h3>
<ul>
<li>Rejected AI drafts are logged for model improvement</li>
<li>If AI confidence is below threshold → skip draft, flag for manual response</li>
<li>ITAR/export control keywords → auto-flag, no AI draft, human only</li>
<li>Profanity/threats in inbound → alert team immediately</li>
</ul>
</div>
<div class="brand-card">
<h3>Thread Intelligence</h3>
<ul>
<li>Customer replies to sent response → ticket reopens automatically</li>
<li>AI sees full conversation history for context</li>
<li>Auto-merge: same customer, similar subject within 24h → same ticket</li>
<li>Customer profile builds over time: past orders, past issues, preferences</li>
</ul>
</div>
</div>
</section>
<!-- ==================== TECH PLAN ==================== -->
<div class="divider"></div>
<section id="tech" class="fade-in">
<div class="section-label">Section 03</div>
<div class="section-title">TECHNICAL <span>PLAN</span></div>
<div class="section-intro">
Self-hosted on Ragnar. Docker-composed. Node.js backend because that's what we run. PostgreSQL because tickets deserve a real database. AI provider is pluggable.
</div>
<!-- Architecture diagram -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin-bottom:1rem;">Architecture</h3>
<div class="arch-diagram"><span class="blue">┌─────────────────┐</span> <span class="green">┌──────────────────┐</span> <span class="highlight">┌─────────────────┐</span>
<span class="blue">│ Google Workspace│</span> <span class="green">│ Forward Assist │</span> <span class="highlight">│ AI Provider │</span>
<span class="blue">│ sales@xyz.com │</span>──IMAP──<span class="green">│ │</span>──API──<span class="highlight">│ │</span>
<span class="blue">│ │</span>◄─SMTP──<span class="green">│ Node.js/Express│</span> <span class="highlight">│ Claude / OpenAI │</span>
<span class="blue">└─────────────────┘</span> <span class="green">│ + Bull queues │</span> <span class="highlight">│ / Ollama (local)│</span>
<span class="green">│ │</span> <span class="highlight">└─────────────────┘</span>
<span class="green">└────────┬─────────┘</span>
┌─────────────┼─────────────┐
│ │ │
<span class="highlight">┌──────┴──────┐</span> <span class="green">┌──────┴──────┐</span> <span class="red">┌──────┴──────┐</span>
<span class="highlight">│ PostgreSQL │</span> <span class="green">│ React │</span> <span class="red">│ Redis │</span>
<span class="highlight">│ (tickets, │</span> <span class="green">│ Frontend │</span> <span class="red">│ (sessions, │</span>
<span class="highlight">│ emails, │</span> <span class="green">│ (dashboard)│</span> <span class="red">│ queues) │</span>
<span class="highlight">│ users) │</span> <span class="green">│ │</span> <span class="red">│ │</span>
<span class="highlight">└─────────────┘</span> <span class="green">└─────────────┘</span> <span class="red">└─────────────┘</span>
<span class="green">All containers on Ragnar (192.168.1.107) via Docker Compose</span>
<span class="green">Reverse proxy through existing Nginx Proxy Manager on HAOS</span></div>
<!-- Tech stack details -->
<div class="tech-grid">
<div class="tech-card">
<h3>⚙️ Backend</h3>
<ul>
<li><code>Node.js</code> + <code>Express</code> — REST API</li>
<li><code>Bull</code> (Redis-backed) — job queues for email polling, AI drafting, sending</li>
<li><code>node-imap</code> or <code>imapflow</code> — IMAP client for Google Workspace</li>
<li><code>nodemailer</code> — SMTP outbound</li>
<li><code>mailparser</code> — email parsing (HTML → text, attachments)</li>
<li><code>passport.js</code> — local auth + optional Google OAuth</li>
<li><code>socket.io</code> — real-time ticket updates in dashboard</li>
</ul>
</div>
<div class="tech-card">
<h3>🗄️ Database</h3>
<ul>
<li><code>PostgreSQL 16</code> — primary data store</li>
<li><code>Prisma</code> ORM — schema management + migrations</li>
<li>Tables: users, tickets, messages, ai_drafts, approvals, knowledge_base, email_accounts</li>
<li>Full-text search on ticket subject + body (pg_trgm)</li>
<li><code>Redis</code> — sessions, Bull queues, rate limiting, real-time pub/sub</li>
</ul>
</div>
<div class="tech-card">
<h3>🎨 Frontend</h3>
<ul>
<li><code>React</code> + <code>Vite</code> — SPA dashboard</li>
<li><code>TailwindCSS</code> — utility-first styling with custom "Armory" theme</li>
<li><code>React Router</code> — client-side routing</li>
<li><code>TanStack Query</code> — server state management</li>
<li><code>Socket.io client</code> — live ticket updates</li>
<li>Dark mode only — this is the way</li>
</ul>
</div>
<div class="tech-card">
<h3>🤖 AI Layer</h3>
<ul>
<li>Pluggable provider interface — swap without code changes</li>
<li><code>Claude API</code> (recommended) — best at nuanced, professional responses</li>
<li><code>OpenAI API</code> — GPT-4o as fallback</li>
<li><code>Ollama</code> (local) — for air-gapped / cost-conscious setups</li>
<li>Knowledge base: product catalog, FAQ, past responses fed as context</li>
<li>Confidence scoring: low confidence = skip auto-draft</li>
</ul>
</div>
<div class="tech-card">
<h3>🐳 Infrastructure</h3>
<ul>
<li>Docker Compose on <strong>Ragnar</strong> (Proxmox LXC or VM)</li>
<li>Containers: app, postgres, redis, (optional: ollama)</li>
<li>Reverse proxy: Nginx Proxy Manager on HAOS (192.168.1.140)</li>
<li>Domain: <code>tickets.xyz.com</code> or <code>fa.xyz.com</code></li>
<li>SSL via Let's Encrypt through NPM</li>
<li>Backups: pg_dump cron → local + offsite</li>
<li>Git repo: <code>git@git.jfamily.io:eric/forward-assist.git</code></li>
</ul>
</div>
<div class="tech-card">
<h3>👥 Multi-User &amp; Roles</h3>
<ul>
<li><strong>Admin</strong> — full access, manage users, configure AI, manage knowledge base</li>
<li><strong>Operator</strong> — view tickets, approve/reject AI drafts, send replies</li>
<li><strong>Viewer</strong> — read-only dashboard access (for managers/owners)</li>
<li>Ticket assignment — round-robin or manual</li>
<li>Activity log — who did what, when</li>
<li>Per-user notification preferences</li>
</ul>
</div>
</div>
<!-- Data model -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 1rem;">Core Data Model</h3>
<div class="arch-diagram"><span class="highlight">users</span> <span class="green">tickets</span> <span class="blue">messages</span>
├── id (uuid) ├── id (uuid) ├── id (uuid)
├── email ├── ticket_number (FA-001) ├── ticket_id → tickets
├── name ├── subject ├── direction (inbound/outbound)
├── role (admin/op/viewer) ├── status ├── from_email
├── password_hash ├── priority ├── body_text
└── created_at ├── assigned_to → users ├── body_html
├── customer_email ├── message_id (email)
<span class="highlight">ai_drafts</span> ├── customer_name ├── in_reply_to
├── id (uuid) ├── created_at ├── attachments (jsonb)
├── ticket_id → tickets ├── updated_at └── created_at
├── message_id → messages ├── resolved_at
├── draft_text └── sla_due_at <span class="red">knowledge_base</span>
├── confidence ├── id (uuid)
├── provider (claude/gpt) <span class="green">approvals</span> ├── title
├── model ├── id (uuid) ├── content
├── status (pending/ ├── ai_draft_id → ai_drafts ├── category
│ approved/rejected) ├── user_id → users ├── embedding (vector)
├── approved_by → users ├── action (approve/reject) └── updated_at
├── approved_at ├── edited_text
└── created_at └── created_at <span class="blue">email_accounts</span>
├── id (uuid)
├── email_address
├── imap_host / smtp_host
├── credentials (encrypted)
└── polling_interval</div>
<!-- Phasing -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 1rem;">Build Phases</h3>
<div class="tech-grid">
<div class="tech-card">
<h3>🔫 Phase 1 — "First Round Downrange"</h3>
<ul>
<li>Docker Compose setup (Node + Postgres + Redis)</li>
<li>Email ingestion: IMAP polling → ticket creation</li>
<li>Basic dashboard: ticket list, detail view, manual reply</li>
<li>User auth (local, 2-3 users)</li>
<li>Thread tracking (replies attach to existing tickets)</li>
<li>SMTP outbound through Google Workspace</li>
</ul>
<p style="margin-top:1rem; color:var(--od-green-light); font-size:0.8rem;">
<strong>Goal:</strong> Working ticket system. No AI yet. Prove the plumbing works.
</p>
</div>
<div class="tech-card">
<h3>🤖 Phase 2 — "Spotter Online"</h3>
<ul>
<li>AI integration: pluggable provider (Claude/OpenAI/Ollama)</li>
<li>Auto-draft on new tickets + new replies</li>
<li>Approval queue UI (side-by-side, edit, approve/reject)</li>
<li>Knowledge base CRUD + vector search for context</li>
<li>Confidence scoring + auto-skip for low confidence</li>
<li>Audit trail for all AI actions</li>
</ul>
<p style="margin-top:1rem; color:var(--od-green-light); font-size:0.8rem;">
<strong>Goal:</strong> AI drafts responses. Humans stay in the loop. Trust builds over time.
</p>
</div>
<div class="tech-card">
<h3>💅 Phase 3 — "Full Send"</h3>
<ul>
<li>Full branding pass — Armory theme, all the fun UI language</li>
<li>Real-time updates (Socket.io)</li>
<li>SLA tracking + dashboards + metrics</li>
<li>Notification system (Slack, email alerts)</li>
<li>Customer profiles + history</li>
<li>Auto-approve rules for trusted categories</li>
</ul>
<p style="margin-top:1rem; color:var(--od-green-light); font-size:0.8rem;">
<strong>Goal:</strong> Production-ready. Looks amazing. Your buddy actually wants to use it.
</p>
</div>
<div class="tech-card">
<h3>🚀 Phase 4 — "Sustained Fire" (Future)</h3>
<ul>
<li>Multi-inbox support (sales@, support@, returns@)</li>
<li>ITAR/compliance flagging</li>
<li>Canned responses library</li>
<li>Customer-facing portal ("check my ticket status")</li>
<li>Reporting: response times, AI accuracy, volume trends</li>
<li>Mobile-responsive / PWA</li>
</ul>
<p style="margin-top:1rem; color:var(--od-green-light); font-size:0.8rem;">
<strong>Goal:</strong> Scale it. Maybe other shops want this too. 👀
</p>
</div>
</div>
</section>
<!-- ==================== APP MOCKUP ==================== -->
<div class="divider"></div>
<section id="mockup" class="fade-in">
<div class="section-label">Section 04</div>
<div class="section-title">APP <span>MOCKUP</span></div>
<div class="section-intro">
What the dashboard could look like. Dark mode only. Mil-spec meets modern SaaS. The kind of app that makes Zendesk look like it was designed by someone who's never touched a rifle.
</div>
<!-- Dashboard mockup -->
<div class="mock-window">
<div class="mock-titlebar">
<div class="mock-dot red"></div>
<div class="mock-dot yellow"></div>
<div class="mock-dot green"></div>
<span class="title">Forward Assist — The Armory</span>
</div>
<div class="mock-body">
<div class="dash-layout">
<div class="dash-sidebar">
<div class="logo-area">
<h2>FORWARD <span>ASSIST</span></h2>
<small>ticket command center</small>
</div>
<div class="dash-nav-item active">
<span class="icon">🎯</span> The Armory
</div>
<div class="dash-nav-item">
<span class="icon"></span> In The Chamber
<span style="margin-left:auto; background:var(--warning); color:var(--midnight); font-size:0.65rem; padding:0.1rem 0.5rem; font-family:'JetBrains Mono',monospace; border-radius:2px;">3</span>
</div>
<div class="dash-nav-item">
<span class="icon">📋</span> All Tickets
</div>
<div class="dash-nav-item">
<span class="icon">📖</span> The Manual
</div>
<div class="dash-nav-item">
<span class="icon">👥</span> Operators
</div>
<div class="dash-nav-item">
<span class="icon">🔧</span> Field Strip
</div>
<div style="margin-top:auto; padding:1rem 1.2rem; border-top:1px solid var(--dark-border); margin-top:3rem;">
<div style="display:flex; align-items:center; gap:0.8rem;">
<div style="width:32px; height:32px; border-radius:50%; background:var(--od-green); display:flex; align-items:center; justify-content:center; font-size:0.75rem; color:white; font-weight:600;">EJ</div>
<div>
<div style="font-size:0.8rem; color:var(--text-primary);">Eric J.</div>
<div style="font-size:0.65rem; color:var(--text-muted); font-family:'JetBrains Mono',monospace;">ADMIN</div>
</div>
</div>
</div>
</div>
<div class="dash-main">
<div class="dash-header">
<h1>THE ARMORY</h1>
<div style="display:flex; gap:0.5rem;">
<button class="btn btn-ghost">🔍 SEARCH</button>
<button class="btn btn-primary">+ NEW TICKET</button>
</div>
</div>
<div class="stats-row">
<div class="stat-card">
<div class="label">Incoming Today</div>
<div class="value blue">12</div>
</div>
<div class="stat-card">
<div class="label">In The Chamber</div>
<div class="value fde">3</div>
</div>
<div class="stat-card">
<div class="label">Cleared Hot Today</div>
<div class="value green">8</div>
</div>
<div class="stat-card">
<div class="label">Danger Close</div>
<div class="value red">1</div>
</div>
</div>
<table class="ticket-table">
<thead>
<tr>
<th>Ticket</th>
<th>Subject</th>
<th>Customer</th>
<th>Status</th>
<th>Priority</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="ticket-id">FA-0042</span></td>
<td><span class="ticket-subject">Need lead time on BCG batch order (500 units)</span></td>
<td>Mike T. — Tier 1 Defense</td>
<td><span class="status-badge hot">DANGER CLOSE</span></td>
<td><span class="priority-indicator crit"></span>Critical</td>
<td>4h</td>
</tr>
<tr>
<td><span class="ticket-id">FA-0041</span></td>
<td><span class="ticket-subject">AI draft ready: Return policy for cerakote defect</span></td>
<td>Sarah K. — Sportsman's Supply</td>
<td><span class="status-badge queued">IN THE CHAMBER</span></td>
<td><span class="priority-indicator high"></span>High</td>
<td>6h</td>
</tr>
<tr>
<td><span class="ticket-id">FA-0040</span></td>
<td><span class="ticket-subject">AI draft ready: Barrel threading specs question</span></td>
<td>Jim R. — Personal</td>
<td><span class="status-badge queued">IN THE CHAMBER</span></td>
<td><span class="priority-indicator med"></span>Medium</td>
<td>8h</td>
</tr>
<tr>
<td><span class="ticket-id">FA-0039</span></td>
<td><span class="ticket-subject">Invoice request for PO #7734</span></td>
<td>Dave L. — Patriot Arms LLC</td>
<td><span class="status-badge queued">IN THE CHAMBER</span></td>
<td><span class="priority-indicator low"></span>Low</td>
<td>1d</td>
</tr>
<tr>
<td><span class="ticket-id">FA-0038</span></td>
<td><span class="ticket-subject">Confirmed: Gas block alignment specs sent</span></td>
<td>Chris M. — AR Performance</td>
<td><span class="status-badge sent">CLEARED HOT</span></td>
<td><span class="priority-indicator med"></span>Medium</td>
<td>1d</td>
</tr>
<tr>
<td><span class="ticket-id">FA-0037</span></td>
<td><span class="ticket-subject">Wholesale pricing inquiry — dealer application</span></td>
<td>Tom B. — Liberty Firearms</td>
<td><span class="status-badge new">INCOMING</span></td>
<td><span class="priority-indicator high"></span>High</td>
<td>2h</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Approval queue mockup -->
<h3 style="font-family:'Bebas Neue',sans-serif; font-size:1.3rem; letter-spacing:2px; color:var(--fde); margin:2rem 0 1rem;">Approval Queue — "The Chamber"</h3>
<p style="color:var(--text-muted); font-size:0.85rem; margin-bottom:1.5rem;">Side-by-side: what the customer said vs. what the AI wants to say. You're the final trigger pull.</p>
<div class="mock-window">
<div class="mock-titlebar">
<div class="mock-dot red"></div>
<div class="mock-dot yellow"></div>
<div class="mock-dot green"></div>
<span class="title">Forward Assist — In The Chamber (3 pending)</span>
</div>
<div class="mock-body" style="padding:1.5rem;">
<div class="approval-card">
<div class="approval-header">
<div class="ticket-info">
<span class="ticket-id">FA-0041</span>
<span class="ticket-subject" style="font-size:0.9rem;">Return policy for cerakote defect</span>
</div>
<span class="status-badge queued">IN THE CHAMBER</span>
</div>
<div class="approval-body">
<div class="approval-col">
<h4>📧 Customer Email</h4>
<p>
Hi,<br><br>
I received my order of 50 buffer tubes last week and about 8 of them have cerakote flaking near the threads.
These are going into builds for a local PD contract so I need them right. Can I get replacements sent out ASAP?
Happy to send photos.<br><br>
Thanks,<br>
Sarah K.<br>
Sportsman's Supply
</p>
</div>
<div class="approval-col">
<h4>🤖 AI Draft (Spotter Call)</h4>
<div class="ai-badge">CLAUDE-3.5-SONNET • CONFIDENCE: 92%</div>
<p>
Hi Sarah,<br><br>
Sorry to hear about the cerakote issue on those buffer tubes — that's not the standard we hold ourselves to, especially on a LE contract build.
<br><br>
Go ahead and send photos to this email and we'll get 8 replacements shipped out priority. No need to return the defective ones — toss 'em in the parts bin or send them back at our expense, your call.
<br><br>
I'll flag this batch for QC review on our end. If you need anything else to keep that PD build on schedule, let me know.
<br><br>
— [Your Name]
</p>
</div>
</div>
<div class="approval-actions">
<button class="btn btn-danger">✕ MISFIRE</button>
<button class="btn btn-ghost">✏️ EDIT &amp; SEND</button>
<button class="btn btn-fde">✓ CLEARED HOT</button>
</div>
</div>
</div>
</div>
</section>
<!-- ==================== FOOTER ==================== -->
<div class="divider"></div>
<div class="footer">
<div class="fa-text">FORWARD ASSIST</div>
<p>Project plan — March 19, 2026 — A&E Ventures, LLC</p>
<p style="margin-top:0.5rem; color:var(--text-muted);">"When your tickets won't chamber."</p>
</div>
<!-- Scroll animations -->
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));
</script>
</body>
</html>