/* global React */
const { useState, useEffect, useRef, useContext, createContext, useMemo } = React;

// ====== Brand Logo ======
// Uses the official brand PNGs from the brand book.
// variant: "mark" (SA monogram), "lockup" (combo), "horizontal" (wordmark+ghost),
//          "stack" (vertical), "wordmark" (text only)
// tone:    "light" (for dark bg) | "dark" (for light bg)
const LOGO_SRC = {
  "mark-light":       "assets/logo-mark-light.png",
  "mark-dark":        "assets/logo-mark-dark.png",
  "lockup-light":     "assets/logo-lockup-light.png",
  "lockup-dark":      "assets/logo-lockup-dark.png",
  "horizontal-light": "assets/logo-horizontal-light.png",
  "horizontal-dark":  "assets/logo-horizontal-dark.png",
  "stack-light":      "assets/logo-stack-light-v2.png",
  "stack-dark":       "assets/logo-stack-dark.png",
  "wordmark-light":   "assets/logo-wordmark-light-v2.png",
  "wordmark-dark":    "assets/logo-wordmark-dark-v2.png",
};
function Logo({ variant = "mark", tone = "light", className = "", alt = "Sandler Atelier" }) {
  const src = LOGO_SRC[`${variant}-${tone}`] || LOGO_SRC["mark-light"];
  return <img src={src} alt={alt} className={`brand-logo ${className}`} />;
}
// Legacy alias — some files still import MonogramSVG
function MonogramSVG({ className = "", stroke }) {
  const tone = stroke && stroke !== "#fff" && stroke !== "#ffffff" && stroke !== "currentColor" ? "dark" : "light";
  return <Logo variant="mark" tone={tone} className={className}/>;
}

// ====== Cart Store (context) ======
const StoreCtx = createContext(null);
const useStore = () => useContext(StoreCtx);

const PRODUCTS = [
{ id: "top", name: "ТОП", nameEn: "TOP", price: 5800, sizes: ["XS-S", "S-M"], category: "tops",
  img: ["assets/look-13.jpg", "assets/look-14.jpg"],
  gallery: ["assets/look-13.jpg", "assets/look-14.jpg", "assets/product-top-01.jpg", "assets/product-top-02.jpg"],
  composition: "85% полиамид, 15% эластан", care: "Стирка при 30°. Не отбеливать. Сушить в тени.",
  desc: "Архитектурный топ с длинным рукавом и двойной бретелью. Брелочная плотность ткани сохраняет силуэт.",
  tag: "BASE" },
{ id: "body", name: "БОДИ", nameEn: "BODY", price: 6900, sizes: ["XS", "S", "M"], category: "tops",
  img: ["assets/look-12.jpg", "assets/look-11.jpg"],
  gallery: ["assets/look-12.jpg", "assets/look-11.jpg", "assets/look-13.jpg", "assets/look-14.jpg"],
  composition: "92% полиамид, 8% эластан",
  care: "Стирка при 30°. Не отбеливать.",
  desc: "Открытое боди с завязками по линии бёдер. Заявляет себя без слов.",
  tag: "BASE" },
{ id: "pants", name: "ШТАНЫ", nameEn: "PANTS", price: 7400, sizes: ["XS-S", "S-M"], category: "bottoms",
  img: ["assets/product-pants-04.jpg", "assets/product-pants-03.jpg"],
  gallery: ["assets/product-pants-04.jpg", "assets/product-pants-03.jpg", "assets/product-pants-01.jpg", "assets/product-pants-02.jpg"],
  composition: "90% полиамид, 10% эластан",
  care: "Стирка при 30°. Сушить горизонтально.",
  desc: "Брюки с расклешением от колена и шнуровкой на бёдрах. Каркас и поток.",
  tag: "BASE" },
{ id: "tshirt", name: "ФУТБОЛКА", nameEn: "T-SHIRT", price: 5200, sizes: ["XS", "S", "M"], category: "tops",
  img: ["assets/look-04.jpg", "assets/look-03.jpg"],
  gallery: ["assets/look-04.jpg", "assets/look-03.jpg", "assets/look-05.jpg"],
  composition: "100% хлопок, тяжёлый трикотаж",
  care: "Стирка при 30°.",
  desc: "Базовая футболка с акцентной нашивкой. Слой, который держит всё остальное.",
  tag: "BASE" },
{ id: "jeans", name: "ДЖИНСЫ", nameEn: "JEANS", price: 7800, sizes: ["XS-S", "S-M"], category: "bottoms",
  img: ["assets/look-09.jpg", "assets/look-10.jpg"],
  gallery: ["assets/look-09.jpg", "assets/look-10.jpg", "assets/look-08.jpg", "assets/look-07.jpg"],
  composition: "98% хлопок, 2% эластан",
  care: "Стирка при 30°. Не выкручивать.",
  desc: "Прямой силуэт с заниженной талией. Жёсткая ткань ломается по фигуре.",
  tag: "NEW" },
{ id: "corset", name: "КОРСЕТ", nameEn: "CORSET", price: 8200, sizes: ["XS", "S", "M"], category: "tops",
  img: ["assets/look-17.jpg", "assets/look-18.jpg"],
  gallery: ["assets/look-17.jpg", "assets/look-18.jpg", "assets/look-15.jpg", "assets/look-16.jpg"],
  composition: "Стрейч-сатин с косточками",
  care: "Только сухая чистка.",
  desc: "Корсет архитектурного кроя. Силуэт как утверждение.",
  tag: "BASE" }];


