Fix report pagination and rebuild saved plan navigation
Test and deploy / test-and-deploy (push) Successful in 1m43s
Test and deploy / test-and-deploy (push) Successful in 1m43s
This commit is contained in:
1 parent
824a964f9d
commit
5f3a015ea2
20 files changed
+1480
-809
No files matched your search
+5
-362
@@ -64,8 +64,7 @@
|
||||
<nav class="section-nav" id="section-nav" aria-label="Plan sections">
|
||||
<a href="#sec-coffee">Plan</a>
|
||||
<a href="#sec-bean">Bean</a>
|
||||
<a href="#sec-machine">Machine</a>
|
||||
<a href="#sec-roastlog">Log</a>
|
||||
<a href="/roasts">Post-roast records</a>
|
||||
</nav>
|
||||
|
||||
<div class="header-actions header-tools">
|
||||
@@ -83,9 +82,7 @@
|
||||
⚙ Tools ▾
|
||||
</button>
|
||||
<div class="header-tools-group" id="header-tools-group">
|
||||
<button id="nav-plans" type="button" class="ghost-btn small">
|
||||
▤ Plans
|
||||
</button>
|
||||
<a id="nav-plans" href="/plans" class="ghost-btn small">▤ Your plans</a>
|
||||
<button id="nav-chat" type="button" class="ghost-btn small">
|
||||
✳ Ask the LLM
|
||||
</button>
|
||||
@@ -259,37 +256,7 @@
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<aside
|
||||
class="drawer hidden"
|
||||
id="panel-plans"
|
||||
aria-hidden="true"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="plans-title"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div class="drawer-head">
|
||||
<h3 id="plans-title">Your plans</h3>
|
||||
<button
|
||||
class="icon-btn"
|
||||
type="button"
|
||||
data-close-drawer
|
||||
aria-label="Close"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div class="drawer-body">
|
||||
<button id="btn-new-plan" type="button" class="primary-btn">
|
||||
New plan
|
||||
</button>
|
||||
<p class="drawer-result">
|
||||
Choose a plan to continue. Every edit is stored on this device first
|
||||
and then synced when online.
|
||||
</p>
|
||||
<ul class="plan-list" id="plan-list" aria-live="polite"></ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
<aside
|
||||
class="drawer hidden"
|
||||
@@ -591,7 +558,7 @@
|
||||
first-crack anchors is another valid time on the same
|
||||
clock. An average of two temperatures means nothing: first
|
||||
crack is a property of the chemistry, not a dial you set.
|
||||
</p>
|
||||
</p><div class="inventory-consume hidden" id="inventory-consume"><span id="inventory-consume-label"></span><button type="button" class="ghost-btn small" id="btn-consume">Draw from lot</button></div>
|
||||
<p>
|
||||
If one component is 60% or more of the batch, roast the
|
||||
whole batch as that coffee and let the rest ride along. If
|
||||
@@ -710,6 +677,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<label class="field">Development target (m:ss, optional override)<input class="field-input" name="4.4" placeholder="e.g. 1:15" /></label>
|
||||
<div class="field-grid">
|
||||
<label class="field" data-fid="3.2"
|
||||
><span class="field-label">Dev modifier</span
|
||||
@@ -862,332 +830,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel-card" id="sec-machine">
|
||||
<div class="panel-head"><h2>Machine Plan</h2></div>
|
||||
<div class="panel-body">
|
||||
<details class="why-panel" data-why="sec-machine">
|
||||
<summary>
|
||||
Why the rate of rise must fall, and never touch zero
|
||||
</summary>
|
||||
<p>
|
||||
A bean that is still gaining heat, but gaining it more
|
||||
slowly, is moving through its reactions in order. Two
|
||||
shapes break that. The crash: RoR falls off a cliff just
|
||||
after first crack, when the exotherm ends and an oversized
|
||||
heat cut lands at the same moment. The bake: RoR flattens
|
||||
toward zero, the bean sits at temperature without
|
||||
progressing, and the cup goes flat, papery and
|
||||
sweetness-free — nothing after the drop rescues a bake.
|
||||
</p>
|
||||
<p>
|
||||
So the rule is: decline steadily from the
|
||||
post-turning-point peak, through small frequent heat cuts
|
||||
rather than a few big ones, and stay ahead of the
|
||||
machine’s response delay — changes take time to affect the bean, so cut <em>before</em> the
|
||||
exotherm, gently. If a phase would need a rate outside the
|
||||
illustrative ranges to hit its milestone, the plan is not
|
||||
reachable — fix the ledger, not the roaster.
|
||||
</p>
|
||||
</details>
|
||||
<div class="subhead">Temperatures & rate-of-rise</div>
|
||||
<p class="field-note">Blank fields use an illustrative curve: charge 392°F, yellow 320°F, first crack 392°F. These are not preheat settings. First crack must be heard; enter your own probe readings to replace the illustration. Drop is derived from development time and a declining planned rise.</p>
|
||||
<div class="field-grid">
|
||||
<label class="field">Preheat setpoint<input class="field-input" name="preheat.tempC" placeholder="°F" /></label>
|
||||
<label class="field">Preheat time (min)<input class="field-input" name="preheat.minutes" /></label>
|
||||
<label class="field">Preheat fan (%)<input class="field-input" name="preheat.fanPct" /></label>
|
||||
<label class="field">Drum (%)<input class="field-input" name="preheat.drumPct" /></label>
|
||||
</div>
|
||||
<label class="field-label">Development target (m:ss, optional override)<input class="field-input" name="4.4" placeholder="e.g. 1:15" /></label>
|
||||
<div class="milestone-list">
|
||||
<div
|
||||
class="milestone-row band-row"
|
||||
data-band-lo="133"
|
||||
data-band-hi="195"
|
||||
>
|
||||
<div class="milestone-label">Charge</div>
|
||||
<output class="milestone-plan" data-out="t-charge"
|
||||
>0:00</output
|
||||
>
|
||||
<div class="band-track">
|
||||
<div class="band-range"></div>
|
||||
<div class="band-marker"></div>
|
||||
</div>
|
||||
<div class="unit-input sm">
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="temps.charge.tempC"
|
||||
placeholder="°C"
|
||||
aria-label="Charge planned temperature"
|
||||
/><span class="unit">°C</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="milestone-row band-row"
|
||||
data-band-lo="77"
|
||||
data-band-hi="100"
|
||||
>
|
||||
<div class="milestone-label">Turning point</div>
|
||||
<input
|
||||
class="field-input sm milestone-time"
|
||||
name="temps.tp.time"
|
||||
placeholder="m:ss"
|
||||
aria-label="Turning point planned time"
|
||||
/>
|
||||
<div class="band-track">
|
||||
<div class="band-range"></div>
|
||||
<div class="band-marker"></div>
|
||||
</div>
|
||||
<div class="unit-input sm">
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="temps.tp.tempC"
|
||||
placeholder="°C"
|
||||
aria-label="Turning point planned temperature"
|
||||
/><span class="unit">°C</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="milestone-row band-row"
|
||||
data-band-lo="148"
|
||||
data-band-hi="166"
|
||||
>
|
||||
<div class="milestone-label">Yellow</div>
|
||||
<output class="milestone-plan" data-out="t-yellow">—</output>
|
||||
<div class="band-track">
|
||||
<div class="band-range"></div>
|
||||
<div class="band-marker"></div>
|
||||
</div>
|
||||
<div class="unit-input sm">
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="temps.yellow.tempC"
|
||||
placeholder="°C"
|
||||
aria-label="Yellow planned temperature"
|
||||
/><span class="unit">°C</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="milestone-row band-row"
|
||||
data-band-lo="176"
|
||||
data-band-hi="187"
|
||||
>
|
||||
<div class="milestone-label">First crack</div>
|
||||
<output class="milestone-plan" data-out="t-fc">—</output>
|
||||
<div class="band-track">
|
||||
<div class="band-range"></div>
|
||||
<div class="band-marker"></div>
|
||||
</div>
|
||||
<div class="unit-input sm">
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="temps.fc.tempC"
|
||||
placeholder="°C"
|
||||
aria-label="First crack planned temperature"
|
||||
/><span class="unit">°C</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="milestone-row band-row"
|
||||
data-band-lo="183"
|
||||
data-band-hi="197"
|
||||
>
|
||||
<div class="milestone-label">Drop</div>
|
||||
<output class="milestone-plan" data-out="t-drop">—</output>
|
||||
<div class="band-track">
|
||||
<div class="band-range"></div>
|
||||
<div class="band-marker"></div>
|
||||
</div>
|
||||
<div class="unit-input sm">
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="temps.drop.tempC"
|
||||
placeholder="°C"
|
||||
aria-label="Drop planned temperature"
|
||||
/><span class="unit">°C</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="subhead">Actuator schedule (planned)</div>
|
||||
<p class="field-note">
|
||||
The timing of your first heat cut is the main first-crack
|
||||
lever — later cut, earlier crack. Say why you make each
|
||||
change; that's what makes this log readable next week.
|
||||
</p>
|
||||
<div class="actuator-timeline" id="actuator-timeline"></div>
|
||||
<button
|
||||
type="button"
|
||||
class="ghost-btn small"
|
||||
id="btn-add-actuator"
|
||||
>
|
||||
+ Add step
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="phase-divider" role="separator" aria-label="Roast day begins">
|
||||
<span class="phase-divider-label">Roast day</span>
|
||||
<span class="phase-divider-text"
|
||||
>Everything above is decided before you charge. Fill in from
|
||||
here down at the machine, then after cupping. Print takes the
|
||||
plan with you.</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<section class="panel-card phase-later" id="sec-roastlog">
|
||||
<div class="panel-head">
|
||||
<h2>Roast Log — Plan vs. Actual</h2>
|
||||
<span class="phase-chip">during the roast</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<details class="why-panel" data-why="sec-roastlog">
|
||||
<summary>Record what you observed, never what you planned</summary>
|
||||
<p>
|
||||
A planned milestone written into the log as though it
|
||||
happened destroys the only evidence you have. If you never
|
||||
actually heard first crack, write that down — "not heard,
|
||||
called at 8:10 by smell" is a useful record. "8:00"
|
||||
because that was the plan is worse than nothing, because
|
||||
next batch you will trust it. The plan column stays fixed
|
||||
beside your entries precisely so the gap is visible. The
|
||||
gap is the data.
|
||||
</p>
|
||||
</details>
|
||||
<div class="milestone-list">
|
||||
<div class="milestone-row log-row">
|
||||
<div class="milestone-label">Charge</div>
|
||||
<output class="milestone-plan" data-out="pa-charge"
|
||||
>0:00</output
|
||||
>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.charge.actualTime"
|
||||
placeholder="0:00"
|
||||
aria-label="Charge actual time"
|
||||
/>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.charge.actualBt"
|
||||
placeholder="°C"
|
||||
aria-label="Charge actual temperature"
|
||||
/>
|
||||
<input
|
||||
class="field-input note"
|
||||
name="planActual.charge.note"
|
||||
placeholder="Note"
|
||||
aria-label="Charge note"
|
||||
/>
|
||||
</div>
|
||||
<div class="milestone-row log-row">
|
||||
<div class="milestone-label">Turning point</div>
|
||||
<output class="milestone-plan" data-out="pa-tp">—</output>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.tp.actualTime"
|
||||
placeholder="0:00"
|
||||
aria-label="Turning point actual time"
|
||||
/>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.tp.actualBt"
|
||||
placeholder="°C"
|
||||
aria-label="Turning point actual temperature"
|
||||
/>
|
||||
<input
|
||||
class="field-input note"
|
||||
name="planActual.tp.note"
|
||||
placeholder="Note"
|
||||
aria-label="Turning point note"
|
||||
/>
|
||||
</div>
|
||||
<div class="milestone-row log-row">
|
||||
<div class="milestone-label">Yellow</div>
|
||||
<output class="milestone-plan" data-out="pa-yellow">—</output>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.yellow.actualTime"
|
||||
placeholder="0:00"
|
||||
aria-label="Yellow actual time"
|
||||
/>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.yellow.actualBt"
|
||||
placeholder="°C"
|
||||
aria-label="Yellow actual temperature"
|
||||
/>
|
||||
<input
|
||||
class="field-input note"
|
||||
name="planActual.yellow.note"
|
||||
placeholder="Note"
|
||||
aria-label="Yellow note"
|
||||
/>
|
||||
</div>
|
||||
<div class="milestone-row log-row">
|
||||
<div class="milestone-label">First crack</div>
|
||||
<output class="milestone-plan" data-out="pa-fc">—</output>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.fc.actualTime"
|
||||
placeholder="0:00"
|
||||
aria-label="First crack actual time"
|
||||
/>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.fc.actualBt"
|
||||
placeholder="°C"
|
||||
aria-label="First crack actual temperature"
|
||||
/>
|
||||
<input
|
||||
class="field-input note"
|
||||
name="planActual.fc.note"
|
||||
placeholder="Note"
|
||||
aria-label="First crack note"
|
||||
/>
|
||||
</div>
|
||||
<div class="milestone-row log-row">
|
||||
<div class="milestone-label">Drop</div>
|
||||
<output class="milestone-plan" data-out="pa-drop">—</output>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.drop.actualTime"
|
||||
placeholder="0:00"
|
||||
aria-label="Drop actual time"
|
||||
/>
|
||||
<input
|
||||
class="field-input sm"
|
||||
name="planActual.drop.actualBt"
|
||||
placeholder="°C"
|
||||
aria-label="Drop actual temperature"
|
||||
/>
|
||||
<input
|
||||
class="field-input note"
|
||||
name="planActual.drop.note"
|
||||
placeholder="Note"
|
||||
aria-label="Drop note"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inventory-consume hidden" id="inventory-consume">
|
||||
<span class="inventory-consume-label" id="inventory-consume-label"></span>
|
||||
<button type="button" class="ghost-btn small" id="btn-consume">
|
||||
Draw from lot
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px"
|
||||
>
|
||||
<button type="button" class="ghost-btn" id="btn-open-cupping">
|
||||
Open cupping session
|
||||
</button>
|
||||
<span class="field-note" id="cupping-link-note" style="margin:0"></span>
|
||||
</div>
|
||||
<p class="field-note">
|
||||
After the roast, upload the .alog on the
|
||||
<a href="/roasts">Roasts page</a> — weights, colour, cup notes,
|
||||
and "one change next batch" now live there with the LLM review.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user