// src/f-shared.jsx — Option F shared components
// Header, Hero image, Title with italic fragment, Section-aware ingredients.
// Used by all viewport variants (desktop / tablet / mobile).
// Artboard surface — wraps each F screen with the dark theme class.
const ArtboardSurface = ({ children, padding = 56, bg = 'var(--paper)', dark = false, theme = 'f', style }) => (
{children}
);
// Real photo path — committed asset
const FPHOTO = 'assets/sichuan-chicken.png';
// ─── F · Wordmark ───────────────────────────────────────────────
const FWordmark = ({ size = 26 }) => (
luis
cooks.
);
// ─── F · Display title with italic flavour fragment ─────────────
const FTitle = ({ name, size = 108, lineHeight = 0.9, color = 'var(--ink)',
italicColor = 'var(--olive)', breakBeforeWith = true }) => {
const m = name.match(/^(.+?)(\s+with\s+.+?)(\.|$)/i);
if (!m) {
return (
{name}.
);
}
return (
{m[1]}{breakBeforeWith &&
}
{breakBeforeWith ? m[2].trim() : m[2]}.
);
};
// ─── F · Nav (desktop / tablet) ─────────────────────────────────
const FNav = ({ active = 'Recipes', compact = false }) => (
);
// Avatar — the "L" gradient pill
const FAvatar = ({ size = 34, initial = 'L' }) => (
{initial}
);
// ─── F · Desktop / tablet header ─────────────────────────────────
const FHeader = ({ active = 'Recipes' }) => (
);
// ─── F · Mobile header (just wordmark + hamburger + avatar) ──────
const FMobileHeader = () => (
);
// ─── F · Mobile bottom nav ─────────────────────────────────────
const FMobileBottomNav = ({ active = 'Recipes' }) => (
);
// ─── F · Hero image — the real photo ────────────────────────────
const FHeroImage = ({ height, radius = 18, src = FPHOTO, alt = 'sichuan cold chicken',
overlay = true, badge = true, style = {} }) => (

{overlay && (
)}
{badge && (
Enhanced
)}
);
// ─── F · Section-aware ingredient groups ────────────────────────
const FIngredients = ({ ingredients, mode = 'view', checked = new Set(),
activeGroupTitle = null }) => {
// Parse into groups by "For …:" headers
const groups = [];
let current = { title: null, items: [] };
ingredients.forEach((line) => {
if (line === '') return;
if (line.endsWith(':')) {
if (current.items.length || current.title) groups.push(current);
current = { title: line.replace(':', ''), items: [] };
} else {
current.items.push(line);
}
});
if (current.items.length) groups.push(current);
if (groups.length === 1 && !groups[0].title) {
return (
{groups[0].items.map((line, i) => (
))}
);
}
return (
{groups.map((g, gi) => {
const isActive = mode === 'cook' && activeGroupTitle &&
g.title && g.title.toLowerCase().includes(activeGroupTitle.toLowerCase());
return (
{g.title && (
{g.title.replace(/^For\s+(the\s+)?/i, '').trim() || g.title}
{g.items.length} items
)}
{g.items.map((line, i) => (
))}
);
})}
);
};
const FIngredientRow = ({ line, checked, mode = 'view', highlight }) => {
if (mode === 'view') {
return (
{line}
);
}
return (
);
};
// ─── F · Amber primary CTA ───────────────────────────────────────
const FButton = ({ children, size = 'm', variant = 'amber', style, onClick }) => {
const sizes = {
s: { font: 13, pad: '10px 16px' },
m: { font: 15, pad: '14px 22px' },
l: { font: 17, pad: '18px 28px' },
xl: { font: 18, pad: '20px 32px' },
};
const s = sizes[size];
const variants = {
amber: {
background: 'linear-gradient(180deg, #f0a850, #c97818)',
color: '#1a1208',
boxShadow: '0 10px 28px rgba(240,168,80,0.30), inset 0 1px 0 rgba(255,255,255,0.35)',
border: 'none',
},
ghost: {
background: 'rgba(255,255,255,0.04)',
color: 'var(--ink-2)',
border: '1px solid var(--hairline)',
boxShadow: 'none',
},
quiet: {
background: 'transparent',
color: 'var(--ink-2)',
border: '1px solid var(--hairline)',
boxShadow: 'none',
},
};
return (
);
};
// ─── F · Pill row (timers, tags, etc.) ──────────────────────────
const FPill = ({ children, accent, style }) => (
{children}
);
// ─── F · Recipe card (for library) ──────────────────────────────
const FRecipeCard = ({ recipe, photoSrc, size = 'm' }) => {
const r = recipe;
// Decide title display
const m = r.name.match(/^(.+?)(\s+with\s+.+?)(\.|$)/i);
return (
{photoSrc ? (

) : (
)}
{/* meta pip top-right — active effort (hidden when unknown) */}
{(() => {
const eff = window.LCDomain && window.LCDomain.effortInfo(r);
if (!eff || !eff.known) return null;
return (
);
})()}
{/* Bottom gradient + category */}
{r.categories[0]}
{m ? (
<>{m[1]}
{m[2].trim()}.>
) : `${r.name}.`}
{r.rating > 0
?
: unrated}
{(() => {
const label = window.LCDomain && window.LCDomain.costPerServeLabel(r);
return label
?
{label} /serve
: no cost yet;
})()}
);
};
// Map of recipe id → real photo
const FPhotos = {
'sichuan-chicken': FPHOTO,
};
Object.assign(window, {
ArtboardSurface,
FPHOTO, FPhotos,
FWordmark, FTitle, FNav, FAvatar, FHeader, FMobileHeader, FMobileBottomNav,
FHeroImage, FIngredients, FIngredientRow,
FButton, FPill, FRecipeCard,
});