Add shadows to recipe detail tabs

This commit is contained in:
2026-04-06 20:32:54 +02:00
parent a29b01e413
commit c341e2e813
2 changed files with 32 additions and 20 deletions

View File

@@ -7,6 +7,9 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Recipe"> <meta name="apple-mobile-web-app-title" content="Recipe">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Recipe App - Modular</title> <title>Recipe App - Modular</title>
<link rel="manifest" href="./manifest.webmanifest?v=20260406-60"> <link rel="manifest" href="./manifest.webmanifest?v=20260406-60">
<link rel="icon" type="image/png" sizes="192x192" href="./icons/icon-192.png"> <link rel="icon" type="image/png" sizes="192x192" href="./icons/icon-192.png">

View File

@@ -43,6 +43,21 @@ function setTabButtonState(btn, active) {
export function getRecipeDetailHTML() { export function getRecipeDetailHTML() {
return ` return `
<style>
#rd-tab-bar::after {
content: '';
position: absolute;
left: 0; right: 0; bottom: -8px;
height: 8px;
background: linear-gradient(to bottom, rgba(0,0,0,0.25), transparent);
opacity: 0;
transition: opacity 0.2s;
pointer-events: none;
}
#rd-tab-bar.rd-scrolled::after {
opacity: 1;
}
</style>
<div id="recipe-detail-view" class="absolute inset-0 bg-[#2d2e2b] z-30 transition-all duration-300 ease-in-out translate-x-full opacity-0 pointer-events-none flex flex-col overflow-hidden" style="background:#2d2e2b !important; background-image:none !important;"> <div id="recipe-detail-view" class="absolute inset-0 bg-[#2d2e2b] z-30 transition-all duration-300 ease-in-out translate-x-full opacity-0 pointer-events-none flex flex-col overflow-hidden" style="background:#2d2e2b !important; background-image:none !important;">
<div class="absolute top-0 w-full p-3.5 flex justify-between z-40 mt-3"> <div class="absolute top-0 w-full p-3.5 flex justify-between z-40 mt-3">
<button onclick="closeRecipeDetail()" class="w-9 h-9 rounded-full border flex items-center justify-center transition-opacity opacity-95 hover:opacity-100" style="background:rgba(47,47,45,0.92) !important; backdrop-filter:none !important; border-color:#444442 !important; color:#ddd6ca !important;"> <button onclick="closeRecipeDetail()" class="w-9 h-9 rounded-full border flex items-center justify-center transition-opacity opacity-95 hover:opacity-100" style="background:rgba(47,47,45,0.92) !important; backdrop-filter:none !important; border-color:#444442 !important; color:#ddd6ca !important;">
@@ -59,7 +74,7 @@ export function getRecipeDetailHTML() {
<span id="rd-hero-label" class="absolute inset-0 z-10 flex items-center justify-center font-medium text-[15px]" style="color:#ddd6ca;"></span> <span id="rd-hero-label" class="absolute inset-0 z-10 flex items-center justify-center font-medium text-[15px]" style="color:#ddd6ca;"></span>
</div> </div>
<div class="bg-[#2d2e2b] rounded-t-3xl -mt-6 relative z-30 pt-6 flex flex-col flex-1 overflow-hidden" style="background:#2d2e2b !important; background-image:none !important;"> <div class="bg-[#2d2e2b] rounded-t-3xl -mt-6 relative z-30 pt-6 flex flex-col flex-1 overflow-hidden" style="background:#2d2e2b !important; background-image:none !important; box-shadow:0 -8px 20px rgba(0,0,0,0.35) !important;">
<div class="mb-3 px-5 shrink-0"> <div class="mb-3 px-5 shrink-0">
<div class="flex justify-between items-start mb-2.5"> <div class="flex justify-between items-start mb-2.5">
<h1 id="rd-title" class="text-xl font-bold leading-tight" style="color:#ddd6ca;"></h1> <h1 id="rd-title" class="text-xl font-bold leading-tight" style="color:#ddd6ca;"></h1>
@@ -70,14 +85,10 @@ export function getRecipeDetailHTML() {
<i class="fas fa-clock text-[10px]" style="color:#9b978f;"></i> <i class="fas fa-clock text-[10px]" style="color:#9b978f;"></i>
<span id="rd-time"></span> <span id="rd-time"></span>
</div> </div>
<div class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full border" style="background:#2f2f2d; border-color:#444442; color:#d7d2c8;">
<i class="fas fa-fire text-[10px]" style="color:#9b978f;"></i>
<span id="rd-kcal" class="tabular-nums"></span>
</div>
</div> </div>
</div> </div>
<div class="flex border-b mb-2 px-5 shrink-0" style="border-color:#444442;"> <div id="rd-tab-bar" class="flex border-b mb-2 px-5 shrink-0 relative z-10" style="border-color:#444442;">
<button class="flex-1 pb-2.5 text-[13px] border-b-2 rd-tab-btn" data-rd-tab="ingredients" style="color:#ddd6ca; border-bottom-color:#787876; font-weight:600;">Składniki</button> <button class="flex-1 pb-2.5 text-[13px] border-b-2 rd-tab-btn" data-rd-tab="ingredients" style="color:#ddd6ca; border-bottom-color:#787876; font-weight:600;">Składniki</button>
<button class="flex-1 pb-2.5 text-[13px] border-b-2 rd-tab-btn" data-rd-tab="steps" style="color:#9b978f; border-bottom-color:transparent; font-weight:500;">Kroki</button> <button class="flex-1 pb-2.5 text-[13px] border-b-2 rd-tab-btn" data-rd-tab="steps" style="color:#9b978f; border-bottom-color:transparent; font-weight:500;">Kroki</button>
</div> </div>
@@ -127,7 +138,6 @@ function populateDetail(recipeId) {
} }
document.getElementById('rd-title').textContent = recipe.title; document.getElementById('rd-title').textContent = recipe.title;
document.getElementById('rd-time').textContent = `${recipe.minutes} min`; document.getElementById('rd-time').textContent = `${recipe.minutes} min`;
updateKcalDisplay();
const tagsHtml = []; const tagsHtml = [];
for (const slotId of recipe.allowedSlots) { for (const slotId of recipe.allowedSlots) {
@@ -155,15 +165,6 @@ function populateDetail(recipeId) {
/* ── helpers ───────────────────────────────────────────── */ /* ── helpers ───────────────────────────────────────────── */
function updateKcalDisplay() {
const el = document.getElementById('rd-kcal');
if (!el) return;
const recipe = RECIPES[currentRecipeId];
if (!recipe) return;
const kcal = Math.round(recipe.nutritionPerServing.kcal * currentServings);
el.textContent = `${kcal} kcal`;
}
function nutritionForAmount(ingredientId, amount, unit) { function nutritionForAmount(ingredientId, amount, unit) {
const def = INGREDIENTS[ingredientId]; const def = INGREDIENTS[ingredientId];
if (!def?.nutritionPer100g) return null; if (!def?.nutritionPer100g) return null;
@@ -315,14 +316,12 @@ function renderIngredients(recipe) {
if (currentServings <= 1) return; if (currentServings <= 1) return;
currentServings--; currentServings--;
renderIngredients(recipe); renderIngredients(recipe);
updateKcalDisplay();
}); });
container.querySelector('#rd-serv-plus')?.addEventListener('click', () => { container.querySelector('#rd-serv-plus')?.addEventListener('click', () => {
if (currentServings >= 12) return; if (currentServings >= 12) return;
currentServings++; currentServings++;
renderIngredients(recipe); renderIngredients(recipe);
updateKcalDisplay();
}); });
container.querySelectorAll('.rd-alt-toggle').forEach((btn) => { container.querySelectorAll('.rd-alt-toggle').forEach((btn) => {
@@ -369,8 +368,8 @@ function renderSteps(recipe) {
container.innerHTML = ` container.innerHTML = `
<div class="space-y-2 pb-5"> <div class="space-y-2 pb-5">
${steps.map((step, i) => ` ${steps.map((step, i) => `
<div class="rounded-xl p-3 flex gap-3" style="${forceBg(RD_THEME.surface)} border:none !important;"> <div class="rounded-xl p-3 flex gap-3" style="background:transparent !important; background-image:none !important; box-shadow:none !important; border:none !important;">
<div class="w-6 h-6 rounded-full flex items-center justify-center text-[11px] font-bold shrink-0" style="${forceBgBorder(RD_THEME.surfaceActive, RD_THEME.borderSoft)} color:${RD_THEME.textSecondary} !important;">${i + 1}</div> <div class="w-6 h-6 rounded-full flex items-center justify-center text-[11px] font-bold shrink-0" style="background:transparent !important; border:none !important; box-shadow:none !important; color:${RD_THEME.textSecondary} !important;">${i + 1}</div>
<div class="pt-0.5"><p class="text-[13px] leading-relaxed" style="color:${RD_THEME.textSecondary};">${escapeHtml(step)}</p></div> <div class="pt-0.5"><p class="text-[13px] leading-relaxed" style="color:${RD_THEME.textSecondary};">${escapeHtml(step)}</p></div>
</div>`).join('')} </div>`).join('')}
</div>`; </div>`;
@@ -400,6 +399,16 @@ export function setupRecipeDetail() {
}); });
}); });
/* ── tab-bar scroll shadow ─────────────────── */
const scrollContainer = document.querySelector('#recipe-detail-view .overflow-y-auto');
const tabBar = document.getElementById('rd-tab-bar');
if (scrollContainer && tabBar) {
scrollContainer.addEventListener('scroll', () => {
tabBar.classList.toggle('rd-scrolled', scrollContainer.scrollTop > 2);
});
}
/* ── planner — delegate to MealPlanEditor ─────── */ /* ── planner — delegate to MealPlanEditor ─────── */
document.getElementById('rd-add-to-planner-btn')?.addEventListener('click', () => { document.getElementById('rd-add-to-planner-btn')?.addEventListener('click', () => {