Signal/pitch/assets/signal-workflow-flowchart.html
Kisa 42a79c6682 add pitch assets, fix UI and backend bugs, add test utilities
- add 3 signal pitch assets (workflow flowchart, market opportunity, win-win-win) as HTML + PNG
- fix doc_state_machine cascade and supplied sentinel flags
- fix CSVImport mapping review, WorklistTable colored bullets and expand row
- fix App.jsx auth gate, api.js CORS handling
- add signal E2E test script and stress test generator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 12:52:29 -04:00

361 lines
12 KiB
HTML
Raw 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>Signal — How It Works</title>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Plus Jakarta Sans', sans-serif;
background: #F0EAE1;
width: 1080px;
height: 1080px;
overflow: hidden;
position: relative;
}
.top-bar {
position: absolute;
top: 0; left: 0; right: 0;
height: 5px;
background: #2EA3A3;
}
.signal-brand {
position: absolute;
top: 28px; right: 80px;
text-align: right;
z-index: 3;
}
.brand-name { font-size: 18px; font-weight: 800; color: #1A5050; letter-spacing: 0.02em; }
.brand-sub { font-size: 9px; font-weight: 500; color: #8AABAB; letter-spacing: 0.12em; text-transform: uppercase; margin-top: 3px; }
.rings { position: absolute; top: 0; right: 0; pointer-events: none; }
.dots { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; opacity: 0.18; }
/* Main content area */
.content {
position: absolute;
top: 60px; left: 60px; right: 60px; bottom: 52px;
display: flex;
flex-direction: column;
}
.headline {
text-align: center;
margin-bottom: 24px;
flex-shrink: 0;
}
.headline h1 { font-size: 30px; font-weight: 800; color: #1A5050; letter-spacing: -0.02em; }
.headline p { font-size: 13px; color: #5A7A7A; margin-top: 6px; font-weight: 500; }
/* Two-column wrapper — takes available height */
.columns {
display: flex;
gap: 24px;
flex: 1;
min-height: 0;
}
.col {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
}
.col-header {
text-align: center;
padding: 10px 20px;
border-radius: 8px;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
margin-bottom: 14px;
flex-shrink: 0;
}
.col-header.without { background: #D8CFC4; color: #7A6A5A; }
.col-header.with { background: #1A5050; color: #fff; }
.flow {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
justify-content: space-between;
}
.node {
width: 100%;
padding: 13px 16px;
border-radius: 8px;
text-align: center;
font-size: 12.5px;
font-weight: 600;
line-height: 1.4;
}
.node.w-step { background: #EAE3DA; color: #5A4E42; border: 1.5px solid #C8BFB4; }
.node.w-pain { background: #F5EDE0; color: #7A4A1A; border: 1.5px solid #D4A070; }
.node.w-outcome { background: #F5E8E0; color: #8A2A10; border: 1.5px solid #D07060; }
.node.s-step { background: #E5F0F0; color: #1A5050; border: 1.5px solid #2EA3A3; }
.node.s-check { background: #1A5050; color: #fff; border: none; }
.node.s-gap { background: #FDF0E0; color: #884010; border: 1.5px solid #CB6B20; }
.node.s-win { background: #2EA3A3; color: #fff; border: none; font-size: 13px; font-weight: 700; }
.arrow {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
justify-content: center;
}
.arrow-line { width: 2px; flex: 1; max-height: 28px; min-height: 8px; background: #A8B8B8; }
.arrow-line.red { background: #C06050; }
.arrow-line.teal { background: #2EA3A3; }
.arrow-head { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 7px solid #A8B8B8; flex-shrink: 0; }
.arrow-head.red { border-top-color: #C06050; }
.arrow-head.teal { border-top-color: #2EA3A3; }
.check-items { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.check-item {
background: rgba(255,255,255,0.15);
border-radius: 4px;
padding: 4px 8px;
font-size: 11px;
font-weight: 500;
display: flex;
align-items: center;
gap: 6px;
text-align: left;
}
.check-item .dot { width: 6px; height: 6px; border-radius: 50%; background: #2EA3A3; flex-shrink: 0; }
.pain-sub { font-size: 10.5px; font-weight: 500; margin-top: 4px; opacity: 0.8; }
.gap-items { display: flex; gap: 8px; margin-top: 6px; justify-content: center; }
.gap-tag { background: #CB6B20; color: #fff; border-radius: 4px; padding: 2px 7px; font-size: 10px; font-weight: 700; }
.divider {
width: 1px;
background: linear-gradient(to bottom, transparent, #B0A898 20%, #B0A898 80%, transparent);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
.divider-label {
background: #F0EAE1;
color: #8A7A6A;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
padding: 6px 4px;
writing-mode: vertical-lr;
transform: rotate(180deg);
}
/* Stats bar — outside columns, at bottom of content */
.stats-bar {
display: flex;
flex-shrink: 0;
margin-top: 16px;
border-radius: 8px;
overflow: hidden;
}
.stat-cell {
flex: 1;
padding: 11px 12px;
text-align: center;
}
.stat-cell.neg { background: #DDD5C8; }
.stat-cell.pos { background: #1A5050; }
.stat-num {
font-size: 20px;
font-weight: 800;
line-height: 1;
margin-bottom: 3px;
}
.stat-cell.neg .stat-num { color: #8A2A10; }
.stat-cell.pos .stat-num { color: #2EA3A3; }
.stat-lbl {
font-size: 9.5px;
font-weight: 500;
line-height: 1.3;
}
.stat-cell.neg .stat-lbl { color: #6A5A4A; }
.stat-cell.pos .stat-lbl { color: rgba(255,255,255,0.72); }
.stat-div { width: 1px; background: rgba(0,0,0,0.1); flex-shrink: 0; }
.stat-section-label {
flex-shrink: 0;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: center;
}
.stat-section-label span {
writing-mode: vertical-lr;
transform: rotate(180deg);
font-size: 8px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.stat-section-label.neg-label { background: #C8BFB2; }
.stat-section-label.neg-label span { color: #8A7A6A; }
.stat-section-label.pos-label { background: #163E3E; }
.stat-section-label.pos-label span { color: rgba(255,255,255,0.5); }
.footer {
position: absolute;
bottom: 16px;
left: 60px; right: 60px;
display: flex;
justify-content: space-between;
align-items: center;
}
.footer-left { font-size: 10px; color: #8AABAB; font-weight: 500; }
.footer-right { font-size: 10px; color: #8AABAB; font-weight: 500; }
</style>
</head>
<body>
<div class="top-bar"></div>
<svg class="rings" width="1080" height="1080" viewBox="0 0 1080 1080" xmlns="http://www.w3.org/2000/svg">
<circle cx="920" cy="130" r="110" fill="none" stroke="#CB6B20" stroke-width="0.8" opacity="0.12"/>
<circle cx="920" cy="130" r="60" fill="none" stroke="#CB6B20" stroke-width="1.0" opacity="0.26"/>
<circle cx="920" cy="130" r="9" fill="#CB6B20" opacity="0.82"/>
</svg>
<svg class="dots" width="1080" height="1080" viewBox="0 0 1080 1080" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="fade" cx="89%" cy="12%" r="70%">
<stop offset="0%" stop-color="#1A5050" stop-opacity="1"/>
<stop offset="100%" stop-color="#1A5050" stop-opacity="0"/>
</radialGradient>
<pattern id="hex" x="0" y="0" width="24" height="20.8" patternUnits="userSpaceOnUse">
<circle cx="12" cy="4" r="1.4" fill="#1A5050"/>
<circle cx="0" cy="10.4" r="1.4" fill="#1A5050"/>
<circle cx="24" cy="10.4" r="1.4" fill="#1A5050"/>
<circle cx="12" cy="16.8" r="1.4" fill="#1A5050"/>
</pattern>
<mask id="radmask">
<rect width="1080" height="1080" fill="url(#fade)"/>
</mask>
</defs>
<rect width="1080" height="1080" fill="url(#hex)" mask="url(#radmask)"/>
</svg>
<div class="signal-brand">
<div class="brand-name">Signal.</div>
<div class="brand-sub">Powered by STTIL Solutions</div>
</div>
<div class="content">
<div class="headline">
<h1>How Signal Works</h1>
<p>Catching documentation gaps before they become denied claims</p>
</div>
<div class="columns">
<!-- WITHOUT SIGNAL -->
<div class="col">
<div class="col-header without">Without Signal</div>
<div class="flow">
<div class="node w-step">Patient flagged for CGM resupply</div>
<div class="arrow"><div class="arrow-line red"></div><div class="arrow-head red"></div></div>
<div class="node w-step">Staff manually tracks documentation across spreadsheets and faxes</div>
<div class="arrow"><div class="arrow-line red"></div><div class="arrow-head red"></div></div>
<div class="node w-step">Claim filed to payer</div>
<div class="arrow"><div class="arrow-line red"></div><div class="arrow-head red"></div></div>
<div class="node w-pain">
Denial: documentation incomplete
<div class="pain-sub">SWO missing &middot; Qualifying visit overdue &middot; PA not confirmed</div>
</div>
<div class="arrow"><div class="arrow-line red"></div><div class="arrow-head red"></div></div>
<div class="node w-step">Appeal filed &mdash; 6 to 8 week delay</div>
<div class="arrow"><div class="arrow-line red"></div><div class="arrow-head red"></div></div>
<div class="node w-outcome">Write-off or supply shipped at a loss</div>
</div>
</div>
<div class="divider"><div class="divider-label">vs</div></div>
<!-- WITH SIGNAL -->
<div class="col">
<div class="col-header with">With Signal</div>
<div class="flow">
<div class="node s-step">Patient flagged for CGM resupply</div>
<div class="arrow"><div class="arrow-line teal"></div><div class="arrow-head teal"></div></div>
<div class="node s-step">Staff uploads patient list CSV &mdash; Signal ingests in seconds</div>
<div class="arrow"><div class="arrow-line teal"></div><div class="arrow-head teal"></div></div>
<div class="node s-check">
Signal checks documentation status automatically
<div class="check-items">
<div class="check-item"><div class="dot"></div>Standard Written Order (SWO)</div>
<div class="check-item"><div class="dot"></div>Qualifying visit &mdash; within 6 months</div>
<div class="check-item"><div class="dot"></div>Prior Authorization status</div>
</div>
</div>
<div class="arrow"><div class="arrow-line teal"></div><div class="arrow-head teal"></div></div>
<div class="node s-gap">
Gaps flagged on prioritized worklist &mdash; before any claim is filed
<div class="gap-items">
<div class="gap-tag">&#9679; SWO needed</div>
<div class="gap-tag">&#9679; Visit overdue</div>
</div>
</div>
<div class="arrow"><div class="arrow-line teal"></div><div class="arrow-head teal"></div></div>
<div class="node s-step">Staff resolves gaps upstream &mdash; contacts prescriber, requests records</div>
<div class="arrow"><div class="arrow-line teal"></div><div class="arrow-head teal"></div></div>
<div class="node s-win">Clear to Ship &mdash; supply delivered on time</div>
</div>
</div>
</div>
<!-- Stats bar below both columns -->
<div class="stats-bar">
<div class="stat-section-label neg-label"><span>Problem</span></div>
<div class="stat-cell neg">
<div class="stat-num">1 in 3</div>
<div class="stat-lbl">CGM claims with a doc error<br><span style="font-size:8.5px;opacity:0.7">CERT 2019</span></div>
</div>
<div class="stat-div"></div>
<div class="stat-cell neg">
<div class="stat-num">~25%</div>
<div class="stat-lbl">Of CGM supplies shipped at a loss when docs fail</div>
</div>
<div class="stat-div"></div>
<div class="stat-cell neg">
<div class="stat-num">68 wks</div>
<div class="stat-lbl">Average denial recovery after appeal</div>
</div>
<div class="stat-section-label pos-label"><span>Signal</span></div>
<div class="stat-cell pos">
<div class="stat-num">Day 1</div>
<div class="stat-lbl">Gaps visible before claim is filed</div>
</div>
<div class="stat-div"></div>
<div class="stat-cell pos">
<div class="stat-num">$0</div>
<div class="stat-lbl">Claims filed with known documentation gaps</div>
</div>
</div>
</div>
<div class="footer">
<div class="footer-left">signal.sttilsolutions.com</div>
<div class="footer-right">Source: CERT 2019 &nbsp;&middot;&nbsp; &copy; 2026 STTIL Solutions LLC</div>
</div>
</body>
</html>