+
+
{t("cookingSession.title")}
+
+
+
{t("cookingSession.subtitle")}
+
+ {state.status === "loading" && (
+
{t("cookingSession.loading")}
+ )}
+
+ {state.status === "error" && (
+
+ {t("common.loadError")}
+
+ )}
+
+ {state.status === "loaded" &&
}
+
+ );
+}
+
+/** The plan body — the recipe legend then every phase, or the empty-week message. */
+function CookingPlan({ plan }: { plan: OptimizedCookingPlanView }) {
+ const { t } = useTranslation();
+
+ if (plan.phases.length === 0) {
+ return
+
+ {taskHeadline(task, t)}
+ {task.kind === "merged-prep" && (
+ {t("cookingSession.task.sharedBadge")}
+ )}
+
+
+ {t("cookingSession.task.forRecipes", { recipes: taskRecipeNames(task) })}
+
+ {task.utensils.length > 0 && (
+
+ {t("cookingSession.task.utensils")} :{" "}
+ {task.utensils.map((utensil) => t(`catalog.utensils.${utensil.key}`)).join(", ")}
+
+ )}
+
+ );
+}
+
+/** One "meanwhile, X is cooking" line inside a phase's background band. */
+function BackgroundLine({ task }: { task: CookingBackgroundTaskView }) {
+ const { t } = useTranslation();
+ const technique = task.technique ? `${t(`catalog.techSteps.${task.technique.key}`)} — ` : "";
+ return (
+