const ORDERS = [
{ id: "SA-1024", date: "21.05.2026", customer: "Анна Соколова", email: "anna@example.com", phone: "+7 916 123 45 67", address: "Москва, ул. Большая Никитская 14, кв. 7", items: [{ productId:"body", size:"S", qty:1 }, { productId:"pants", size:"S-M", qty:1 }], total: 14800, status: "новый" },
{ id: "SA-1023", date: "21.05.2026", customer: "Маша Кравченко", email: "masha@example.com", phone: "+7 921 555 88 12", address: "СПб, Невский 78, кв. 24", items: [{ productId:"body", size:"M", qty:1 }], total: 6900, status: "в обработке" },
{ id: "SA-1022", date: "20.05.2026", customer: "Юлия Петрова", email: "yulia@example.com", phone: "+7 905 222 33 44", address: "Москва, Тверская 8", items: [{ productId:"tshirt", size:"S", qty:1 }, { productId:"jeans", size:"XS-S", qty:1 }, { productId:"top", size:"S-M", qty:1 }], total: 19400, status: "отправлен" },
{ id: "SA-1021", date: "20.05.2026", customer: "Дарья Литвинова", email: "darya@example.com", phone: "+7 999 111 22 33", address: "Казань, ул. Баумана 12", items: [{ productId:"jeans", size:"S-M", qty:1 }], total: 7800, status: "выполнен" },
{ id: "SA-1020", date: "19.05.2026", customer: "Ева Никонова", email: "eva@example.com", phone: "+7 985 444 55 66", address: "Москва, Покровка 22", items: [{ productId:"top", size:"XS-S", qty:1 }, { productId:"tshirt", size:"M", qty:1 }], total: 13100, status: "выполнен" },
{ id: "SA-1019", date: "19.05.2026", customer: "Алина Фёдорова", email: "alina@example.com", phone: "+7 916 777 88 99", address: "Екатеринбург, Ленина 50", items: [{ productId:"tshirt", size:"XS", qty:1 }], total: 5200, status: "выполнен" }];


