// ───────────────────────────────────────────────────────────── // COMPONENTS — Sistema único de apresentação de produto // Os MESMOS componentes renderizam Suplemento, Manipulado e Peptídeo. // O conteúdo é dirigido por dados (sections[]). // ───────────────────────────────────────────────────────────── const { useState, useEffect, useRef, useMemo } = React; // ──────────────────────────────────────── // QUEBRA DE LINHA MANUAL nos nomes/textos // Escreva
(ou quebre a linha de verdade no arquivo) DENTRO do texto // pra forçar uma quebra exatamente onde você quer. Ex.: // name: "Citrulina
e Arginina" // Não usa "/" como separador (vários nomes já usam barra). // ──────────────────────────────────────── function nl2br(text) { if (text == null) return text; const parts = String(text).split(/|\n/i); if (parts.length === 1) return text; const out = []; parts.forEach((part, i) => { if (i > 0) out.push(React.createElement("br", { key: "br" + i })); out.push(part); }); return out; } window.nl2br = nl2br; // ──────────────────────────────────────── // ICONS (de linha, finos — premium) // ──────────────────────────────────────── const Icon = ({ name, size = 16, stroke = "currentColor", strokeWidth = 1.5 }) => { const p = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke, strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }; const PATHS = { search: <>, back: <>, close: <>, share: <>, bookmark: <>, chevR: <>, home: <>, flask: <>, pill: <>, drop: <>, user: <>, clock: <>, check: <>, alert: <>, quote: <>, star: <>, filter: <>, sparkle: <>, grid: <>, chat: <>, }; return {PATHS[name]}; }; // ──────────────────────────────────────── // PRIMITIVES // ──────────────────────────────────────── const Pill = ({ children, tone = "neutral", t }) => { const map = { positive: { bg: "rgba(120,200,140,0.10)", fg: t.success, bd: "rgba(120,200,140,0.35)" }, neutral: { bg: "transparent", fg: t.ink2, bd: t.border }, negative: { bg: "rgba(220,90,90,0.10)", fg: t.danger, bd: "rgba(220,90,90,0.40)" }, premium: { bg: t.accentMuted, fg: t.ink1, bd: t.borderStrong }, caution: { bg: "rgba(220,180,90,0.10)", fg: t.warn, bd: "rgba(220,180,90,0.40)" }, }[tone]; return ( {children} ); }; const SectionLabel = ({ children, t, num }) => (
{num != null && {String(num).padStart(2,"0")}} {children}
); // product visual — placeholder padronizado (substituível por foto real) const ProductVisual = ({ product, size = 64, t }) => { return (
{product.visualCode || product.name.slice(0,2)}
); }; // ──────────────────────────────────────── // PRODUCT CARD (lista) — minimalista // Só nome + tagline. Sem siglas, sem subtítulo, sem tags. // As classificações aparecem só DENTRO do detalhe (gaveta). // ──────────────────────────────────────── const ProductCard = ({ product, t, onOpen, showVisual = false, density = "spacious" }) => { const isCompact = density === "compact"; const padding = isCompact ? "16px 18px" : "20px 22px"; return ( ); }; // ──────────────────────────────────────── // SECTION BLOCKS — uma função por "kind" // ──────────────────────────────────────── const SBList = ({ items, t, tone }) => { const isCaution = tone === "caution"; const isNeutral = tone === "neutral"; // Os check/marcadores ficam BRANCOS (ink2) por padrão. // Tons amarelo/vermelho são reservados para verdict. // Triângulos e marcadores acompanham a cor do texto (branco em modo escuro, preto em claro) const markColor = isCaution ? t.ink1 : (isNeutral ? t.ink3 : t.ink2); return ( ); }; const SBProtocol = ({ grid, t }) => { const entries = Object.entries(grid); return (
{entries.map(([k, v], i) => (
{k}
{v}
))}
); }; const SBParagraph = ({ body, t }) => (

{body}

); const SBQuote = ({ body, t }) => (
"{body}"
Dr. Ulisses Nakagawa · CRM-MS 16293
); const SBAtivos = ({ items, t }) => (
{items.map((it, i) => (
{it.name} {it.dose}
))}
); const SBPhase = ({ phase, notes, t }) => { // Labels conforme padrão de estudos clínicos const phases = ["Animal", "Fase I", "Pilotos humanos", "Fase III", "Aprovado"]; return (
{phases.map((p, i) => (
{p}
))}
{notes && (

{notes}

)}
); }; // SBCost — agora só mostra o veredict do produto, grande e colorido. // Sem régua, sem "Veredito", sem subtexto. const SBCost = ({ verdict, t }) => { if (!verdict) return null; const map = { positive: t.success, caution: t.warn, negative: t.danger, neutral: t.ink2, premium: t.accent, }; const color = map[verdict.tone] || t.ink1; // Escala a tipografia para rótulos longos não quebrarem em linhas estranhas const len = (verdict.label || "").length; const fontSize = len > 22 ? 30 : len > 14 ? 36 : 44; // Respeita \n explícito no rótulo para forçar a quebra exatamente onde queremos const lines = (verdict.label || "").split("\n"); return (
{lines.map((ln, i) => ( {i > 0 &&
} {ln}
))}
); }; const SBSocial = ({ patientCount, timeToEffect, citation, t }) => (
{patientCount}
pacientes em uso desta fórmula
{timeToEffect}
tempo médio até o primeiro sinal
{citation && (
"{citation}"
)}
); // ──────────────────────────────────────── // RELATOS — depoimentos de pacientes (positivo + negativo) // ──────────────────────────────────────── const SBRelatos = ({ items, t }) => (
{items.map((r, i) => { const pos = r.tone === "positivo"; const bg = pos ? "rgba(90,154,90,0.08)" : "rgba(191,122,122,0.08)"; const bd = pos ? "rgba(90,154,90,0.30)" : "rgba(191,122,122,0.30)"; const fg = pos ? "rgb(122,191,122)" : "rgb(191,122,122)"; return (
{r.pessoa} {pos ? "Positivo" : "Sem resultado"}
"{r.texto}"
); })}
Relatos individuais não garantem resultado. Respostas variam conforme saúde geral, qualidade do produto e protocolo. Sem avaliação médica, o risco de não resultado é alto.
); // Section renderer — escolhe o bloco certo const Section = ({ section, t, num, product }) => { let body; switch (section.kind) { case "list": body = ; break; case "protocol": body = ; break; case "paragraph": body = ; break; case "quote": body = ; break; case "ativos": body = ; break; case "phase": body = ; break; case "cost": body = ; break; case "social": body = ; break; case "relatos": body = ; break; default: body = null; } return (
{section.title} {body}
); }; Object.assign(window, { Icon, Pill, SectionLabel, ProductVisual, ProductCard, Section, LegalDisclaimer, }); // ──────────────────────────────────────── // DISCLAIMER LEGAL — usado em todas as telas // (mesmo texto que o usuário usa nas legendas do Instagram) // ──────────────────────────────────────── function LegalDisclaimer({ t, compact = false }) { return (
Dr. Ulisses Nakagawa · CRM-MS 16293

Se você busca uma avaliação médica individualizada, com abordagem clínica global e responsável, fale "consulta" no WhatsApp para receber as informações.

Conteúdo informativo. Busque sempre informações médicas qualificadas, individualizadas e sem julgamento. Toda substância capaz de alterar funções fisiológicas envolve riscos e deve ser avaliada caso a caso, com acompanhamento médico adequado.

O papel do médico é realizar uma avaliação clínica ampla, iniciar investigações diagnósticas e conduzir o caso com responsabilidade clínica, realizando encaminhamentos quando indicados.

); }