Improve readability and add simple/pro UX mode

This commit is contained in:
Hermes Agent
2026-07-25 14:35:06 +00:00
parent 5ea820c3ef
commit 60d6361ecf
+102 -32
View File
@@ -9,16 +9,17 @@
<style> <style>
:root{ :root{
--bg:#07080B; --bg:#07080B;
--panel:#0E1117; --panel:#10151F;
--panel-2:#121722; --panel-2:#151C29;
--line:#1B2430; --line:#263241;
--line-hot:#243447; --line-hot:#34475C;
--cyan:#00F0FF; --cyan:#00F0FF;
--magenta:#FF2D78; --magenta:#FF2D78;
--amber:#FFB000; --amber:#FFB000;
--lime:#8CFF3B; --lime:#8CFF3B;
--txt:#C9D6E2; --txt:#E2ECF5;
--dim:#6E7B8B; --dim:#A5B4C5;
--muted:#8796A8;
--mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
--r:2px; --r:2px;
} }
@@ -48,8 +49,8 @@ header{padding:28px 0 18px;border-bottom:1px solid var(--line);margin-bottom:20p
text-shadow:0 0 18px rgba(0,240,255,.35); text-shadow:0 0 18px rgba(0,240,255,.35);
} }
.brand em{font-style:normal;color:var(--magenta);text-shadow:0 0 18px rgba(255,45,120,.45)} .brand em{font-style:normal;color:var(--magenta);text-shadow:0 0 18px rgba(255,45,120,.45)}
.tag{color:var(--dim);font-size:11px;letter-spacing:.22em;text-transform:uppercase;margin:10px 0 0} .tag{color:var(--muted);font-size:11px;letter-spacing:.22em;text-transform:uppercase;margin:10px 0 0}
.status{display:flex;gap:8px;align-items:center;margin-top:12px;font-size:11px;letter-spacing:.14em;color:var(--dim);text-transform:uppercase} .status{display:flex;gap:8px;align-items:center;margin-top:12px;font-size:11px;letter-spacing:.14em;color:var(--muted);text-transform:uppercase}
.dot{width:7px;height:7px;background:var(--lime);border-radius:50%;box-shadow:0 0 10px var(--lime);animation:pulse 2.4s infinite} .dot{width:7px;height:7px;background:var(--lime);border-radius:50%;box-shadow:0 0 10px var(--lime);animation:pulse 2.4s infinite}
@keyframes pulse{50%{opacity:.25}} @keyframes pulse{50%{opacity:.25}}
@@ -79,7 +80,7 @@ header{padding:28px 0 18px;border-bottom:1px solid var(--line);margin-bottom:20p
.chips{display:flex;flex-wrap:wrap;gap:6px} .chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{ .chip{
font:inherit;font-size:12px; font:inherit;font-size:12px;
background:transparent;color:var(--dim); background:rgba(255,255,255,.015);color:#B4C3D3;
border:1px solid var(--line-hot);border-radius:var(--r); border:1px solid var(--line-hot);border-radius:var(--r);
padding:7px 11px;cursor:pointer;letter-spacing:.06em; padding:7px 11px;cursor:pointer;letter-spacing:.06em;
transition:.15s; transition:.15s;
@@ -90,11 +91,38 @@ header{padding:28px 0 18px;border-bottom:1px solid var(--line);margin-bottom:20p
box-shadow:0 0 16px rgba(0,240,255,.35);font-weight:700; box-shadow:0 0 16px rgba(0,240,255,.35);font-weight:700;
} }
/* ---------- UX-Modus & Schnellstart ---------- */
.quick-summary{
position:sticky;top:0;z-index:20;
display:flex;gap:8px;overflow:auto;align-items:center;
margin:0 -14px 14px;padding:8px 14px;
background:rgba(7,8,11,.92);backdrop-filter:blur(8px);
border-bottom:1px solid var(--line-hot);
scrollbar-width:none;
}
.quick-summary::-webkit-scrollbar{display:none}
.quick-summary span{
white-space:nowrap;border:1px solid var(--line-hot);border-radius:var(--r);
background:#0A0E15;color:var(--txt);padding:6px 9px;font-size:12px;
font-variant-numeric:tabular-nums;
}
.quick-summary b{color:var(--cyan);font-weight:700}
body[data-ux="simple"] .advanced-only{display:none!important}
body[data-ux="simple"] .pro-only-note{display:block}
.pro-only-note{display:none}
.help{
margin-left:6px;width:18px;height:18px;border:1px solid var(--line-hot);border-radius:50%;
background:#0A0E15;color:var(--cyan);font:inherit;font-size:11px;line-height:16px;
display:inline-flex;align-items:center;justify-content:center;cursor:help;padding:0;
}
.warn b{color:#fff;font-weight:700}
/* ---------- Controls ---------- */ /* ---------- Controls ---------- */
.ctl{display:block;margin:15px 0 0} .ctl{display:block;margin:15px 0 0}
.ctl:first-of-type{margin-top:0} .ctl:first-of-type{margin-top:0}
.ctl-top{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:5px} .ctl-top{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:5px}
.ctl-l{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim)} .ctl-l{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.ctl-v{font-size:17px;color:var(--cyan);font-weight:700;text-shadow:0 0 12px rgba(0,240,255,.3);font-variant-numeric:tabular-nums} .ctl-v{font-size:17px;color:var(--cyan);font-weight:700;text-shadow:0 0 12px rgba(0,240,255,.3);font-variant-numeric:tabular-nums}
.ctl-v small{color:var(--dim);font-size:11px;font-weight:400;letter-spacing:.1em;text-shadow:none} .ctl-v small{color:var(--dim);font-size:11px;font-weight:400;letter-spacing:.1em;text-shadow:none}
input[type=range]{ input[type=range]{
@@ -112,7 +140,12 @@ input[type=range]::-moz-range-thumb{
} }
input[type=range]:focus-visible::-webkit-slider-thumb{outline:2px solid var(--magenta);outline-offset:2px} input[type=range]:focus-visible::-webkit-slider-thumb{outline:2px solid var(--magenta);outline-offset:2px}
.row{display:grid;grid-template-columns:1fr 1fr;gap:14px} .row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:520px){.row{grid-template-columns:1fr}} @media(max-width:520px){.row{grid-template-columns:1fr}
body{font-size:16px}
.ctl-v{font-size:19px}
.chip{font-size:13px;padding:9px 12px}
.panel{padding:18px 15px 20px}
}
select,input[type=number],input[type=datetime-local]{ select,input[type=number],input[type=datetime-local]{
font:inherit;font-size:14px;width:100%; font:inherit;font-size:14px;width:100%;
@@ -138,7 +171,7 @@ select:focus,input:focus{outline:2px solid var(--cyan);outline-offset:1px}
.badge{ .badge{
font-size:10.5px;letter-spacing:.12em;text-transform:uppercase; font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
border:1px solid var(--line-hot);border-radius:var(--r); border:1px solid var(--line-hot);border-radius:var(--r);
padding:4px 8px;color:var(--dim);background:#0A0E15 padding:4px 8px;color:var(--muted);background:#0A0E15
} }
.badge b{color:var(--txt);font-weight:700} .badge b{color:var(--txt);font-weight:700}
.note{font-size:12px;color:var(--dim);margin-top:10px;line-height:1.5} .note{font-size:12px;color:var(--dim);margin-top:10px;line-height:1.5}
@@ -158,8 +191,8 @@ select:focus,input:focus{outline:2px solid var(--cyan);outline-offset:1px}
.sub:first-child{margin-top:0} .sub:first-child{margin-top:0}
table{width:100%;border-collapse:collapse} table{width:100%;border-collapse:collapse}
td{padding:8px 0;border-bottom:1px dotted var(--line-hot);vertical-align:baseline} td{padding:8px 0;border-bottom:1px dotted var(--line-hot);vertical-align:baseline}
td.n{text-align:right;font-variant-numeric:tabular-nums;font-weight:700;color:#EAF6FF;white-space:nowrap} td.n{text-align:right;font-variant-numeric:tabular-nums;font-weight:700;color:#F3FAFF;white-space:nowrap}
td.p{text-align:right;width:62px;color:var(--dim);font-size:12px;font-variant-numeric:tabular-nums} td.p{text-align:right;width:62px;color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
tr.tot td{border-bottom:0;border-top:1px solid var(--line-hot);padding-top:11px;color:var(--cyan)} tr.tot td{border-bottom:0;border-top:1px solid var(--line-hot);padding-top:11px;color:var(--cyan)}
tr.tot td.n{color:var(--cyan);text-shadow:0 0 12px rgba(0,240,255,.3);font-size:17px} tr.tot td.n{color:var(--cyan);text-shadow:0 0 12px rgba(0,240,255,.3);font-size:17px}
.hero{ .hero{
@@ -186,7 +219,7 @@ tr.tot td.n{color:var(--cyan);text-shadow:0 0 12px rgba(0,240,255,.3);font-size:
.tl .t{font-size:17px;font-weight:700;color:var(--cyan);font-variant-numeric:tabular-nums;text-shadow:0 0 12px rgba(0,240,255,.25)} .tl .t{font-size:17px;font-weight:700;color:var(--cyan);font-variant-numeric:tabular-nums;text-shadow:0 0 12px rgba(0,240,255,.25)}
.tl .t em{font-style:normal;font-size:11px;letter-spacing:.14em;color:var(--dim);margin-left:8px;text-transform:uppercase;text-shadow:none} .tl .t em{font-style:normal;font-size:11px;letter-spacing:.14em;color:var(--dim);margin-left:8px;text-transform:uppercase;text-shadow:none}
.tl .a{color:#EAF6FF;font-size:14px;margin-top:1px} .tl .a{color:#EAF6FF;font-size:14px;margin-top:1px}
.tl .d{color:var(--dim);font-size:12px;margin-top:2px;line-height:1.45} .tl .d{color:var(--muted);font-size:12px;margin-top:2px;line-height:1.45}
.tl li.bake .t{color:var(--amber);text-shadow:0 0 12px rgba(255,176,0,.3)} .tl li.bake .t{color:var(--amber);text-shadow:0 0 12px rgba(255,176,0,.3)}
.countdown{ .countdown{
border:1px solid var(--magenta);background:rgba(255,45,120,.07); border:1px solid var(--magenta);background:rgba(255,45,120,.07);
@@ -204,7 +237,7 @@ tr.tot td.n{color:var(--cyan);text-shadow:0 0 12px rgba(0,240,255,.3);font-size:
.btn:hover{border-color:var(--cyan);color:var(--cyan)} .btn:hover{border-color:var(--cyan);color:var(--cyan)}
.btn.pri{background:var(--magenta);border-color:var(--magenta);color:#fff;font-weight:700} .btn.pri{background:var(--magenta);border-color:var(--magenta);color:#fff;font-weight:700}
.btn.pri:hover{box-shadow:0 0 20px rgba(255,45,120,.5);color:#fff} .btn.pri:hover{box-shadow:0 0 20px rgba(255,45,120,.5);color:#fff}
footer{color:var(--dim);font-size:11.5px;line-height:1.6;margin-top:22px;border-top:1px solid var(--line);padding-top:16px} footer{color:var(--muted);font-size:11.5px;line-height:1.6;margin-top:22px;border-top:1px solid var(--line);padding-top:16px}
footer b{color:var(--txt)} footer b{color:var(--txt)}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}} @media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
@@ -256,6 +289,22 @@ footer b{color:var(--txt)}
<div class="status"><span class="dot"></span><span id="statusline">System bereit</span></div> <div class="status"><span class="dot"></span><span id="statusline">System bereit</span></div>
</header> </header>
<div class="quick-summary noprint" id="quickSummary" aria-label="Kurzüberblick"></div>
<section class="panel noprint">
<p class="ph"><b>00 // Schnellstart</b><span>Einfach oder Profi</span></p>
<div class="ctl">
<div class="ctl-top"><span class="ctl-l">Ansicht</span></div>
<div class="chips" id="uxModes" role="group" aria-label="Ansicht"></div>
<p class="note">Einfach zeigt nur die wichtigsten Schritte. Profi blendet alle Stellschrauben ein.</p>
</div>
<label class="ctl">
<div class="ctl-top"><span class="ctl-l">Pizza fertig am</span></div>
<input type="datetime-local" id="bakeAtQuick">
</label>
<p class="note pro-only-note">Profi-Werte wie Hydration, Gare und Vorteig laufen mit sinnvollen Defaults im Hintergrund. Wechsel auf „Profi“, wenn du sie anpassen möchtest.</p>
</section>
<!-- CHARGE --> <!-- CHARGE -->
<section class="panel noprint"> <section class="panel noprint">
<p class="ph"><b>01 // Charge</b><span id="doughsum"></span></p> <p class="ph"><b>01 // Charge</b><span id="doughsum"></span></p>
@@ -316,7 +365,7 @@ footer b{color:var(--txt)}
</section> </section>
<!-- REZEPTUR --> <!-- REZEPTUR -->
<section class="panel noprint"> <section class="panel noprint advanced-only">
<p class="ph"><b>03 // Rezeptur</b><span>Bäckerprozent</span></p> <p class="ph"><b>03 // Rezeptur</b><span>Bäckerprozent</span></p>
<label class="ctl"> <label class="ctl">
<div class="ctl-top"><span class="ctl-l">Hydration</span><span class="ctl-v" id="v-hyd"></span></div> <div class="ctl-top"><span class="ctl-l">Hydration</span><span class="ctl-v" id="v-hyd"></span></div>
@@ -343,7 +392,7 @@ footer b{color:var(--txt)}
</section> </section>
<!-- GARE --> <!-- GARE -->
<section class="panel noprint"> <section class="panel noprint advanced-only">
<p class="ph"><b>04 // Gare</b><span id="fermsum"></span></p> <p class="ph"><b>04 // Gare</b><span id="fermsum"></span></p>
<div class="ctl"> <div class="ctl">
@@ -385,7 +434,7 @@ footer b{color:var(--txt)}
</section> </section>
<!-- VORTEIG --> <!-- VORTEIG -->
<section class="panel noprint"> <section class="panel noprint advanced-only">
<p class="ph"><b>05 // Vorteig</b><span id="pfsum"></span></p> <p class="ph"><b>05 // Vorteig</b><span id="pfsum"></span></p>
<div class="chips" id="pfTypes" role="group" aria-label="Vorteig"></div> <div class="chips" id="pfTypes" role="group" aria-label="Vorteig"></div>
<div id="pfBox" hidden> <div id="pfBox" hidden>
@@ -423,7 +472,7 @@ footer b{color:var(--txt)}
<!-- ZEITPLAN --> <!-- ZEITPLAN -->
<section class="panel"> <section class="panel">
<p class="ph"><b>07 // Zeitplan</b><span>rückwärts ab Backzeit</span></p> <p class="ph"><b>07 // Zeitplan</b><span>rückwärts ab Backzeit</span></p>
<label class="ctl noprint" style="margin-bottom:16px"> <label class="ctl noprint advanced-only" style="margin-bottom:16px">
<div class="ctl-top"><span class="ctl-l">Pizza fertig am</span></div> <div class="ctl-top"><span class="ctl-l">Pizza fertig am</span></div>
<input type="datetime-local" id="bakeAt"> <input type="datetime-local" id="bakeAt">
</label> </label>
@@ -434,8 +483,8 @@ footer b{color:var(--txt)}
<div id="printfoot" class="printonly"></div> <div id="printfoot" class="printonly"></div>
<div class="actions noprint"> <div class="actions noprint">
<button type="button" class="btn pri" id="share">Rezept-Link kopieren</button> <button type="button" class="btn pri" id="share">Rezept teilen</button>
<button type="button" class="btn" id="pdf">Als PDF speichern</button> <button type="button" class="btn" id="pdf">Druck/PDF</button>
<button type="button" class="btn" id="copyTxt">Als Text kopieren</button> <button type="button" class="btn" id="copyTxt">Als Text kopieren</button>
<button type="button" class="btn" id="reset">Zurücksetzen</button> <button type="button" class="btn" id="reset">Zurücksetzen</button>
</div> </div>
@@ -525,13 +574,14 @@ const STAGLIO = {
const MODES = {w:"Ballgewicht", d:"Durchmesser", p:"Blech L×B"}; const MODES = {w:"Ballgewicht", d:"Durchmesser", p:"Blech L×B"};
const YEASTS = {fresh:"Frischhefe", dry:"Trockenhefe", sour:"Sauerteig"}; const YEASTS = {fresh:"Frischhefe", dry:"Trockenhefe", sour:"Sauerteig"};
const PFS = {none:"Ohne (Direktteig)", poolish:"Poolish", biga:"Biga"}; const PFS = {none:"Ohne (Direktteig)", poolish:"Poolish", biga:"Biga"};
const UX_MODES = {simple:"Einfach", pro:"Profi"};
const PF_HYD = {poolish:1.0, biga:0.45}; const PF_HYD = {poolish:1.0, biga:0.45};
/* ============================================================ /* ============================================================
STATE STATE
============================================================ */ ============================================================ */
const DEFAULT = { const DEFAULT = {
style:"napo", flour:"cap-pizzeria", balls:4, mode:"w", style:"napo", flour:"cap-pizzeria", balls:4, mode:"w", uxMode:"simple",
ball:250, dia:30, panL:40, panW:30, ball:250, dia:30, panL:40, panW:30,
hyd:62, salt:2.8, oil:0, sugar:0, yeast:"fresh", hyd:62, salt:2.8, oil:0, sugar:0, yeast:"fresh",
plan:"d24", seq:"warmcold", staglio:"before", plan:"d24", seq:"warmcold", staglio:"before",
@@ -780,6 +830,7 @@ function applyPlan(){
function initUI(){ function initUI(){
buildFlourSelect(); buildFlourSelect();
chips($("uxModes"), UX_MODES, "uxMode");
chips($("styles"), STYLES, "style", k=>{ chips($("styles"), STYLES, "style", k=>{
const st=STYLES[k]; const st=STYLES[k];
S.ball=st.ball; S.hyd=st.hyd; S.salt=st.salt; S.oil=st.oil; S.sugar=st.sugar; S.mode=st.mode; S.ball=st.ball; S.hyd=st.hyd; S.salt=st.salt; S.oil=st.oil; S.sugar=st.sugar; S.mode=st.mode;
@@ -807,9 +858,11 @@ function initUI(){
}); });
$("ballsMinus").onclick=()=>{ S.balls=Math.max(1,S.balls-1); render(); }; $("ballsMinus").onclick=()=>{ S.balls=Math.max(1,S.balls-1); render(); };
$("ballsPlus").onclick =()=>{ S.balls=Math.min(60,S.balls+1); render(); }; $("ballsPlus").onclick =()=>{ S.balls=Math.min(60,S.balls+1); render(); };
$("bakeAt").addEventListener("input", e=>{ const bakeInputHandler = e=>{
if (e.target.value){ S.bake=new Date(e.target.value).getTime(); render(); } if (e.target.value){ S.bake=new Date(e.target.value).getTime(); render(); }
}); };
$("bakeAt").addEventListener("input", bakeInputHandler);
$("bakeAtQuick").addEventListener("input", bakeInputHandler);
$("applyFlour").onclick=()=>{ $("applyFlour").onclick=()=>{
const f=FLOURS.find(x=>x.id===S.flour); const f=FLOURS.find(x=>x.id===S.flour);
@@ -823,16 +876,17 @@ function initUI(){
$("share").onclick=share; $("share").onclick=share;
$("copyTxt").onclick=copyText; $("copyTxt").onclick=copyText;
$("pdf").onclick=savePdf; $("pdf").onclick=savePdf;
$("reset").onclick=()=>{ S=Object.assign({},DEFAULT); S.bake=defaultBake(); location.hash=""; render(); }; $("reset").onclick=()=>{ if(!confirm("Alle Werte zurücksetzen?")) return; S=Object.assign({},DEFAULT); S.bake=defaultBake(); location.hash=""; render(); };
} }
function syncInputs(){ function syncInputs(){
document.body.dataset.ux = S.uxMode;
RANGES.forEach(id=>{ $(id).value=S[id]; }); RANGES.forEach(id=>{ $(id).value=S[id]; });
$("ballsOut").textContent=S.balls; $("ballsOut").textContent=S.balls;
$("flour").value=S.flour; $("flour").value=S.flour;
["styles","modes","yeastTypes","pfTypes","plans","seqs","staglios"].forEach(h=>{ ["uxModes","styles","modes","yeastTypes","pfTypes","plans","seqs","staglios"].forEach(h=>{
const key={styles:"style",modes:"mode",yeastTypes:"yeast",pfTypes:"pf",plans:"plan",seqs:"seq",staglios:"staglio"}[h]; const key={uxModes:"uxMode",styles:"style",modes:"mode",yeastTypes:"yeast",pfTypes:"pf",plans:"plan",seqs:"seq",staglios:"staglio"}[h];
const keys=Object.keys({styles:STYLES,modes:MODES,yeastTypes:YEASTS,pfTypes:PFS,plans:PLANS,seqs:SEQ,staglios:STAGLIO}[h]); const keys=Object.keys({uxModes:UX_MODES,styles:STYLES,modes:MODES,yeastTypes:YEASTS,pfTypes:PFS,plans:PLANS,seqs:SEQ,staglios:STAGLIO}[h]);
[...$(h).children].forEach((b,i)=>b.setAttribute("aria-pressed", S[key]===keys[i])); [...$(h).children].forEach((b,i)=>b.setAttribute("aria-pressed", S[key]===keys[i]));
}); });
$("seqNote").textContent = SEQ[S.seq].note; $("seqNote").textContent = SEQ[S.seq].note;
@@ -859,7 +913,9 @@ function syncInputs(){
$("v-pfT").innerHTML = n1(S.pfT)+" <small>°C</small>"; $("v-pfT").innerHTML = n1(S.pfT)+" <small>°C</small>";
const d=new Date(S.bake); const d=new Date(S.bake);
$("bakeAt").value = new Date(d.getTime()-d.getTimezoneOffset()*60e3).toISOString().slice(0,16); const bakeVal = new Date(d.getTime()-d.getTimezoneOffset()*60e3).toISOString().slice(0,16);
$("bakeAt").value = bakeVal;
$("bakeAtQuick").value = bakeVal;
} }
function renderFlour(r){ function renderFlour(r){
@@ -880,7 +936,7 @@ function renderWarnings(f,r){
const w=[]; const w=[];
if (S.flour!=="custom"){ if (S.flour!=="custom"){
if (r.U > f.reife[1]*1.15) if (r.U > f.reife[1]*1.15)
w.push(["bad",`Dein Plan entspricht rund ${Math.round(r.U)} h Reife bei 20 °C. ${f.n} trägt etwa ${f.reife[1]} h — der Teig baut ab und wird schlaff. Kürzer führen oder ein backstärkeres Mehl nehmen.`]); w.push(["bad",`<b>Zu lange Gare für dieses Mehl.</b><br>Dein Plan entspricht rund ${Math.round(r.U)} h Reife bei 20 °C. ${f.n} trägt etwa ${f.reife[1]} h. Empfehlung: kürzer führen, Kühlschrank kälter stellen oder ein backstärkeres Mehl wählen.`]);
else if (r.U < f.reife[0]*0.6) else if (r.U < f.reife[0]*0.6)
w.push(["",`Nur rund ${Math.round(r.U)} h Reifeäquivalent. ${f.n} kann deutlich mehr — mit längerer Gare wird der Teig aromatischer und bekömmlicher.`]); w.push(["",`Nur rund ${Math.round(r.U)} h Reifeäquivalent. ${f.n} kann deutlich mehr — mit längerer Gare wird der Teig aromatischer und bekömmlicher.`]);
if (S.hyd > f.hyd[1]+3) if (S.hyd > f.hyd[1]+3)
@@ -970,6 +1026,18 @@ function renderTimeline(r){
return tl; return tl;
} }
function renderQuickSummary(r){
const tl = lastTl || timeline(S,r);
const start = tl.start;
$("quickSummary").innerHTML = [
`<span><b>${S.balls} × ${Math.round(r.ballW)} g</b> Teiglinge</span>`,
`<span><b>${Math.round(r.flour)} g</b> Mehl</span>`,
`<span>Start <b>${fmtT(start)} ${fmtDay(start)}</b></span>`,
`<span>Backen <b>${fmtT(new Date(S.bake))} ${fmtDay(new Date(S.bake))}</b></span>`
].join("");
}
/* ============================================================ /* ============================================================
RENDER RENDER
============================================================ */ ============================================================ */
@@ -982,6 +1050,7 @@ function render(){
renderWarnings(f,r); renderWarnings(f,r);
renderRecipe(r); renderRecipe(r);
lastTl=renderTimeline(r); lastTl=renderTimeline(r);
renderQuickSummary(r);
renderPrint(r); renderPrint(r);
$("doughsum").textContent = `${S.balls} × ${Math.round(r.ballW)} g = ${Math.round(r.total)} g`; $("doughsum").textContent = `${S.balls} × ${Math.round(r.ballW)} g = ${Math.round(r.total)} g`;
@@ -994,7 +1063,7 @@ function render(){
/* ============================================================ /* ============================================================
URL-SHARING URL-SHARING
============================================================ */ ============================================================ */
const KEYS=["style","flour","balls","mode","ball","dia","panL","panW","hyd","salt","oil","sugar","yeast","plan","seq","staglio","roomH","roomT","fridgeH","fridgeT","pf","pfPct","pfH","pfT"]; const KEYS=["style","flour","balls","mode","uxMode","ball","dia","panL","panW","hyd","salt","oil","sugar","yeast","plan","seq","staglio","roomH","roomT","fridgeH","fridgeT","pf","pfPct","pfH","pfT"];
let hashLock=false; let hashLock=false;
function writeHash(){ function writeHash(){
const p=new URLSearchParams(); const p=new URLSearchParams();
@@ -1012,6 +1081,7 @@ function readHash(){
S[k] = (typeof DEFAULT[k]==="number") ? parseFloat(v) : v; S[k] = (typeof DEFAULT[k]==="number") ? parseFloat(v) : v;
}); });
if (!STYLES[S.style]) S.style="napo"; if (!STYLES[S.style]) S.style="napo";
if (!UX_MODES[S.uxMode]) S.uxMode="simple";
if (!PLANS[S.plan]) S.plan="free"; if (!PLANS[S.plan]) S.plan="free";
if (p.has("method")){ // alte Links: method=room|cold if (p.has("method")){ // alte Links: method=room|cold
S.seq = p.get("method")==="room" ? "room" : "warmcold"; S.seq = p.get("method")==="room" ? "room" : "warmcold";