// Kir Loginov Objects - primary components

// ─────────────────────────────────────────────────────────
// Reveal-on-scroll wrapper
// ─────────────────────────────────────────────────────────
const Reveal = ({ children, delay = 0, as: Tag = 'div', className = '', style = {}, ...rest }) => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => {
        if (e.isIntersecting) {
          setTimeout(() => el.classList.add('is-visible'), delay);
          io.unobserve(el);
        }
      }),
      { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }
    );
    io.observe(el);
    return () => io.disconnect();
  }, [delay]);
  return <Tag ref={ref} className={`reveal ${className}`} style={style} {...rest}>{children}</Tag>;
};

// ─────────────────────────────────────────────────────────
// Smart image: tries real photo, falls back to ClayPlaceholder
// ─────────────────────────────────────────────────────────
const IMG_BUST = 'v=114';
const WorkImage = ({ work, className = '', style = {}, label = true, ratio, lang = 'ru', eager = false }) => {
  const [errored, setErrored] = React.useState(false);
  React.useEffect(() => { setErrored(false); }, [work.image]);
  const r = ratio || work.ratio || '3/4';
  // Vladimir 2026-05-02 (v=114): описательный alt из title[lang] (a11y BLOCKER fix)
  // + lazy-loading на 32 work-card images (perf fix, ~9MB savings on first paint).
  const altText = (work.title && work.title[lang]) || work.title?.ru || work.code || '';
  if (errored || !work.image) {
    return (
      <ClayPlaceholder
        code={work.code}
        label={label ? `[ ${work.title.en.toUpperCase()} ]` : ''}
        ratio={r}
        tone={work.tone}
        className={className}
        style={style} />);


  }
  return (
    <div
      className={`work-img ${className}`}
      style={{ position: 'relative', aspectRatio: r, overflow: 'hidden', background: 'var(--c-paper-3)', ...style }}>

      <img
        src={`${work.image}?${IMG_BUST}`}
        alt={altText}
        loading={eager ? 'eager' : 'lazy'}
        decoding="async"
        onError={() => setErrored(true)}
        style={{
          width: '100%', height: '100%',
          display: 'block', objectFit: "cover"
        }} />

    </div>);

};

// ─────────────────────────────────────────────────────────
// Top bar - logotype, nav, language toggle
// ─────────────────────────────────────────────────────────
const TopBar = ({ lang, setLang, route, navigate }) => {
  const t = COPY[lang];
  const headerRef = React.useRef(null);
  // Vladimir 2026-05-02 (v=106): откат к состоянию v=103 — soft hairline + mask.
  // Линия мягкая (opacity 0.32 + blur 0.6 на y=0), при скролле растворяется за 200px.
  // Mask на шапке: всегда минимум 10px растворения снизу, до 48px при скролле.
  // Шапка тает 220→460. Без отдельной fade-зоны.
  React.useEffect(() => {
    let raf = null;
    const easeInOut = (t) => t * t * (3 - 2 * t);
    const apply = () => {
      raf = null;
      const el = headerRef.current;
      if (!el) return;
      const y = window.scrollY;
      const lineOp     = easeInOut(Math.max(0, Math.min(1, 1 - y / 200)));
      const fadeProgress = easeInOut(Math.max(0, Math.min(1, y / 280)));
      const fadeAmount = 10 + fadeProgress * 38;
      const hdrOp      = easeInOut(Math.max(0, Math.min(1, 1 - (y - 220) / 240)));
      el.style.setProperty('--line-op', lineOp);
      el.style.setProperty('--fade-amount', fadeAmount + 'px');
      el.style.setProperty('--hdr-op', hdrOp);
      el.style.pointerEvents = hdrOp < 0.05 ? 'none' : 'auto';
    };
    const onScroll = () => { if (raf == null) raf = requestAnimationFrame(apply); };
    apply();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => {
      window.removeEventListener('scroll', onScroll);
      if (raf != null) cancelAnimationFrame(raf);
    };
  }, []);
  const items = [
  { id: 'works', label: t.nav.works },
  { id: 'about', label: t.nav.about },
  { id: 'series', label: t.nav.series },
  { id: 'press', label: t.nav.press },
  { id: 'process', label: t.nav.process },
  { id: 'contact', label: t.nav.contact }];

  return (
    <header ref={headerRef} className="topbar">
      <div className="container topbar-row">
        <button className="logo logo-svg-lockup" onClick={() => navigate({ name: 'home' })} aria-label="Kir Loginov Objects">
          <img src="images/logo/lockup-en.svg?v=114" alt="Kir Loginov Objects" className="logo-svg-lockup-img" />
        </button>
        <nav className="topnav" aria-label={lang === 'en' ? 'Main' : 'Основная навигация'}>
          {items.map((i) =>
          <button
            key={i.id}
            onClick={() => navigate({ name: i.id })}
            className={`navlink ${route.name === i.id ? 'is-active' : ''}`}
            aria-current={route.name === i.id ? 'page' : undefined}>

              {i.label}
            </button>
          )}
        </nav>
        <div className="lang">
          <button className={lang === 'ru' ? 'is-on' : ''} onClick={() => setLang('ru')}>RU</button>
          <span className="lang-sep">/</span>
          <button className={lang === 'en' ? 'is-on' : ''} onClick={() => setLang('en')}>EN</button>
        </div>
      </div>
      <div className="topbar-hairline" aria-hidden="true" />
    </header>);

};

