/* LightLife — sekcje strony głównej */
const { Button, Badge, Card, Icon, FeatureItem, Avatar } = window.LightLifeDesignSystem_eb2a9e;
const HD = window.LL_DATA;

/* ── Hero (wariant F: statyczna makieta apki wg wzoru — bez animacji i interakcji) ──
   Cel: 1650 kcal spożyte / 850 kcal spalone; dziennik dnia + karta posiłku. */
function Gauge({ label, value, sub, color, pct }) {
  const len = Math.round(Math.PI * 50 * Math.min(1, pct));
  return (
    <div className="hg-gauge">
      <span className="hg-label">{label}</span>
      <div className="hg-arc">
        <svg width="128" height="72" viewBox="0 0 128 72" aria-hidden="true">
          <path d="M 14 66 A 50 50 0 0 1 114 66" fill="none" stroke="var(--white)" strokeWidth="9" strokeLinecap="round" />
          <path d="M 14 66 A 50 50 0 0 1 114 66" fill="none" stroke={color} strokeWidth="9" strokeLinecap="round"
            strokeDasharray={len + ' 999'} />
        </svg>
        <div className="hg-val"><b>{value}</b> kcal</div>
      </div>
      <span className="hg-sub">{sub}</span>
    </div>
  );
}

const HS_WEEK = [
  { l: 'P', n: 6, st: 'done' }, { l: 'W', n: 7, st: 'done' }, { l: 'Ś', n: 8, st: 'done' },
  { l: 'C', n: 9, st: 'today' }, { l: 'P', n: 10, st: '' }, { l: 'S', n: 11, st: '' }, { l: 'N', n: 12, st: '' },
];

function HeroAppScreen({ meal }) {
  return (
    <div className="happ-screen">
      <div className="hs-title">Dzisiaj</div>
      <div className="hs-week">
        {HS_WEEK.map((d) => (
          <div key={d.n} className={'hs-day ' + d.st}>
            <i>{d.l}</i>
            <span>{d.n}</span>
          </div>
        ))}
      </div>
      <div className="hs-gcard">
        <Gauge label="Spożyte kcal" value={1030} sub="z 1650" color="var(--gold)" pct={1030 / 1650} />
        <Gauge label="Spalone kcal" value={850} sub="dzisiaj" color="var(--ink)" pct={850 / 1650} />
      </div>
      <div className="hs-dots"><span className="on"></span><span></span><span></span></div>
      <div className="hs-sect">Posiłki <Icon name="chevron-right" size={18} /></div>
      <div className="hs-meal">
        <div className="hs-meal-top">
          <div className="hs-meal-info">
            <i>{meal.time} – 15:30</i>
            <b>{meal.title}</b>
            <span>{meal.kcal} kcal · B {meal.p} g · T {meal.f} g · W {meal.c} g</span>
          </div>
          <img src={meal.img} alt="" />
        </div>
        <div className="hs-actions">
          <span className="hs-act"><Icon name="arrow-right" size={13} /> Zmień</span>
          <span className="hs-act"><Icon name="x" size={13} /> Pomiń</span>
          <span className="hs-act gold"><Icon name="check" size={13} /> Zjedzony</span>
        </div>
      </div>
      <div className="hs-pag">
        <em><Icon name="check" size={12} /></em>
        <span className="on"></span><span></span><span></span>
      </div>
      <div className="hs-input">
        <span>Zjadłeś coś spoza planu?</span>
        <b><Icon name="plus" size={16} /></b>
        <b><Icon name="send" size={14} /></b>
      </div>
      <div className="hs-tabs">
        <span className="on"><Icon name="calendar-days" size={19} /><i>Dziennik</i></span>
        <span><Icon name="check-circle" size={19} /><i>Plan</i></span>
        <span><Icon name="bar-chart-3" size={19} /><i>Postęp</i></span>
        <span><Icon name="message-circle" size={19} /><i>Czat</i></span>
        <span><Icon name="ellipsis" size={19} /><i>Więcej</i></span>
      </div>
    </div>
  );
}

/* Czarna obudowa iPhone'a — tytanowa ramka, boczne przyciski, bezel */
function IPhoneFrame({ children }) {
  return (
    <div className="iph-frame">
      <span className="iph-btn iph-action" aria-hidden="true"></span>
      <span className="iph-btn iph-volup" aria-hidden="true"></span>
      <span className="iph-btn iph-voldn" aria-hidden="true"></span>
      <span className="iph-btn iph-power" aria-hidden="true"></span>
      <div className="iph-screen">{children}</div>
    </div>
  );
}

function HomeHero() {
  return (
    <section className="section bg-white ofh home-hero" data-screen-label="Hero">
      <SectionWave fill="cream" />
      <div className="container">
        <div className="home-hero-layout">
          <div className="home-hero-copy">
            <h1>Ty żyj po swojemu.<br />Co jeść, zaplanujemy&nbsp;my.</h1>
            <p className="home-hero-lead">Nasi dietetycy ułożą jadłospis pod Twoje ciało, smaki i codzienny rytm, a potem poprowadzą Cię przez zmianę, aż zdrowe nawyki zostaną z Tobą na stałe. Bez głodówek i liczenia kalorii.</p>
            <div className="hero-cta">
              <Button size="md" arrow href="oferta.html">Sprawdź ofertę</Button>
              <Button variant="secondary" size="md" arrow href="metamorfozy.html">Zobacz metamorfozy</Button>
            </div>
            <div className="home-hero-proof">
              <p className="home-hero-proof-label">Dowody, nie słowa</p>
              <div className="home-hero-proof-stats" aria-label="Efekty podopiecznych LightLife">
                <p><strong>5000+</strong><span>metamorfoz</span></p>
                <p><strong>−9,9&nbsp;kg</strong><span>średni spadek wagi</span></p>
                <p><strong>9/10</strong><span>utrzymuje efekt</span></p>
              </div>
              <div className="home-hero-rating" aria-label="Średnia ocena LightLife">
                <span className="home-hero-avatars" aria-hidden="true">
                  <img src="assets/dish-gen/hero-avatar-1.png" alt="" />
                  <img src="assets/dish-gen/hero-avatar-2.png" alt="" />
                  <img src="assets/dish-gen/hero-avatar-3.png" alt="" />
                  <img src="assets/dish-gen/hero-avatar-4.png" alt="" />
                </span>
                <div className="home-hero-rating-copy">
                  <p><strong>4,9/5</strong><span className="home-hero-stars" aria-hidden="true">★★★★★</span></p>
                  <span>Tak oceniają nas podopieczni</span>
                </div>
              </div>
            </div>
          </div>
          <div className="home-hero-media">
            <img src="assets/hero-kornelia.webp" alt="Kornelia, dietetyk i twórczyni metody LightLife, podaje kolorowy, zdrowy posiłek" />
          </div>
        </div>
      </div>
    </section>
  );
}

/* ── Oceny z platform (liczby przykładowe — do podmiany) ── */
const PLATFORM_RATINGS = [
  { id: 'google', value: '4,9', count: 216 },
  { id: 'facebook', value: '5,0', count: 94 },
];
const GOOGLE_COLORS = ['#4285F4', '#EA4335', '#FBBC05', '#4285F4', '#34A853', '#EA4335'];

function RatingsStrip() {
  return (
    <div className="ratings-strip">
      {PLATFORM_RATINGS.map((r) => (
        <div key={r.id} className="rs-card">
          {r.id === 'google' ? (
            <span className="rs-logo rs-google" aria-label="Google">
              {'Google'.split('').map((ch, i) => <b key={i} style={{ color: GOOGLE_COLORS[i] }}>{ch}</b>)}
            </span>
          ) : (
            <span className="rs-logo rs-facebook" aria-label="Facebook">facebook</span>
          )}
          <span className="rs-score">
            <Icon name="star" size={21} filled />
            <b>{r.value}</b> z {r.count} opinii
          </span>
        </div>
      ))}
    </div>
  );
}

/* ── Zajawka kalkulatora (blok w sekcji metamorfoz; kalkulator.html powstanie później) ── */
function CalcTeaser() {
  return (
    <div className="calc-teaser" data-comment-anchor="calc-teaser">
      <h2>Być może jesz za dużo…<br />albo właśnie za mało.</h2>
      <span className="gold-line" aria-hidden="true"></span>
      <Button size="md" arrow href="oferta.html#kalkulator">Sprawdź, ile kalorii potrzebujesz</Button>
    </div>
  );
}

/* ── Slider metamorfoz (wspólny ArrowSlider z paskiem postępu) ── */
function shuffleHomeMetas(items) {
  const out = items.slice();
  for (let i = out.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [out[i], out[j]] = [out[j], out[i]];
  }
  return out;
}

function pickHomeMetas(items) {
  // „Wszystkie” oznacza pełną bazę bez filtrowania po dodatkowych kategoriach.
  // Do slidera trafiają wyłącznie kompletne historie ze zdjęciem przed i po.
  const complete = (items || []).filter((m) => m && m.przed && m.po);
  const women = shuffleHomeMetas(complete.filter((m) => m.plec === 'K')).slice(0, 5);
  const men = shuffleHomeMetas(complete.filter((m) => m.plec === 'M')).slice(0, 5);
  if (women.length < 5 || men.length < 5) return [];

  const womenFirst = Math.random() < 0.5;
  const selected = [];
  for (let i = 0; i < 5; i++) {
    selected.push(womenFirst ? women[i] : men[i]);
    selected.push(womenFirst ? men[i] : women[i]);
  }
  return selected;
}

