// Shared building blocks used by all three landing-page variants.
// Each variant supplies a palette object via React context (DBPCtx),
// so components below pick text/background/accent dynamically without
// re-rendering against hard-coded hex.

const DBPCtx = React.createContext(null);


function useBreakpoint() {
  const getWidth = () => {
    if (typeof window === 'undefined') return 1280;
    return window.innerWidth || document.documentElement.clientWidth || 1280;
  };

  const [width, setWidth] = React.useState(getWidth);

  React.useEffect(() => {
    const onResize = () => setWidth(getWidth());
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  return {
    width,
    isMobile: width < 700,
    isTablet: width >= 700 && width < 1024,
    isDesktop: width >= 1024,
  };
}

// ─────────────────────────────────────────────────────────────
// Placeholder — striped SVG with a monospace caption so the user
// knows EXACTLY what photography belongs in this slot. Used in
// hero, "co tu znajdziesz", IG grid, etc. Never tries to draw a
// real product or person.
// ─────────────────────────────────────────────────────────────
function Placeholder({ label, ratio = '4/5', tone = 'light', dense = false, style }) {
  const ctx = React.useContext(DBPCtx);
  const stripeBg = tone === 'dark' ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.05)';
  const stripeFg = tone === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(0,0,0,0.02)';
  const text = tone === 'dark' ? 'rgba(255,255,255,0.55)' : 'rgba(0,0,0,0.45)';
  const border = tone === 'dark' ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.08)';
  const stripeSize = dense ? 6 : 10;
  return (
    <div style={{
      aspectRatio: ratio,
      width: '100%',
      background: `repeating-linear-gradient(135deg, ${stripeBg} 0 ${stripeSize}px, ${stripeFg} ${stripeSize}px ${stripeSize * 2}px)`,
      border: `1px solid ${border}`,
      position: 'relative',
      overflow: 'hidden',
      ...style,
    }}>
      <div style={{
        position: 'absolute',
        bottom: 12, left: 12, right: 12,
        fontFamily: '"JetBrains Mono", ui-monospace, monospace',
        fontSize: 11,
        letterSpacing: 0.2,
        color: text,
        lineHeight: 1.4,
        textTransform: 'lowercase',
      }}>
        <div style={{ opacity: 0.6, marginBottom: 2 }}>placeholder</div>
        <div>{label}</div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// NewsletterForm — controlled input + email regex validation +
// success state. Each variant restyles via className map passed
// through props (so the form's logic is identical across all 3).
// ─────────────────────────────────────────────────────────────
function NewsletterForm({ variant = 'editorial', placeholder = 'twoj@email.pl', cta = 'Zapisz mnie' }) {
  const { isMobile } = useBreakpoint();
  const [email, setEmail] = React.useState('');
  const [state, setState] = React.useState('idle'); // idle | error | submitting | success
  const [touched, setTouched] = React.useState(false);

  const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);

  const submit = (e) => {
    e.preventDefault();
    setTouched(true);
    if (!valid) { setState('error'); return; }
    setState('submitting');
    setTimeout(() => setState('success'), 700);
  };

  if (state === 'success') {
    return (
      <div data-variant={variant} style={{ display: 'flex', alignItems: 'center', gap: 12, textAlign: 'left' }}>
        <SuccessTick variant={variant} />
        <div>
          <div style={{ fontWeight: 600, fontSize: 15 }}>Jesteś na liście.</div>
          <div style={{ fontSize: 13, opacity: 0.7, marginTop: 2 }}>
            Pierwszy newsletter dostaniesz w niedzielę o 10:00.
          </div>
        </div>
      </div>
    );
  }

  const inputStyle = {
    flex: 1,
    minWidth: 0,
    width: isMobile ? '100%' : 'auto',
    padding: isMobile ? '13px 14px' : '14px 16px',
    border: 'none',
    background: variant === 'modern' ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.04)',
    color: 'inherit',
    fontFamily: 'inherit',
    fontSize: 16,
    outline: 'none',
    borderRadius: variant === 'aesop' ? 0 : (variant === 'modern' ? 0 : 0),
    borderBottom: state === 'error' && touched ? '1px solid #c44' : `1px solid ${variant === 'modern' ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.15)'}`,
  };

  const btnStyle = {
    width: isMobile ? '100%' : 'auto',
    padding: isMobile ? '14px 18px' : '14px 22px',
    border: 'none',
    cursor: 'pointer',
    fontFamily: 'inherit',
    fontSize: 14,
    fontWeight: 600,
    letterSpacing: variant === 'modern' ? 0.4 : 0.2,
    textTransform: variant === 'modern' ? 'uppercase' : 'none',
    background: variant === 'modern' ? '#fafafa' : (variant === 'aesop' ? '#2a241e' : '#1a1814'),
    color: variant === 'modern' ? '#0a0a0a' : '#fff',
    transition: 'opacity .15s, transform .15s',
  };

  return (
    <form onSubmit={submit} data-variant={variant}
      style={{
        display: 'flex',
        flexDirection: isMobile ? 'column' : 'row',
        gap: isMobile ? 10 : 0,
        alignItems: 'stretch',
        width: '100%',
      }}>
      <input
        type="email"
        value={email}
        onChange={(e) => { setEmail(e.target.value); if (state === 'error') setState('idle'); }}
        onBlur={() => setTouched(true)}
        placeholder={placeholder}
        style={inputStyle}
        aria-label="Adres email"
      />
      <button type="submit" style={btnStyle}
        onMouseEnter={(e) => (e.currentTarget.style.opacity = '0.85')}
        onMouseLeave={(e) => (e.currentTarget.style.opacity = '1')}>
        {state === 'submitting' ? '...' : cta}
      </button>
    </form>
  );
}