const LOOKS = [
{ id: 1,  src: "assets/look-01.jpg", title: "Soft Architecture",   products: ["body", "pants"] },
{ id: 2,  src: "assets/look-02.jpg", title: "Long Line",            products: ["body", "pants"] },
{ id: 3,  src: "assets/look-03.jpg", title: "Off Duty",             products: ["tshirt", "jeans"] },
{ id: 4,  src: "assets/look-04.jpg", title: "Layer One",            products: ["tshirt"] },
{ id: 5,  src: "assets/look-05.jpg", title: "Slow Burn",            products: ["body", "pants"] },
{ id: 6,  src: "assets/look-06.jpg", title: "Negative Space",       products: ["body", "pants"] },
{ id: 7,  src: "assets/look-07.jpg", title: "Hard Light",           products: ["tshirt", "jeans"] },
{ id: 8,  src: "assets/look-08.jpg", title: "After Hours",          products: ["tshirt", "jeans"] },
{ id: 9,  src: "assets/look-13.jpg", title: "Front Row",            products: ["top", "pants"] },
{ id: 10, src: "assets/look-14.jpg", title: "Side Profile",         products: ["top", "pants"] },
{ id: 11, src: "assets/look-15.jpg", title: "Structure",            products: ["corset", "pants"] },
{ id: 12, src: "assets/look-16.jpg", title: "Detail · Strap",       products: ["top", "pants"] }];


const COLLECTIONS = [
{ id:"baza", name:"БАЗА", subtitle:"Дроп 01 · SS 2026", productIds:["top","body","pants","tshirt","jeans","corset"], active:true },
{ id:"next", name:"Следующая глава", subtitle:"Дроп 02 · готовится", productIds:[], active:false }];


const SITE_DEFAULTS = {
  slogan: "Для тех, кто не просит разрешения",
  manifestoHead: "Не одежда.",
  manifestoBody: "Заявление. Архитектура, в которую ты входишь, и из которой не выходишь прежней.",
  collectionName: "БАЗА",
  collectionEyebrow: "Дроп 01 · Весна / Лето 2026",
  newCollEyebrow: "Скоро · 06 / 2026",
  newCollHead: "Следующая\nглава.",
  newCollBody: "Вторая капсула расширяет БАЗУ — корсетные конструкции, длинные платья, латексные акценты. Подписка открыта для тех, кто хочет первым.",
  contactEmail: "hello@sandler.atelier",
  contactCity: "Россия · 2026",
};

const PAGES_DEFAULT = [
  { id:"home",      title:"Главная",         route:"home",      desc:"Hero, манифест, образы, новая коллекция",     visible:true,  inNav:false, inFooter:false, metaTitle:"SANDLER ATELIER · Для тех, кто не просит разрешения", metaDesc:"Российский бренд женской одежды mid-premium сегмента. Коллекция БАЗА.", updatedAt:"21.05.2026" },
  { id:"catalog",   title:"Каталог",         route:"catalog",   desc:"Сетка всех товаров с фильтрами",              visible:true,  inNav:true,  inFooter:true,  metaTitle:"Каталог · SANDLER ATELIER",            metaDesc:"Все позиции коллекции БАЗА. Топы, боди, штаны, корсеты, джинсы.", updatedAt:"20.05.2026" },
  { id:"lookbook",  title:"Образы",          route:"lookbook",  desc:"Кампания SS / AW, shop-the-look",             visible:true,  inNav:true,  inFooter:false, metaTitle:"Образы · SANDLER ATELIER",             metaDesc:"Кампания SS 2026. Купи образ целиком в один клик.",          updatedAt:"19.05.2026" },
  { id:"about",     title:"Атéлье",          route:"about",     desc:"О бренде, манифест, roadmap",                 visible:true,  inNav:true,  inFooter:false, metaTitle:"Атéлье · SANDLER ATELIER",             metaDesc:"О бренде Sandler Atelier. Diana Sandler.",                    updatedAt:"18.05.2026" },
  { id:"delivery",  title:"Доставка",        route:"delivery",  desc:"Условия доставки СДЭК",                       visible:true,  inNav:false, inFooter:true,  metaTitle:"Доставка · SANDLER ATELIER",           metaDesc:"Доставка СДЭК по России и СНГ.",                              updatedAt:"15.05.2026" },
  { id:"sizeguide", title:"Размерная сетка", route:"sizeguide", desc:"Таблица замеров + посадка",                   visible:true,  inNav:false, inFooter:true,  metaTitle:"Размерная сетка · SANDLER ATELIER",    metaDesc:"Таблица замеров для XS / S / M / XS-S / S-M.",                updatedAt:"15.05.2026" },
  { id:"offer",     title:"Оферта",          route:"offer",     desc:"Публичная оферта · 152-ФЗ",                   visible:true,  inNav:false, inFooter:true,  metaTitle:"Оферта · SANDLER ATELIER",             metaDesc:"Публичная оферта ИП Сандлер Д.Б.",                            updatedAt:"10.05.2026" },
  { id:"returns",   title:"Возврат",         route:"returns",   desc:"Условия возврата (14 дней)",                  visible:true,  inNav:false, inFooter:true,  metaTitle:"Возврат · SANDLER ATELIER",            metaDesc:"Возврат в течение 14 дней без объяснений.",                   updatedAt:"10.05.2026" },
  { id:"privacy",   title:"Политика данных", route:"privacy",   desc:"Обработка персональных данных",               visible:true,  inNav:false, inFooter:true,  metaTitle:"Политика данных · SANDLER ATELIER",    metaDesc:"Обработка персональных данных. 152-ФЗ.",                       updatedAt:"10.05.2026" },
];

