zoe-pitches/focusflow/index.html

732 lines
38 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">
<meta name="description" content="FocusFlow — a live academic operating system for neurodivergent students. Business plan &amp; pitch.">
<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Ctext%20y='.9em'%20font-size='90'%3E%F0%9F%94%92%3C/text%3E%3C/svg%3E">
<title>FocusFlow — Business Plan</title>
<style>
:root {
--bg: #F6F7FB;
--surface: #FFFFFF;
--surface-2: #EEF0F8;
--ink: #14161D;
--muted: #565C6C;
--faint: #858B9C;
--line: #E2E4EE;
--line-strong: #CDD1E0;
--brand: #4B3FD1;
--brand-soft: #ECEAFB;
--brand-strong: #372BB0;
--accent: #E8920C;
--accent-soft: #FCEFD5;
--good: #1C9464;
--good-soft: #DDF1E8;
--warn: #C77A11;
--warn-soft: #FBEBCF;
--slate: #6A7080;
--slate-soft: #E7E9F0;
--shadow: 0 1px 2px rgba(20,22,29,.04), 0 8px 28px rgba(20,22,29,.06);
--shadow-lg: 0 2px 6px rgba(20,22,29,.06), 0 24px 60px rgba(30,25,90,.12);
--radius: 16px;
--maxw: 1120px;
--sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--mono: ui-monospace, "SF Mono", "JetBrains Mono", "Roboto Mono", Menlo, monospace;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #0B0D14;
--surface: #13161F;
--surface-2: #1A1E29;
--ink: #EEF0F7;
--muted: #9BA1B4;
--faint: #6E7488;
--line: #242938;
--line-strong: #333A4C;
--brand: #8F84F6;
--brand-soft: #1E2138;
--brand-strong: #ABA2F9;
--accent: #F4B24C;
--accent-soft: #2C2415;
--good: #37C08A;
--good-soft: #14261F;
--warn: #E0A63E;
--warn-soft: #2A2211;
--slate: #9198AC;
--slate-soft: #20242F;
--shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 30px rgba(0,0,0,.35);
--shadow-lg: 0 2px 8px rgba(0,0,0,.4), 0 30px 70px rgba(0,0,0,.5);
}
}
:root[data-theme="light"] {
--bg: #F6F7FB; --surface: #FFFFFF; --surface-2: #EEF0F8; --ink: #14161D;
--muted: #565C6C; --faint: #858B9C; --line: #E2E4EE; --line-strong: #CDD1E0;
--brand: #4B3FD1; --brand-soft: #ECEAFB; --brand-strong: #372BB0;
--accent: #E8920C; --accent-soft: #FCEFD5; --good: #1C9464; --good-soft: #DDF1E8;
--warn: #C77A11; --warn-soft: #FBEBCF; --slate: #6A7080; --slate-soft: #E7E9F0;
--shadow: 0 1px 2px rgba(20,22,29,.04), 0 8px 28px rgba(20,22,29,.06);
--shadow-lg: 0 2px 6px rgba(20,22,29,.06), 0 24px 60px rgba(30,25,90,.12);
}
:root[data-theme="dark"] {
--bg: #0B0D14; --surface: #13161F; --surface-2: #1A1E29; --ink: #EEF0F7;
--muted: #9BA1B4; --faint: #6E7488; --line: #242938; --line-strong: #333A4C;
--brand: #8F84F6; --brand-soft: #1E2138; --brand-strong: #ABA2F9;
--accent: #F4B24C; --accent-soft: #2C2415; --good: #37C08A; --good-soft: #14261F;
--warn: #E0A63E; --warn-soft: #2A2211; --slate: #9198AC; --slate-soft: #20242F;
--shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 30px rgba(0,0,0,.35);
--shadow-lg: 0 2px 8px rgba(0,0,0,.4), 0 30px 70px rgba(0,0,0,.5);
}
* { box-sizing: border-box; }
body {
margin: 0; background: var(--bg); color: var(--ink);
font-family: var(--sans); font-size: 17px; line-height: 1.6;
-webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
overflow-x: hidden;
}
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
section { padding: 76px 0; border-top: 1px solid var(--line); scroll-margin-top: 68px; }
section:first-of-type { border-top: none; }
/* ---------- sticky nav + reading progress ---------- */
.progress { position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 60;
background: linear-gradient(90deg, var(--brand), var(--accent)); }
.topnav { position: sticky; top: 0; z-index: 50;
background: color-mix(in srgb, var(--bg) 80%, transparent);
backdrop-filter: saturate(1.5) blur(14px); -webkit-backdrop-filter: saturate(1.5) blur(14px);
border-bottom: 1px solid var(--line); }
.topnav .in { max-width: var(--maxw); margin: 0 auto; padding: 11px 24px; display: flex; align-items: center; gap: 16px; }
.topnav .nb { display: flex; align-items: center; gap: 9px; font-weight: 720; font-size: 15px; letter-spacing: -0.01em; }
.topnav .nb .m { width: 22px; height: 22px; border-radius: 6px; flex: none;
background: linear-gradient(150deg, var(--brand), var(--brand-strong)); color: #fff;
display: grid; place-items: center; font-size: 12px; font-weight: 800; }
.topnav nav { margin-left: auto; display: flex; gap: 2px; }
.topnav nav a { font-family: var(--mono); font-size: 12px; letter-spacing: .02em; color: var(--muted);
text-decoration: none; padding: 6px 10px; border-radius: 7px; white-space: nowrap; transition: background .15s, color .15s; }
.topnav nav a:hover { color: var(--ink); background: var(--surface-2); }
.topnav .cta { font-family: var(--sans); font-size: 13px; font-weight: 620; color: #fff;
background: var(--brand); padding: 7px 13px; border-radius: 8px; text-decoration: none; white-space: nowrap; }
.topnav .cta:hover { background: var(--brand-strong); }
@media (max-width: 860px) { .topnav nav { display: none; } .topnav .nb { margin-right: auto; } }
h1, h2, h3 { text-wrap: balance; letter-spacing: -0.02em; line-height: 1.1; margin: 0; }
h2 { font-size: clamp(28px, 4vw, 40px); font-weight: 720; }
h3 { font-size: 20px; font-weight: 680; letter-spacing: -0.01em; }
p { margin: 0; }
a { color: var(--brand-strong); text-decoration-color: color-mix(in srgb, var(--brand) 40%, transparent); text-underline-offset: 3px; }
.eyebrow {
font-family: var(--mono); font-size: 12px; font-weight: 600;
letter-spacing: 0.16em; text-transform: uppercase; color: var(--brand);
}
.lede { font-size: clamp(18px, 2.2vw, 21px); color: var(--muted); max-width: 62ch; }
.kicker { color: var(--faint); font-size: 15px; }
/* ---------- Hero ---------- */
.hero {
position: relative; overflow: hidden;
padding: 84px 0 70px; border-top: none;
}
.hero::before {
content: ""; position: absolute; inset: -40% 30% auto -10%; height: 620px;
background: radial-gradient(52% 60% at 30% 30%, color-mix(in srgb, var(--brand) 26%, transparent), transparent 70%);
filter: blur(10px); pointer-events: none; z-index: 0;
}
.hero::after {
content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
background-size: 46px 46px;
-webkit-mask-image: radial-gradient(70% 60% at 72% 20%, #000, transparent 75%);
mask-image: radial-gradient(70% 60% at 72% 20%, #000, transparent 75%);
opacity: .5;
}
.hero .wrap { position: relative; z-index: 1; }
.brandrow { display: flex; align-items: center; gap: 12px; margin-bottom: 30px; }
.mark {
width: 34px; height: 34px; border-radius: 9px; flex: none;
background: linear-gradient(150deg, var(--brand), var(--brand-strong));
display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 17px;
box-shadow: 0 6px 16px color-mix(in srgb, var(--brand) 45%, transparent);
}
.brandname { font-weight: 720; letter-spacing: -0.01em; font-size: 18px; }
.brandname span { color: var(--faint); font-weight: 500; }
.hero h1 {
font-size: clamp(44px, 8.5vw, 88px); font-weight: 760; letter-spacing: -0.045em;
margin: 8px 0 0;
}
.hero h1 .accentword {
background: linear-gradient(100deg, var(--brand), var(--accent) 130%);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero .thesis { margin-top: 26px; font-size: clamp(19px, 2.4vw, 24px); line-height: 1.45; max-width: 42ch; color: var(--ink); font-weight: 450; }
.hero .thesis b { font-weight: 680; }
.herometa { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; align-items: center; }
.badge {
display: inline-flex; align-items: center; gap: 7px;
font-family: var(--mono); font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line-strong);
background: var(--surface); color: var(--muted);
}
.badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--good); box-shadow: 0 0 0 3px var(--good-soft); }
.badge.live { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, var(--line-strong)); }
/* fade-up */
.fu { opacity: 0; transform: translateY(14px); animation: fu .7s cubic-bezier(.2,.7,.2,1) forwards; }
.fu.d1{animation-delay:.05s}.fu.d2{animation-delay:.13s}.fu.d3{animation-delay:.22s}.fu.d4{animation-delay:.32s}.fu.d5{animation-delay:.42s}
@keyframes fu { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .fu { animation: none; opacity: 1; transform: none; } }
/* ---------- metric strip ---------- */
.metrics {
display: grid; grid-template-columns: repeat(5, 1fr); gap: 0;
margin-top: 48px; border: 1px solid var(--line); border-radius: var(--radius);
background: var(--surface); box-shadow: var(--shadow); overflow: hidden;
}
.metric { padding: 22px 20px; border-left: 1px solid var(--line); }
.metric:first-child { border-left: none; }
.metric .n { font-size: 30px; font-weight: 740; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.metric .n .u { color: var(--accent); }
.metric .l { font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); margin-top: 5px; line-height: 1.35; }
/* ---------- generic grid ---------- */
.grid { display: grid; gap: 18px; }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.card {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
padding: 24px; box-shadow: var(--shadow);
}
.card h3 { margin-bottom: 8px; }
.card p { color: var(--muted); font-size: 15.5px; }
.card .ic { font-size: 22px; margin-bottom: 12px; display: block; }
.tag {
display: inline-block; font-family: var(--mono); font-size: 11px; font-weight: 600;
letter-spacing: .04em; text-transform: uppercase; padding: 3px 8px; border-radius: 6px;
background: var(--brand-soft); color: var(--brand-strong); margin-right: 6px; margin-top: 10px;
}
.sechead { max-width: 60ch; margin-bottom: 40px; }
.sechead h2 { margin: 12px 0 14px; }
/* problem stat row */
.statband { display: grid; grid-template-columns: repeat(3,1fr); gap: 18px; margin-top: 8px; }
.statband .card { padding: 26px 24px; }
.statband .big { font-size: 42px; font-weight: 760; letter-spacing: -0.03em; color: var(--brand); font-variant-numeric: tabular-nums; }
.statband .cap { color: var(--muted); font-size: 15px; margin-top: 6px; }
/* why-list */
.why { display: grid; gap: 14px; }
.whyrow {
display: grid; grid-template-columns: 40px 1fr; gap: 18px; align-items: start;
padding: 22px 24px; background: var(--surface); border: 1px solid var(--line);
border-radius: var(--radius); box-shadow: var(--shadow);
}
.whyrow .num { font-family: var(--mono); font-weight: 700; font-size: 15px; color: var(--accent);
border: 1.5px solid var(--accent); border-radius: 9px; width: 40px; height: 40px; display: grid; place-items: center; }
.whyrow h3 { margin-bottom: 5px; }
.whyrow p { color: var(--muted); font-size: 15.5px; }
/* status dashboard table */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); background: var(--surface); }
table { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 15px; }
thead th {
text-align: left; font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em;
text-transform: uppercase; color: var(--faint); font-weight: 600;
padding: 15px 18px; border-bottom: 1px solid var(--line); background: var(--surface-2);
}
tbody td { padding: 15px 18px; border-bottom: 1px solid var(--line); vertical-align: top; }
tbody tr:last-child td { border-bottom: none; }
td.feat { font-weight: 600; white-space: nowrap; }
td.note { color: var(--muted); font-size: 14px; }
.pill {
display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono);
font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
padding: 4px 10px; border-radius: 999px; white-space: nowrap;
}
.pill .d { width: 7px; height: 7px; border-radius: 50%; }
.pill.live { background: var(--good-soft); color: var(--good); }
.pill.live .d { background: var(--good); }
.pill.test { background: var(--accent-soft); color: var(--warn); }
.pill.test .d { background: var(--warn); }
.pill.dark { background: var(--slate-soft); color: var(--slate); }
.pill.dark .d { background: var(--slate); }
/* revenue */
.rev { display: grid; grid-template-columns: repeat(3,1fr); gap: 18px; }
.rev .card { display: flex; flex-direction: column; }
.rev .price { font-size: 30px; font-weight: 740; letter-spacing: -0.02em; margin: 4px 0 2px; }
.rev .price small { font-size: 15px; color: var(--faint); font-weight: 500; }
.rev .stat { margin-top: auto; padding-top: 16px; }
.revpill { display:inline-block; font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing:.04em; text-transform: uppercase; padding: 3px 9px; border-radius: 6px; }
.revpill.now { background: var(--good-soft); color: var(--good); }
.revpill.built { background: var(--accent-soft); color: var(--warn); }
.revpill.next { background: var(--slate-soft); color: var(--slate); }
/* callout */
.callout {
border: 1px solid color-mix(in srgb, var(--brand) 35%, var(--line));
background: linear-gradient(180deg, var(--brand-soft), transparent);
border-radius: var(--radius); padding: 30px 28px;
}
.callout h3 { color: var(--brand-strong); }
.callout p { color: var(--muted); margin-top: 8px; max-width: 68ch; }
/* ask / next moves */
.moves { display: grid; gap: 14px; margin-top: 8px; }
.move { display: grid; grid-template-columns: auto 1fr auto; gap: 18px; align-items: center;
padding: 20px 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.move .rk { font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 5px 10px; border-radius: 7px; white-space: nowrap; }
.move.p1 .rk { background: var(--brand); color: #fff; }
.move.p2 .rk { background: var(--accent-soft); color: var(--warn); }
.move.p3 .rk { background: var(--slate-soft); color: var(--slate); }
.move h3 { font-size: 17px; margin-bottom: 3px; }
.move p { color: var(--muted); font-size: 14.5px; }
.move .eff { font-family: var(--mono); font-size: 12px; color: var(--faint); text-align: right; white-space: nowrap; }
/* gaps */
.gaps { display: grid; grid-template-columns: repeat(2,1fr); gap: 14px; }
.gap { display: grid; grid-template-columns: 26px 1fr; gap: 14px; padding: 18px 20px;
border: 1px solid var(--line); border-left: 3px solid var(--warn); border-radius: 12px; background: var(--surface); }
.gap .g { color: var(--warn); font-weight: 700; }
.gap b { font-weight: 650; }
.gap p { color: var(--muted); font-size: 14.5px; margin-top: 3px; }
footer { border-top: 1px solid var(--line); padding: 44px 0 60px; color: var(--faint); font-size: 14px; }
footer .wrap { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; align-items: center; }
.foot-mono { font-family: var(--mono); font-size: 12.5px; }
.stackline { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.chip { font-family: var(--mono); font-size: 12px; color: var(--muted); background: var(--surface-2);
border: 1px solid var(--line); padding: 5px 10px; border-radius: 7px; }
@media (max-width: 860px) {
.metrics { grid-template-columns: repeat(2, 1fr); }
.metric:nth-child(odd) { border-left: none; }
.metric { border-top: 1px solid var(--line); }
.metric:nth-child(1), .metric:nth-child(2) { border-top: none; }
.g2, .g3, .rev, .statband, .gaps { grid-template-columns: 1fr; }
.move { grid-template-columns: auto 1fr; }
.move .eff { grid-column: 2; text-align: left; }
}
@media (max-width: 520px) {
.metrics { grid-template-columns: 1fr; }
.metric { border-left: none; border-top: 1px solid var(--line); }
.metric:first-child { border-top: none; }
}
/* ---------- print / PDF ---------- */
@media print {
:root, :root[data-theme="dark"] {
--bg: #fff; --surface: #fff; --surface-2: #f4f5fa; --ink: #14161d;
--muted: #3d4250; --faint: #6a7080; --line: #dfe2ec; --line-strong: #c9cddb;
--brand: #3a2fb0; --brand-soft: #eeecfb; --brand-strong: #2c2288;
--accent: #a9690a; --accent-soft: #f8eed6; --good: #157a53; --good-soft: #e0f1e9;
--warn: #9a5f0d; --warn-soft: #f7ebd3; --slate: #565c6c; --slate-soft: #eaecf2;
--shadow: none; --shadow-lg: none;
}
* { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
.progress, .topnav { display: none !important; }
.hero::before, .hero::after { display: none !important; }
.fu { animation: none !important; opacity: 1 !important; transform: none !important; }
body { font-size: 11.5pt; background: #fff; }
section { padding: 20px 0; }
.hero { padding: 8px 0 16px; }
.hero h1 { font-size: 40pt; }
.card, .whyrow, .move, .gap, .callout, .rev .card, .statband .card, .metric, tr, thead {
break-inside: avoid; page-break-inside: avoid;
}
h2, h3 { page-break-after: avoid; }
.metrics, .tablewrap, .card { box-shadow: none; }
@page { margin: 13mm; }
}
</style>
</head>
<body>
<div class="progress" id="progress" aria-hidden="true"></div>
<div class="topnav">
<div class="in">
<span class="nb"><span class="m">F</span>FocusFlow</span>
<nav aria-label="Sections">
<a href="#problem">Problem</a>
<a href="#product">Product</a>
<a href="#wedge">Why it wins</a>
<a href="#status">Where we are</a>
<a href="#model">Model</a>
<a href="#ask">The ask</a>
</nav>
<a class="cta" href="https://focusflow-lock-in.ca" target="_blank" rel="noopener">Visit the app ↗</a>
</div>
</div>
<header class="hero">
<div class="wrap">
<div class="brandrow fu d1">
<div class="mark">F</div>
<div class="brandname">FocusFlow <span>· focusflow-lock-in.ca</span></div>
</div>
<div class="eyebrow fu d1">Business Plan &nbsp;·&nbsp; Confidential &nbsp;·&nbsp; August 2026</div>
<h1 class="fu d2">Study tools assume<br>focus. Ours <span class="accentword">builds&nbsp;it.</span></h1>
<p class="thesis fu d3">FocusFlow is an <b>academic operating system for neurodivergent students</b> — an AI study coach, an executive-function toolkit, and a safe tutor marketplace, in one app. It's not a prototype. It's <b>live in production</b> today.</p>
<div class="herometa fu d4">
<span class="badge live"><span class="dot"></span>Live in production</span>
<span class="badge">4 user roles</span>
<span class="badge">Freemium · revenue built-in</span>
<span class="badge">Solo-built in ~2.5 months</span>
</div>
<div class="metrics fu d5">
<div class="metric"><div class="n">49</div><div class="l">Data models<br>in production</div></div>
<div class="metric"><div class="n">51</div><div class="l">Product<br>screens</div></div>
<div class="metric"><div class="n">600<span class="u">+</span></div><div class="l">Automated tests<br>CI on real DB</div></div>
<div class="metric"><div class="n">~27<span class="u">k</span></div><div class="l">Lines of<br>app code</div></div>
<div class="metric"><div class="n">3</div><div class="l">Sided market<br>student·parent·tutor</div></div>
</div>
</div>
</header>
<!-- PROBLEM -->
<section id="problem">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">01 · The opening</div>
<h2>Mainstream study tools are built for students who are already organized.</h2>
<p class="lede">Notion, Quizlet and generic tutoring all assume the hard part is content. For a neurodivergent student, the hard part is <b>starting, staying on track, and self-regulating under pressure</b> — the executive-function layer no other tool owns.</p>
</div>
<div class="statband">
<div class="card">
<div class="big">~1 in 5</div>
<div class="cap">learners is neurodivergent — ADHD, autism, dyslexia, dysgraphia, executive-function and anxiety profiles. A large, underserved, growing market.</div>
</div>
<div class="card">
<div class="big">Fragmented</div>
<div class="cap">Today they duct-tape a planner, a flashcard app, a tutor, a calendar and a wellbeing app. Nothing talks to anything. Every seam is a place to fall off.</div>
</div>
<div class="card">
<div class="big">Bolt-on</div>
<div class="cap">"Accessibility" in existing tools is a settings afterthought. FocusFlow is built accessibility-first, with coaching that adapts to <em>how</em> a brain works.</div>
</div>
</div>
</div>
</section>
<!-- WHAT IT IS -->
<section id="product">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">02 · The product</div>
<h2>Nine things in one app — and they share a brain.</h2>
<p class="lede">Every module writes to the same student model, so the coach knows what's due, what's stressful, and what a student is weak on — and gets proactive before a test. This is the full surface, all shipped.</p>
</div>
<div class="grid g3">
<div class="card">
<span class="ic">🧭</span>
<h3>AI study coach</h3>
<p>A Socratic tutor that adapts to the student's mode (ADHD, autism, exec-function, exam-prep) and <b>refuses to hand over answers</b> — it teaches, it doesn't cheat. Safe for parents and schools.</p>
<span class="tag">3-provider engine</span>
</div>
<div class="card">
<span class="ic">🎯</span>
<h3>Executive-function toolkit</h3>
<p>Command Centre "mission control," AI task-breakdown into tiny steps, one-tap quick-capture brain dump, Pomodoro focus mode, a Calm/overwhelm flow, and a pre-exam "lockdown" mode.</p>
<span class="tag">Command Centre</span>
</div>
<div class="card">
<span class="ic">📚</span>
<h3>Complete study system</h3>
<p>Flashcard decks with spaced repetition, auto-generated quizzes & practice exams, printable guides, an <b>Explain-it-back</b> (Feynman) mode, and an OCR homework scanner.</p>
<span class="tag">SRS + Feynman</span>
</div>
<div class="card">
<span class="ic">📊</span>
<h3>Grades & GPA</h3>
<p>School → term → course → weighted categories, live GPA on an editable scale, and a "what do I need on the final?" calculator that solves the target for you.</p>
<span class="tag">Live GPA</span>
</div>
<div class="card">
<span class="ic">♿</span>
<h3>Accessibility engine</h3>
<p>Dyslexia-friendly typeface, text scaling, read-aloud TTS, voice dictation, reduced-motion, high-contrast and simplified layouts — applied app-wide from an onboarding neuro-profile.</p>
<span class="tag">First-class, not bolt-on</span>
</div>
<div class="card">
<span class="ic">🤝</span>
<h3>Tutor marketplace</h3>
<p>Two-sided marketplace with ID-verified tutors, transparent ranking, a full booking lifecycle, reviews, referrals, and moderation — <b>parent-mediated & safety-gated for under-18s</b>.</p>
<span class="tag">Payments built-in</span>
</div>
<div class="card">
<span class="ic">💛</span>
<h3>Life tracker</h3>
<p>Because school isn't the whole student: mood check-ins, a wellness log, to-dos, and a private budget (income & expenses). Feeds the coach — heavy stress dials back the workload.</p>
<span class="tag">Whole-student</span>
</div>
<div class="card">
<span class="ic">🔗</span>
<h3>"Sign in with FocusFlow"</h3>
<p>A Connect SDK any external study app can drop in. It streams a student's weak topics back in, so the coach nudges practice on exactly what they're struggling with — before the test.</p>
<span class="tag">Platform play</span>
</div>
<div class="card">
<span class="ic">🔔</span>
<h3>Proactive outreach</h3>
<p>Installable PWA with web push and email. Adaptive nudges fire at each student's <b>personal best focus hour</b>, and swap to urgent copy inside a pre-exam lockdown window.</p>
<span class="tag">Meets them where they are</span>
</div>
</div>
</div>
</section>
<!-- WHY IT WINS -->
<section id="wedge">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">03 · The wedge</div>
<h2>Why this wins — and why it's defensible.</h2>
</div>
<div class="why">
<div class="whyrow">
<div class="num">1</div>
<div>
<h3>Accessibility-first is the moat, not a feature</h3>
<p>Retrofitting real neuro-adaptive coaching onto a general study app is a rebuild, not a setting. FocusFlow's data model, coaching modes and UI were designed for this from line one — the incumbents can't fast-follow it cheaply.</p>
</div>
</div>
<div class="whyrow">
<div class="num">2</div>
<div>
<h3>The AI coach teaches instead of cheating</h3>
<p>It's Socratic by design and redirects answer-seeking. That's the exact property parents and schools require before they'll trust — and pay for — an AI in their child's education. It's a trust asset competitors giving away answers can't claim.</p>
</div>
</div>
<div class="whyrow">
<div class="num">3</div>
<div>
<h3>Near-zero cost to run, by architecture</h3>
<p>The default AI engine runs <b>locally and free</b> — no API bill, works offline. Paid providers are optional upgrades. Every premium capability (payments, video, alerting) is a dark "seam" flipped on by a single environment variable. Gross margin is structurally high from day one.</p>
</div>
</div>
<div class="whyrow">
<div class="num">4</div>
<div>
<h3>It owns the whole student, so it's sticky</h3>
<p>Grades, wellbeing, tutoring and daily planning in one place means switching cost compounds. A student's history, streaks, and weak-area signals live here — leaving means starting over.</p>
</div>
</div>
<div class="whyrow">
<div class="num">5</div>
<div>
<h3>The revenue engine is already built</h3>
<p>This isn't "we'll monetize later." A two-sided marketplace with real payments and a $5/mo tutor subscription is coded, tested, and already proven end-to-end against live Stripe — waiting on a go-live decision, not a build.</p>
</div>
</div>
</div>
</div>
</section>
<!-- WHERE WE ARE -->
<section id="status">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">04 · Where we are</div>
<h2>Production-grade today — with room to switch on.</h2>
<p class="lede">This reads like a funded team's Series-Seed codebase, built solo in about ten weeks. It's deployed, tested, and monitored. Several revenue and premium features are fully built and sitting <b>one credential away</b> from live.</p>
</div>
<h3 style="margin-bottom:16px;">Feature status</h3>
<div class="tablewrap">
<table>
<thead>
<tr><th>Capability</th><th>Status</th><th>What it takes to switch on</th></tr>
</thead>
<tbody>
<tr><td class="feat">Core app (coach, study, grades, life)</td><td><span class="pill live"><span class="d"></span>Live</span></td><td class="note">Running in production on the free local AI engine.</td></tr>
<tr><td class="feat">Accessibility engine</td><td><span class="pill live"><span class="d"></span>Live</span></td><td class="note">Shipped and applied app-wide.</td></tr>
<tr><td class="feat">Email + web-push notifications</td><td><span class="pill live"><span class="d"></span>Live</span></td><td class="note">Sending in production.</td></tr>
<tr><td class="feat">Premium AI (Gemini / Claude)</td><td><span class="pill live"><span class="d"></span>Live</span></td><td class="note">Wired; premium responses enabled via API key.</td></tr>
<tr><td class="feat">Tutor marketplace + payments</td><td><span class="pill test"><span class="d"></span>Test mode</span></td><td class="note">Proven end-to-end against live Stripe in <b>test mode</b>. Go-live = swap to live keys + onboard first tutors.</td></tr>
<tr><td class="feat">Live video tutoring (LiveKit)</td><td><span class="pill dark"><span class="d"></span>Built · dark</span></td><td class="note">Fully coded; needs LiveKit credentials (3 env vars).</td></tr>
<tr><td class="feat">Error alerting webhook</td><td><span class="pill dark"><span class="d"></span>Built · dark</span></td><td class="note">Sentry live; team alerts need one Slack/Discord URL.</td></tr>
</tbody>
</table>
</div>
<div class="grid g2" style="margin-top:22px;">
<div class="card">
<h3>Engineering maturity</h3>
<p style="margin-top:10px;">Not a weekend hack — this is disciplined, testable, deployable software.</p>
<div class="stackline">
<span class="chip">600+ tests</span>
<span class="chip">CI on real Postgres</span>
<span class="chip">PR-gated</span>
<span class="chip">33 tracked migrations</span>
<span class="chip">Sentry monitoring</span>
<span class="chip">371 commits</span>
<span class="chip">IDOR / auth tested</span>
</div>
</div>
<div class="card">
<h3>Modern, boring-in-a-good-way stack</h3>
<p style="margin-top:10px;">Current, mainstream, hireable-for technology — nothing exotic to maintain.</p>
<div class="stackline">
<span class="chip">Next.js 15</span>
<span class="chip">React 19</span>
<span class="chip">TypeScript</span>
<span class="chip">Postgres + Prisma</span>
<span class="chip">Tailwind v4</span>
<span class="chip">Stripe</span>
<span class="chip">LiveKit</span>
<span class="chip">Vercel</span>
</div>
</div>
</div>
</div>
</section>
<!-- BUSINESS MODEL -->
<section id="model">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">05 · How it makes money</div>
<h2>Free to land. Multiple ways to earn.</h2>
<p class="lede">The whole student experience is free — that's the growth engine. Revenue rides on the marketplace and premium tiers, and the plumbing for both is already in the codebase.</p>
</div>
<div class="rev">
<div class="card">
<span class="revpill now">Built · proven</span>
<div class="price">$5<small>/mo</small></div>
<h3>Tutor listing subscription</h3>
<p style="color:var(--muted);font-size:15px;margin-top:8px;">Verified tutors pay to appear in discovery. Coded, tested, and validated against live Stripe. Supply-side recurring revenue that scales with the tutor base.</p>
<div class="stat"><span class="chip">Stripe subscriptions + billing portal</span></div>
</div>
<div class="card">
<span class="revpill built">Seam built</span>
<div class="price">Premium<small> tier</small></div>
<h3>Student / family plan</h3>
<p style="color:var(--muted);font-size:15px;margin-top:8px;">A feature-gating billing seam already exists — every feature currently sits in the free tier. Flip advanced coaching, unlimited premium-AI, or family accounts into a paid plan with no rebuild.</p>
<div class="stat"><span class="chip">Entitlement gate ready</span></div>
</div>
<div class="card">
<span class="revpill next">Roadmap</span>
<div class="price">B2B<small> / schools</small></div>
<h3>Institutional licensing</h3>
<p style="color:var(--muted);font-size:15px;margin-top:8px;">Multi-role support (admin, teacher, class dashboards, moderation, audit logs) is already in place — the foundation for selling seats to schools, districts, and learning-support programs.</p>
<div class="stat"><span class="chip">Admin + classes shipped</span></div>
</div>
</div>
<div class="card" style="margin-top:18px;">
<div style="display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap;">
<h3>What the subscription line alone looks like</h3>
<span class="chip">Arithmetic · not a forecast</span>
</div>
<p style="color:var(--muted);font-size:15px;margin-top:8px;max-width:70ch;">Just $5/mo × paying tutors — <em>before</em> any premium student tier, marketplace take-rate, or B2B seats. It shows the shape of the recurring line once supply is on the platform.</p>
<div class="tablewrap" style="margin-top:16px;">
<table style="font-variant-numeric:tabular-nums;">
<thead><tr><th>Paying tutors</th><th>Monthly recurring</th><th>Annual recurring</th></tr></thead>
<tbody>
<tr><td class="feat">100</td><td>$500</td><td>$6,000</td></tr>
<tr><td class="feat">500</td><td>$2,500</td><td>$30,000</td></tr>
<tr><td class="feat">1,000</td><td>$5,000</td><td>$60,000</td></tr>
<tr><td class="feat">5,000</td><td>$25,000</td><td>$300,000</td></tr>
</tbody>
</table>
</div>
</div>
<div class="callout" style="margin-top:18px;">
<h3>The margin story</h3>
<p>Because the default AI runs locally and free, and every paid dependency is optional, the cost to serve a free user is essentially hosting. Revenue features add cost only when they're already earning. That's a rare position: <b>we can grow the free base aggressively without growing the bill.</b></p>
</div>
</div>
</section>
<!-- WHAT IT TAKES -->
<section id="gaps">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">06 · Straight talk</div>
<h2>What it'll take to scale — the honest gaps.</h2>
<p class="lede">The product risk is largely retired. The remaining work is go-to-market and operational, and it's normal for this stage.</p>
</div>
<div class="gaps">
<div class="gap"><div class="g">→</div><div><b>No live users yet</b><p>The marketplace is pre-launch. We have a proven product but zero usage/retention data. First priority is a real pilot cohort to generate evidence.</p></div></div>
<div class="gap"><div class="g">→</div><div><b>Payments are in test mode</b><p>Flipping to real charges is a config + compliance step (live Stripe keys, business verification), not a build.</p></div></div>
<div class="gap"><div class="g">→</div><div><b>Single-builder bus factor</b><p>One person built all of this. To scale reliably it needs a small team — the clean, tested, documented codebase makes onboarding realistic.</p></div></div>
<div class="gap"><div class="g">→</div><div><b>Hosted on a free tier</b><p>Currently on Vercel's Hobby plan (crons worked around via GitHub Actions). A modest infra spend unlocks headroom for real traffic.</p></div></div>
</div>
</div>
</section>
<!-- THE ASK -->
<section id="ask">
<div class="wrap">
<div class="sechead">
<div class="eyebrow">07 · The ask</div>
<h2>Three moves, in priority order.</h2>
<p class="lede">The product is done enough to test with real students <em>this term</em>. My recommendation is to prove demand before spending on scale.</p>
</div>
<div class="moves">
<div class="move p1">
<span class="rk">Do first</span>
<div>
<h3>Run a small pilot with real students</h3>
<p>Recruit 15–30 students (a class, a tutoring group, a support program). Turn on premium AI, watch usage and retention, and gather testimonials. Near-zero cost; produces the evidence every later decision needs.</p>
</div>
<div class="eff">~2 weeks<br>to stand up</div>
</div>
<div class="move p2">
<span class="rk">Then</span>
<div>
<h3>Flip the marketplace live</h3>
<p>Swap Stripe to live mode, onboard a first handful of verified tutors, and switch on LiveKit video. Turns a built feature into an actual revenue line. Blocked only on a go/no-go and business verification.</p>
</div>
<div class="eff">Days of<br>config</div>
</div>
<div class="move p3">
<span class="rk">To scale</span>
<div>
<h3>Back it: a small team + infra budget</h3>
<p>With pilot evidence in hand, invest in a second engineer, a modest hosting/infra tier, and a focused go-to-market motion (schools & learning-support orgs). Retire the bus factor; open the B2B channel.</p>
</div>
<div class="eff">Post-pilot<br>decision</div>
</div>
</div>
<div class="callout" style="margin-top:26px;">
<h3>Bottom line</h3>
<p>We have a live, production-grade, accessibility-first learning platform with a built-in revenue engine — created for a fraction of what it would normally cost. The expensive, risky part (building it) is done. What's left is the fun part: <b>putting it in front of students and turning the revenue on.</b></p>
</div>
</div>
</section>
<footer>
<div class="wrap">
<div class="foot-mono">FocusFlow — focusflow-lock-in.ca · Live in production</div>
<div class="foot-mono">Confidential business plan · Prepared August 2026</div>
</div>
</footer>
<script>
(function () {
var bar = document.getElementById('progress');
if (!bar) return;
var ticking = false;
function update() {
var el = document.scrollingElement || document.documentElement;
var max = el.scrollHeight - el.clientHeight;
var p = max > 0 ? el.scrollTop / max : 0;
bar.style.width = (Math.max(0, Math.min(1, p)) * 100).toFixed(2) + '%';
ticking = false;
}
function onScroll() { if (!ticking) { ticking = true; requestAnimationFrame(update); } }
document.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', update);
update();
})();
</script>
</body>
</html>