function MetaSlider() {
  const [metas, setMetas] = React.useState([]);

  React.useEffect(() => {
    let active = true;
    const fallback = () => {
      const picked = pickHomeMetas(HD.METAS || []);
      if (active) setMetas(picked);
    };

    if (!window.LL_DB || typeof window.LL_DB.getMetamorfozy !== 'function') {
      fallback();
      return () => { active = false; };
    }

    window.LL_DB.getMetamorfozy()
      .then((items) => {
        if (!active) return;
        const picked = pickHomeMetas(items);
        if (picked.length === 10) setMetas(picked);
        else fallback();
      })
      .catch(fallback);

    return () => { active = false; };
  }, []);

  return (
    <section className="section bg-cream" data-screen-label="Metamorfozy — slider">
      <SectionWave fill="white" />
      <div className="container">
        <CenterHead title="Jedna decyzja. 5 433 przemiany. 54 287 kg mniej."
          sub="Każda z tych osób miała swoje „nie dam rady”: pracę zmianową, dzieci, kontuzje albo lata diet z efektem jojo. Zamiast kolejnej rewolucji wybrali plan dopasowany do życia. Twoja historia może zacząć się tak samo." />
        <ArrowSlider progress>
          {metas.map((m) => <MetaCard key={m.id} m={m} showQuote />)}
        </ArrowSlider>
        <RatingsStrip />
        <CalcTeaser />
      </div>
    </section>
  );
}

/* ── Dieta dla kobiet / dla mężczyzn ── */
const GENDER_PLANS = [
  {
    id: 'kobiety', mark: '♀', label: 'Dla kobiet', title: 'Dieta dla kobiet', drivers: ['Cykl', 'Tarczyca', 'Estrogen'],
    lead: 'Plan, który respektuje cykl, tarczycę i wahania energii. Bez głodu, bez restrykcji, z efektem, który utrzymuje się po zakończeniu współpracy.',
    points: [
      { icon: 'cycle', t: 'Uwzględnia fazy cyklu: w lutealnej zapotrzebowanie rośnie nawet o 300 kcal.' },
      { icon: 'thyroid', t: 'Wsparcie przy PCOS, insulinooporności i niedoczynności tarczycy.' },
      { icon: 'apple', t: 'Pokrywa żelazo, ferrytynę, witaminę D i kwasy omega-3.' },
      { icon: 'metabolism', t: 'Stabilizuje metabolizm po 35. roku życia i w perimenopauzie.' },
    ],
    note: 'Zgodne z rekomendacjami EFSA, PTD i Instytutu Żywności i Żywienia.',
  },
  {
    id: 'mezczyzni', mark: '♂', label: 'Dla mężczyzn', title: 'Dieta dla mężczyzn', dark: true, drivers: ['Testosteron', 'Mięśnie', 'Metabolizm'],
    lead: 'Konkretne porcje, wyższa kaloryczność i wsparcie testosteronu. Zredukujesz tkankę tłuszczową lub zbudujesz formę, bez liczenia każdego grama.',
    points: [
      { icon: 'muscle', t: '1,6–2,2 g białka na kg, pod redukcję tłuszczu lub budowę mięśni.' },
      { icon: 'metabolism', t: 'Kaloryka dopasowana do wyższego BMR, o 10–15% wyższego niż u kobiet.' },
      { icon: 'cardio', t: 'Profilaktyka serca: cholesterol, ciśnienie, trójglicerydy.' },
      { icon: 'meal', t: 'Sycące posiłki pod siłownię i pracę fizyczną, bez głodu w ciągu dnia.' },
    ],
    note: 'Oparte na wytycznych WHO, ESC i Polskiego Towarzystwa Dietetyki.',
  },
];