// ─────────────────────────────────────────────────────────
// HERO
// ─────────────────────────────────────────────────────────
const Hero = ({ lang, navigate }) => {
  const t = COPY[lang].hero;
  return (
    <section className="hero">
      <div className="container hero-grid">
        <div className="hero-meta">
          <Reveal className="t-eyebrow">{t.eyebrow}</Reveal>
          <Reveal className="t-mono hero-place" delay={100}>{t.meta}</Reveal>
        </div>
        <Reveal as="h1" className="hero-title t-display" delay={50}>
          {t.title}
        </Reveal>
        <Reveal className="hero-sub t-body" delay={150}>
          {t.sub}
        </Reveal>
        <Reveal className="hero-cta-row" delay={220}>
          <button className="btn-link btn-link-primary" onClick={() => navigate({ name: 'works' })}>
            <span>{t.cta}</span>
            <svg width="20" height="10" viewBox="0 0 20 10" aria-hidden="true"><path d="M0 5 H18 M14 1 L18 5 L14 9" stroke="currentColor" fill="none" strokeWidth="1.2" /></svg>
          </button>
          <a className="btn-link btn-link-secondary" href={`https://t.me/kirloginovceramic?text=${encodeURIComponent(lang === 'ru' ? 'Здравствуйте, Кир! Хочу связаться по поводу ваших работ.' : 'Hello, Kir. I would like to get in touch about your work.')}`} target="_blank" rel="noreferrer">
            <span>{t.cta2}</span>
            <svg width="20" height="10" viewBox="0 0 20 10" aria-hidden="true"><path d="M0 5 H18 M14 1 L18 5 L14 9" stroke="currentColor" fill="none" strokeWidth="1.2" /></svg>
          </a>
        </Reveal>
      </div>
      {/* Vladimir 2026-05-02 v=100: убрана белая hairline под hero — выглядела странно */}
      {/* featured grid */}
      <div className="container hero-featured">
        {WORKS.slice(0, 3).map((w, i) =>
        <Reveal key={w.id} delay={120 * (i + 1)} className="hero-feat-item">
            <button className="hero-feat-btn" onClick={() => navigate({ name: 'work', id: w.id })}>
              <WorkImage work={w} ratio="4/5" lang={lang} eager />
              <div className="hero-feat-meta">
                <span className="t-mono">{w.code}</span>
                <span className="t-h3">{w.title[lang]}</span>
              </div>
            </button>
          </Reveal>
        )}
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// Works grid - variants A (Editorial / Museum / Diary)
// + density tweak
// ─────────────────────────────────────────────────────────
const WorksGrid = ({ lang, navigate, layout = 'editorial', density = 3 }) => {
  const t = COPY[lang].sections;
  const [cat, setCat] = React.useState('all');
  const isLamp = (w) => !!w.kind;
  // Per Kir's request - gallery sorted alphabetically by current-language title.
  const filtered = WORKS
    .filter((w) => cat === 'all' ? true : cat === 'lamps' ? isLamp(w) : !isLamp(w))
    .slice()
    .sort((a, b) => a.title[lang].localeCompare(b.title[lang], lang === 'ru' ? 'ru' : 'en'));
  const cats = [
    { id: 'all',   label: lang === 'ru' ? 'все'         : 'all',    count: WORKS.length },
    { id: 'vases', label: lang === 'ru' ? 'вазы'        : 'vases',  count: WORKS.filter((w) => !isLamp(w)).length },
    { id: 'lamps', label: lang === 'ru' ? 'светильники' : 'lamps',  count: WORKS.filter(isLamp).length },
  ];
  return (
    <section className="works">
      <div className="container">
        <Reveal className="works-head">
          <span className="t-eyebrow">- {t.selected}</span>
          <h2 className="t-h2">{lang === 'ru' ? 'объекты' : 'objects'} <span className="muted">/ 2024 - 2026</span></h2>
        </Reveal>
        <div className="works-cats" role="tablist">
          {cats.map((c) =>
          <button
            key={c.id}
            role="tab"
            aria-selected={cat === c.id}
            className={`works-cat ${cat === c.id ? 'is-on' : ''}`}
            onClick={() => setCat(c.id)}>
              <span className="works-cat-label">{c.label}</span>
              <span className="works-cat-count t-mono">{String(c.count).padStart(2, '0')}</span>
            </button>
          )}
        </div>
        <div
          className={`works-grid layout-${layout}`}
          style={{ '--cols': density }}>
          
          {filtered.map((w, i) => {
            return (
              <Reveal key={w.id} delay={Math.min(80 * i, 360)} className={`work-card pos-${i % 6}`}>
                <button
                  type="button"
                  className="work-card-btn"
                  onClick={() => navigate({ name: 'work', id: w.id })}
                  aria-label={`${w.title[lang]}, ${w.year}${w.dim ? ', ' + w.dim + ' см' : ''}`}>
                  <div className="work-card-image-wrap">
                    <WorkImage work={w} ratio={w.ratio} lang={lang} eager={i < 4} />
                    <div className="work-card-hover">
                      <span className="t-mono">{w.code}{w.dim ? ` · ${w.dim} cm` : ''}</span>
                      <span className="t-h3">{w.title[lang]}</span>
                    </div>
                  </div>
                  <div className="work-card-caption">
                    <div className="wcc-l">
                      <span className="t-h3">{w.title[lang]}</span>
                    </div>
                    <div className="wcc-r t-mono">{w.year}</div>
                  </div>
                </button>
              </Reveal>
            );
          })}
        </div>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// Single work page
// ─────────────────────────────────────────────────────────
const SingleWork = ({ lang, id, navigate }) => {
  const idx = WORKS.findIndex((w) => w.id === id);
  if (idx < 0) return null;
  const w = WORKS[idx];
  const next = WORKS[(idx + 1) % WORKS.length];
  const prev = WORKS[(idx - 1 + WORKS.length) % WORKS.length];
  const t = COPY[lang].sections;

  React.useEffect(() => {window.scrollTo({ top: 0, behavior: 'instant' });}, [id]);

  return (
    <section className="single">
      <div className="container single-top t-mono">
        <button className="back" onClick={() => navigate({ name: 'works' })}>
          <svg width="18" height="10" viewBox="0 0 18 10"><path d="M18 5 H2 M6 1 L2 5 L6 9" stroke="currentColor" fill="none" strokeWidth="1.2" /></svg>
          {t.backToWorks}
        </button>
        <span className="muted">{w.code}</span>
      </div>
      <div className="container single-grid">
        <div className="single-image">
          <WorkImage work={w} ratio={w.ratio} label={false} lang={lang} eager />
          {w.images && w.images.length > 1 &&
          <div className="single-thumbs">
              {w.images.slice(1).map((src, i) =>
            <div key={i} className="single-thumb">
                  <img src={`${src}?${IMG_BUST}`} alt="" loading="lazy" />
                </div>
            )}
            </div>
          }
        </div>
        <aside className="single-meta">
          <Reveal className="t-eyebrow">{w.series[lang]}</Reveal>
          <Reveal as="h1" className="single-title t-h1" delay={80}>{w.title[lang]}</Reveal>

          <Reveal className="single-cta" delay={120}>
            <a className="btn-primary" href={`https://t.me/kirloginovceramic?text=${encodeURIComponent(lang === 'ru'
              ? `Здравствуйте, Кир! Интересует стоимость объекта «${w.title.ru}»?`
              : `Hello, Kir. Could you tell me the price of "${w.title.en}"?`)}`}
              target="_blank" rel="noreferrer"
              style={{ textDecoration: 'none' }}>
              {lang === 'ru' ? 'Купить (Telegram)' : 'Buy (Telegram)'}
              <svg width="20" height="10" viewBox="0 0 20 10"><path d="M0 5 H18 M14 1 L18 5 L14 9" stroke="currentColor" fill="none" strokeWidth="1.2" /></svg>
            </a>
          </Reveal>

          <Reveal className="single-specs" delay={180}>
            <div><span className="t-mono muted">{t.yearLabel}</span><span>{w.year}</span></div>
            <div><span className="t-mono muted">{t.dimLabel}</span><span>{w.dim}</span></div>
            <div><span className="t-mono muted">{t.materialsLabel}</span><span>{w.materials[lang]}</span></div>
          </Reveal>

          <Reveal className="single-desc t-body" delay={240}>
            {w.desc[lang].split('\n\n').map((para, i) =>
              <p key={i} style={{ margin: i === 0 ? 0 : '1em 0 0' }}>{para}</p>
            )}
          </Reveal>
        </aside>
      </div>

      <hr className="hairline" />
      <div className="container single-nav">
        <button className="single-nav-btn" onClick={() => navigate({ name: 'work', id: prev.id })}>
          <div className="single-nav-thumb">
            <img src={`${prev.image}?${IMG_BUST}`} alt="" loading="lazy" />
          </div>
          <div className="single-nav-text">
            <span className="t-mono muted">← {t.prev}</span>
            <span className="t-h3">{prev.title[lang]}</span>
          </div>
        </button>
        <button className="single-nav-btn align-right" onClick={() => navigate({ name: 'work', id: next.id })}>
          <div className="single-nav-text">
            <span className="t-mono muted">{t.next} →</span>
            <span className="t-h3">{next.title[lang]}</span>
          </div>
          <div className="single-nav-thumb">
            <img src={`${next.image}?${IMG_BUST}`} alt="" loading="lazy" />
          </div>
        </button>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// About / Bio
// ─────────────────────────────────────────────────────────
const About = ({ lang }) => {
  const t = COPY[lang];
  return (
    <section className="about">
      <div className="container">
        <Reveal className="section-h about-lead t-h1">{t.sections.aboutTitle}</Reveal>
        <Reveal className="t-body about-lead-sub" delay={80} style={{ marginTop: 16, maxWidth: 'none' }}>{t.bio.lead}</Reveal>

        <div className="about-grid">
          <Reveal className="about-portrait" delay={120}>
            <div className="about-portrait-wrap" style={{ border: '1px solid #111', background: '#fff' }}>
              <img src="images/portrait.jpg" alt="Кир Логинов в студии"
              onError={(e) => {e.currentTarget.style.display = 'none';}}
              style={{ width: '100%', aspectRatio: '3/4', objectFit: 'cover', display: 'block' }} />
            </div>
          </Reveal>

          <div className="about-text">
            <Reveal className="t-body" delay={160}>{t.bio.p1}</Reveal>
            <Reveal className="t-body" delay={220}>{t.bio.p2}</Reveal>
            <Reveal className="t-body" delay={280}>{t.bio.p3}</Reveal>
          </div>
        </div>

        <hr className="hairline" style={{ margin: 'var(--s-10) 0 var(--s-8)' }} />

        {/* CV — biographical (born/based, education) */}
        <Reveal className="t-h1" style={{ maxWidth: '20ch' }}>
          {lang === 'ru' ? 'Кир Логинов' : 'Kir Loginov'}
        </Reveal>
        <Reveal className="t-body muted" delay={80} style={{ marginTop: 8 }}>
          {CV.born[lang]} · {CV.basedIn[lang]}
        </Reveal>

        {/* Образование */}
        <Reveal as="h2" className="section-h cv-h t-h2" style={{ marginTop: 64, display: 'block' }}>{lang === 'ru' ? 'образование' : 'education'}</Reveal>
        <div className="series-list">
          {CV.education.map((e, i) =>
          <Reveal key={i} delay={80 * i} className="series-row">
              <span className="t-mono muted">{e.years}</span>
              <span></span>
              <p className="t-body">{e.text[lang]}</p>
            </Reveal>
          )}
        </div>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// Press — три подраздела: выставки / маркеты / коллаборации (Кир 2026-05-01)
// ─────────────────────────────────────────────────────────
const Press = ({ lang }) => {
  const t = COPY[lang].sections;
  const renderItem = (p, i) => {
    const titleStr = (typeof p.title === 'object' && p.title !== null) ? p.title[lang] : p.title;
    const placeStr = (typeof p.place === 'object' && p.place !== null) ? p.place[lang] : p.place;
    const cityStr  = (typeof p.city  === 'object' && p.city  !== null) ? p.city[lang]  : p.city;
    const titleNode = p.link
      ? <a className="t-h3 press-link" href={p.link} target="_blank" rel="noreferrer"
           style={{ textDecoration: 'underline', textUnderlineOffset: '4px' }}>
          {titleStr}
        </a>
      : <span className="t-h3">{titleStr}</span>;
    const meta = [placeStr, cityStr, p.curator?.[lang], p.note?.[lang]].filter(Boolean).join(' · ');
    return (
      <Reveal as="li" key={i} delay={Math.min(80 * i, 360)} className="press-row press-row-2col">
        <span className="t-mono">{p.year}</span>
        {titleNode}
        <span className="t-small">{meta}</span>
      </Reveal>
    );
  };
  const sortByYear = (arr) => arr.slice().sort((a, b) => b.year - a.year);
  return (
    <section className="press">
      <div className="container">
        <Reveal className="section-h press-head t-h1">{t.pressTitle}</Reveal>

        <Reveal as="h2" className="section-h cv-h t-h2" style={{ marginTop: 56, display: 'block' }}>
          {lang === 'ru' ? 'выставки' : 'exhibitions'}
        </Reveal>
        <ul className="press-list">{sortByYear(CV.exhibitions).map(renderItem)}</ul>

        <Reveal as="h2" className="section-h cv-h t-h2" style={{ marginTop: 56, display: 'block' }}>
          {lang === 'ru' ? 'маркеты' : 'markets'}
        </Reveal>
        <ul className="press-list">{sortByYear(CV.markets).map(renderItem)}</ul>

        <Reveal as="h2" className="section-h cv-h t-h2" style={{ marginTop: 56, display: 'block' }}>
          {lang === 'ru' ? 'коллаборации' : 'collaborations'}
        </Reveal>
        <ul className="press-list">{sortByYear(CV.collabs).map(renderItem)}</ul>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// Lightbox — overlay для просмотра фото на полный экран
// (Кир 2026-05-01) с подписью + размером + описанием
// ─────────────────────────────────────────────────────────
const Lightbox = ({ open, onClose, photo, title, dim, materials, desc, lang }) => {
  const closeBtnRef = React.useRef(null);
  const lastFocusedRef = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    // Vladimir 2026-05-02 (v=114): Esc + focus-trap + return focus on close (a11y).
    lastFocusedRef.current = document.activeElement;
    const handler = (e) => {
      if (e.key === 'Escape') { e.stopPropagation(); onClose(); }
    };
    window.addEventListener('keydown', handler, true);
    document.addEventListener('keydown', handler, true);
    document.body.style.overflow = 'hidden';
    setTimeout(() => closeBtnRef.current && closeBtnRef.current.focus(), 0);
    return () => {
      window.removeEventListener('keydown', handler, true);
      document.removeEventListener('keydown', handler, true);
      document.body.style.overflow = '';
      if (lastFocusedRef.current && typeof lastFocusedRef.current.focus === 'function') {
        try { lastFocusedRef.current.focus(); } catch (e) {}
      }
    };
  }, [open, onClose]);
  if (!open) return null;
  const closeLabel = lang === 'en' ? 'Close' : 'Закрыть';
  return (
    <div className="lightbox" onClick={onClose} role="dialog" aria-modal="true" aria-label={closeLabel}>
      <button ref={closeBtnRef} className="lightbox-close" onClick={onClose} aria-label={closeLabel}>×</button>
      <div className="lightbox-inner" onClick={(e) => e.stopPropagation()}>
        <div className="lightbox-image-wrap">
          <img src={photo} alt={title || ''} />
        </div>
        {(title || dim || desc) && (
          <div className="lightbox-meta">
            {title && <h3 className="lightbox-title t-h2">{title}</h3>}
            {dim && <div className="lightbox-dim t-mono muted">{dim} см</div>}
            {materials && <div className="lightbox-materials t-small muted">{materials}</div>}
            {desc && (
              <div className="lightbox-desc t-body">
                {desc.split('\n\n').map((p, i) => <p key={i}>{p}</p>)}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────
// Series — раздел серий (Кир 2026-05-01)
// Каждая миниатюра кликабельна → Lightbox с подписью + размером + описанием
// ─────────────────────────────────────────────────────────
const Series = ({ lang }) => {
  const [opened, setOpened] = React.useState(null); // {photo, title, dim, materials, desc}
  // Helper: для серии fragments items ссылаются на WORKS, для kto-zdes — данные внутри item
  const resolveItem = (item) => {
    if (item.workId) {
      const w = WORKS.find(x => x.id === item.workId);
      if (w) return {
        photo: item.photo,
        title: w.title[lang],
        dim: w.dim,
        materials: w.materials?.[lang],
        desc: w.desc?.[lang],
      };
    }
    return {
      photo: item.photo,
      title: item.title?.[lang],
      dim: item.dim,
      materials: item.materials?.[lang],
      desc: item.desc?.[lang],
    };
  };
  return (
    <section className="series-section">
      <div className="container">
        <Reveal className="section-h t-h1">
          {lang === 'ru' ? 'серии' : 'series'}
        </Reveal>
        {SERIES.map((s) => (
          <div key={s.id} className="series-block">
            <Reveal as="h2" className="series-block-title t-h2" delay={0}>
              «{s.title[lang]}»
              <span className="series-block-year t-mono muted"> · {s.year}</span>
            </Reveal>
            <Reveal className="series-block-desc t-body" delay={80} style={{ marginTop: 16, maxWidth: '64ch' }}>
              {s.description[lang].split('\n\n').map((para, i) => (
                <p key={i} style={{ margin: i === 0 ? 0 : '1em 0 0' }}>{para}</p>
              ))}
            </Reveal>
            <div className="series-block-photos" style={{ gridTemplateColumns: `repeat(${s.items.length}, 1fr)` }}>
              {s.items.map((item, i) => {
                const r = resolveItem(item);
                return (
                  <Reveal key={i} delay={Math.min(80 * i, 320)} className="series-block-photo">
                    <button
                      className="series-block-photo-btn"
                      onClick={() => setOpened(r)}
                      aria-label={r.title || ''}>
                      <img src={`${item.photo}?v=114`} alt="" loading="lazy" decoding="async" />
                    </button>
                    {r.title && (
                      <span className="series-block-photo-caption t-small">{r.title}</span>
                    )}
                  </Reveal>
                );
              })}
            </div>
          </div>
        ))}
      </div>
      <Lightbox
        open={!!opened}
        onClose={() => setOpened(null)}
        photo={opened?.photo}
        title={opened?.title}
        dim={opened?.dim}
        materials={opened?.materials}
        desc={opened?.desc}
        lang={lang}
      />
    </section>
  );
};

// ─────────────────────────────────────────────────────────
// Stockists / Представительство — отдельная секция (Кир 2026-05-01)
// ─────────────────────────────────────────────────────────
const Stockists = ({ lang }) => {
  return (
    <section className="stockists-section">
      <div className="container">
        <Reveal className="section-h t-h1">
          {lang === 'ru' ? 'представительство' : 'representation'}
        </Reveal>
        <div className="stockists-grid">
          {STOCKISTS.map((s) => (
            <a key={s.id} className="stockist" href={s.link} target="_blank" rel="noreferrer" aria-label={s.name}>
              <img src={s.logo} alt={s.name} className="stockist-logo" />
              <span className="stockist-meta">
                <span className="t-mono">{s.name}</span>
                <span className="t-small muted">{s.city[lang]}</span>
              </span>
            </a>
          ))}
        </div>
      </div>
    </section>
  );
};

// ─────────────────────────────────────────────────────────
// Contact
// ─────────────────────────────────────────────────────────
const Contact = ({ lang, presetSubject, presetWork }) => {
  const t = COPY[lang];

  return (
    <section className="contact">
      <div className="container">
        <Reveal className="section-h t-h1">{t.sections.contactTitle}</Reveal>
        <Reveal className="contact-head t-body about-lead-sub" delay={80} style={{ marginTop: 16, maxWidth: '46ch' }}>{t.contact.lead}</Reveal>

        <div className="contact-info-only">
          <Reveal className="contact-info" delay={140}>
            <div>
              <span className="t-eyebrow">- email</span>
              <a className="t-h3" href="mailto:4kirloginov@gmail.com">4kirloginov@gmail.com</a>
            </div>
            <div>
              <span className="t-eyebrow">- {lang === 'ru' ? 'телефон' : 'phone'}</span>
              <a className="t-h3" href="tel:+79895922720">+7 989 592 27 20</a>
            </div>
            <div>
              <span className="t-eyebrow">- telegram</span>
              <a className="t-h3" href="https://t.me/kirloginovobjects" target="_blank" rel="noreferrer">@kirloginovobjects</a>
            </div>
            <div>
              <span className="t-eyebrow">- instagram</span>
              <a className="t-h3" href="https://instagram.com/kirloginovobjects" target="_blank" rel="noreferrer">@kirloginovobjects</a>
            </div>
            <div>
              <span className="t-eyebrow">- {lang === 'ru' ? 'соцсети' : 'social'}</span>
              <div className="contact-social">
                <a href="https://instagram.com/kirloginovobjects" target="_blank" rel="noreferrer" aria-label="Instagram">
                  <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                    <rect x="2.5" y="2.5" width="19" height="19" rx="5" ry="5" />
                    <circle cx="12" cy="12" r="4.2" />
                    <circle cx="17.4" cy="6.6" r="0.9" fill="currentColor" stroke="none" />
                  </svg>
                </a>
                <a href="https://t.me/kirloginovobjects" target="_blank" rel="noreferrer" aria-label="Telegram">
                  <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                    <circle cx="12" cy="12" r="9.5" />
                    <path d="M7.4 12.3 16.2 7.6 14.6 16.7 11.4 14 13.4 12 9.6 14.5 7.4 13.4Z" />
                  </svg>
                </a>
              </div>
            </div>
            <div>
              <span className="t-eyebrow">- {lang === 'ru' ? 'студия' : 'studio'}</span>
              <span className="t-h3">{lang === 'ru' ? 'Москва' : 'Moscow'}</span>
            </div>
            <p className="t-small muted contact-note">{t.contact.formNote}</p>
          </Reveal>
          {/* contact form removed per Kir's request 2026-04-30 */}
        </div>
      </div>
    </section>);

};

// ─────────────────────────────────────────────────────────
// Footer
// ─────────────────────────────────────────────────────────
const Footer = ({ lang, navigate }) => {
  const t = COPY[lang];
  return (
    <footer className="foot">
      <hr className="hairline" />
      <div className="container foot-row">
        <div className="foot-col foot-brand">
          <a className="logo-foot-horizontal" href="#" onClick={(e) => { e.preventDefault(); navigate({ name: 'home' }); }} aria-label="Kir Loginov Objects">
            <img src="images/logo/lockup-en.svg?v=114" alt="Kir Loginov Objects" />
          </a>
          <p className="t-small muted" style={{ marginTop: 16 }}>{t.footer.tagline}</p>
        </div>
        <div className="foot-col">
          <span className="t-eyebrow">- {lang === 'ru' ? 'навигация' : 'navigate'}</span>
          <button className="t-body" onClick={() => navigate({ name: 'works' })}>{t.nav.works}</button>
          <button className="t-body" onClick={() => navigate({ name: 'about' })}>{t.nav.about}</button>
          <button className="t-body" onClick={() => navigate({ name: 'press' })}>{t.nav.press}</button>
          <button className="t-body" onClick={() => navigate({ name: 'process' })}>{t.nav.process}</button>
          <button className="t-body" onClick={() => navigate({ name: 'contact' })}>{t.nav.contact}</button>
        </div>
        <div className="foot-col">
          <span className="t-eyebrow">- {lang === 'ru' ? 'связь' : 'reach'}</span>
          <a className="t-body" href="mailto:4kirloginov@gmail.com">4kirloginov@gmail.com</a>
          <div className="foot-social">
            <a href="https://instagram.com/kirloginovobjects" target="_blank" rel="noreferrer" aria-label="Instagram">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <rect x="2.5" y="2.5" width="19" height="19" rx="5" ry="5" />
                <circle cx="12" cy="12" r="4.2" />
                <circle cx="17.4" cy="6.6" r="0.9" fill="currentColor" stroke="none" />
              </svg>
            </a>
            <a href="https://t.me/kirloginovobjects" target="_blank" rel="noreferrer" aria-label="Telegram">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <circle cx="12" cy="12" r="9.5" />
                <path d="M7.4 12.3 16.2 7.6 14.6 16.7 11.4 14 13.4 12 9.6 14.5 7.4 13.4Z" />
              </svg>
            </a>
          </div>
        </div>
        <div className="foot-col">
          <span className="t-mono muted">{t.footer.rights}</span>
          <span className="t-mono muted">{lang === 'ru' ? 'Сделано вручную' : 'Made by hand'}</span>
        </div>
      </div>
    </footer>);

};

// ─────────────────────────────────────────────────────────
// Process / Studio
// ─────────────────────────────────────────────────────────
const Process = ({ lang }) => {
  const t = COPY[lang];
  const [opened, setOpened] = React.useState(null);
  return (
    <section className="process">
      <div className="container">
        <Reveal className="section-h t-h1">{t.sections.processTitle}</Reveal>
        <div className="process-grid">
          {PROCESS.map((p, i) => (
            <Reveal key={i} delay={Math.min(80 * i, 360)} className="process-item">
              <button
                className="process-item-btn"
                onClick={() => setOpened({ photo: `${p.src}?v=114` })}
                aria-label="Открыть фото">
                <img src={`${p.src}?v=114`} alt={p.alt} loading="lazy" decoding="async" />
              </button>
            </Reveal>
          ))}
        </div>
      </div>
      <Lightbox
        open={!!opened}
        onClose={() => setOpened(null)}
        photo={opened?.photo}
        lang={lang}
      />
    </section>
  );
};

Object.assign(window, {
  Reveal, WorkImage, TopBar, Hero, WorksGrid, SingleWork, About, Series, Lightbox, Press, Stockists, Process, Contact, Footer
});