const STAFF_DEFAULT = [
  { id:"u-owner",   name:"Diana Sandler",    email:"diana@sandler.atelier",  role:"owner",   password:"diana123",  active:true },
  { id:"u-manager", name:"Алексей Кравцов",   email:"alex@sandler.atelier",   role:"manager", password:"manager123", active:true },
  { id:"u-shipper", name:"Мария Орлова",     email:"maria@sandler.atelier",   role:"shipper", password:"ship123",   active:true },
  { id:"u-content", name:"Ева Никитина",     email:"eva@sandler.atelier",     role:"content", password:"content123",active:false },
];

const ROLES = {
  owner:   { label:"Владелец",     desc:"Полный доступ ко всему",                   perms:["dashboard","orders","products","looks","collections","pages","brand","team"] },
  manager: { label:"Менеджер",     desc:"Каталог, образы, коллекции, заказы",       perms:["dashboard","orders","products","looks","collections"] },
  shipper: { label:"Логист",       desc:"Только заказы (без статистики и цифр)",    perms:["orders"] },
  content: { label:"Контент",      desc:"Контент сайта, страницы, образы",          perms:["pages","brand","looks"] },
};

function StoreProvider({ children }) {
  const [cart, setCart] = useState([]);
  const [route, setRoute] = useState(() => location.hash.replace("#", "") || "home");
  const [cartBump, setCartBump] = useState(false);
  const [wipe, setWipe] = useState(false);

  // Editable site state
  const [products, setProducts]       = useState(PRODUCTS);
  const [orders, setOrders]           = useState(ORDERS);
  const [looks, setLooks]             = useState(LOOKS);
  const [collections, setCollections] = useState(COLLECTIONS);
  const [site, setSite]               = useState(SITE_DEFAULTS);
  const [staff, setStaff]             = useState(STAFF_DEFAULT);
  const [pages, setPages]             = useState(PAGES_DEFAULT);
  const [currentStaffId, setCurrentStaffId] = useState("u-owner");

  // CRUD helpers
  const upsertProduct = (p) => setProducts(prev => prev.find(x=>x.id===p.id) ? prev.map(x=>x.id===p.id?p:x) : [...prev, p]);
  const removeProduct = (id) => setProducts(prev => prev.filter(x=>x.id!==id));

  const upsertLook   = (l) => setLooks(prev => prev.find(x=>x.id===l.id) ? prev.map(x=>x.id===l.id?l:x) : [...prev, l]);
  const removeLook   = (id) => setLooks(prev => prev.filter(x=>x.id!==id));

  const upsertCollection = (c) => setCollections(prev => prev.find(x=>x.id===c.id) ? prev.map(x=>x.id===c.id?c:x) : [...prev, c]);
  const removeCollection = (id) => setCollections(prev => prev.filter(x=>x.id!==id));

  const upsertStaff = (s) => setStaff(prev => prev.find(x=>x.id===s.id) ? prev.map(x=>x.id===s.id?s:x) : [...prev, s]);
  const removeStaff = (id) => setStaff(prev => prev.filter(x=>x.id!==id));

  const updatePage = (id, patch) => setPages(prev => prev.map(p => p.id === id ? {...p, ...patch, updatedAt: new Date().toLocaleDateString("ru-RU")} : p));

  const setOrderStatus = (id, status) => setOrders(prev => prev.map(o => o.id === id ? {...o, status} : o));
  const updateSite = (patch) => setSite(prev => ({...prev, ...patch}));

  const currentStaff = staff.find(s => s.id === currentStaffId) || staff[0];
  const currentPerms = (currentStaff && ROLES[currentStaff.role]?.perms) || [];
  const can = (perm) => currentPerms.includes(perm);

  useEffect(() => {
    const fn = () => setRoute(location.hash.replace("#", "") || "home");
    addEventListener("hashchange", fn);
    return () => removeEventListener("hashchange", fn);
  }, []);

  const navigate = (path) => {
    setWipe(true);
    setTimeout(() => {location.hash = path;window.scrollTo(0, 0);}, 380);
    setTimeout(() => setWipe(false), 920);
  };

  const addToCart = (productId, size, qty = 1) => {
    setCart((prev) => {
      const existing = prev.find((l) => l.productId === productId && l.size === size);
      if (existing) {
        return prev.map((l) => l === existing ? { ...l, qty: l.qty + qty } : l);
      }
      return [...prev, { productId, size, qty }];
    });
    setCartBump(true);
    setTimeout(() => setCartBump(false), 400);
  };

  const removeLine = (idx) => setCart((prev) => prev.filter((_, i) => i !== idx));
  const setQty = (idx, q) => setCart((prev) => prev.map((l, i) => i === idx ? { ...l, qty: Math.max(1, q) } : l));
  const clearCart = () => setCart([]);

  const total = cart.reduce((s, l) => {
    const p = products.find((p) => p.id === l.productId);
    return s + (p ? p.price * l.qty : 0);
  }, 0);

  const count = cart.reduce((s, l) => s + l.qty, 0);

  return (
    <StoreCtx.Provider value={{
      products, orders, looks, collections, site, staff, pages, ROLES,
      currentStaff, can, setCurrentStaffId,
      upsertProduct, removeProduct,
      upsertLook, removeLook,
      upsertCollection, removeCollection,
      upsertStaff, removeStaff,
      updatePage,
      setOrderStatus, updateSite,
      cart, addToCart, removeLine, setQty, clearCart, total, count,
      route, navigate, cartBump, wipe
    }}>
      {children}
    </StoreCtx.Provider>);

}