function GenderPlans() {
  return (
    <section className="section bg-white gender-plans" data-screen-label="Dieta dla kobiet i mężczyzn">
      <SectionWave fill="cream" />
      <div className="container">
        <CenterHead title="Dlaczego ta sama dieta odchudza jego, a Ciebie nie?"
          sub="Kobiece ciało rządzi się cyklem, tarczycą i estrogenem, a męskie testosteronem, masą mięśniową i szybszym metabolizmem. Uniwersalny jadłospis udaje, że tej różnicy nie ma, więc u większości nie działa." />
        <div className="gp-bands">
          {GENDER_PLANS.map((g) => (
            <article key={g.id} className={'gp-band' + (g.dark ? ' gp-band--men' : ' gp-band--women')} data-comment-anchor={'gp-' + g.id}>
              <div className="gp-band-head">
                <span className="gp-mark">{g.mark}</span>
                <h3>{g.title}</h3>
                <div className="gp-rec">
                  <span className="gp-rec-label">Polecany start</span>
                  <span className="gp-rec-plan">Comfort · 3 miesiące</span>
                </div>
                <Button variant="primary" arrow href="oferta.html" className="gp-cta-btn">Sprawdź ofertę</Button>
              </div>
              <div className="gp-band-body">
                <p className="gp-lead">{g.lead}</p>
                <ol className="gp-points">
                  {g.points.map((p, i) => (
                    <li key={p.t}><span className="gp-num">{String(i + 1).padStart(2, '0')}</span><span className="gp-ptxt">{p.t}</span></li>
                  ))}
                </ol>
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ── Slider posiłków ── */
function DishSlider() {
  const picks = [[0, 2], [1, 0], [5, 2], [0, 4], [2, 4], [4, 0], [6, 2], [3, 4]];
  const dishes = picks.map(([d, i]) => HD.WEEK[d].meals[i]);
  return (
    <section className="section bg-cream" data-screen-label="Posiłki — slider">
      <div className="container">
        <Slider head={
          <SectionHead overline="Tak smakuje LightLife" title="Posiłki z przykładowego tygodnia"
            sub="Normalne jedzenie z prostych składników — bez głodówek i bez gotowania na dwa domy." />
        }>
          {dishes.map((x, i) => (
            <article className="dish-card" key={i}>
              <img src={x.img} alt={x.title} />
              <div className="dish-body">
                <span className="dish-type">{x.type}</span>
                <h4>{x.title}</h4>
                <div className="dish-macros">
                  <span><b>{x.kcal}</b> kcal</span>
                  <span>B <b>{x.p} g</b></span>
                  <span>T <b>{x.f} g</b></span>
                  <span>W <b>{x.c} g</b></span>
                </div>
              </div>
            </article>
          ))}
        </Slider>
      </div>
    </section>
  );
}

/* ── „Twoja dieta zawsze pod ręką” — interaktywna makieta aplikacji ── */
const AP_FEATURES = [
  { icon: 'meal', screen: 'plan', t: 'Menu ułożone pod Twój dzień',
    s: '4 posiłki na dziś, dopasowane do smaku i kalorii — z przepisem krok po kroku.',
    d: 'Masz 4 posiłki dziennie dopasowane do Twojego smaku, czasu i kaloryczności. Otwierasz przepis, klikasz i przechodzisz przez kolejne kroki. Koniec ze zgadywaniem, co dziś ugotować.' },
  { icon: 'shopping', screen: 'zakupy', t: 'Zakupy bez kartek i chaosu',
    s: 'Lista układa się sama z menu, poukładana pod półki w sklepie.',
    d: 'Lista tworzy się sama z Twojego menu. Produkty są ułożone według półek w sklepie, z dokładnymi gramaturami. Koniec z krążeniem między alejkami i myślą „Co ja miałam kupić?”.' },
  { icon: 'chat', screen: 'czat', t: 'Dietetyk odpisuje także w weekend',
    s: 'Piszesz w piątek wieczór i dostajesz konkretną odpowiedź — bez oceniania.',
    d: 'Piątek wieczór, dzieci chcą pizzę, a Ty nie chcesz znów odpuścić. Piszesz na czacie i szybko dostajesz konkretną odpowiedź, bez oceniania, z gotowym rozwiązaniem na tę sytuację.' },
  { icon: 'water', screen: 'woda', t: 'Koniec z zapominaniem o wodzie',
    s: 'Przypomnienia o wodzie wtedy, kiedy to ma sens — bez natarczywych alertów.',
    d: 'Za mało wody spowalnia metabolizm i odbiera energię. Aplikacja przypomina wtedy, kiedy to ma sens: rano, przed posiłkiem albo przy popołudniowym spadku sił. Bez natarczywych alertów.' },
];
const AP_GOAL = { kcal: 1650, p: 95, f: 60, c: 190 };
const AP_WATER_GOAL = 2500;
const AP_MEAL_ICONS = ['sunrise', 'apple', 'salad', 'moon']; /* placeholdery zamiast zdjęć posiłków (do uzupełnienia) */
const AP_WATER_LOG0 = [{ t: '08:15', ml: 250 }, { t: '10:30', ml: 300 }, { t: '12:40', ml: 250 }, { t: '14:10', ml: 400 }];
/* ── Kadrowanie zdjęć posiłków (osie X/Y/Z) — jeden zestaw na zdjęcie steruje kaflem i hero ──
   źródło kwadratowe 1024²: z = jaki ułamek WYSOKOŚCI źródła wypełnia placeholder (mniejsze z = większy zoom),
   x/y = punkt źródła (0–1) trafiający w środek placeholdera. Ten sam zestaw działa w kwadracie i w pasie. */
function applyFraming(el, src, fr) {
  if (!el) return;
  el.style.backgroundImage = src ? "url('" + src + "')" : 'none';
  el.style.backgroundRepeat = 'no-repeat';
  if (!src) return;
  // zdjęcia 3:2 mają danie wyśrodkowane w źródle -> proste cover + pozycja (domyślnie środek)
  el.style.backgroundSize = 'cover';
  const x = fr && fr.x != null ? fr.x : 0.5, y = fr && fr.y != null ? fr.y : 0.5;
  el.style.backgroundPosition = (x * 100) + '% ' + (y * 100) + '%';
}
function FramedPhoto({ src, fr, className }) {
  const ref = React.useRef(null);
  React.useLayoutEffect(() => {
    const el = ref.current;
    applyFraming(el, src, fr);
    if (!el || typeof ResizeObserver === 'undefined') return;
    const ro = new ResizeObserver(() => applyFraming(el, src, fr));
    ro.observe(el);
    return () => ro.disconnect();
  }, [src, fr && fr.x, fr && fr.y, fr && fr.z]);
  return <div ref={ref} className={className}></div>;
}
/* rozbicie składnika "Płatki owsiane 60 g" → { n:'Płatki owsiane', q:'60 g' } (ilość z końca — "Mleko 2% 250 ml" zostaje "Mleko 2%") */
function apParseIng(ing) {
  const m = ing.match(/([\d½¼¾⅓⅔][\d.,/]*\s?(?:g|kg|ml|l|szt\.?|łyżk\w*|łyżeczk\w*|puszk\w*|plaster\w*|garś\w*|kromk\w*|opakowan\w*)?)\s*$/i);
  if (!m || m.index === 0) return { n: ing.trim(), q: '' };
  return { n: ing.slice(0, m.index).trim().replace(/[,·]\s*$/, ''), q: m[1].trim() };
}
/* dopasowanie składnika do kategorii sklepowej */
function apCat(name) {
  const s = name.toLowerCase();
  if (/kurczak|indyk|łoso|dorsz|tuńczyk|makrel|wołow|schab|mielon|pulpet|szynk|ryb|krewetk/.test(s)) return 'Mięso i ryby';
  if (/jaj|twar|skyr|jogurt|kefir|serek|\bser\b|mleko|śmietan|feta|mozzarell|maślank|parmez/.test(s)) return 'Nabiał i jaja';
  if (/ryż|kasz|płatk|makaron|chleb|tortill|mąk|pieczyw|tost|bułk|grzank|wrap|spaghetti|kromk|granol/.test(s)) return 'Pieczywo i produkty suche';
  if (/jabłk|banan|borówk|malin|truskawk|gruszk|pomarańcz|owoc|cytryn|rodzynk|bakali|migdał|orzech|daktyl/.test(s)) return 'Owoce i orzechy';
  if (/brokuł|marchew|pomidor|ogór|sałat|warzyw|cebul|papryk|szpinak|awokado|ziemniak|dyni|burak|cukini|rzodkiew|kukurydz|hummus|groszek|fasol|ciecierzyc|seler|batat|rukol|jarmuż/.test(s)) return 'Warzywa';
  return 'Dodatki i przyprawy';
}
/* lista zakupów zbudowana ze składników posiłków danego dnia (dedup) */
function apShopList(meals) {
  const order = ['Warzywa', 'Owoce i orzechy', 'Mięso i ryby', 'Nabiał i jaja', 'Pieczywo i produkty suche', 'Dodatki i przyprawy'];
  const cats = {}, seen = {};
  meals.forEach((m) => (m.ing || []).forEach((ing) => {
    const p = apParseIng(ing);
    const key = p.n.toLowerCase();
    if (!p.n || seen[key]) return;
    seen[key] = 1;
    const c = apCat(p.n);
    (cats[c] = cats[c] || []).push({ id: 'sh-' + key.replace(/[^a-ząćęłńóśźż0-9]+/g, '-'), n: p.n, q: p.q });
  }));
  return order.filter((c) => cats[c]).map((c) => ({ cat: c, items: cats[c] }));
}
/* copy makiety (napisane przez copywritera marki) */
const AP_COPY = {
  greeting: 'Cześć 👋',
  dietitian: 'Kornelia',
  chat: [
    { who: 'me', t: 'Kornelia, ratuj 😩', time: '17:24' },
    { who: 'me', t: 'Mam potworną ochotę na coś słodkiego, walczę z tym od godziny', time: '17:24' },
    { who: 'diet', t: 'To nie walcz 😄 co masz pod ręką w domu?', time: '17:26' },
    { who: 'me', t: 'Jogurt naturalny, banan i trochę orzechów', time: '17:27' },
    { who: 'diet', t: 'Idealnie 🙌 jogurt, pokrojony banan, łyżka orzechów i szczypta cynamonu. Słodko, sycąco i dalej w planie 💛', time: '17:28' },
    { who: 'me', t: 'O, brzmi super. Robię!', time: '17:28' },
    { who: 'diet', t: 'I tak to się robi 💪 daj znać, jak poszło', time: '17:29' },
  ],
  quick: {
    'Nie zdążę dziś ugotować 😅': 'Bez stresu 🙂 podmieniam obiad na wrapa z grillowanym kurczakiem, awokado i sosem jogurtowo-czosnkowym. 10 minut i gotowe 😋 Masz to już w planie 👌',
    'Czym zastąpić chleb?': 'Sprawdzą się placuszki jaglane albo pełnoziarnisty wrap. Wrzucam Ci gramaturę do menu.',
    'Waga stoi od tygodnia 😕': 'To zupełnie normalne, ciało czasem się zatrzymuje. Trzymamy kurs, zwykle w kolejnym tygodniu rusza. Zerknę na Twoje posiłki i napiszę.',
  },
  waterTip: 'Trzymaj butelkę na biurku — łatwiej pić łyk po łyku, niż nadrabiać wieczorem.',
  waterReminder: (n) => n === 0
    ? 'Cel na dziś osiągnięty 💧'
    : 'Do celu ' + (n === 1 ? 'została 1 szklanka' : n < 5 ? 'zostały ' + n + ' szklanki' : 'zostało ' + n + ' szklanek') + ' — przypomnę Ci w dobrym momencie.',
  eatCta: 'Zjadłam to',
  eatDone: 'Zjedzone ✓',
  shopHint: 'Lista układa się sama z Twojego menu — nic nie musisz spisywać.',
  notScreenshot: 'To nie zrzut ekranu — kliknij i sprawdź, jak to działa. Zaznacz posiłek, dolej wodę, napisz do mnie na czacie.',
};

/* pierścień postępu (dowolna liczba współśrodkowych łuków) */
function AppRing({ arcs, big, sub, size = 118 }) {
  return (
    <div className="ap-ring" style={{ width: size, height: size }}>
      <svg viewBox="0 0 120 120" width={size} height={size}>
        <g transform="rotate(-90 60 60)" fill="none" strokeLinecap="round">
          {arcs.map((a, i) => {
            const c = 2 * Math.PI * a.r;
            return (
              <React.Fragment key={i}>
                <circle cx="60" cy="60" r={a.r} stroke={a.track} strokeWidth={a.w} />
                <circle cx="60" cy="60" r={a.r} stroke={a.color} strokeWidth={a.w}
                  strokeDasharray={(c * Math.min(1, Math.max(0, a.pct))).toFixed(1) + ' ' + c.toFixed(1)} />
              </React.Fragment>
            );
          })}
        </g>
      </svg>
      <div className="ap-ring-c"><b>{big}</b><span>{sub}</span></div>
    </div>
  );
}

function AppPhone({ tab, setTab, framing }) {
  const [dayIdx, setDayIdx] = React.useState(0);
  const [meal, setMeal] = React.useState(null);
  const [eaten, setEaten] = React.useState({ 0: true, 1: true });
  const [checked, setChecked] = React.useState({ 'sh-płatki-owsiane': true, 'sh-borówki': true, 'sh-mleko-2-': true, 'sh-oliwa': true, 'sh-miód': true, 'sh-cytryna': true, 'sh-migdały': true, 'sh-granola': true, 'sh-komosa-ryżowa': true });
  const [filter, setFilter] = React.useState('all');
  const [waterMl, setWaterMl] = React.useState(1200);
  const [waterLog, setWaterLog] = React.useState(AP_WATER_LOG0);
  const [chat, setChat] = React.useState(AP_COPY.chat);
  const [usedQuick, setUsedQuick] = React.useState([]);
  const [typing, setTyping] = React.useState(false);
  const [stepsDone, setStepsDone] = React.useState({});
  const scrollRef = React.useRef(null);
  const apNow = () => { const d = new Date(); return d.getHours() + ':' + String(d.getMinutes()).padStart(2, '0'); };

  const meals = [0, 1, 2, 4].map((i) => HD.WEEK[dayIdx].meals[i]);
  const shop = React.useMemo(() => apShopList(meals), [dayIdx]);
  React.useEffect(() => { setMeal(null); }, [tab]);
  React.useEffect(() => {
    if (!scrollRef.current) return;
    scrollRef.current.scrollTop = tab === 'czat' ? scrollRef.current.scrollHeight : 0;
  }, [tab, meal, chat, typing]);
  /* scroll wnętrza telefonu: kółko myszy + przeciąganie jak palcem po ekranie */
  React.useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    const col = el.closest('.ap-phone-col');
    const scale = (col && parseFloat(getComputedStyle(col).getPropertyValue('--happ-s'))) || 1;
    const onWheel = (e) => {
      if (el.scrollHeight <= el.clientHeight) return; /* nic do przewinięcia — puść stronę */
      el.scrollTop += e.deltaY;
      e.preventDefault();
    };
    let dragY = null, dragTop = 0, moved = 0;
    const down = (e) => { dragY = e.clientY; dragTop = el.scrollTop; moved = 0; };
    const move = (e) => {
      if (dragY == null) return;
      const dy = e.clientY - dragY;
      moved = Math.max(moved, Math.abs(dy));
      if (moved > 6) el.scrollTop = dragTop - dy / scale;
    };
    const up = () => { dragY = null; };
    const click = (e) => { /* po przeciągnięciu nie odpalaj kliknięcia w przycisk */
      if (moved > 6) { e.stopPropagation(); e.preventDefault(); moved = 0; }
    };
    el.addEventListener('wheel', onWheel, { passive: false });
    el.addEventListener('pointerdown', down);
    window.addEventListener('pointermove', move);
    window.addEventListener('pointerup', up);
    el.addEventListener('click', click, true);
    return () => {
      el.removeEventListener('wheel', onWheel);
      el.removeEventListener('pointerdown', down);
      window.removeEventListener('pointermove', move);
      window.removeEventListener('pointerup', up);
      el.removeEventListener('click', click, true);
    };
  }, []);

  const eatenT = meals.reduce((a, x, i) => eaten[i] ? { kcal: a.kcal + x.kcal, p: a.p + x.p, f: a.f + x.f, c: a.c + x.c } : a, { kcal: 0, p: 0, f: 0, c: 0 });
  const remaining = Math.max(0, AP_GOAL.kcal - eatenT.kcal);
  const allIds = shop.flatMap((c) => c.items.map((i) => i.id));
  const doneCount = allIds.filter((id) => checked[id]).length;
  const sendQuick = (q) => {
    setUsedQuick((u) => [...u, q]);
    setChat((c) => [...c, { who: 'me', t: q, time: apNow() }]);
    setTyping(true);
    setTimeout(() => { setTyping(false); setChat((c) => [...c, { who: 'diet', t: AP_COPY.quick[q], time: apNow() }]); }, 1300);
  };
  const addWater = () => {
    const d = new Date();
    setWaterMl((w) => w + 250);
    setWaterLog((l) => [...l, { t: d.getHours() + ':' + String(d.getMinutes()).padStart(2, '0'), ml: 250 }]);
  };

  let screen;
  if (meal != null) {
    const m = meals[meal];
    screen = (
      <div className="ap-recipe">
        <div className="ap-rphoto" role="img" aria-label="Zdjęcie posiłku (do wstawienia)">
          <button type="button" className="ap-back-fl" onClick={() => setMeal(null)} aria-label="Wróć do planu"><Icon name="arrow-left" size={17} /></button>
          {m.img ? <FramedPhoto src={m.img} fr={framing && framing[m.img]} className="fph" /> : <LucideIcon name={AP_MEAL_ICONS[meal]} size={32} />}
        </div>
        <div className="ap-rbody">
          <span className="ap-rtype">{m.type} · {m.time}</span>
          <h4>{m.title}</h4>
          <div className="ap-rkcal">
            <div className="ap-rkcal-n"><b>{m.kcal}</b><span>kcal</span></div>
            <div className="ap-rkcal-m">
              <span className="mac-p"><b>{m.p} g</b><i>białko</i></span>
              <span className="mac-f"><b>{m.f} g</b><i>tłuszcze</i></span>
              <span className="mac-c"><b>{m.c} g</b><i>węgle</i></span>
            </div>
          </div>
          <button type="button" className={'ap-eat-btn' + (eaten[meal] ? ' on' : '')} onClick={() => setEaten((e) => ({ ...e, [meal]: !e[meal] }))}>
            <Icon name={eaten[meal] ? 'check-circle' : 'plus'} size={16} /> {eaten[meal] ? AP_COPY.eatDone : AP_COPY.eatCta}
          </button>
          <div className="ap-sec">Składniki <em>{m.ing.length}</em></div>
          <ul className="ap-ing">
            {m.ing.map((x) => { const p = apParseIng(x); return <li key={x}><span>{p.n}</span><b>{p.q}</b></li>; })}
          </ul>
          <div className="ap-sec">Przygotowanie <em>{m.steps.length} kroki</em></div>
          <ol className="ap-steps">
            {m.steps.map((s, i) => {
              const k = meal + '-' + i;
              return (
                <li key={i} className={stepsDone[k] ? 'done' : ''} onClick={() => setStepsDone((d) => ({ ...d, [k]: !d[k] }))}>{s}</li>
              );
            })}
          </ol>
          <p className="ap-rhint">Kliknij krok, kiedy go skończysz — nic nie umknie.</p>
        </div>
      </div>
    );
  } else if (tab === 'plan') {
    const bars = [['Węgle', eatenT.c, AP_GOAL.c, 'mac-c'], ['Białka', eatenT.p, AP_GOAL.p, 'mac-p'], ['Tłuszcze', eatenT.f, AP_GOAL.f, 'mac-f']];
    screen = (
      <div className="ap-plan">
        <div className="ap-head">
          <div><span>{AP_COPY.greeting}</span><b>Karolina</b></div>
          <span className="ap-ava" aria-hidden="true"><img src="assets/reviews/karolina.webp" alt="" /></span>
        </div>
        <div className="hs-week ap-hs">
          {HD.WEEK.map((d, i) => (
            <button key={d.d} type="button" className={'hs-day' + (i === dayIdx ? ' today' : '') + (i < dayIdx ? ' done' : '')} onClick={() => setDayIdx(i)}>
              <i>{d.d[0]}</i>
              <span>{i < dayIdx ? <Icon name="check" size={13} /> : d.date.split('.')[0]}</span>
            </button>
          ))}
        </div>
        <div className="ap-card">
          <div className="ap-ringrow">
            <div className="ap-rside"><span>Spożyte</span><b>{eatenT.kcal}</b><i>kcal</i></div>
            <AppRing size={122}
              arcs={[
                { r: 52, w: 11, color: 'var(--gold)', track: 'var(--gold-100)', pct: eatenT.kcal / AP_GOAL.kcal },
              ]}
              big={remaining} sub="kcal zostało" />
            <div className="ap-rside"><span>Cel</span><b>{AP_GOAL.kcal}</b><i>kcal</i></div>
          </div>
          <div className="ap-bars">
            {bars.map(([l, v, g, k]) => (
              <div key={l} className={'ap-bar ' + k}>
                <i>{l}</i>
                <u><s style={{ width: Math.min(100, Math.round(v / g * 100)) + '%' }}></s></u>
                <em><b>{v}</b> / {g} g</em>
              </div>
            ))}
          </div>
        </div>
        <div className="ap-label">Plan na dziś <em>{eatenT.kcal} / {AP_GOAL.kcal} kcal</em></div>
        <div className="ap-meals">
          {meals.map((x, i) => (
            <div key={i} className={'ap-meal' + (eaten[i] ? ' eaten' : '')}>
              <button type="button" className="ap-meal-main" onClick={() => setMeal(i)}>
                <span className="ap-meal-ph" role="img" aria-label={'Zdjęcie: ' + x.title}>{x.img ? <FramedPhoto src={x.img} fr={framing && framing[x.img]} className="fph" /> : <LucideIcon name={AP_MEAL_ICONS[i]} size={20} />}</span>
                <span>
                  <i>{x.type} · {x.time}</i>
                  <b>{x.title}</b>
                  <u>{x.kcal} kcal · B {x.p} · T {x.f} · W {x.c}</u>
                </span>
              </button>
              <button type="button" className="ap-eat" onClick={() => setEaten((e) => ({ ...e, [i]: !e[i] }))} aria-label="Zjedzone">
                <Icon name={eaten[i] ? 'check' : 'plus'} size={15} />
              </button>
            </div>
          ))}
        </div>
      </div>
    );
  } else if (tab === 'zakupy') {
    const vis = (it) => filter === 'all' || (filter === 'todo' ? !checked[it.id] : !!checked[it.id]);
    screen = (
      <div className="ap-shop">
        <div className="ap-shop-top">
          <div className="ap-shop-title"><b>Lista zakupów</b><span>{AP_COPY.shopHint}</span></div>
          <div className="ap-store"><LucideIcon name="shopping-bag" size={14} /> <em>{allIds.length}</em> produktów · {meals.length} posiłki</div>
        </div>
        <div className="hs-week ap-hs">
          {HD.WEEK.map((d, i) => (
            <button key={d.d} type="button" className={'hs-day' + (i === dayIdx ? ' today' : '') + (i < dayIdx ? ' done' : '')} onClick={() => setDayIdx(i)}>
              <i>{d.d[0]}</i>
              <span>{i < dayIdx ? <Icon name="check" size={13} /> : d.date.split('.')[0]}</span>
            </button>
          ))}
        </div>
        <div className="ap-filters">
          {[['all', 'Wszystko'], ['todo', 'Do kupienia'], ['have', 'Mam w domu']].map(([k, l]) => (
            <button key={k} type="button" className={'ap-filter' + (filter === k ? ' on' : '')} onClick={() => setFilter(k)}>{l}</button>
          ))}
          <span className="ap-count">{doneCount}/{allIds.length}</span>
        </div>
        <div className="ap-shop-prog" role="progressbar"><s style={{ width: (allIds.length ? Math.round(doneCount / allIds.length * 100) : 0) + '%' }}></s></div>
        <div className="ap-shop-list">
          {shop.map((c) => {
            const items = c.items.filter(vis);
            if (!items.length) return null;
            return (
              <div key={c.cat} className="ap-cat">
                <div className="ap-cat-l">{c.cat}</div>
                {items.map((it) => (
                  <button key={it.id} type="button" className={'ap-item' + (checked[it.id] ? ' done' : '')} onClick={() => setChecked((s) => ({ ...s, [it.id]: !s[it.id] }))}>
                    <span className="ap-box">{checked[it.id] ? <Icon name="check" size={13} /> : null}</span>
                    <span className="ap-item-n">{it.n}</span>
                    <span className="ap-item-q">{it.q}</span>
                  </button>
                ))}
              </div>
            );
          })}
          <div className="ap-add"><Icon name="plus" size={15} /> Dodaj własny produkt</div>
        </div>
      </div>
    );
  } else if (tab === 'czat') {
    const quick = Object.keys(AP_COPY.quick).filter((q) => !usedQuick.includes(q));
    screen = (
      <div className="ap-chat">
        <div className="ap-chat-head">
          <span className="ap-chat-ava" aria-hidden="true"><img src="assets/kornelia-ava.webp" alt="" /></span>
          <div>
            <b>{AP_COPY.dietitian} · Twój dietetyk</b>
            <span className="ap-online"><i></i> {typing ? 'pisze…' : 'aktywna teraz'}</span>
          </div>
          <div className="ap-chat-actions">
            <button type="button" className="ap-chat-act" aria-label="Połączenie wideo"><LucideIcon name="video" size={18} /></button>
            <button type="button" className="ap-chat-act" aria-label="Połączenie głosowe"><LucideIcon name="phone" size={16} /></button>
          </div>
        </div>
        <div className="ap-chat-body">
          <div className="ap-chat-day">dzisiaj</div>
          {chat.map((m, i) => (
            <div key={i} className={'ap-row ' + m.who}>
              <div className={'ap-msg ' + m.who}>{m.t}<time>{m.time}</time></div>
              {m.who === 'me' && i === chat.length - 1 && !typing ? <span className="ap-seen">Wyświetlono</span> : null}
            </div>
          ))}
          {typing ? <div className="ap-row diet"><div className="ap-typing"><span></span><span></span><span></span></div></div> : null}
        </div>
        <div className="ap-chat-foot">
          {quick.length ? (
            <div className="ap-sugg">
              {quick.map((q) => <button key={q} type="button" onClick={() => sendQuick(q)}>{q}</button>)}
            </div>
          ) : null}
          <div className="ap-inputbar">
            <span className="ap-input">Napisz wiadomość…</span>
            <button type="button" className="ap-send" aria-label="Wyślij"><LucideIcon name="send-solid" size={17} /></button>
          </div>
        </div>
      </div>
    );
  } else {
    const wpct = Math.round(waterMl / AP_WATER_GOAL * 100);
    screen = (
      <div className="ap-water">
        <div className="ap-water-head">
          <div><b>Nawodnienie</b><span>Cel {(AP_WATER_GOAL / 1000).toFixed(1)} l dziennie</span></div>
          <span className="ap-water-pct">{wpct}%</span>
        </div>
        <div className="ap-water-ring">
          <AppRing size={150}
            arcs={[{ r: 52, w: 11, color: 'var(--blue)', track: 'var(--blue-100)', pct: waterMl / AP_WATER_GOAL }]}
            big={waterMl} sub={'/ ' + AP_WATER_GOAL + ' ml'} />
        </div>
        <button type="button" className="ap-water-add" onClick={addWater}>
          <LucideIcon name="droplet" size={18} /> Wypiłam szklankę (250 ml)
        </button>
        <div className="ap-water-tip"><Icon name="info" size={14} /> {AP_COPY.waterTip}</div>
        <div className="ap-water-rem"><Icon name="bell" size={13} /> {AP_COPY.waterReminder(Math.ceil(Math.max(0, AP_WATER_GOAL - waterMl) / 250))}</div>
        <div className="ap-log-h">Dzisiejsze zapisy</div>
        <div className="ap-log">
          {[...waterLog].reverse().map((e, i) => (
            <div key={i} className="ap-log-row">
              <span className="ap-log-ic"><LucideIcon name="droplet" size={13} /></span>
              <b>{e.t}</b><em>+{e.ml} ml</em>
            </div>
          ))}
        </div>
      </div>
    );
  }

  const tabs = [
    { id: 'plan', icon: 'calendar-check' },
    { id: 'zakupy', icon: 'shopping-bag' },
    { id: 'czat', icon: 'message-circle' },
    { id: 'woda', icon: 'droplet' },
  ];

  return (
    <div className="ap-screen">
      <div className="ap-scroll" ref={scrollRef}>{screen}</div>
      <div className="ap-tabs">
        {tabs.map((t) => (
          <button key={t.id} type="button" className={'ap-tab' + (tab === t.id ? ' on' : '')} onClick={() => setTab(t.id)} aria-label={t.id}>
            <LucideIcon name={t.icon} size={21} />
          </button>
        ))}
      </div>
    </div>
  );
}

function FramingEditor({ framing, setFr }) {
  const meals = [];
  (HD.WEEK || []).forEach((day) => (day.meals || []).forEach((mm) => {
    if (mm.img && mm.img.indexOf('dish-gen/') >= 0) meals.push({ key: mm.img, label: day.d + ' · ' + mm.type + ' — ' + mm.title });
  }));
  const [sel, setSel] = React.useState(meals.length ? meals[0].key : '');
  const [status, setStatus] = React.useState('');
  if (!meals.length) return null;
  const fr = Object.assign({ x: 0.5, y: 0.5, z: 0.5 }, framing[sel] || {});
  const rows = [['x', 'X · lewo — prawo', 0, 1], ['y', 'Y · góra — dół', 0, 1], ['z', 'Z · zoom (mniej = bliżej)', 0.12, 1]];
  const save = () => {
    fetch('/api/meal-framing', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(framing) })
      .then((r) => r.json()).then(() => setStatus('Zapisano do pliku ✓')).catch(() => setStatus('Błąd zapisu — serwer?'));
    setTimeout(() => setStatus(''), 3000);
  };
  return (
    <div className="kadr-panel">
      <div className="kadr-h">Kadrowanie zdjęć <em>osie X / Y / Z</em></div>
      <select className="kadr-sel" value={sel} onChange={(e) => setSel(e.target.value)}>
        {meals.map((m) => <option key={m.key} value={m.key}>{m.label}</option>)}
      </select>
      <div className="kadr-prev">
        <div className="kadr-prev-hero"><FramedPhoto src={sel} fr={fr} className="fph" /><span>hero</span></div>
        <div className="kadr-prev-tile"><FramedPhoto src={sel} fr={fr} className="fph" /><span>kafel</span></div>
      </div>
      {rows.map(([k, lab, mn, mx]) => (
        <label key={k} className="kadr-row">
          <span>{lab}</span>
          <input type="range" min={mn} max={mx} step="0.002" value={fr[k]} onChange={(e) => setFr(sel, { [k]: parseFloat(e.target.value) })} />
          <b>{Number(fr[k]).toFixed(3)}</b>
        </label>
      ))}
      <button type="button" className="kadr-save" onClick={save}>Zapisz wszystkie kadry</button>
      <span className="kadr-status">{status}</span>
    </div>
  );
}

function AppShowcase() {
  const [tab, setTab] = React.useState('plan');
  const [framing, setFraming] = React.useState({});
  const kadr = typeof location !== 'undefined' && /kadr/.test(location.hash + location.search);
  React.useEffect(() => {
    try { localStorage.removeItem('mealFraming'); } catch (e) {}   // usuń stare nadpisania z przeglądarki
    // plik meal-framing.json jest JEDYNYM źródłem prawdy
    fetch('data/meal-framing.json?v=' + Date.now()).then((r) => (r.ok ? r.json() : {})).then((base) => setFraming(base || {})).catch(() => setFraming({}));
  }, []);
  const setFr = (key, patch) => setFraming((f) => {
    const next = Object.assign({}, f);
    next[key] = Object.assign({ x: 0.5, y: 0.5, z: 0.5 }, f[key] || {}, patch);
    return next;
  });
  return (
    <section className="section bg-cream ap-section" id="aplikacja" data-screen-label="Aplikacja — interaktywna makieta">
      <SectionWave fill="white" />
      <div className="container">
        <CenterHead
          title={<>Otwierasz telefon i od razu wiesz,<br />co zjeść, co kupić i co dalej.</>}
          sub={'Menu na dziś, lista zakupów pod sklep, przepisy krok po kroku i dietetyk na czacie, wszystko w jednym miejscu. Bez zgadywania, bez kartek, bez „co ja miałam dzisiaj ugotować”.'} />
        <div className="ap4-grid">
          <div className="ap4-phone">
            <div className="iphone-fit">
              <IPhoneFrame>
                <IOSDevice width={402} height={874}><AppPhone tab={tab} setTab={setTab} framing={framing} /></IOSDevice>
              </IPhoneFrame>
            </div>
          </div>
          <div className="ap4-rows">
            {AP_FEATURES.map((f, i) => (
              <article key={f.screen} className={'ap4-row' + (tab === f.screen ? ' on' : '')}>
                <button type="button" className="ap4-btn" onClick={() => setTab(f.screen)} aria-pressed={tab === f.screen}>
                  <span className="ap4-num">{String(i + 1).padStart(2, '0')}</span>
                  <span className="ap4-body">
                    <span className="ap4-t">{f.t}</span>
                    <span className="ap4-d">{f.d}</span>
                  </span>
                </button>
              </article>
            ))}
          </div>
        </div>
        <div className="jb jb--coral ap-band">
          <p className="jb-q">Otwierasz telefon i wiesz, co zjeść, co kupić i co dalej.</p>
          <Button variant="primary" className="jb-btn" arrow href="oferta.html">Sprawdź ofertę</Button>
        </div>
        {kadr && <FramingEditor framing={framing} setFr={setFr} />}
      </div>
    </section>
  );
}

/* ── „Historia metamorfozy” — oś czasu jednej przemiany (zdjęcie reaguje na wybrany miesiąc) ── */
const MS_STEPS = [
  { n: '01', icon: 'wine', label: 'Start', kg: '0 kg', d: 'Po drugim dziecku waga została i rosła dalej, a Aneta tłumaczyła to zmęczeniem i brakiem czasu. Aż na badaniach kontrolnych wyszła insulinooporność i podwyższony cukier, a lekarka powiedziała wprost, że tak zaczyna się cukrzyca. Nie chciała czekać, aż „zaczyna się” zamieni się w diagnozę, więc następnego dnia napisała do LightLife.' },
  { n: '02', icon: 'leaf-hand', label: '1 miesiąc', kg: '−4 kg', d: 'Pierwszy miesiąc nie był łatwy: dwójka dzieci, gotowanie na szybko i wieczne dojadanie po maluchach. Dietetyk z LightLife nie kazał jej gotować osobno, tylko ułożył plan pod to, co i tak robiła dla rodziny. Zeszły 4 kilo, ale ważniejsze było to, że po posiłkach przestało ją tak ścinać z sił.' },
  { n: '03', icon: 'trending-down', label: '2 miesiąc', kg: '−8 kg', d: 'W drugim miesiącu złapała rytm. Pudełka do pracy szykowała przy okazji śniadania dla dzieci, a popołudniami miała siłę pobiegać z nimi po placu zabaw, zamiast siedzieć na ławce. Waga pokazała 8 kilo mniej, a napady na słodkie, które kiedyś ratowały ją przy zmęczeniu, po prostu odpuściły.' },
  { n: '04', icon: 'activity', label: '3 miesiąc', kg: '−14 kg', d: 'Po trzech miesiącach zniknęło 14 kilo, ale najbardziej ucieszyły ją wyniki. Cukier na czczo wrócił do normy, a lekarka pierwszy raz powiedziała „tak trzymać”. Aneta zapięła kurtkę, w której po ciąży nie mogła złapać nawet zamka, i pomyślała, że robi to nie dla rozmiaru, tylko żeby być zdrową dla dzieci.' },
  { n: '05', icon: 'heart', label: '4 miesiąc', kg: '−20 kg', d: 'Przy minus 20 kilo zmieniło się coś więcej niż liczba na wadze. Na rodzinnym obiedzie nie chowała się już w luźnym swetrze narzuconym „na wszelki wypadek”, tylko włożyła sukienkę i sama poprosiła męża o wspólne zdjęcie z dziećmi. Nie skasowała go po chwili, jak kiedyś.' },
  { n: '06', icon: 'sparkles', label: '5 miesiąc', kg: '−26 kg', d: 'W piątym miesiącu wszystko zrobiło się zwyczajne. Jedzenie przestało chodzić jej po głowie od rana do wieczora, jak przez ostatnie lata. Wieczorami, zamiast zajadać zmęczenie chipsami przed serialem, kroiła dzieciom owoce i szykowała plan na rano, bo to był już jej rytm, nie dieta.' },
  { n: '07', icon: 'trophy', label: '6 miesiąc', kg: '−30 kg', d: 'Po pół roku było jej o 30 kilo lżej, a badania wyglądały tak, jakby insulinooporności nigdy nie było. Weszła z zakupami na trzecie piętro i nie musiała już łapać oddechu w połowie schodów. Pierwszy raz od lat czuła, że nadąża za własnymi dziećmi.' },
];

function MetamorfozaStory() {
  const [step, setStep] = React.useState(0);
  const active = MS_STEPS[step];
  const framesRef = React.useRef(null);
  React.useEffect(() => {
    const frames = framesRef.current;
    if (!frames) return;
    const el = frames.children[step];
    if (!el) return;
    const cRect = frames.getBoundingClientRect();
    const eRect = el.getBoundingClientRect();
    const target = frames.scrollLeft + (eRect.left - cRect.left) - (frames.clientWidth - eRect.width) / 2;
    frames.scrollLeft = Math.max(0, target);
  }, [step]);
  return (
    <section className="section bg-white ms-section" id="metamorfoza-aneta" data-screen-label="Historia metamorfozy — Aneta">
      <div className="container">
        <CenterHead
          title="Diagnoza była alarmem. Pół roku później nie ma po niej śladu."
          sub="Po drugiej ciąży waga rosła, aż lekarka ostrzegła, że tak zaczyna się cukrzyca. Zobacz, jak między pracą a dwójką dzieci Aneta zrzuciła w pół roku 30 kg i odzyskała zdrowie, bez głodówek i ważenia się co rano." />
        <div className="msf-strip">
          <button type="button" className="ms-arrow ms-left" onClick={() => setStep(Math.max(0, step - 1))} disabled={step === 0} aria-label="Poprzedni miesiąc"><Icon name="arrow-left" size={22} /></button>
          <div className="msf-frames" ref={framesRef}>
            {MS_STEPS.map((s, i) => (
              <div key={s.n} className={'msf-frame' + (i === step ? ' on' : '')} role="button" tabIndex={0}
                aria-label={s.label + ', ' + s.kg} aria-pressed={i === step}
                onClick={() => setStep(i)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setStep(i); } }}>
                <span className="msf-ph">
                  <image-slot id={'meta-aneta-' + s.n} shape="rect" fit="cover"
                    src={'assets/aneta/aneta-' + s.n + '.webp'}
                    placeholder={'Aneta — ' + s.label}
                    style={{ width: '100%', height: '100%' }}></image-slot>
                </span>
                <span className="msf-cap">{s.label}</span>
              </div>
            ))}
          </div>
          <button type="button" className="ms-arrow ms-right" onClick={() => setStep(Math.min(MS_STEPS.length - 1, step + 1))} disabled={step === MS_STEPS.length - 1} aria-label="Następny miesiąc"><Icon name="arrow-right" size={22} /></button>
        </div>
        <div className="msf-body">
          <div className="msf-head">
            <p className="msx-kg">{active.kg}</p>
            <p className="msx-label">{active.label}</p>
          </div>
          <p className="msf-d">{active.d}</p>
        </div>
        <div className="band-duo">
          <div className="jb jb--blue">
            <p className="jb-q">Następna taka historia może być Twoja.</p>
            <Button variant="primary" className="jb-btn" arrow href="oferta.html">Sprawdź ofertę</Button>
          </div>
          <div className="jb jb--gold">
            <p className="jb-q">Aneta nie jest wyjątkiem. Zobacz resztę.</p>
            <Button variant="primary" className="jb-btn" arrow href="metamorfozy.html">Zobacz metamorfozy</Button>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ── „Smak, do którego się wraca” — MealCard przeniesiona do site/shared.jsx (jedno źródło: home + oferta) ── */
const MENU_CAT_ICON = { 'Śniadanie': 'sunrise', 'II śniadanie': 'apple', 'Obiad': 'utensils', 'Kolacja': 'moon' };
function TastySection() {
  const cats = HD.MENU;
  const [cat, setCat] = React.useState(0);
  return (
    <section className="section bg-cream tasty" data-screen-label="Smak, do którego się wraca">
      <SectionWave fill="white" />
      <div className="container">
        <CenterHead
          title="Schudniesz jedząc to, co naprawdę kochasz."
          sub="Naleśniki w niedzielę, makaron po pracy, schabowy u rodziców, pizza z dzieciakami. To nie odstępstwa od diety. To część planu. Układamy jadłospis z tego, co naprawdę jesz, tylko w proporcjach, przy których waga w końcu rusza w dół." />
        <div className="menu-hint">Wybierz kategorię, aby zobaczyć posiłki</div>
        <div className="menu-tabs" role="tablist">
          {cats.map((c, i) => (
            <button key={c.cat} type="button" role="tab" aria-selected={cat === i}
              className={'menu-tab' + (cat === i ? ' on' : '')} onClick={() => setCat(i)}>
              <span className="menu-fi-icon" aria-hidden="true"><LucideIcon name={MENU_CAT_ICON[c.cat] || 'utensils'} size={18} /></span>
              <span>{c.cat}</span>
            </button>
          ))}
        </div>
        <ArrowSlider key={cat} progress autoplay>
          {cats[cat].meals.map((m, i) => <MealCard key={i} m={m} slotId={'menu-' + cat + '-' + i} />)}
        </ArrowSlider>
      </div>
    </section>
  );
}

/* ── Opinie (symulacja Google) ── */
/* ── Ikony Lucide (dokładne ścieżki ze strony LightLife), renderowane w naszym kolorze ── */
const LUCIDE = {
  'heart-handshake': <path d="M19.414 14.414C21 12.828 22 11.5 22 9.5a5.5 5.5 0 0 0-9.591-3.676.6.6 0 0 1-.818.001A5.5 5.5 0 0 0 2 9.5c0 2.3 1.5 4 3 5.5l5.535 5.362a2 2 0 0 0 2.879.052 2.12 2.12 0 0 0-.004-3 2.124 2.124 0 1 0 3-3 2.124 2.124 0 0 0 3.004 0 2 2 0 0 0 0-2.828l-1.881-1.882a2.41 2.41 0 0 0-3.409 0l-1.71 1.71a2 2 0 0 1-2.828 0 2 2 0 0 1 0-2.828l2.823-2.762" />,
  /* ikony osi metamorfozy — dokładnie z lightlifediet.pl */
  'wine': <><path d="M12 3v18" /><path d="m19 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" /><path d="m5 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M7 21h10" /></>,
  'leaf-hand': <><path d="M14 9.536V7a4 4 0 0 1 4-4h1.5a.5.5 0 0 1 .5.5V5a4 4 0 0 1-4 4 4 4 0 0 0-4 4c0 2 1 3 1 5a5 5 0 0 1-1 3" /><path d="M4 9a5 5 0 0 1 8 4 5 5 0 0 1-8-4" /><path d="M5 21h14" /></>,
  'trending-down': <><path d="M16 17h6v-6" /><path d="m22 17-8.5-8.5-5 5L2 7" /></>,
  'activity': <path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />,
  'heart': <path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5" />,
  'trophy': <><path d="M10 14.66v1.626a2 2 0 0 1-.976 1.696A5 5 0 0 0 7 21.978" /><path d="M14 14.66v1.626a2 2 0 0 0 .976 1.696A5 5 0 0 1 17 21.978" /><path d="M18 9h1.5a1 1 0 0 0 0-5H18" /><path d="M4 22h16" /><path d="M6 9a6 6 0 0 0 12 0V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1z" /><path d="M6 9H4.5a1 1 0 0 1 0-5H6" /></>,
  'message-circle': <path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />,
  'sparkles': <><path d="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z" /><path d="M20 2v4" /><path d="M22 4h-4" /><circle cx="4" cy="20" r="2" /></>,
  'calendar-check': <><path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /><path d="m9 16 2 2 4-4" /></>,
  'compass': <><circle cx="12" cy="12" r="10" /><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z" /></>,
  'heart-pulse': <><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5" /><path d="M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27" /></>,
  'clock': <><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></>,
  'wallet': <><path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" /><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" /></>,
  'utensils': <><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2" /><path d="M7 2v20" /><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7" /></>,
  'shopping-bag': <><path d="M16 10a4 4 0 0 1-8 0" /><path d="M3.103 6.034h17.794" /><path d="M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z" /></>,
  'moon': <path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" />,
  'apple': <><path d="M12 6.528V3a1 1 0 0 1 1-1h0" /><path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21" /></>,
  'flame': <path d="M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4" />,
  'dumbbell': <><path d="M17.596 12.768a2 2 0 1 0 2.829-2.829l-1.768-1.767a2 2 0 0 0 2.828-2.829l-2.828-2.828a2 2 0 0 0-2.829 2.828l-1.767-1.768a2 2 0 1 0-2.829 2.829z" /><path d="m2.5 21.5 1.4-1.4" /><path d="m20.1 3.9 1.4-1.4" /><path d="M5.343 21.485a2 2 0 1 0 2.829-2.828l1.767 1.768a2 2 0 1 0 2.829-2.829l-6.364-6.364a2 2 0 1 0-2.829 2.829l1.768 1.767a2 2 0 0 0-2.828 2.829z" /><path d="m9.6 14.4 4.8-4.8" /></>,
  'droplet': <path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z" />,
  'send': <><path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z" /><path d="m21.854 2.147-10.94 10.939" /></>,
  'sunrise': <><path d="M12 2v8" /><path d="m4.93 10.93 1.41 1.41" /><path d="M2 18h2" /><path d="M20 18h2" /><path d="m19.07 10.93-1.41 1.41" /><path d="M22 22H2" /><path d="m8 6 4-4 4 4" /><path d="M16 18a4 4 0 0 0-8 0" /></>,
  'salad': <><path d="M7 21h10" /><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9Z" /><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1" /><path d="m13 12 4-4" /><path d="M10.9 7.25A3.99 3.99 0 0 0 4 10c0 .73.2 1.41.54 2" /></>,
  'phone': <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" />,
  'video': <><path d="m23 7-7 5 7 5V7z" /><rect x="1" y="5" width="15" height="14" rx="2" ry="2" /></>,
  'arrow-up': <><path d="M12 20V5" /><path d="m6 11 6-6 6 6" /></>,
  'send-solid': <path fill="currentColor" stroke="none" d="M2.01 21 23 12 2.01 3 2 10l15 2-15 2z" />,
};
function LucideIcon({ name, size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      {LUCIDE[name]}
    </svg>
  );
}

/* ── Ikony sekcji — Streamline (CC BY 4.0, przez Iconify), 1:1, cienka linia jak w sekcjach care/founder.
   Dobrane pod znaczenie każdego punktu; kolor z currentColor (czarny --ink na tle 12% gold). ── */
const SL = {
  cycle: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M8 7a7 7 0 0 1 3.44-6A6.6 6.6 0 0 0 9 .5a6.5 6.5 0 1 0 0 13a6.6 6.6 0 0 0 2.47-.5A7 7 0 0 1 8 7"/>`,
  thyroid: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M9.625 4.27a1.738 1.738 0 1 0 3.388.776a1.738 1.738 0 1 0-3.388-.776M1.74 1.656H.645V5.25a3.22 3.22 0 0 0 3.218 3.219v0a3.22 3.22 0 0 0 3.22-3.219V1.656H5.989"/><path d="M3.927 8.5v1.208a3.7 3.7 0 0 0 3.698 3.698v0a3.7 3.7 0 0 0 3.699-3.698V6.594"/></g>`,
  apple: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M10.182 7.49a2.49 2.49 0 0 1 1.737-2.366a2.906 2.906 0 0 0-4.214-.999a1 1 0 0 1-.999 0a3.086 3.086 0 0 0-4.404 1.208a5.12 5.12 0 0 0-.54 3.356A7.24 7.24 0 0 0 3.7 12.893a2.09 2.09 0 0 0 2.697.15a1.32 1.32 0 0 1 1.568 0a2.06 2.06 0 0 0 2.656-.06a6.57 6.57 0 0 0 1.698-2.996a2.476 2.476 0 0 1-2.137-2.497M8.184 1.998L9.682.5"/>`,
  metabolism: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M4.25.5L2 5.81a.5.5 0 0 0 .46.69h2.79l-2 7l8.59-8.14a.5.5 0 0 0-.34-.86H7.75l2-4z"/>`,
  muscle: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><rect width="4" height="6" x=".5" y="4" rx="1"/><rect width="4" height="6" x="9.5" y="4" rx="1"/><path d="M4.5 7h5"/></g>`,
  cardio: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M6.992 12.413L1.573 7.401c-2.953-2.966 1.355-8.71 5.419-4.064c4.064-4.632 8.412 1.111 5.418 4.064z"/><path d="M3.515 6.753h1.53l1.032-1.968L7.64 8.41l1.343-1.657h1.5"/></g>`,
  meal: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M8.5 13.5V.5c4 2 4.5 7.5 4.5 9.5H8.5M3.5.5v13M6 .5V3a2.5 2.5 0 0 1-2.5 2.5v0A2.5 2.5 0 0 1 1 3V.5"/>`,
  success: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M7 9.5v4m-3.5 0h7m-7-13h-3v3a3 3 0 0 0 3 3zm7 0h3v3a3 3 0 0 1-3 3z"/><path d="M3.5.5V6a3.5 3.5 0 1 0 7 0V.5z"/></g>`,
  time: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M7 13.5a5.5 5.5 0 1 0 0-11a5.5 5.5 0 0 0 0 11M.5 2.5A8.7 8.7 0 0 1 3 .5m10.5 2a8.7 8.7 0 0 0-2.5-2"/><path d="M7 5v3h2.5"/></g>`,
  wallet: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M12 10.5v2a1 1 0 0 1-1 1H1.5a1 1 0 0 1-1-1V5a3 3 0 0 1 3-3H10v2.5"/><path d="M13 7.5H9.5A.5.5 0 0 0 9 8v2a.5.5 0 0 0 .5.5H13a.5.5 0 0 0 .5-.5V8a.5.5 0 0 0-.5-.5m-1 0v-2a1 1 0 0 0-1-1H3.5"/></g>`,
  health: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 1.5H11a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-10a1 1 0 0 1 1-1h1.5"/><path d="M8.5.5h-3a1 1 0 0 0-1 1V2a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-.5a1 1 0 0 0-1-1M6.303 5.21a.43.43 0 0 0-.43.43v1.207H4.666a.43.43 0 0 0-.43.43v1.395c0 .237.193.43.43.43h1.207v1.207c0 .237.193.43.43.43h1.395a.43.43 0 0 0 .43-.43V9.1h1.207a.43.43 0 0 0 .43-.43V7.277a.43.43 0 0 0-.43-.429H8.128V5.639a.43.43 0 0 0-.43-.429z"/></g>`,
  care: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M11.28 9.34a1.91 1.91 0 0 0 0-2.77a2.07 2.07 0 0 0-2.85 0L7 8L5.57 6.57a2.07 2.07 0 0 0-2.85 0a1.91 1.91 0 0 0 0 2.77L7 13.5zM7 4.5a2 2 0 1 0 0-4a2 2 0 0 0 0 4"/>`,
  chat: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M4.145 12.84a6.5 6.5 0 1 0-2.556-2.238m2.556 2.239L.5 13.5l1.089-2.897m2.556 2.238l.005-.001m-2.561-2.237l.001-.003"/>`,
  flexible: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="m12.64 1.87l-.84 2.48a.41.41 0 0 0 0 .37l1.57 2.1a.4.4 0 0 1-.33.64h-2.62a.43.43 0 0 0-.33.17l-1.46 2.1a.4.4 0 0 1-.71-.11l-.78-2.5a.38.38 0 0 0-.26-.26l-2.5-.78a.4.4 0 0 1-.11-.71l2.14-1.51a.43.43 0 0 0 .17-.33V.91a.4.4 0 0 1 .6-.33l2.1 1.57a.41.41 0 0 0 .37.05l2.48-.84a.4.4 0 0 1 .51.51m-5.6 5.09L.5 13.5"/>`,
  calendar: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M1.5 2a1 1 0 0 0-1 1v9.5a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1h-2M3.5.5v3m7-3v3M3.5 2h5"/><path d="m7.249 4.652l.836 1.683a.26.26 0 0 0 .214.156l1.858.282a.282.282 0 0 1 .156.487L8.941 8.563a.27.27 0 0 0 0 .253l.263 1.848a.282.282 0 0 1-.418.302l-1.654-.876a.33.33 0 0 0-.272 0l-1.654.876a.283.283 0 0 1-.418-.302l.31-1.848a.27.27 0 0 0-.048-.253L3.68 7.25a.282.282 0 0 1 .155-.477l1.858-.272a.26.26 0 0 0 .214-.156l.837-1.683a.282.282 0 0 1 .506-.01"/></g>`,
  goal: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M11.04 1.605a1.099 1.099 0 0 1 1.355 1.355l-1.902 6.772a1.1 1.1 0 0 1-.76.761L2.96 12.395a1.099 1.099 0 0 1-1.355-1.355l1.902-6.772c.103-.37.392-.658.76-.761z"/><path d="M5.689 5.689a1.854 1.854 0 1 0 2.622 2.622a1.854 1.854 0 1 0-2.622-2.622"/></g>`,
  shopping: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M12.88 12.39a1 1 0 0 1-1 1.11H2.12a1 1 0 0 1-1-1.11L2 4.5h10zM4.5 4.5V3a2.5 2.5 0 1 1 5 0v1.5"/>`,
  water: `<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M11.2 11.73a2 2 0 0 1-2 1.77H4.78a2 2 0 0 1-2-1.77L1.5.5h11zM1.96 4.5h10.08"/>`,
};
function SIcon({ name, size = 22 }) {
  return <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="0.9" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" dangerouslySetInnerHTML={{ __html: SL[name] || '' }} />;
}

/* ── „Twoje tempo, Twoje zasady” — akordeon obiekcji + zdjęcie ── */
const NAWET_CARDS = [
  { sit: 'odpadłaś już sześć razy', sol: 'Tym razem plan dopasowuje się do Twojej codzienności, a dietetyk reaguje, zanim jeden gorszy tydzień przekreśli resztę.' },
  { sit: 'masz 15 minut między pracą a dziećmi', sol: 'Większość posiłków zrobisz w 10–15 minut, bez meal prepu w niedzielę i pojemników po całej kuchni.' },
  { sit: 'nie chcesz przepłacać za jedzenie', sol: 'Zakupy robisz w Biedronce i Lidlu, bez egzotycznych superfoods. U większości podopiecznych wydatki spadają, a nie rosną.' },
  { sit: 'lubisz najeść się do syta', sol: 'Nie liczysz każdego grama. Pizza w piątek i schabowy w niedzielę mają swoje miejsce w planie.' },
  { sit: 'masz Hashimoto lub insulinooporność', sol: 'Plan uwzględnia Twoje wyniki, leki i samopoczucie. Układamy go pod Twoją fizjologię, nie pod ogólny schemat.' },
  { sit: 'gotujesz dla całej rodziny', sol: 'Jeden jadłospis dla całego domu, zamiast osobnego obiadu dla Ciebie i osobnego dla męża i dzieci.' },
];

function LifestyleSection() {
  return (
    <section className="section bg-white lifestyle" data-screen-label="Twoje tempo, Twoje zasady">
      <SectionWave fill="cream" />
      <div className="container">
        <CenterHead
          title="Schudniesz bez wywracania życia do góry nogami. I to na stałe."
          sub={'Pudełka, głodówki i „od poniedziałku” nie działały nie dlatego, że brakuje Ci silnej woli, tylko dlatego, że nikt nie ułożył ich pod Twój dzień. Tym razem plan dopasowuje się do Twojego czasu, budżetu, ulubionych dań i badań, a dietetyk reaguje, zanim jeden gorszy tydzień przekreśli resztę.'} />
        <div className="ncards">
          {NAWET_CARDS.map((c, i) => (
            <article key={i} className="ncard">
              <span className="ncard-eyebrow">Nawet jeśli</span>
              <h3 className="ncard-sit">{c.sit}</h3>
              <p className="ncard-sol">{c.sol}</p>
            </article>
          ))}
        </div>
        <div className="jb jb--gold ncard-band">
          <p className="jb-q">Zobacz, jak taki plan wyglądałby u Ciebie.</p>
          <Button variant="primary" className="jb-btn" arrow href="oferta.html">Sprawdź ofertę</Button>
        </div>
      </div>
    </section>
  );
}

/* ── „Twój osobisty opiekun” — dwie kolumny: zdjęcie + karty cech ── */
const CARER_FEATURES = [
  { icon: 'care', t: 'Ten sam dietetyk, który Cię zna',
    d: 'To nie infolinia, gdzie za każdym razem odpowiada ktoś inny. Twój dietetyk zna Cię na tyle, że nie musisz przypominać, że pracujesz zmianowo albo nie tykasz nabiału.' },
  { icon: 'chat', t: 'Kontakt jak z kimś bliskim',
    d: 'Niedziela, gotujesz i brakuje Ci jednego składnika. Jedna wiadomość w aplikacji i w kilka minut wiesz, czym go zastąpić, bez czekania.' },
  { icon: 'flexible', t: 'Nie smakuje? Zamieniasz w apce',
    d: 'Nie masz ochoty na dzisiejszy obiad? Wymieniasz go w aplikacji, wybierając z listy rezerwowej dobranej pod Twoje kalorie i makro. Jesz to, na co masz ochotę, a plan dalej się zgadza.' },
  { icon: 'calendar', t: 'Co tydzień 30 minut tylko o Tobie',
    d: 'Co tydzień bierzemy Twój tydzień na warsztat: waga, centymetry, energia, co poszło gładko, a co Cię wykoleiło. Zamiast błądzić w domysłach, wychodzisz z konkretem: co zostaje, a co zmieniamy na kolejne siedem dni.' },
  { icon: 'goal', t: 'Nie znikamy z ostatnią wpłatą',
    d: 'Większość diet kończy się z ostatnią wpłatą, a po kilku tygodniach kilogramy wracają. My zostajemy dłużej, aż nauczysz się jeść tak, że waga trzyma się sama, bez ciągłego pilnowania.' },
  { icon: 'alert', t: 'Reagujemy, zanim się poddasz',
    d: 'Gorszy tydzień nie musi kończyć się rezygnacją. Gdy coś się nie klei, dietetyk pisze pierwszy, podpowiada, co teraz, i wyciąga Cię z dołka, zanim machniesz na wszystko ręką.' },
];

function CarerSection() {
  return (
    <section className="section bg-white carer" data-screen-label="Twój osobisty opiekun">
      <div className="container">
        <CenterHead
          title="Tym razem ktoś patrzy, czy dajesz radę. I reaguje, zanim odpuścisz."
          sub="Próbowałaś już sama: z aplikacją, z liczeniem kalorii, z kolejnym poniedziałkiem, który zawsze coś krzyżowało. To nie była kwestia silnej woli; po prostu nikt nie sprawdzał, czy dajesz radę, i nie miał kto zareagować, gdy przychodził gorszy tydzień." />
        <div className="carer-grid">
          <div className="carer-media">
            <div className="carer-frame">
              <img src="assets/carer-kornelia.webp"
                alt="Kornelia, dietetyk LightLife, z centymetrem krawieckim na szyi" />
            </div>
          </div>
          <div className="carer-cards">
            {CARER_FEATURES.map((f) => (
              <article key={f.t} className="crd-item">
                <h3>{f.t}</h3>
                <p>{f.d}</p>
              </article>
            ))}
          </div>
        </div>
        <div className="jb jb--gold carer-cta-band">
          <p className="jb-q">Tym razem masz kogoś po swojej stronie. Zacznij już dziś.</p>
          <Button variant="primary" className="jb-btn" arrow href="oferta.html">Sprawdź ofertę</Button>
        </div>
      </div>
      <SectionWave fill="cream" />
    </section>
  );
}


function SocialProof() {
  // losowa kolejność opinii przy każdym odświeżeniu strony (Fisher-Yates, raz na wejście)
  const reviews = React.useMemo(() => {
    const a = GOOGLE_REVIEWS.slice();
    for (let i = a.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
  }, []);
  return (
    <section className="section bg-cream" data-screen-label="Opinie">
      <SectionWave fill="white" />
      <div className="container">
        <CenterHead title="Tak wygląda życie, kiedy dieta wreszcie zadziałała." sub="Zanim zaczniesz, chcesz wiedzieć, że u kogoś takiego jak Ty naprawdę zadziałało. Poniżej setki takich osób: piszą o jedzeniu bez głodówek, wsparciu dietetyka i efektach, które zostają." />
        <ArrowSlider progress>
          {reviews.map((r) => <GoogleReview key={r.name} r={r} />)}
        </ArrowSlider>
        <div className="jb jb--blue ap-band">
          <p className="jb-q">Zamiast czytać o cudzych metamorfozach, zacznij własną.</p>
          <Button variant="primary" className="jb-btn" arrow href="oferta.html">Sprawdź ofertę</Button>
        </div>
      </div>
    </section>
  );
}

/* ── Zajawka cennika ── */
function PricingTeaser() {
  return (
    <section className="section bg-white" data-screen-label="Pakiety — zajawka">
      <div className="container">
        <SectionHead center overline="Oferta" title="Pakiet dopasowany do Twoich potrzeb"
          sub="Basic, Comfort albo Pro — każdy w wariancie 1, 3, 6 lub 12 miesięcy. Im dłuższy okres, tym niższa cena miesięczna." />
        <div className="teaser-grid">
          {HD.PLANS.map((p) => (
            <Card key={p.id} interactive padding="lg" onClick={() => { window.location.href = 'oferta.html'; }} style={{ cursor: 'pointer' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
                <h3 style={{ font: 'var(--text-h3)' }}>{p.name}</h3>
                {p.popular ? <Badge star>Najczęściej wybierany</Badge> : null}
              </div>
              <p style={{ font: 'var(--text-body-sm)', color: 'var(--text-muted)', margin: '10px 0 18px' }}>{p.desc}</p>
              <div className="plan-price" style={{ marginTop: 0 }}>
                <span style={{ font: 'var(--text-body-sm)', color: 'var(--text-muted)' }}>od</span>
                <b style={{ font: '700 34px/1 var(--font-body)', color: 'var(--text-heading)' }}>{fmtPLN(p.monthly[12])}</b>
                <span>/ mies.</span>
              </div>
              <span className="read-more" style={{ marginTop: 16, display: 'inline-flex' }}>
                Zobacz szczegóły <Icon name="arrow-right" size={14} />
              </span>
            </Card>
          ))}
        </div>
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 40 }}>
          <Button size="lg" arrow href="oferta.html">Porównaj pełną ofertę</Button>
        </div>
      </div>
    </section>
  );
}

/* Faliste przejście na dole sekcji — Elementor „Waves" 1:1; fill = kolor NASTĘPNEJ sekcji */
function SectionWave({ fill }) {
  return (
    <svg className={'sec-wave sec-wave--' + fill} viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true">
      <path d="M421.9,6.5c22.6-2.5,51.5,0.4,75.5,5.3c23.6,4.9,70.9,23.5,100.5,35.7c75.8,32.2,133.7,44.5,192.6,49.7c23.6,2.1,48.7,3.5,103.4-2.5c54.7-6,106.2-25.6,106.2-25.6V0H0v30.3c0,0,72,32.6,158.4,30.5c39.2-0.7,92.8-6.7,134-22.4c21.2-8.1,52.2-18.2,79.7-24.2C399.3,7.9,411.6,7.5,421.9,6.5z" />
    </svg>
  );
}

/* Ikona belki CTA — Streamline (1:1 jak JbIcon na ofercie) */
const JB_ICONS = {
  target: `<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M13.48 7.516a6.5 6.5 0 1 1-6.93-7"/><path d="M9.79 8.09A3 3 0 1 1 5.9 4.21M7 7l2.5-2.5m2 .5l-2-.5l-.5-2l2-2l.5 2l2 .5z"/></g>`
};
function JbIcon({ name, size = 30 }) {
  return <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="0.8" aria-hidden="true" dangerouslySetInnerHTML={{ __html: JB_ICONS[name] || '' }} />;
}

function HomePage() {
  return (
    <React.Fragment>
      <SiteHeader active="home" />
      <main className="home-page">
        <HomeHero />
        <MetaSlider />
        <GenderPlans />
        <SocialProof />
        <LifestyleSection />
        <TastySection />
        <CarerSection />
        <AppShowcase />
        <MetamorfozaStory />
      </main>
      <SiteFooter />
    </React.Fragment>
  );
}

Object.assign(window, { HomePage });
