diff --git a/docker/frontend/src/App.tsx b/docker/frontend/src/App.tsx index 9182cf5..2a6dd49 100644 --- a/docker/frontend/src/App.tsx +++ b/docker/frontend/src/App.tsx @@ -292,12 +292,23 @@ export function Workspace() { const [comparing, setComparing] = useState(false); const [compareUrl, setCompareUrl] = useState(null); - const [recipe, setRecipe] = useState(() => ({ - ...DEFAULT_RECIPES[0], - id: 'web-current', - name: DEFAULT_RECIPES[0]?.name ?? 'PROVIA', - ...session.recipe, - })); + const [recipe, setRecipe] = useState(() => { + // The stage opens on the photo itself — the neutral stock, every knob at its + // default and no film filter, the same recipe COMPARE splits against — so a + // file that is dropped in is shown as the file. The bundled CLASSIC NEGIPES + // preset used to sit here as the boot look, and it baked exposure +2 (+0.5 + // EV) plus a 6300K / tint +2 white balance onto every photo the moment it + // landed: that is what blew the highlights and turned skin pink on a fresh + // NEF. A look is now there only because a chip was clicked. + const boot = DEFAULT_RECIPES[0]; + // A session written by that old boot still holds the preset verbatim, which + // was never the visitor's choice; it is dropped instead of restored. Any + // edit to a knob moved the stored object off this exact fingerprint. + const stale = !!boot && session.recipe?.id === 'web-current' && + session.recipe.baseFilter === boot.baseFilter && + JSON.stringify(session.recipe.adjustments) === JSON.stringify(boot.adjustments); + return { ...BASE_RECIPE, id: 'web-current', ...(stale ? null : session.recipe) }; + }); const [simId, setSimId] = useState(() => session.simId ?? null); // HOVER PREVIEW: the look of the sim or recipe the pointer is over, laid on the // photo for as long as it stays there. It never becomes `recipe`, so SAVE,