function SuccessTick({ variant }) {
  const stroke = variant === 'modern' ? '#fafafa' : '#1a1814';
  return (
    <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
      <circle cx="16" cy="16" r="15" stroke={stroke} strokeWidth="1" opacity="0.3" />
      <path d="M10 16.5l4 4 8-9" stroke={stroke} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// BrandSubmitModal — multi-step form for "Masz polską markę?".
// Three steps: brand info → category → contact. Submits either
// to a configured endpoint or falls back to a prefilled mailto.
// Success screen on submit. Trapped inside the artboard via
// position: absolute (not fixed), so each variant's modal sits
// inside its own card, not the whole viewport.
// ─────────────────────────────────────────────────────────────
function getBrandSubmitConfig() {
  const config = (typeof window !== 'undefined' && window.DBP_CONFIG) || {};
  return {
    brandSubmitEmail: typeof config.brandSubmitEmail === 'string' ? config.brandSubmitEmail.trim() : '',
    brandSubmitEndpoint: typeof config.brandSubmitEndpoint === 'string' ? config.brandSubmitEndpoint.trim() : '',
    brandSubmitAccessKey: typeof config.brandSubmitAccessKey === 'string' ? config.brandSubmitAccessKey.trim() : '',
  };
}

function formatBrandSubmissionEmail(data) {
  return [
    'Nowe zgloszenie marki',
    '',
    `Marka: ${data.brand}`,
    `Strona / Instagram: ${data.url || '-'}`,
    `Kategoria: ${data.category}`,
    `Imie: ${data.name || '-'}`,
    `Email: ${data.email}`,
    '',
    'Opis:',
    data.note || '-',
  ].join('\n');
}

const BRAND_SUBMIT_STATUS_PARAM = 'brand-submit';

function getBrandSubmitReturnUrl() {
  if (typeof window === 'undefined') return '';
  const url = new URL(window.location.href);
  url.searchParams.set(BRAND_SUBMIT_STATUS_PARAM, 'success');
  return url.toString();
}

function getBrandSubmitStatus() {
  if (typeof window === 'undefined') return '';
  const url = new URL(window.location.href);
  return url.searchParams.get(BRAND_SUBMIT_STATUS_PARAM) || '';
}

function clearBrandSubmitStatus() {
  if (typeof window === 'undefined') return;
  const url = new URL(window.location.href);
  if (!url.searchParams.has(BRAND_SUBMIT_STATUS_PARAM)) return;
  url.searchParams.delete(BRAND_SUBMIT_STATUS_PARAM);
  window.history.replaceState({}, '', `${url.pathname}${url.search}${url.hash}`);
}

async function submitWeb3FormsApplication(endpoint, accessKey, data) {
  if (typeof FormData === 'undefined') {
    throw new Error('form-submit-unavailable');
  }

  const formData = new FormData();
  formData.append('access_key', accessKey);
  formData.append('subject', `Zgloszenie marki: ${data.brand}`);
  formData.append('from_name', 'Dobre bo z Polski');
  formData.append('name', data.name || data.brand);
  formData.append('email', data.email);
  formData.append('message', formatBrandSubmissionEmail(data));
  formData.append('brand', data.brand);
  formData.append('url', data.url || '');
  formData.append('category', data.category);
  formData.append('note', data.note || '');
  formData.append('source', 'dobre-bo-z-polski');

  const response = await fetch(endpoint, {
    method: 'POST',
    body: formData,
  });

  const contentType = response.headers.get('content-type') || '';

  if (contentType.includes('application/json')) {
    const payload = await response.json().catch(() => null);
    if (!response.ok || (payload && payload.success === false)) {
      throw new Error((payload && payload.message) || 'submit-failed');
    }
    return payload;
  }

  const payloadText = await response.text().catch(() => '');

  if (!response.ok && /just a moment|attention required|cloudflare/i.test(payloadText)) {
    throw new Error('web3forms-firewall');
  }

  throw new Error('web3forms-non-json-error');
}

async function submitBrandApplication(data) {
  const { brandSubmitEmail, brandSubmitEndpoint, brandSubmitAccessKey } = getBrandSubmitConfig();

  if (brandSubmitEndpoint) {
    const isWeb3Forms = /web3forms\.com\/submit/i.test(brandSubmitEndpoint);
    let response;

    if (isWeb3Forms) {
      if (!brandSubmitAccessKey) {
        throw new Error('missing-access-key');
      }

      await submitWeb3FormsApplication(brandSubmitEndpoint, brandSubmitAccessKey, data);
      return;
    } else {
      response = await fetch(brandSubmitEndpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
        },
        body: JSON.stringify({
          brand: data.brand,
          url: data.url,
          category: data.category,
          name: data.name,
          email: data.email,
          note: data.note,
          source: 'dobre-bo-z-polski',
          submittedAt: new Date().toISOString(),
        }),
      });

      if (!response.ok) {
        const payload = await response.json().catch(() => null);
        throw new Error((payload && payload.message) || 'submit-failed');
      }
    }

    return;
  }

  if (brandSubmitEmail) {
    const subject = encodeURIComponent(`Zgloszenie marki: ${data.brand}`);
    const body = encodeURIComponent(formatBrandSubmissionEmail(data));
    window.location.href = `mailto:${brandSubmitEmail}?subject=${subject}&body=${body}`;
    return;
  }

  throw new Error('missing-submit-target');
}