// ====== Custom Cursor ======
function Cursor() {
  const dotRef = useRef(null);
  const ringRef = useRef(null);
  const targetRef = useRef({ x: 0, y: 0 });
  const ringRef2 = useRef({ x: 0, y: 0 });

  useEffect(() => {
    const onMove = (e) => {
      targetRef.current = { x: e.clientX, y: e.clientY };
      if (dotRef.current) {
        dotRef.current.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%,-50%)`;
      }
    };
    const tick = () => {
      ringRef2.current.x += (targetRef.current.x - ringRef2.current.x) * 0.18;
      ringRef2.current.y += (targetRef.current.y - ringRef2.current.y) * 0.18;
      if (ringRef.current) {
        ringRef.current.style.transform = `translate(${ringRef2.current.x}px, ${ringRef2.current.y}px) translate(-50%,-50%)`;
      }
      raf = requestAnimationFrame(tick);
    };
    let raf = requestAnimationFrame(tick);

    const enter = (e) => {
      const t = e.target;
      if (t.closest && t.closest('a,button,.product-card,[data-cursor="hover"]')) {
        ringRef.current && ringRef.current.classList.add("hover");
      }
    };
    const leave = (e) => {
      const t = e.target;
      if (t.closest && t.closest('a,button,.product-card,[data-cursor="hover"]')) {
        ringRef.current && ringRef.current.classList.remove("hover");
      }
    };

    addEventListener("mousemove", onMove);
    document.addEventListener("mouseover", enter);
    document.addEventListener("mouseout", leave);
    return () => {
      removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseover", enter);
      document.removeEventListener("mouseout", leave);
      cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <>
      <div ref={dotRef} className="cursor-dot"></div>
      <div ref={ringRef} className="cursor-ring"></div>
    </>);

}

// ====== Reveal hook ======
function Reveal({ children, delay = 0, className = "", as: As = "div" }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setTimeout(() => setShown(true), delay);
          io.disconnect();
        }
      });
    }, { threshold: 0.12 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [delay]);
  return <As ref={ref} className={`reveal ${shown ? "in" : ""} ${className}`}>{children}</As>;
}

// ====== Header ======
function Header() {
  const { route, navigate, count, cartBump, pages } = useStore();
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    const fn = () => setScrolled(window.scrollY > 40);
    fn();addEventListener("scroll", fn);
    return () => removeEventListener("scroll", fn);
  }, []);
  useEffect(() => { setMenuOpen(false); }, [route]);
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  if (route.startsWith("admin")) return null;

  const allLinks = [
    { p: "catalog", label: "Каталог" },
    { p: "lookbook", label: "Образы" },
    { p: "about", label: "Атéлье" },
  ];
  const links = allLinks.filter(l => {
    const page = pages.find(pg => pg.route === l.p);
    return !page || (page.visible && page.inNav);
  });


  return (
    <>
    <header className={`site-header ${scrolled || menuOpen ? "solid" : ""}`}>
      <button className="nav-burger" onClick={()=>setMenuOpen(v=>!v)} aria-label="Меню">
        <span className={menuOpen?"open":""}></span>
      </button>
      <nav className="nav-left">
        {links.map((l) =>
        <a key={l.p} className={route === l.p ? "active" : ""}
        onClick={(e) => {e.preventDefault();navigate(l.p);}} href={`#${l.p}`}>{l.label}</a>
        )}
      </nav>
      <a className="brand-mark" href="#home" onClick={(e) => {e.preventDefault();navigate("home");}}>
        <Logo variant="wordmark" tone="light" className="brand-wordmark"/>
      </a>
      <nav className="nav-right">
        <a className="nav-lang" href="#" onClick={(e) => e.preventDefault()}>RU / EN</a>
        <a className="cart-pill" onClick={(e) => {e.preventDefault();navigate("cart");}} href="#cart">
          <span className="cart-label">Корзина</span>
          <span className={`count ${cartBump ? "bump" : ""}`}>{count}</span>
        </a>
      </nav>
    </header>

    <div className={`mobile-drawer ${menuOpen?"open":""}`} onClick={()=>setMenuOpen(false)}>
      <div className="mobile-drawer-inner" onClick={(e)=>e.stopPropagation()}>
        <div className="mobile-drawer-head">
          <Logo variant="wordmark" tone="light" className="brand-wordmark"/>
          <button className="mobile-drawer-close" onClick={()=>setMenuOpen(false)} aria-label="Закрыть">×</button>
        </div>
        <nav className="mobile-drawer-nav">
          <a onClick={(e)=>{e.preventDefault();navigate("home");}} href="#home">Главная</a>
          {links.map(l => (
            <a key={l.p} onClick={(e)=>{e.preventDefault();navigate(l.p);}} href={`#${l.p}`}>{l.label}</a>
          ))}
          <div className="mobile-drawer-sep"></div>
          <a onClick={(e)=>{e.preventDefault();navigate("delivery");}} href="#delivery">Доставка</a>
          <a onClick={(e)=>{e.preventDefault();navigate("sizeguide");}} href="#sizeguide">Размерная сетка</a>
          <a onClick={(e)=>{e.preventDefault();navigate("returns");}} href="#returns">Возврат</a>
        </nav>
        <div className="mobile-drawer-foot">
          <span>RU / EN</span>
          <span>SANDLER ATELIER · 2026</span>
        </div>
      </div>
    </div>
    </>);

}

