Add green-bean inventory and cupping features

Ports inventory management and SCA-style cupping scoring from
hope_roaster: lot tracking with audit-logged consumption, cupping
sessions with server-authoritative scoring and a live radar chart,
and links from the planner (draw-from-lot, open-cupping-session).

Also fixes the Blend/Single-origin toggle layout, replaces tooltips
with an in-context "why" teaching layer, and stages the planner UI
into pre-roast vs. post-roast phases.
This commit is contained in:
2026-07-30 14:47:15 -04:00
parent 9f0a3dbc74
commit 59645e59b5
43 changed files with 7582 additions and 566 deletions
+148 -43
View File
@@ -3,51 +3,156 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Roast Planner</title>
<title>Roast Planner — Plan the roast before you light the burner</title>
<meta
name="description"
content="A structured worksheet that computes first crack, development, and drop from your bean — then keeps the plan next to what actually happened."
/>
<link rel="stylesheet" href="/app.css" />
<meta name="theme-color" content="#A8481A" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<meta name="theme-color" content="#2A1D16" />
</head>
<body>
<main class="auth-page">
<section class="panel-card auth-card">
<h1>Roast Planner</h1>
<p>Build, save, and revisit your coffee roast plans.</p>
<div id="message" role="status"></div>
<form id="auth-form">
<label
>Email
<input
class="field-input"
required
type="email"
name="email"
autocomplete="email" /></label
><label
>Password
<input
class="field-input"
required
type="password"
minlength="12"
name="password"
autocomplete="current-password" /></label
><label
>Initial admin setup token (first account only)
<input
class="field-input"
type="password"
name="setupToken"
autocomplete="off" /></label
><button class="primary-btn" type="submit">Log in</button
><button class="ghost-btn" type="button" id="signup">
Create account
</button>
</form>
<p class="muted">
Accounts require a password of at least 12 characters.
</p>
</section>
</main>
<script type="module" src="/js/landing.js"></script>
<header class="marketing-header">
<div class="brand">
<span class="brand-mark" aria-hidden="true"></span>
<span>Roast Planner</span>
</div>
<nav>
<a class="ghost-btn" href="/login">Log in</a>
<a class="primary-btn" href="/signup">Get started</a>
</nav>
</header>
<section class="hero">
<div class="hero-inner">
<div>
<h1>Plan the roast before you light the burner.</h1>
<p class="lede">
A structured worksheet that computes first crack, development, and
drop from your bean — then keeps the plan next to what actually
happened.
</p>
<div class="hero-ctas">
<a class="primary-btn" href="/signup">Start planning — free</a>
<a class="ghost-btn" href="#how-it-works">See how it works</a>
</div>
</div>
<div class="hero-visual" aria-hidden="true">
<div class="dock-card-head">
<h2>Time Ledger</h2>
</div>
<div class="ledger-row">
<span class="l-fid">1.4</span
><span class="l-label">First crack anchor</span
><span class="l-val">9:30</span>
</div>
<div class="ledger-row">
<span class="l-fid">5.6</span
><span class="l-label">Bean-condition refinement</span
><span class="l-val">+0:10</span>
</div>
<div class="ledger-row">
<span class="l-fid">4.3</span
><span class="l-label">Development base</span
><span class="l-val">2:15</span>
</div>
<div class="ledger-total drop">
<span>Drop time</span><output>11:55</output>
</div>
</div>
</div>
</section>
<section class="marketing-section" id="how-it-works">
<h2>Built around the worksheet, not a generic form</h2>
<p class="section-lede">
Every field ties back to the same time-ledger math professional
roasters already use on paper — now it computes itself.
</p>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon" aria-hidden="true"></div>
<h3>The Time Ledger</h3>
<p>
Anchor first crack by cultivar, then let refinements, bean
condition, and batch size sum into a plan you can defend.
</p>
</div>
<div class="feature-card">
<div class="feature-icon" aria-hidden="true"></div>
<h3>Sanity checks</h3>
<p>
Drying, Maillard, and development ratios validated against known
bands before you roast.
</p>
</div>
<div class="feature-card">
<div class="feature-icon" aria-hidden="true"></div>
<h3>Plan vs. actual</h3>
<p>
Log milestones at the machine, attach an Artisan .alog reference
curve, and see plan against reality.
</p>
</div>
</div>
<div class="feature-row">
<div class="feature-row-item">
<span class="feature-icon" aria-hidden="true"></span
><span>Prefill straight from a bean product page URL</span>
</div>
<div class="feature-row-item">
<span class="feature-icon" aria-hidden="true">🖶</span
><span>Printable two-page worksheet, faithful to the original</span>
</div>
<div class="feature-row-item">
<span class="feature-icon" aria-hidden="true"></span
><span>Installable PWA that keeps working offline</span>
</div>
<div class="feature-row-item">
<span class="feature-icon" aria-hidden="true"></span
><span>Autosave with sync the moment you're back online</span>
</div>
</div>
</section>
<section class="marketing-section">
<h2>Three steps, every roast</h2>
<div class="steps-row">
<div class="step-item">
<h3>Describe the coffee</h3>
<p>
Cultivar, process, bean condition — the worksheet pulls in the
right reference numbers automatically.
</p>
</div>
<div class="step-item">
<h3>Review ledger &amp; checks</h3>
<p>
Watch first crack, development, and drop compute live, with every
ratio checked against known-good bands.
</p>
</div>
<div class="step-item">
<h3>Roast and record</h3>
<p>
Log milestones as you go, then compare against an Artisan
reference curve after the roast.
</p>
</div>
</div>
</section>
<section class="cta-band">
<h2>Plan your next roast properly.</h2>
<a class="primary-btn" href="/signup">Get started — it's free</a>
</section>
<footer class="marketing-footer">
<span>© Roast Planner</span>
<span
><a href="/login">Log in</a><a href="/signup">Sign up</a></span
>
</footer>
</body>
</html>