function BrandSubmitModal({ open, onClose, variant = 'editorial' }) {
  const { isMobile } = useBreakpoint();
  const [step, setStep] = React.useState(0);
  const [data, setData] = React.useState({
    brand: '', url: '',
    category: '',
    name: '', email: '', note: '',
  });
  const [submitted, setSubmitted] = React.useState(false);
  const [submitState, setSubmitState] = React.useState('idle');
  const [submitError, setSubmitError] = React.useState('');

  React.useEffect(() => {
    if (open) {
      setStep(0);
      setSubmitted(false);
      setSubmitState('idle');
      setSubmitError('');
    }
  }, [open]);

  if (!open) return null;

  const cats = ['Marka', 'Rzemiosło', 'Lokalny biznes', 'Kosmetyki', 'Design i wnętrza', 'Produkty regionalne'];
  const canNext = (
    (step === 0 && data.brand.length >= 2) ||
    (step === 1 && data.category) ||
    (step === 2 && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email))
  );

  const isDark = variant === 'modern';
  const surface = isDark ? '#0a0a0a' : '#fff';
  const text = isDark ? '#fafafa' : '#1a1814';
  const muted = isDark ? 'rgba(255,255,255,0.55)' : 'rgba(0,0,0,0.55)';
  const fieldBg = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)';
  const fieldBorder = isDark ? 'rgba(255,255,255,0.18)' : 'rgba(0,0,0,0.12)';

  const handleSubmit = async () => {
    setSubmitState('submitting');
    setSubmitError('');

    try {
      await submitBrandApplication(data);
      setSubmitted(true);
      setSubmitState('success');
    } catch (error) {
      setSubmitState('error');
      if (error && error.message === 'missing-submit-target') {
        setSubmitError('Dodaj brandSubmitEmail albo brandSubmitEndpoint w index.html, zeby formularz mial gdzie wysylac zgloszenia.');
        return;
      }
      if (error && error.message === 'missing-access-key') {
        setSubmitError('Dodaj brandSubmitAccessKey w index.html, bo Web3Forms wymaga access key.');
        return;
      }
      if (error && error.message === 'form-submit-unavailable') {
        setSubmitError('Ta przegladarka nie pozwala wyslac formularza w tym trybie.');
        return;
      }
      if (error && error.message === 'web3forms-firewall') {
        setSubmitError('Web3Forms zablokowal to z ich firewalla. W ich dokumentacji jest wprost, ze niektore hostowane domeny i TLD wymagaja recznego review po stronie supportu. Napisz do Web3Forms, zeby zatwierdzili dobrebozpolski.pl.');
        return;
      }
      if (error && error.message === 'web3forms-non-json-error') {
        setSubmitError('Web3Forms odeslal blad spoza API JSON. To zwykle oznacza blokade po ich stronie, a nie blad w formularzu. Najbardziej prawdopodobny nastepny krok to support Web3Forms i prosba o review domeny dobrebozpolski.pl.');
        return;
      }
      if (error instanceof TypeError && /fetch/i.test(error.message || '')) {
        setSubmitError('Przegladarka nie mogla polaczyc sie z Web3Forms. To zwykle oznacza blokade po stronie Web3Forms, rozszerzenia typu adblock albo problem z dozwolona domena.');
        return;
      }
      setSubmitError(error && error.message ? error.message : 'Nie udalo sie wyslac zgloszenia. Sprawdz konfiguracje endpointu albo sproboj ponownie.');
    }
  };

  const inputStyle = {
    width: '100%',
    padding: '12px 14px',
    background: fieldBg,
    border: `1px solid ${fieldBorder}`,
    color: text,
    fontFamily: 'inherit',
    fontSize: 16,
    outline: 'none',
    borderRadius: variant === 'editorial' ? 2 : 0,
  };

  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 50,
      background: 'rgba(20,16,12,0.5)',
      backdropFilter: 'blur(8px)',
      WebkitBackdropFilter: 'blur(8px)',
      display: 'flex', alignItems: isMobile ? 'stretch' : 'flex-start', justifyContent: 'center',
      padding: isMobile ? 12 : 32,
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        background: surface,
        color: text,
        width: isMobile ? '100%' : 560,
        maxWidth: '100%',
        maxHeight: isMobile ? 'calc(100vh - 24px)' : 'calc(100vh - 64px)',
        overflowY: 'auto',
        marginTop: isMobile ? 0 : 60,
        padding: isMobile ? 24 : 36,
        position: 'relative',
        boxShadow: '0 24px 80px rgba(0,0,0,0.25)',
      }}>
        <button onClick={onClose} aria-label="Zamknij" style={{
          position: 'absolute', top: 16, right: 16,
          width: 32, height: 32, borderRadius: 16,
          border: 'none', background: fieldBg, color: text,
          cursor: 'pointer', fontSize: 18, lineHeight: '32px',
        }}>×</button>

        {submitted ? (
          <div style={{ paddingRight: isMobile ? 0 : 24 }}>
            <SuccessTick variant={variant} />
            <h3 style={{ fontFamily: 'Fraunces, serif', fontWeight: 500, fontSize: isMobile ? 24 : 28, margin: '16px 0 8px', letterSpacing: -0.5 }}>
              Dzięki, mamy zgłoszenie.
            </h3>
            <p style={{ fontSize: 15, lineHeight: 1.55, color: muted, margin: '0 0 24px' }}>
              Odezwiemy się na <strong style={{ color: text }}>{data.email}</strong> w ciągu kilku dni.
              Jeśli pasujesz do projektu — zaprosimy Cię do pierwszej fali.
            </p>
            <button onClick={onClose} style={{
              width: isMobile ? '100%' : 'auto',
              padding: '12px 24px',
              background: text, color: surface,
              border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', fontSize: 14, fontWeight: 600,
              letterSpacing: 0.3,
            }}>Zamknij</button>
          </div>
        ) : (
          <>
            <div style={{ fontFamily: '"JetBrains Mono", monospace', fontSize: 11, letterSpacing: 1.5, color: muted, textTransform: 'uppercase', marginBottom: 12 }}>
              Krok {step + 1} z 3
            </div>
            <h3 style={{ fontFamily: 'Fraunces, serif', fontWeight: 500, fontSize: isMobile ? 23 : 26, margin: '0 32px 6px 0', letterSpacing: -0.5, lineHeight: 1.15 }}>
              {step === 0 && 'Powiedz nam o swojej marce'}
              {step === 1 && 'Do której kategorii pasujesz?'}
              {step === 2 && 'Jak się skontaktować?'}
            </h3>
            <p style={{ fontSize: 14, lineHeight: 1.55, color: muted, margin: '0 0 24px' }}>
              {step === 0 && 'Sama nazwa wystarczy na początek. Resztę uzupełnimy później.'}
              {step === 1 && 'Wybierz najbliższą — jedna marka może pasować do kilku, to OK.'}
              {step === 2 && 'Gdzie możemy się odezwać? I co jeszcze powinniśmy wiedzieć.'}
            </p>

            {submitError && (
              <div style={{
                margin: '0 0 20px',
                padding: '12px 14px',
                border: `1px solid ${isDark ? 'rgba(255,120,120,0.45)' : 'rgba(180,40,40,0.25)'}`,
                background: isDark ? 'rgba(140,20,20,0.14)' : 'rgba(180,40,40,0.06)',
                color: isDark ? '#ffd7d7' : '#8a1f1f',
                fontSize: 13,
                lineHeight: 1.5,
              }}>
                {submitError}
              </div>
            )}

            <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginBottom: 28 }}>
              {step === 0 && (
                <>
                  <label style={{ display: 'block' }}>
                    <div style={{ fontSize: 12, fontWeight: 500, marginBottom: 6, color: muted }}>Nazwa marki</div>
                    <input autoFocus value={data.brand} onChange={(e) => setData({ ...data, brand: e.target.value })} placeholder="np. Wytwórnia Kraftowa" style={inputStyle} />
                  </label>
                  <label style={{ display: 'block' }}>
                    <div style={{ fontSize: 12, fontWeight: 500, marginBottom: 6, color: muted }}>Strona / Instagram <span style={{ opacity: 0.5 }}>(opcjonalnie)</span></div>
                    <input value={data.url} onChange={(e) => setData({ ...data, url: e.target.value })} placeholder="instagram.com/twojamarka" style={inputStyle} />
                  </label>
                </>
              )}
              {step === 1 && (
                <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: 8 }}>
                  {cats.map((c) => {
                    const sel = data.category === c;
                    return (
                      <button key={c} onClick={() => setData({ ...data, category: c })} type="button" style={{
                        padding: '14px 16px',
                        background: sel ? text : fieldBg,
                        color: sel ? surface : text,
                        border: `1px solid ${sel ? text : fieldBorder}`,
                        cursor: 'pointer',
                        fontFamily: 'inherit', fontSize: 14, fontWeight: 500,
                        textAlign: 'left',
                        transition: 'all .12s',
                      }}>{c}</button>
                    );
                  })}
                </div>
              )}
              {step === 2 && (
                <>
                  <label style={{ display: 'block' }}>
                    <div style={{ fontSize: 12, fontWeight: 500, marginBottom: 6, color: muted }}>Imię</div>
                    <input value={data.name} onChange={(e) => setData({ ...data, name: e.target.value })} placeholder="Twoje imię" style={inputStyle} />
                  </label>
                  <label style={{ display: 'block' }}>
                    <div style={{ fontSize: 12, fontWeight: 500, marginBottom: 6, color: muted }}>Email</div>
                    <input type="email" value={data.email} onChange={(e) => setData({ ...data, email: e.target.value })} placeholder="ty@twojamarka.pl" style={inputStyle} />
                  </label>
                  <label style={{ display: 'block' }}>
                    <div style={{ fontSize: 12, fontWeight: 500, marginBottom: 6, color: muted }}>Krótko o marce <span style={{ opacity: 0.5 }}>(opcjonalnie)</span></div>
                    <textarea rows={3} value={data.note} onChange={(e) => setData({ ...data, note: e.target.value })} placeholder="Co robicie, co Was wyróżnia, gdzie was szukać..." style={{ ...inputStyle, resize: 'vertical', fontFamily: 'inherit' }} />
                  </label>
                </>
              )}
            </div>

            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
              <button disabled={submitState === 'submitting'} onClick={() => step > 0 ? setStep(step - 1) : onClose()} style={{
                padding: '10px 12px',
                background: 'transparent',
                color: muted,
                border: 'none', cursor: submitState === 'submitting' ? 'not-allowed' : 'pointer',
                fontFamily: 'inherit', fontSize: 14, fontWeight: 500,
              }}>{step === 0 ? 'Anuluj' : '← Wstecz'}</button>
              <button
                disabled={!canNext || submitState === 'submitting'}
                onClick={() => {
                  if (step < 2) setStep(step + 1);
                  else handleSubmit();
                }}
                style={{
                  flex: isMobile ? 1 : 'initial',
                  padding: '12px 18px',
                  background: (canNext && submitState !== 'submitting') ? text : (isDark ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.2)'),
                  color: (canNext && submitState !== 'submitting') ? surface : (isDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.4)'),
                  border: 'none', cursor: (canNext && submitState !== 'submitting') ? 'pointer' : 'not-allowed',
                  fontFamily: 'inherit', fontSize: 14, fontWeight: 600, letterSpacing: 0.3,
                  transition: 'all .12s',
                }}>
                {submitState === 'submitting' ? 'Wysyłanie...' : (step < 2 ? 'Dalej →' : 'Wyślij zgłoszenie')}
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// ScrollReveal — IntersectionObserver wrapper. Each variant
// uses this to fade-and-rise sections into view; observer roots
// to the artboard's nearest scroll ancestor (the design canvas
// world), which works fine since the canvas itself doesn't
// scroll — items become visible as the user pans/zooms or as
// the artboard mounts.
// ─────────────────────────────────────────────────────────────
function ScrollReveal({ children, delay = 0, y = 16 }) {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => { if (e.isIntersecting) { setSeen(true); io.disconnect(); } });
    }, { threshold: 0.15 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <div ref={ref} style={{
      transform: seen ? 'translateY(0)' : `translateY(${y}px)`,
      opacity: seen ? 1 : 0,
      transition: `transform .8s ${delay}ms cubic-bezier(.2,.7,.3,1), opacity .8s ${delay}ms cubic-bezier(.2,.7,.3,1)`,
    }}>{children}</div>
  );
}