// ====== Footer ======
function Footer() {
  const { navigate, route, site, pages } = useStore();
  if (route.startsWith("admin") || route === "confirmation") return null;
  const showInFoot = (r) => {
    const pg = pages.find(p=>p.route===r);
    return !pg || (pg.visible && pg.inFooter);
  };
  return (
    <footer className="site-footer">
      <img className="footer-mono" src="assets/logo-mark-light.png" alt=""/>
      <div className="foot-grid">
        <div>
          <h4>Атéлье</h4>
          <p style={{ fontFamily: "var(--f-display)", fontWeight: 300, fontSize: 15, lineHeight: 1.6, color: "var(--gray)", maxWidth: 380 }}>Для тех, кто не просит разрешения.

          </p>
          <p style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: ".24em", textTransform: "uppercase", color: "var(--gray-2)", marginTop: 30 }}>РОССИЯ · SANDLER ATELIER

          </p>
        </div>
        <div>
          <h4>Магазин</h4>
          <ul>
            {showInFoot("catalog") &&    <li><a onClick={(e) => {e.preventDefault();navigate("catalog");}} href="#catalog">Каталог</a></li>}
            <li><a onClick={(e) => {e.preventDefault();navigate("home");}} href="#home">Коллекция БАЗА</a></li>
            {showInFoot("sizeguide") &&  <li><a onClick={(e)=>{e.preventDefault();navigate("sizeguide");}} href="#sizeguide">Размерная сетка</a></li>}
            {showInFoot("delivery") &&   <li><a onClick={(e)=>{e.preventDefault();navigate("delivery");}} href="#delivery">Доставка</a></li>}
          </ul>
        </div>
        <div>
          <h4>Контакты</h4>
          <ul>
            <li><a href={`mailto:${site.contactEmail}`}>{site.contactEmail}</a></li>
            <li><a href="#">Telegram</a></li>
            <li><a href="#">Instagram*</a></li>
            <li><a href="#">VK</a></li>
          </ul>
        </div>
        <div>
          <h4>Правовое</h4>
          <ul>
            {showInFoot("offer") &&    <li><a onClick={(e)=>{e.preventDefault();navigate("offer");}} href="#offer">Оферта</a></li>}
            {showInFoot("returns") &&  <li><a onClick={(e)=>{e.preventDefault();navigate("returns");}} href="#returns">Возврат</a></li>}
            {showInFoot("privacy") &&  <li><a onClick={(e)=>{e.preventDefault();navigate("privacy");}} href="#privacy">Политика данных</a></li>}
            <li>
              <a onClick={(e) => {e.preventDefault();navigate("admin");}} href="#admin"
              style={{ color: "var(--gray-2)" }}>Админ-панель →</a>
            </li>
          </ul>
        </div>
      </div>
      <div className="foot-bottom">
        <span>© 2026 Sandler Atelier · Diana Sandler</span>
        <span>СДЕЛАНО В РОССИИ
</span>
      </div>
    </footer>);
}

// ====== Wipe Overlay ======
function Wipe() {
  const { wipe } = useStore();
  return <div className={`wipe ${wipe ? "run" : ""}`}></div>;
}

// ====== Loader ======
function Loader() {
  const [hide, setHide] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => setHide(true), 1700);
    return () => clearTimeout(t);
  }, []);
  return (
    <div className={`loader ${hide ? "hide" : ""}`}>
      <Logo variant="stack" tone="light" className="loader-logo"/>
      <div className="loader-bar"></div>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 10, letterSpacing: ".32em", color: "var(--gray-2)" }}>SANDLER ATELIER · LOADING</div>
    </div>);

}

// Export to window
Object.assign(window, { useStore, Logo, MonogramSVG, StoreProvider, Cursor, Reveal, Header, Footer, Wipe, Loader, PRODUCTS, ORDERS });