// Categories + "did you know it's polish?" copy used across all 3 designs.
const CATEGORIES = [
  { num: '01', name: 'Marki', desc: 'Polskie firmy które warto znać po nazwisku.' },
  { num: '02', name: 'Rzemiosło', desc: 'Manufaktury, warsztaty, robione ręką.' },
  { num: '03', name: 'Lokalne biznesy', desc: 'Kawiarnie, bary, miejsca z duszą.' },
  { num: '04', name: 'Kosmetyki', desc: 'Naturalne, etyczne, zaprojektowane w Polsce.' },
  { num: '05', name: 'Design i wnętrza', desc: 'Meble, oświetlenie, ceramika, tekstylia.' },
  { num: '06', name: 'Produkty regionalne', desc: 'Smaki z konkretnego miejsca w Polsce.' },
];

const DID_YOU_KNOW = [
  { what: 'kosmetyk z butelki, którą widujesz u znajomych', who: 'jest z Wrocławia' },
  { what: 'sneakery noszone w Berlinie i Tokio', who: 'powstają pod Łodzią' },
  { what: 'krzesło z hotelu w Lizbonie', who: 'projektuje studio z Gdańska' },
  { what: 'rzemieślniczy chleb sprzedawany w Kopenhadze', who: 'piecze piekarnia z Małopolski' },
  { what: 'lampa z plakatów na Pintereście', who: 'jest robiona w Warszawie' },
  { what: 'marka ceramiki, którą śledzą na Insta', who: 'pracuje w Bieszczadach' },
];

Object.assign(window, {
  DBPCtx, useBreakpoint,
  Placeholder, NewsletterForm, BrandSubmitModal, ScrollReveal, SuccessTick,
  getBrandSubmitStatus, clearBrandSubmitStatus,
  CATEGORIES, DID_YOU_KNOW,
});
