// Hi-fi UI primitives — editorial premium B2B HoReCa.
// Cormorant Garamond (serif display) + Manrope (sans body) + small caps eyebrow.
// White paper, black ink, mustard accent. Hairline borders. Lots of whitespace.

const HF = {
  ink: '#0d0d0d',
  ink2: 'rgba(13,13,13,0.78)',
  ink3: 'rgba(13,13,13,0.55)',
  line: 'rgba(13,13,13,0.10)',
  line2: 'rgba(13,13,13,0.18)',
  paper: '#fafaf7',
  paper2: '#f3f0e8',
  paper3: '#ebe6d8',
};

const hfDisplay = '"Cormorant Garamond", "Cormorant", "EB Garamond", Georgia, serif';
const hfBody = '"Manrope", "Inter", system-ui, sans-serif';

// ── Routing — relative paths used by the standalone clickable prototype in /site.
// In the canvas HIFI page, these still render as <a href>; a global click handler
// there (see Demo Owithu B2B HoReCa HIFI V1.html) calls preventDefault so the
// canvas doesn't navigate. In /site/*.html files, navigation works normally.
const HFRoutes = {
  home: 'site/index.html',
  rest: 'site/restaurante.html',
  cafe: 'site/cafenele.html',
  hot:  'site/hoteluri.html',
  col:  'site/colectii.html',
  // 'Despre' a fost integrat în homepage (secțiunea #despre); site/despre.html
  // rămâne doar ca redirect către index.
  desp: 'site/index.html#despre',
  rfq:  'site/cere-oferta.html',
  detail: 'site/genesis-terre.html', // for now only GENESIS Terre has a detail page
  prod:   'site/produs.html',
};

// ── hfSlug — canonical slugifier (diacritics + accents stripped via NFD, so
// 'Pétrole' → 'petrole', 'Crème' → 'creme' — matches COLLECTION_DETAILS keys).
const hfSlug = (s) => (s || '')
  .toLowerCase()
  .normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  .replace(/[ăâ]/g, 'a').replace(/[î]/g, 'i').replace(/[ș]/g, 's').replace(/[ț]/g, 't')
  .replace(/[^a-z0-9]+/g, '-')
  .replace(/^-+|-+$/g, '');

// ── hfRfqHref — builds the request-offer URL with pre-fill context. Used ONLY
// by contextual CTAs (collection detail, piece pages, collection cards) — the
// generic navbar / pre-footer "Cere ofertă" links stay plain (HFRoutes.rfq).
function hfRfqHref(colectie, piesa) {
  const q = [];
  if (colectie) q.push('colectie=' + encodeURIComponent(colectie));
  if (piesa) q.push('piesa=' + encodeURIComponent(piesa));
  return HFRoutes.rfq + (q.length ? '?' + q.join('&') : '');
}

// ── Hover-image lookup — maps a collection card's primary photo to its
// alternate (lifestyle / detail shot). HfCollectionCard reads from here when
// no explicit `imgHover` prop is passed, so the same lookup works whether
// the card is rendered from ALL_COLLECTIONS in page-collections.jsx, or from
// an inline array in page-home.jsx / page-landings.jsx.
// Both photos come from the SAME Bjorn product (collection + finish), never
// random across collections.
const HF_HOVER = {
  'img/c-genesis-terre.jpg':      'img/h-genesis-terre.jpg',
  'img/c-genesis-mer.jpg':        'img/c-genesis-mer-alt.jpg',
  'img/c-genesis-basalte.jpg':    'img/c-genesis-basalte-alt.jpg',
  'img/c-genesis-plus-terre.jpg': 'img/h-genesis-plus.jpg',
  'img/c-iris-marron.jpg':        'img/h-iris-marron.jpg',
  'img/c-iris-nuit.jpg':          'img/c-iris-nuit-alt.jpg',
  'img/c-iris-ivoire.jpg':        'img/h-iris-ivoire.jpg',
  'img/c-magma-cobalt.jpg':       'img/c-magma-cobalt-alt.jpg',
  'img/c-magma-menthe.jpg':       'img/c-magma-menthe-alt.jpg',
  'img/c-scandi-olive.jpg':       'img/c-scandi-olive-alt.jpg',
  'img/c-scandi-marine.jpg':      'img/c-scandi-marine-alt.jpg',
  'img/c-scandi-ocre.jpg':        'img/c-scandi-ocre-alt.jpg',
  'img/c-gourmet-onyx.jpg':       'img/h-gourmet.jpg',
  'img/c-oxygen-rose.jpg':        'img/h-oxygen-rose.jpg',
  'img/c-oxygen-vert.jpg':        'img/c-oxygen-vert-alt.jpg',
  'img/c-moon-petrole.jpg':       'img/c-moon-petrole-alt.jpg',
  'img/c-moon-encre.jpg':         'img/c-moon-encre-alt.jpg',
  'img/c-zen-natural.jpg':        'img/h-zen.jpg',
  'img/c-island.jpg':             'img/c-island-alt.jpg',
  'img/c-cloud.jpg':              'img/c-cloud-alt.jpg',
  'img/c-stone.jpg':              'img/c-stone-alt.jpg',
  'img/c-cosmos-azur.jpg':        'img/c-cosmos-azur-alt.jpg',
  'img/c-cosmos-creme.jpg':       'img/c-cosmos-creme-alt.jpg',
  'img/c-stellar.jpg':            'img/c-stellar-alt.jpg',
  'img/c-napoli.jpg':             'img/h-napoli.jpg',
  'img/c-pure.jpg':               'img/c-pure-alt.jpg',
};

// ── Wishlist (demo affordance) — localStorage list of saved collection slugs.
// No backend: the heart in the header shows a live count badge; the "Salvează"
// button on the collection detail page toggles membership. Cross-component
// sync via a custom 'hf-wishlist' window event (+ 'storage' across tabs).
const HF_WISHLIST_KEY = 'hfWishlist';
function hfWishlistGet() {
  try { return JSON.parse(localStorage.getItem(HF_WISHLIST_KEY)) || []; }
  catch (e) { return []; }
}
function hfWishlistToggle(id) {
  const list = hfWishlistGet();
  const i = list.indexOf(id);
  if (i >= 0) list.splice(i, 1); else list.push(id);
  try { localStorage.setItem(HF_WISHLIST_KEY, JSON.stringify(list)); } catch (e) {}
  if (typeof window !== 'undefined') window.dispatchEvent(new Event('hf-wishlist'));
  return list;
}
function hfWishlistCount() { return hfWishlistGet().length; }

// ── HfIcon — small inline stroke icons (feather-style), themed via currentColor.
function HfIcon({ name, size = 15, style = {} }) {
  const paths = {
    phone: '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',
    chat:  'M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z',
    heart: 'M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z',
    doc:   'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M16 13H8 M16 17H8',
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden focusable="false"
      style={{ display: 'block', flex: '0 0 auto', ...style }}>
      <path d={paths[name] || ''} fill={name === 'heart' && style.fill ? style.fill : 'none'}
        stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ── HfHoverImg — packshot-first image with cross-fade to a context photo on
// card hover (the CSS rule targets [data-hf-img-hover] inside article:hover).
// Falls back to the HF_HOVER lookup; graceful no-op when no second image.
function HfHoverImg({ src, hoverSrc, alt, ratio = '3 / 2', style = {} }) {
  const hov = hoverSrc || HF_HOVER[src];
  return (
    <div style={{ position: 'relative', overflow: 'hidden', ...style }}>
      <HfImg src={src} alt={alt} ratio={ratio} />
      {hov && (
        <div data-hf-img-hover style={{
          position: 'absolute', inset: 0,
          opacity: 0,
          transition: 'opacity 320ms cubic-bezier(0.2,0.6,0.2,1)',
          pointerEvents: 'none',
        }}>
          <HfImg src={hov} alt={(alt || '') + ' · ambianță'} ratio={ratio}
            style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
        </div>
      )}
    </div>
  );
}

// ── Responsive CSS + animations — injected once at module load. Targets
// inline-style elements via attribute selectors + !important so the same
// components work at desktop (1440 canvas) and on mobile (375-768) viewports.
// Elastic padding + entry animations only apply when document.documentElement
// has `data-hf-standalone` — i.e. in /site/*.html, NOT in the canvas HIFI page.
if (typeof document !== 'undefined' && !document.getElementById('hf-responsive')) {
  const s = document.createElement('style');
  s.id = 'hf-responsive';
  s.textContent = [
    /* ── FIXED HEADER — height var drives the flow spacer + sticky offsets */
    ':root { --hf-header-h: 78px; }',
    /* ── MOBILE ─────────────────────────────────────────────────────── */
    '@media (max-width: 900px) {',
    // Stack any 2/3/4-col grid layout to single column
    '  [style*="grid-template-columns"] {',
    '    grid-template-columns: 1fr !important;',
    '    gap: 24px !important;',
    '  }',
    // Grid children must not widen the stacked column past the viewport
    // (e.g. a nowrap CTA would otherwise drag the hero photo off-screen)
    '  [style*="grid-template-columns"] > * { min-width: 0; }',
    // Buttons (inline-flex + nowrap) wrap their label instead of overflowing
    '  section [style*="white-space: nowrap"][style*="display: inline-flex"] { white-space: normal !important; }',
    // Reduce horizontal section padding from 56px → 20px when both "padding" and "56px" appear in the inline style
    '  [style*="padding"][style*="56px"] {',
    '    padding-left: 20px !important;',
    '    padding-right: 20px !important;',
    '  }',
    // Scale display headings down
    '  h1 { font-size: clamp(36px, 10vw, 64px) !important; line-height: 1.02 !important; }',
    '  h2 { font-size: clamp(28px, 7vw, 48px) !important; line-height: 1.06 !important; }',
    '  h3 { font-size: clamp(20px, 5vw, 30px) !important; line-height: 1.12 !important; }',
    // Hero photos cap height at 60vw
    '  [data-hf-img]:not([data-hf-ratio]):not([data-hf-fill]) { max-height: 62vw !important; min-height: 0 !important; }',
    // Full-bleed split images (height:100% on desktop) collapse on mobile when stacked → give them a real aspect ratio
    '  [data-hf-fill] { aspect-ratio: 3 / 2 !important; height: auto !important; }',
    // Header — hide full nav links, show compact "Meniu" placeholder
    '  [data-hf-nav-links] { display: none !important; }',
    '  [data-hf-nav-menu]  { display: inline-flex !important; }',
    '  [data-hf-lang]      { display: none !important; }',
    '  [data-hf-header-cta] { display: none !important; }',
    // Footer column grid wraps to 2-up
    '  [data-hf-footer-cols] { grid-template-columns: 1fr 1fr !important; gap: 28px !important; }',
    // Prevent horizontal overflow from huge headings or hero photos
    '  body { overflow-x: hidden; }',
    // Neutralise large desktop min-heights (50/50 split blocks) that leave big empty gaps once stacked on mobile
    '  [style*="min-height: 440px"], [style*="min-height: 520px"], [style*="min-height: 540px"] { min-height: 0 !important; }',
    // Let button rows / stat rows / eyebrows wrap instead of overflowing off-screen
    '  section [style*="display: flex"], footer [style*="display: flex"] { flex-wrap: wrap !important; }',
    // Collections filter bar → single swipeable row on mobile (not a tall wrapped block); hide decorative meta + colour-family strip to cut scroll
    '  section[data-hf-filterbar] { flex-wrap: nowrap !important; overflow-x: auto; justify-content: flex-start !important; gap: 12px !important; position: sticky; top: var(--hf-header-h); }',
    '  [data-hf-filterbar] [style*="display: flex"] { flex-wrap: nowrap !important; }',
    '  [data-hf-filterbar] span, [data-hf-filterbar] a, [data-hf-filterbar] button { flex: 0 0 auto; white-space: nowrap; }',
    '  [data-hf-filtermeta], [data-hf-colorfamily] { display: none !important; }',
    // Product/collection gallery → swipe carousel on mobile (desktop thumbs hidden)
    '  [data-hf-gallery-desktop] { display: none !important; }',
    '  [data-hf-gallery-mobile] { display: block !important; }',
    '  [data-hf-gallery-mobile] [data-hf-carousel] { flex-wrap: nowrap !important; }',
    // Long uppercase labels (eyebrows, breadcrumbs) wrap instead of clipping
    '  section [style*="text-transform: uppercase"] { overflow-wrap: anywhere; }',
    // Header quick contact icons (Sună / WhatsApp) — only on mobile
    '  [data-hf-mobile-quick] { display: inline-flex !important; }',
    // Hamburger becomes icon-only on mobile (text label hidden, saves width)
    '  [data-hf-menu-label] { display: none !important; }',
    // WhatsApp floating bubble — mobile + standalone only
    '  [data-hf-standalone] [data-hf-wa-fab] { display: flex !important; }',
    '}',
    // Default state of the mobile menu placeholder — hidden at desktop
    '[data-hf-nav-menu] { display: none; }',
    '@media (min-width: 901px) { [data-hf-mobile-menu] { display: none !important; } }',
    // Mobile quick icons + WhatsApp bubble hidden by default (desktop/canvas)
    '[data-hf-mobile-quick] { display: none; }',
    '[data-hf-wa-fab] { display: none; }',
    // Very narrow screens: drop the "HoReCa" logo suffix so header fits
    '@media (max-width: 420px) { [data-hf-logo-suffix] { display: none !important; } }',
    // Full-screen menu overlay is a mobile-only pattern
    '@media (min-width: 901px) { [data-hf-menu-overlay] { display: none !important; } }',
    /* ── MOBILE MENU OVERLAY + WHATSAPP FAB animations ─────────────── */
    '@keyframes hf-menu-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }',
    '@keyframes hf-menu-out { from { opacity: 1; } to { opacity: 0; } }',
    '@keyframes hf-menu-item { to { opacity: 1; transform: translateY(0); } }',
    '@keyframes hf-fab-in { from { opacity: 0; transform: translateY(16px) scale(0.9); } to { opacity: 1; transform: none; } }',
    '@media (prefers-reduced-motion: no-preference) {',
    '  [data-hf-menu-overlay] { animation: hf-menu-in 360ms cubic-bezier(0.2,0.6,0.2,1) both; }',
    '  [data-hf-menu-overlay].hf-menu-closing { animation: hf-menu-out 300ms ease both; }',
    '  [data-hf-menu-overlay] [data-hf-menu-item] { opacity: 0; transform: translateY(16px); animation: hf-menu-item 460ms cubic-bezier(0.2,0.6,0.2,1) forwards; }',
    '  [data-hf-wa-fab] { animation: hf-fab-in 420ms cubic-bezier(0.2,0.6,0.2,1) 500ms both; }',
    '}',
    // Gallery: desktop layout by default; carousel hidden until mobile
    '[data-hf-gallery-mobile] { display: none; }',
    '[data-hf-carousel] { scrollbar-width: none; }',
    '[data-hf-carousel]::-webkit-scrollbar { display: none; }',
    // Soft hover for real links
    'a[data-hf-link]:hover { color: var(--accent) !important; }',

    /* ── ELASTIC PADDING (standalone only) ─────────────────────────────
       Constrains content width to ~1240 with auto-growing horizontal
       padding so the design feels centered and aerated on wide screens.
       Disabled in canvas (no data-hf-standalone) so artboards stay full.  */
    '@media (min-width: 901px) {',
    '  [data-hf-standalone] section[style*="56px"],',
    '  [data-hf-standalone] header[style*="56px"],',
    '  [data-hf-standalone] footer[style*="56px"] {',
    '    padding-left: max(56px, calc((100vw - 1360px) / 2)) !important;',
    '    padding-right: max(56px, calc((100vw - 1360px) / 2)) !important;',
    '  }',
    '}',

    /* ── MARQUEE + BANNER CAROUSEL ────────────────────────────────────
       The doubled attribute selector beats the mobile "flex-wrap: wrap"
       rule on specificity, so carousel tracks never wrap. */
    '[data-hf-banner-track][data-hf-banner-track] { flex-wrap: nowrap !important; }',
    '@keyframes hf-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }',
    '@keyframes hf-dotfill { from { transform: scaleX(0); } to { transform: scaleX(1); } }',
    '@media (prefers-reduced-motion: no-preference) {',
    '  [data-hf-marquee-track] { animation: hf-marquee var(--hf-marquee-dur, 42s) linear infinite; }',
    '  [data-hf-marquee]:hover [data-hf-marquee-track] { animation-play-state: paused; }',
    '}',

    /* ── ANIMATIONS — entry fade-up + card hover lift ────────────────── */
    '@media (prefers-reduced-motion: no-preference) {',
    // Cards lift on hover
    '  article {',
    '    transition: transform 360ms cubic-bezier(0.2,0.6,0.2,1), box-shadow 360ms ease;',
    '  }',
    '  [data-hf-standalone] article:hover {',
    '    transform: translateY(-4px);',
    '    box-shadow: 0 24px 50px rgba(0,0,0,0.08);',
    '  }',
    // Nav links hover
    '  a[data-hf-link] { transition: color 200ms ease, border-color 200ms ease; }',
    // Header gets a soft shadow once user scrolls past hero
    '  header.hf-scrolled {',
    '    box-shadow: 0 8px 30px rgba(0,0,0,0.06);',
    '    transition: box-shadow 240ms ease;',
    '  }',
    // Entry animation classes (applied via JS in standalone only)
    '  .hf-anim-init {',
    '    opacity: 0;',
    '    transform: translateY(28px);',
    '    transition: opacity 900ms cubic-bezier(0.2,0.6,0.2,1), transform 900ms cubic-bezier(0.2,0.6,0.2,1);',
    '    will-change: opacity, transform;',
    '  }',
    '  .hf-anim-init.hf-anim-in {',
    '    opacity: 1;',
    '    transform: translateY(0);',
    '  }',
    '  .hf-anim-init.hf-anim-delay-1 { transition-delay: 80ms; }',
    '  .hf-anim-init.hf-anim-delay-2 { transition-delay: 160ms; }',
    '  .hf-anim-init.hf-anim-delay-3 { transition-delay: 240ms; }',
    // Subtle photo zoom on hover (cards)
    '  [data-hf-standalone] article:hover [data-hf-img] {',
    '    transform: scale(1.012);',
    '  }',
    // Cross-fade to the alternate image on card hover — quick, full swap.
    '  [data-hf-standalone] article:hover [data-hf-img-hover] {',
    '    opacity: 1 !important;',
    '  }',
    '  [data-hf-img] {',
    '    transition: transform 380ms cubic-bezier(0.2,0.6,0.2,1);',
    '    will-change: transform;',
    '  }',
    '}',
  ].join('\n');
  document.head.appendChild(s);
}

// ── Animations runtime — only in standalone (canvas would conflict with
// the scaled artboard rendering). Adds:
//   • Fade-up reveal on elements scrolling into viewport
//   • Sticky header shadow on scroll
if (typeof window !== 'undefined' && !window.__hfAnimWired) {
  window.__hfAnimWired = true;
  const start = () => {
    if (!document.documentElement.hasAttribute('data-hf-standalone')) return;
    if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;

    // Sticky header shadow
    const onScroll = () => {
      const hdrs = document.querySelectorAll('header');
      const scrolled = window.scrollY > 40;
      hdrs.forEach(h => h.classList.toggle('hf-scrolled', scrolled));
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();

    // Fade-up on scroll into view
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('hf-anim-in');
          io.unobserve(e.target);
        }
      });
    }, { rootMargin: '0px 0px -8% 0px', threshold: 0.05 });

    // Attach to top-level content blocks that are BELOW initial viewport
    // (above-the-fold content stays unanimated to avoid load-flash).
    const targets = document.querySelectorAll('section, article, h1, h2, [data-hf-img]');
    let groupIdx = 0;
    targets.forEach((el) => {
      const rect = el.getBoundingClientRect();
      if (rect.top < window.innerHeight - 100) return; // already visible
      if (el.dataset.hfAnimAttached) return;
      el.dataset.hfAnimAttached = '1';
      el.classList.add('hf-anim-init');
      el.classList.add('hf-anim-delay-' + (groupIdx % 3 + 1));
      groupIdx++;
      io.observe(el);
    });
  };
  // Wait for React to paint, then wire up
  if (document.readyState === 'complete') setTimeout(start, 250);
  else window.addEventListener('load', () => setTimeout(start, 250));
}

// ── HfEyebrow — small caps label with leading line / number
function HfEyebrow({ num, children, light }) {
  const c = light ? 'rgba(255,255,255,0.78)' : HF.ink2;
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      fontFamily: hfBody, fontSize: 11, fontWeight: 600,
      letterSpacing: '0.24em', textTransform: 'uppercase',
      color: c, marginBottom: 14,
    }}>
      {num != null && <span style={{ color: 'var(--accent)', fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{num}</span>}
      <span style={{ display: 'inline-block', width: 22, height: 1, background: c }}></span>
      <span>{children}</span>
    </div>
  );
}

// ── HfH1, HfH2, HfH3 — display type using Cormorant
function HfH1({ children, style = {}, light }) {
  return (
    <h1 style={{
      fontFamily: hfDisplay, fontWeight: 400,
      fontSize: 88, lineHeight: 1.02,
      letterSpacing: '-0.01em',
      color: light ? '#fff' : HF.ink,
      margin: 0,
      ...style,
    }}>{children}</h1>
  );
}
function HfH2({ children, style = {}, light }) {
  return (
    <h2 style={{
      fontFamily: hfDisplay, fontWeight: 400,
      fontSize: 56, lineHeight: 1.05,
      letterSpacing: '-0.005em',
      color: light ? '#fff' : HF.ink,
      margin: 0,
      ...style,
    }}>{children}</h2>
  );
}
function HfH3({ children, style = {}, light }) {
  return (
    <h3 style={{
      fontFamily: hfDisplay, fontWeight: 500,
      fontSize: 30, lineHeight: 1.12,
      color: light ? '#fff' : HF.ink,
      margin: 0,
      ...style,
    }}>{children}</h3>
  );
}
function HfLede({ children, style = {}, light }) {
  return (
    <p style={{
      fontFamily: hfBody, fontWeight: 400,
      fontSize: 19, lineHeight: 1.55,
      color: light ? 'rgba(255,255,255,0.78)' : HF.ink2,
      margin: 0,
      ...style,
    }}>{children}</p>
  );
}
function HfText({ children, style = {}, dim, sm, light }) {
  const color = light
    ? (dim ? 'rgba(255,255,255,0.55)' : 'rgba(255,255,255,0.90)')
    : (dim ? HF.ink2 : HF.ink);
  return (
    <p style={{
      fontFamily: hfBody, fontWeight: 400,
      fontSize: sm ? 14 : 16, lineHeight: 1.55,
      color, margin: 0,
      ...style,
    }}>{children}</p>
  );
}

// ── HfBtn — primary / accent / outline / ghost. Imperative neutral copy.
// Set `href` to render as an <a> link (used for real navigation in /site/).
function HfBtn({ children, variant = 'outline', size = 'md', arrow, style = {}, dark, href, target, onClick }) {
  const sizes = {
    sm: { padding: '7px 14px', fontSize: 13, height: 34 },
    md: { padding: '11px 22px', fontSize: 14, height: 44 },
    lg: { padding: '15px 30px', fontSize: 15, height: 54 },
  };
  const variants = {
    solid:   { background: HF.ink, color: '#fff', border: `1px solid ${HF.ink}` },
    accent:  { background: 'var(--accent)', color: HF.ink, border: '1px solid transparent' },
    outline: dark
      ? { background: 'transparent', color: '#fff', border: `1px solid rgba(255,255,255,0.30)` }
      : { background: 'transparent', color: HF.ink, border: `1px solid ${HF.ink}` },
    ghost: dark
      ? { background: 'transparent', color: 'rgba(255,255,255,0.85)', border: '1px solid transparent' }
      : { background: 'transparent', color: HF.ink, border: '1px solid transparent' },
  };
  const Tag = href ? 'a' : 'span';
  // NOTE: HfBtn deliberately does NOT set data-hf-link — that attribute drives
  // the "underline turns mustard on hover" rule, which would make accent
  // buttons (yellow bg + black text) become yellow-on-yellow → unreadable.
  // Buttons get their own hover state from the variant styles below.
  const linkProps = href ? { href, target } : {};
  return (
    <Tag
      {...linkProps}
      onClick={onClick}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        fontFamily: hfBody, fontWeight: 600, letterSpacing: '0.02em',
        whiteSpace: 'nowrap', cursor: 'pointer',
        textDecoration: 'none',
        transition: 'background 160ms, color 160ms, transform 120ms',
        ...sizes[size], ...variants[variant], ...style,
      }}
    >
      <span>{children}</span>
      {arrow && <span aria-hidden style={{ fontSize: '1.15em', lineHeight: 1, transform: 'translateY(-1px)' }}>→</span>}
    </Tag>
  );
}

// ── HfField — labeled input (visual only)
function HfField({ label, value, required, hint, style = {}, dark }) {
  const labelColor = dark ? 'rgba(255,255,255,0.55)' : HF.ink2;
  const valueColor = dark ? '#fff' : HF.ink;
  const placeholderColor = dark ? 'rgba(255,255,255,0.55)' : HF.ink3;
  const borderColor = dark ? 'rgba(255,255,255,0.20)' : HF.line2;
  return (
    <label style={{ display: 'block', ...style }}>
      <div style={{
        fontFamily: hfBody, fontSize: 11, fontWeight: 600,
        letterSpacing: '0.16em', textTransform: 'uppercase',
        color: labelColor, marginBottom: 8,
      }}>
        {label}{required && <span style={{ color: 'var(--accent)', marginLeft: 4 }}>*</span>}
      </div>
      <div style={{
        borderBottom: `1px solid ${borderColor}`,
        padding: '10px 0', minHeight: 40,
        fontFamily: hfBody, fontSize: 16,
        color: value ? valueColor : placeholderColor,
      }}>
        {value || hint || '—'}
      </div>
    </label>
  );
}

// ── HfTextarea — visual placeholder by default; pass `value` to render a REAL
// editable <textarea> pre-seeded with that text (used by the RFQ pre-fill).
function HfTextarea({ label, hint, dark, h = 110, value }) {
  const labelColor = dark ? 'rgba(255,255,255,0.55)' : HF.ink2;
  const placeholderColor = dark ? 'rgba(255,255,255,0.55)' : HF.ink3;
  const borderColor = dark ? 'rgba(255,255,255,0.20)' : HF.line2;
  return (
    <div>
      <div style={{
        fontFamily: hfBody, fontSize: 11, fontWeight: 600,
        letterSpacing: '0.16em', textTransform: 'uppercase',
        color: labelColor, marginBottom: 8,
      }}>{label}</div>
      {value != null ? (
        <textarea key={value} defaultValue={value} aria-label={label} style={{
          display: 'block', width: '100%', resize: 'vertical',
          border: 'none', borderBottom: `1px solid ${borderColor}`,
          background: 'transparent', outline: 'none',
          padding: '0 0 12px', minHeight: h,
          fontFamily: hfBody, fontSize: 16, lineHeight: 1.5,
          color: dark ? '#fff' : HF.ink,
        }} />
      ) : (
        <div style={{
          borderBottom: `1px solid ${borderColor}`, paddingBottom: 12,
          minHeight: h, fontFamily: hfBody, fontSize: 16,
          color: placeholderColor, lineHeight: 1.5,
        }}>{hint || '—'}</div>
      )}
    </div>
  );
}

// ── HfImg — photo with subtle dark-overlay option for hero text. JIT-loaded background-image.
function HfImg({ src, alt, h = 420, w = '100%', overlay, style = {}, position = 'center', size = 'cover', ratio, fill }) {
  const overlayEl = overlay ? (
    <div style={{
      position: 'absolute', inset: 0,
      background: typeof overlay === 'string' ? overlay : 'linear-gradient(180deg, rgba(13,13,13,0.05) 0%, rgba(13,13,13,0.55) 100%)',
    }}></div>
  ) : null;
  // `ratio` (e.g. "3 / 2") → a REAL <img> with width:100% / height:auto. It has
  // intrinsic dimensions, so it shows the FULL photo at its native aspect ratio
  // and never collapses inside flex/grid/overflow contexts (the robust, native
  // way — immune to the mobile aspect-ratio/padding-box quirks).
  if (ratio) {
    return (
      <img data-hf-img="" data-hf-ratio="" src={src} alt={alt || ''} loading="lazy"
        style={{ display: 'block', width: w, height: 'auto', aspectRatio: ratio, objectFit: 'cover', background: HF.paper2, ...style }} />
    );
  }
  return (
    <div data-hf-img="" data-hf-fill={fill ? '' : undefined} style={{
      width: w, height: h, position: 'relative',
      background: `${HF.paper2} url("${src}") ${position}/${size} no-repeat`,
      ...style,
    }} role="img" aria-label={alt}>
      {overlayEl}
    </div>
  );
}

// ── HfGallery — image gallery. Desktop: large lead image + thumbnail row.
// Mobile: native swipeable snap carousel (one photo at a time) with dot
// indicators centred at the photo's bottom — so the title stays visible.
// Click on any photo opens a fullscreen lightbox (dark backdrop, close on
// click / ESC, ←→ navigation).
function HfGallery({ images = [] }) {
  const imgs = images.filter(Boolean).filter((v, i, a) => a.indexOf(v) === i);
  const [active, setActive] = React.useState(0);
  const [lb, setLb] = React.useState(-1); // lightbox index, -1 = closed
  const ref = React.useRef(null);
  const onScroll = () => {
    const el = ref.current; if (!el) return;
    const i = Math.round(el.scrollLeft / el.clientWidth);
    setActive((prev) => (prev !== i ? i : prev));
  };
  const goTo = (i) => { const el = ref.current; if (el) el.scrollTo({ left: i * el.clientWidth, behavior: 'smooth' }); };
  React.useEffect(() => {
    if (lb < 0) return undefined;
    const onKey = (e) => {
      if (e.key === 'Escape') setLb(-1);
      else if (e.key === 'ArrowRight') setLb((i) => (i + 1) % imgs.length);
      else if (e.key === 'ArrowLeft') setLb((i) => (i - 1 + imgs.length) % imgs.length);
    };
    window.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [lb < 0, imgs.length]);
  if (!imgs.length) return null;
  const lbBtn = {
    position: 'absolute', zIndex: 2, cursor: 'pointer',
    background: 'rgba(255,255,255,0.10)', color: '#fff',
    border: '1px solid rgba(255,255,255,0.25)',
    width: 44, height: 44, borderRadius: '50%',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    fontFamily: hfBody, fontSize: 22, lineHeight: 1, padding: 0,
  };
  return (
    <div>
      {/* DESKTOP — lead image + thumbnails */}
      <div data-hf-gallery-desktop="">
        <div onClick={() => setLb(0)} role="button" aria-label="Mărește imaginea" style={{ cursor: 'zoom-in' }}>
          <HfImg src={imgs[0]} alt="" ratio="3 / 2" />
        </div>
        {imgs.length > 1 && (
          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${Math.min(4, imgs.length)}, 1fr)`, gap: 12, marginTop: 14 }}>
            {imgs.slice(0, 4).map((src, i) => (
              <div key={i} onClick={() => setLb(i)} role="button" aria-label={`Mărește imaginea ${i + 1}`} style={{ cursor: 'zoom-in' }}>
                <HfImg src={src} alt="" ratio="3 / 2" style={{ border: i === 0 ? '2px solid var(--accent)' : `1px solid ${HF.line}` }} />
              </div>
            ))}
          </div>
        )}
      </div>
      {/* MOBILE — swipe carousel + dots */}
      <div data-hf-gallery-mobile="" style={{ position: 'relative' }}>
        <div ref={ref} onScroll={onScroll} data-hf-carousel="" style={{ display: 'flex', overflowX: 'auto', scrollSnapType: 'x mandatory', WebkitOverflowScrolling: 'touch' }}>
          {imgs.map((src, i) => (
            <div key={i} style={{ flex: '0 0 100%', scrollSnapAlign: 'center' }} onClick={() => setLb(i)}>
              <HfImg src={src} alt="" ratio="3 / 2" />
            </div>
          ))}
        </div>
        {imgs.length > 1 && (
          <div style={{ position: 'absolute', left: 0, right: 0, bottom: 12, display: 'flex', justifyContent: 'center', gap: 7 }}>
            {imgs.map((_, i) => (
              <button key={i} aria-label={`Imaginea ${i + 1}`} onClick={() => goTo(i)} style={{
                width: i === active ? 9 : 7, height: i === active ? 9 : 7, borderRadius: '50%', padding: 0, cursor: 'pointer',
                background: i === active ? '#fff' : 'rgba(255,255,255,0.55)', border: 'none',
                boxShadow: '0 0 0 1px rgba(0,0,0,0.25)', transition: 'all 160ms',
              }} />
            ))}
          </div>
        )}
      </div>
      {/* LIGHTBOX — fullscreen view, dark backdrop. Any click closes; the
          arrow buttons stop propagation to navigate instead. */}
      {lb >= 0 && (
        <div onClick={() => setLb(-1)} role="dialog" aria-modal="true" aria-label="Imagine pe tot ecranul" style={{
          position: 'fixed', inset: 0, zIndex: 1000,
          background: 'rgba(8,8,8,0.93)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: '4vh 4vw', cursor: 'zoom-out',
        }}>
          <img src={imgs[lb]} alt="" style={{
            maxWidth: '100%', maxHeight: '100%', width: 'auto', height: 'auto',
            objectFit: 'contain', boxShadow: '0 40px 120px rgba(0,0,0,0.55)',
          }} />
          <button aria-label="Închide" onClick={() => setLb(-1)} style={{ ...lbBtn, top: 18, right: 18 }}>×</button>
          {imgs.length > 1 && (
            <button aria-label="Imaginea anterioară" onClick={(e) => { e.stopPropagation(); setLb((lb - 1 + imgs.length) % imgs.length); }}
              style={{ ...lbBtn, left: 16, top: '50%', transform: 'translateY(-50%)' }}>‹</button>
          )}
          {imgs.length > 1 && (
            <button aria-label="Imaginea următoare" onClick={(e) => { e.stopPropagation(); setLb((lb + 1) % imgs.length); }}
              style={{ ...lbBtn, right: 16, top: '50%', transform: 'translateY(-50%)' }}>›</button>
          )}
          {imgs.length > 1 && (
            <div style={{
              position: 'absolute', bottom: 18, left: 0, right: 0, textAlign: 'center',
              fontFamily: hfBody, fontSize: 13, color: 'rgba(255,255,255,0.7)', letterSpacing: '0.08em',
            }}>{lb + 1} / {imgs.length}</div>
          )}
        </div>
      )}
    </div>
  );
}

// ── HfSwatch — small color chip
function HfSwatch({ color, label, large }) {
  const sz = large ? 22 : 14;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
      <span style={{
        width: sz, height: sz, borderRadius: '50%',
        background: color, border: `1px solid ${HF.line2}`,
        display: 'inline-block', flex: '0 0 auto',
      }}></span>
      {label && <span style={{ fontFamily: hfBody, fontSize: 13, color: HF.ink, letterSpacing: '0.01em' }}>{label}</span>}
    </span>
  );
}

// ── HfSpec — checkmark line for compatibility
function HfSpec({ children }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontFamily: hfBody, fontSize: 14, color: HF.ink }}>
      <svg width="14" height="14" viewBox="0 0 14 14" aria-hidden>
        <path d="M2.5 7.5 L5.5 10.5 L11.5 3.5" stroke="var(--accent)" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
      <span>{children}</span>
    </div>
  );
}

// ── HfHeader — top nav. FIXED + semi-transparent (frosted paper) on every
// page; a spacer div (height: var(--hf-header-h)) keeps content below it.
// No 'Acasă' link — the logo is the only link to the homepage. Right side:
// Sună / WhatsApp / wishlist heart (live localStorage badge) / Cere ofertă.
// On mobile the links collapse into a working hamburger menu
// (data-hf-mobile-menu) toggled by the [data-hf-nav-menu] button.
function HfHeader({ active = 'home' }) {
  const links = [
    { id: 'rest', label: 'Restaurante & evenimente' },
    { id: 'cafe', label: 'Cafenele & bar' },
    { id: 'hot',  label: 'Hoteluri & pensiuni' },
    { id: 'col',  label: 'Colecții' },
    // 'Despre' eliminat — conținutul e integrat în homepage (#despre).
  ];
  // ?hfmenu=1 — testing affordance: opens the mobile overlay on load (used by
  // headless screenshot validation; harmless in production).
  const [open, setOpen] = React.useState(() => {
    try { return new URLSearchParams(window.location.search).get('hfmenu') === '1'; }
    catch (e) { return false; }
  });
  const [closing, setClosing] = React.useState(false);
  const closeMenu = () => {
    const reduced = typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) { setOpen(false); return; }
    setClosing(true);
    setTimeout(() => { setOpen(false); setClosing(false); }, 300);
  };
  React.useEffect(() => {
    if (!open) return undefined;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') closeMenu(); };
    window.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener('keydown', onKey); };
  }, [open]);
  const [wishCount, setWishCount] = React.useState(() => (typeof localStorage !== 'undefined' ? hfWishlistCount() : 0));
  React.useEffect(() => {
    const upd = () => setWishCount(hfWishlistCount());
    window.addEventListener('hf-wishlist', upd);
    window.addEventListener('storage', upd);
    return () => { window.removeEventListener('hf-wishlist', upd); window.removeEventListener('storage', upd); };
  }, []);
  // Icon-pill style shared by Sună / WhatsApp — bordered, themed, not just text.
  const pill = {
    display: 'inline-flex', alignItems: 'center', gap: 7,
    height: 34, padding: '0 13px',
    border: `1px solid ${HF.line2}`, background: 'rgba(255,255,255,0.55)',
    fontFamily: hfBody, fontSize: 13, fontWeight: 600, letterSpacing: '0.02em',
    color: HF.ink, textDecoration: 'none', whiteSpace: 'nowrap',
  };
  return (
    <React.Fragment>
      <div style={{ position: 'fixed', top: 0, left: 0, right: 0, zIndex: 50 }}>
        <header style={{
          padding: '22px 56px',
          background: 'rgba(250,250,247,0.82)',
          backdropFilter: 'blur(14px) saturate(1.4)',
          WebkitBackdropFilter: 'blur(14px) saturate(1.4)',
          borderBottom: `1px solid ${HF.line}`,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          gap: 24,
        }}>
          <a href={HFRoutes.home} data-hf-link="" aria-label="OwithU HoReCa · pagina principală" style={{
            display: 'inline-flex', alignItems: 'center', gap: 10,
            textDecoration: 'none',
          }}>
            <span style={{
              width: 28, height: 28, position: 'relative', flex: '0 0 auto',
            }}>
              <svg viewBox="0 0 28 28" width="28" height="28">
                <circle cx="14" cy="14" r="13" fill={HF.ink} />
                <circle cx="14" cy="14" r="5" fill="var(--accent)" />
              </svg>
            </span>
            <span style={{
              fontFamily: hfDisplay, fontSize: 22, fontWeight: 500,
              letterSpacing: '0.005em', color: HF.ink,
            }}>OwithU<span data-hf-logo-suffix="" style={{ fontFamily: hfBody, fontSize: 13, fontWeight: 600, letterSpacing: '0.18em', marginLeft: 8, color: HF.ink2, textTransform: 'uppercase' }}>HoReCa</span></span>
          </a>
          <nav data-hf-nav-links="" style={{ display: 'flex', gap: 28, fontFamily: hfBody, fontSize: 14, fontWeight: 500 }}>
            {links.map(l => (
              <a key={l.id} href={HFRoutes[l.id]} data-hf-link="" style={{
                color: active === l.id ? HF.ink : HF.ink2,
                textDecoration: 'none',
                paddingBottom: 2,
                borderBottom: active === l.id ? `1.5px solid var(--accent)` : '1.5px solid transparent',
                transition: 'color 160ms, border-color 160ms',
              }}>{l.label}</a>
            ))}
          </nav>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
            <div data-hf-header-cta="" style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
              <a href="tel:+40746970194" title="Sună-ne · +40 746 970 194" style={pill}>
                <span style={{ color: 'var(--accent)', display: 'inline-flex' }}><HfIcon name="phone" /></span>
                <span>Sună</span>
              </a>
              <a href="https://wa.me/40746970194" target="_blank" rel="noopener" title="Scrie-ne pe WhatsApp" style={pill}>
                <span style={{ color: '#1fa855', display: 'inline-flex' }}><HfIcon name="chat" /></span>
                <span>WhatsApp</span>
              </a>
              <HfBtn variant="accent" size="sm" href={HFRoutes.rfq} style={{ gap: 7 }}>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}><HfIcon name="doc" size={14} /> Cere ofertă</span>
              </HfBtn>
            </div>
            {/* Mobile-only quick contact icons — fill the empty header zone */}
            <div data-hf-mobile-quick="" style={{ gap: 8, alignItems: 'center' }}>
              <a href="tel:+40746970194" aria-label="Sună-ne · +40 746 970 194" style={{
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                width: 34, height: 34, border: `1px solid ${HF.line2}`,
                background: 'rgba(255,255,255,0.55)', color: 'var(--accent)', textDecoration: 'none',
              }}><HfIcon name="phone" size={15} /></a>
              <a href="https://wa.me/40746970194" target="_blank" rel="noopener" aria-label="Scrie-ne pe WhatsApp" style={{
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                width: 34, height: 34, border: `1px solid ${HF.line2}`,
                background: 'rgba(255,255,255,0.55)', color: '#1fa855', textDecoration: 'none',
              }}><HfIcon name="chat" size={15} /></a>
            </div>
            <a href={HFRoutes.col} title="Produse salvate" aria-label={`Produse salvate (${wishCount})`} style={{
              position: 'relative', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              width: 34, height: 34, border: `1px solid ${HF.line2}`,
              background: 'rgba(255,255,255,0.55)', color: HF.ink, textDecoration: 'none',
            }}>
              <HfIcon name="heart" size={16} style={wishCount > 0 ? { fill: 'var(--accent)', color: 'var(--accent)' } : {}} />
              {wishCount > 0 && (
                <span style={{
                  position: 'absolute', top: -7, right: -7,
                  minWidth: 17, height: 17, padding: '0 4px', borderRadius: 9,
                  background: 'var(--accent)', color: HF.ink,
                  fontFamily: hfBody, fontSize: 10.5, fontWeight: 700,
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  boxShadow: `0 0 0 2px ${HF.paper}`,
                }}>{wishCount}</span>
              )}
            </a>
            <button data-hf-nav-menu="" onClick={() => (open ? closeMenu() : setOpen(true))} aria-expanded={open} aria-label="Meniu" style={{
              fontFamily: hfBody, fontSize: 13, fontWeight: 600,
              letterSpacing: '0.18em', textTransform: 'uppercase', color: HF.ink,
              alignItems: 'center', gap: 8, cursor: 'pointer',
              background: 'transparent', border: 'none', padding: 0,
            }}>
              <svg width="18" height="18" viewBox="0 0 18 18" aria-hidden><path d="M2 5h14M2 9h14M2 13h14" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" /></svg>
              <span data-hf-menu-label="">Meniu</span>
            </button>
          </div>
        </header>
        {/* FULL-SCREEN MOBILE MENU OVERLAY — smooth in/out (reduced-motion safe),
            big airy serif links + contact actions. Replaces the old dropdown. */}
        {open && (
          <div data-hf-menu-overlay="" className={closing ? 'hf-menu-closing' : ''} role="dialog" aria-modal="true" aria-label="Meniu navigare" style={{
            position: 'fixed', inset: 0, zIndex: 70,
            background: HF.paper, color: HF.ink,
            display: 'flex', flexDirection: 'column', overflowY: 'auto',
          }}>
            {/* top bar — mirrors the header, with close button */}
            <div style={{
              padding: '22px 20px', borderBottom: `1px solid ${HF.line}`,
              display: 'flex', alignItems: 'center', justifyContent: 'space-between', flex: '0 0 auto',
            }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
                <svg viewBox="0 0 28 28" width="28" height="28" aria-hidden>
                  <circle cx="14" cy="14" r="13" fill={HF.ink} />
                  <circle cx="14" cy="14" r="5" fill="var(--accent)" />
                </svg>
                <span style={{ fontFamily: hfDisplay, fontSize: 22, fontWeight: 500, color: HF.ink }}>OwithU</span>
              </span>
              <button onClick={closeMenu} aria-label="Închide meniul" style={{
                display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer',
                background: 'transparent', border: `1px solid ${HF.line2}`,
                width: 40, height: 40, justifyContent: 'center', color: HF.ink, padding: 0,
              }}>
                <svg width="16" height="16" viewBox="0 0 18 18" aria-hidden><path d="M3 3l12 12M15 3L3 15" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" /></svg>
              </button>
            </div>
            {/* links — large, airy, numbered */}
            <nav style={{ padding: '28px 20px 8px', flex: '1 0 auto' }}>
              {[{ id: 'home', label: 'Acasă' }].concat(links).map((l, i) => (
                <a key={l.id} data-hf-menu-item="" href={HFRoutes[l.id]} onClick={closeMenu} style={{
                  display: 'flex', alignItems: 'baseline', gap: 16,
                  fontFamily: hfDisplay, fontSize: 34, fontWeight: 500, lineHeight: 1.1,
                  color: active === l.id ? 'var(--accent)' : HF.ink,
                  textDecoration: 'none', padding: '16px 0',
                  borderBottom: `1px solid ${HF.line}`,
                  animationDelay: (60 + i * 60) + 'ms',
                }}>
                  <span style={{ fontFamily: hfBody, fontSize: 11, fontWeight: 700, letterSpacing: '0.18em', color: active === l.id ? 'var(--accent)' : HF.ink3, minWidth: 24 }}>0{i + 1}</span>
                  <span>{l.label}</span>
                </a>
              ))}
            </nav>
            {/* contact actions */}
            <div data-hf-menu-item="" style={{ padding: '20px 20px 28px', display: 'grid', gap: 10, flex: '0 0 auto', animationDelay: '420ms' }}>
              <HfBtn variant="accent" size="lg" arrow href={HFRoutes.rfq} style={{ justifyContent: 'center' }}>Cere ofertă</HfBtn>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
                <HfBtn variant="outline" size="md" href="tel:+40746970194" style={{ justifyContent: 'center' }}>
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}><HfIcon name="phone" size={14} /> Sună</span>
                </HfBtn>
                <HfBtn variant="outline" size="md" href="https://wa.me/40746970194" target="_blank" style={{ justifyContent: 'center' }}>
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}><HfIcon name="chat" size={14} /> WhatsApp</span>
                </HfBtn>
              </div>
              <div style={{
                marginTop: 8, display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8,
                fontFamily: hfBody, fontSize: 12, color: HF.ink2, letterSpacing: '0.04em',
              }}>
                <span>+40 746 970 194 · L-V 9:00-18:00</span>
                <span>contact@owithu.ro</span>
              </div>
            </div>
          </div>
        )}
      </div>
      <div data-hf-header-spacer="" style={{ height: 'var(--hf-header-h)' }}></div>
    </React.Fragment>
  );
}

// ── HfSaveBtn — wishlist toggle for the collection detail page ("Salvează").
function HfSaveBtn({ id, size = 'lg' }) {
  const [saved, setSaved] = React.useState(() => (typeof localStorage !== 'undefined' ? hfWishlistGet().indexOf(id) >= 0 : false));
  React.useEffect(() => {
    const upd = () => setSaved(hfWishlistGet().indexOf(id) >= 0);
    upd();
    window.addEventListener('hf-wishlist', upd);
    return () => window.removeEventListener('hf-wishlist', upd);
  }, [id]);
  return (
    <HfBtn variant="outline" size={size} onClick={() => hfWishlistToggle(id)}
      style={saved ? { borderColor: 'var(--accent)', color: HF.ink } : {}}>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
        <HfIcon name="heart" size={15} style={saved ? { fill: 'var(--accent)', color: 'var(--accent)' } : {}} />
        {saved ? 'Salvat' : 'Salvează'}
      </span>
    </HfBtn>
  );
}

// ── HfPreFooter — reusable CTA module rendered ABOVE the footer on every
// page. No embedded form: short text + one accent button → the dedicated
// request-offer page. Per-page copy via props.
function HfPreFooter({ eyebrow = 'Următorul pas', title, text, cta = 'Cere ofertă', href }) {
  return (
    <section style={{
      background: HF.ink, color: '#fff', padding: '72px 56px',
      borderBottom: '1px solid rgba(255,255,255,0.12)',
    }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 48, alignItems: 'center' }}>
        <div>
          <HfEyebrow light num="·">{eyebrow}</HfEyebrow>
          <HfH2 light style={{ fontSize: 46, lineHeight: 1.08 }}>
            {title || <>Spune-ne ce locație ai — <em style={{ fontStyle: 'italic', fontWeight: 400, color: 'var(--accent)' }}>revenim cu oferta în 24h</em>.</>}
          </HfH2>
          {text && <HfLede light style={{ marginTop: 16, maxWidth: 560, fontSize: 17 }}>{text}</HfLede>}
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, alignItems: 'flex-end' }}>
          <HfBtn variant="accent" size="lg" arrow href={href || HFRoutes.rfq}>{cta}</HfBtn>
          <HfText light sm style={{ opacity: 0.65, fontSize: 13 }}>formular dedicat · răspuns &lt; 24h</HfText>
        </div>
      </div>
    </section>
  );
}

// ── HfFooter — classic clean footer: logo + short text on the left,
// 3 link columns (Locații, Despre noi, Contact), bottom bar with
// Termeni & condiții / Confidențialitate / GDPR + copyright.
function HfFooter() {
  const cols = [
    { t: 'Locații', items: [
      { l: 'Restaurante & evenimente', h: HFRoutes.rest },
      { l: 'Cafenele & bar',           h: HFRoutes.cafe },
      { l: 'Hoteluri & pensiuni',      h: HFRoutes.hot },
    ] },
    { t: 'Despre noi', items: [
      { l: 'Despre OwithU',    h: HFRoutes.home + '#despre' },
      { l: 'Cum lucrăm',       h: HFRoutes.home + '#proces' },
      { l: 'Toate colecțiile', h: HFRoutes.col },
    ] },
    { t: 'Contact', items: [
      { l: 'Cerere ofertă',     h: HFRoutes.rfq },
      { l: '+40 746 970 194',   h: 'tel:+40746970194' },
      { l: 'WhatsApp Business', h: 'https://wa.me/40746970194' },
      { l: 'contact@owithu.ro', h: 'mailto:contact@owithu.ro' },
    ] },
  ];
  return (
    <footer style={{
      background: HF.ink, color: '#fff',
      padding: '72px 56px 36px',
    }}>
      <div data-hf-footer-cols="" style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr 1.1fr', gap: 36, marginBottom: 56 }}>
        <div>
          <a href={HFRoutes.home} data-hf-link="" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, marginBottom: 18, textDecoration: 'none' }}>
            <svg viewBox="0 0 28 28" width="32" height="32">
              <circle cx="14" cy="14" r="13" fill="#fff" />
              <circle cx="14" cy="14" r="5" fill="var(--accent)" />
            </svg>
            <span style={{ fontFamily: hfDisplay, fontSize: 26, fontWeight: 500, color: '#fff' }}>OwithU<span style={{ fontFamily: hfBody, fontSize: 12, fontWeight: 600, letterSpacing: '0.20em', marginLeft: 10, color: 'rgba(255,255,255,0.55)', textTransform: 'uppercase' }}>HoReCa</span></span>
          </a>
          <HfText light style={{ maxWidth: 320, fontSize: 15 }}>
            Furnizor B2B de veselă profesională pentru restaurante, cafenele și hoteluri. Colecții complete prin cerere de ofertă.
          </HfText>
        </div>
        {cols.map(col => (
          <div key={col.t}>
            <div style={{ fontFamily: hfBody, fontSize: 11, fontWeight: 700, letterSpacing: '0.22em', textTransform: 'uppercase', color: 'var(--accent)', marginBottom: 18 }}>{col.t}</div>
            <div style={{ display: 'grid', gap: 10 }}>
              {col.items.map(i => (
                <a key={i.l} href={i.h} data-hf-link="" style={{ fontFamily: hfBody, fontSize: 14, color: 'rgba(255,255,255,0.78)', textDecoration: 'none' }}>{i.l}</a>
              ))}
            </div>
          </div>
        ))}
      </div>
      <div style={{
        borderTop: '1px solid rgba(255,255,255,0.12)', paddingTop: 22,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        fontFamily: hfBody, fontSize: 13, color: 'rgba(255,255,255,0.55)',
        flexWrap: 'wrap', gap: 12,
      }}>
        <span>© 2026 OwithU · toate drepturile rezervate</span>
        <div style={{ display: 'flex', gap: 24 }}>
          <a href="#" data-hf-link="" style={{ color: 'inherit', textDecoration: 'none' }}>Termeni & condiții</a>
          <a href="#" data-hf-link="" style={{ color: 'inherit', textDecoration: 'none' }}>Confidențialitate</a>
          <a href="#" data-hf-link="" style={{ color: 'inherit', textDecoration: 'none' }}>GDPR</a>
        </div>
      </div>
    </footer>
  );
}

// ── HfWhatsAppFab — floating WhatsApp bubble, MOBILE + standalone only
// (CSS gates visibility). Recognizable green badge, bottom-right, modest size
// so it never covers the pre-footer CTA. Entry animation respects
// prefers-reduced-motion; the menu overlay (z 70) covers it when open.
function HfWhatsAppFab() {
  return (
    <a data-hf-wa-fab="" href="https://wa.me/40746970194" target="_blank" rel="noopener"
      aria-label="Scrie-ne pe WhatsApp" title="Scrie-ne pe WhatsApp" style={{
        position: 'fixed', right: 16, bottom: 16, zIndex: 45,
        width: 54, height: 54, borderRadius: '50%',
        background: '#25D366', color: '#fff',
        alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 10px 28px rgba(0,0,0,0.22)',
        textDecoration: 'none',
      }}>
      <svg width="28" height="28" viewBox="0 0 24 24" aria-hidden focusable="false">
        <path fill="currentColor" d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" />
      </svg>
    </a>
  );
}

// ── HfPage — paper-backgrounded artboard container
function HfPage({ children, style = {} }) {
  return (
    <div style={{
      background: HF.paper, color: HF.ink, fontFamily: hfBody,
      width: '100%', height: '100%',
      ...style,
    }}>
      {children}
      <HfWhatsAppFab />
    </div>
  );
}

// ── HfDivider — section dividing strip with eyebrow label
function HfDivider({ label, sub }) {
  return (
    <div style={{
      borderTop: `1px solid ${HF.line}`, borderBottom: `1px solid ${HF.line}`,
      padding: '20px 56px', background: HF.paper,
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      fontFamily: hfBody, fontSize: 12, fontWeight: 600,
      letterSpacing: '0.22em', textTransform: 'uppercase', color: HF.ink2,
    }}>
      <span>{label}</span>
      {sub && <span style={{ letterSpacing: '0.04em', textTransform: 'none', fontWeight: 400 }}>{sub}</span>}
    </div>
  );
}

// ── HfCollectionCard — image card with overlay info; canonical product card
// for the catalog grid. Compact variant for sidebars.
function HfCollectionCard({ img, imgHover, name, finish, pieces, persons, swatch, material, compat, accent, compact, badge }) {
  // Fall back to the central HF_HOVER lookup so cards rendered from inline
  // arrays (without an explicit imgHover) still get a hover swap.
  const hoverSrc = imgHover || HF_HOVER[img];
  return (
    <article style={{
      background: HF.paper, border: `1px solid ${HF.line}`,
      display: 'flex', flexDirection: 'column',
      transition: 'transform 240ms, box-shadow 240ms',
    }}>
      <div style={{ position: 'relative', overflow: 'hidden' }}>
        <HfHoverImg src={img} hoverSrc={hoverSrc} alt={`${name} · ${finish}`} />
        {badge && (
          <div style={{
            position: 'absolute', top: 14, left: 14,
            background: 'var(--accent)', color: HF.ink,
            fontFamily: hfBody, fontSize: 11, fontWeight: 700,
            letterSpacing: '0.16em', textTransform: 'uppercase',
            padding: '5px 10px',
          }}>{badge}</div>
        )}
        {swatch && (
          <div style={{
            position: 'absolute', top: 14, right: 14,
            width: 28, height: 28, borderRadius: '50%',
            background: swatch, border: `2px solid ${HF.paper}`,
            boxShadow: '0 0 0 1px rgba(0,0,0,0.12)',
          }}></div>
        )}
      </div>
      <div style={{ padding: compact ? '18px 20px 20px' : '24px 26px 26px', display: 'flex', flexDirection: 'column', flex: 1 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
          <h3 style={{
            fontFamily: hfDisplay, fontWeight: 500,
            fontSize: compact ? 26 : 32, lineHeight: 1, letterSpacing: '0.01em',
            margin: 0, color: HF.ink,
          }}>{name}</h3>
          <span style={{ fontFamily: hfBody, fontSize: 11, fontWeight: 600, letterSpacing: '0.16em', textTransform: 'uppercase', color: HF.ink2 }}>
            Set complet
          </span>
        </div>
        <div style={{ fontFamily: hfBody, fontSize: 13, color: HF.ink2, marginBottom: 14 }}>
          finisaj <span style={{ color: HF.ink, fontWeight: 500 }}>{finish}</span>
        </div>
        {material && (
          <HfText sm dim style={{ marginBottom: 14, fontSize: 13 }}>{material}</HfText>
        )}
        {compat && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginBottom: 18 }}>
            {compat.map(c => (
              <span key={c} style={{
                fontFamily: hfBody, fontSize: 11, fontWeight: 500,
                color: HF.ink2, padding: '3px 8px',
                border: `1px solid ${HF.line2}`,
              }}>{c}</span>
            ))}
          </div>
        )}
        <div style={{ display: 'flex', gap: 10, marginTop: 'auto', alignItems: 'center' }}>
          <HfBtn variant={accent ? 'accent' : 'solid'} size="sm" arrow href={hfRfqHref(`${name} ${finish}`)}>Cere ofertă</HfBtn>
          <HfBtn variant="ghost" size="sm" href={`${HFRoutes.detail}#${hfSlug(name + '-' + finish)}`}>Detalii</HfBtn>
        </div>
      </div>
    </article>
  );
}

// ── HfStatRow — small stat callouts used in landings
function HfStat({ n, t, sub, light }) {
  return (
    <div>
      <div style={{
        fontFamily: hfDisplay, fontWeight: 400,
        fontSize: 64, lineHeight: 1,
        color: light ? '#fff' : HF.ink,
      }}>{n}</div>
      <div style={{
        fontFamily: hfBody, fontSize: 13, fontWeight: 600,
        letterSpacing: '0.16em', textTransform: 'uppercase',
        color: light ? 'rgba(255,255,255,0.78)' : HF.ink, marginTop: 8,
      }}>{t}</div>
      {sub && (
        <HfText sm dim light={light} style={{ marginTop: 6, fontSize: 13 }}>{sub}</HfText>
      )}
    </div>
  );
}

// ── HF_HORECA_STATS — cifrele HoReCa pentru benzile de statistici
// (homepage + paginile de locație). Fără „X persoane" — doar game de
// dimensiuni și cifre de catalog. Unitățile sunt redate la 0.5em ca să
// rămână lizibile la orice talie de font. „500+ produse" e placeholder
// agreat cu clientul — de confirmat cu cifra exactă în faza finală.
const HF_HORECA_STATS = [
  { n: <React.Fragment>16–28 <span style={{ fontSize: '0.5em' }}>cm</span></React.Fragment>, t: 'farfurii', sub: 'de la desert la prezentare' },
  { n: <React.Fragment>50–500 <span style={{ fontSize: '0.5em' }}>ml</span></React.Fragment>, t: 'căni & pahare', sub: 'de la espresso la cana de mic dejun' },
  { n: '26', t: 'colecții complete', sub: 'cu istoric · restock previzibil' },
  { n: '500+', t: 'produse', sub: 'prin cerere de ofertă' },
];

// ── HfClosingVista — modul final reutilizabil pe paginile de locație:
// fotografie largă + text scurt inspirațional/educativ pe segment.
// Are un slot opțional de testimonial (quote + author) — structura e
// pregătită pentru faza în care apar citate de la clienți; deocamdată
// paginile îl folosesc doar cu text.
function HfClosingVista({ img, eyebrow = 'La final', title, text, quote, author }) {
  return (
    <section style={{
      position: 'relative',
      backgroundImage: `linear-gradient(180deg, rgba(13,13,13,0.16) 0%, rgba(13,13,13,0.38) 45%, rgba(13,13,13,0.72) 100%), url("${img}")`,
      backgroundSize: 'cover', backgroundPosition: 'center',
      padding: '200px 56px 76px',
      borderBottom: `1px solid ${HF.line}`,
    }}>
      <div style={{ maxWidth: 780 }}>
        <HfEyebrow light num="·">{eyebrow}</HfEyebrow>
        <HfH2 light style={{ fontSize: 54, maxWidth: 700 }}>{title}</HfH2>
        {text && <HfLede light style={{ marginTop: 20, maxWidth: 640, fontSize: 18 }}>{text}</HfLede>}
        {quote && (
          <figure style={{ margin: '36px 0 0', padding: '4px 0 4px 24px', borderLeft: '3px solid var(--accent)' }}>
            <blockquote style={{
              margin: 0, fontFamily: hfDisplay, fontStyle: 'italic', fontWeight: 400,
              fontSize: 26, lineHeight: 1.3, color: '#fff', maxWidth: 560,
            }}>„{quote}"</blockquote>
            {author && (
              <figcaption style={{
                marginTop: 12, fontFamily: hfBody, fontSize: 12, fontWeight: 600,
                letterSpacing: '0.18em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.72)',
              }}>{author}</figcaption>
            )}
          </figure>
        )}
      </div>
    </section>
  );
}

// ── HfMarquee — generic continuous horizontal scroll strip (reusable).
// Content is rendered twice (second copy aria-hidden) and the track
// translates -50% in a loop, so the band never ends. Pauses on hover;
// static when the user prefers reduced motion (CSS handles both).
function HfMarquee({ children, duration = 42, style = {} }) {
  const copy = { display: 'inline-flex', alignItems: 'center', flex: '0 0 auto' };
  // width:0 + minWidth:100% — banda nu contribuie cu lățimea ei intrinsecă
  // (conținutul dublat = mii de px) la dimensionarea părinților grid/flex;
  // altfel track-ul auto al grid-ului crește la min-content-ul benzii și
  // împinge toată secțiunea în afara ecranului (overflow orizontal).
  return (
    <div data-hf-marquee="" style={{ overflow: 'hidden', width: 0, minWidth: '100%', maxWidth: '100%', ...style }}>
      <div data-hf-marquee-track="" style={{
        display: 'inline-flex', alignItems: 'center', width: 'max-content',
        '--hf-marquee-dur': duration + 's',
      }}>
        <div style={copy}>{children}</div>
        <div style={copy} aria-hidden="true">{children}</div>
      </div>
    </div>
  );
}

// ── HfBenefitBar — reusable animated benefits strip: short snippets
// (max 3-4 cuvinte) separated by accent dots, scrolling continuously.
// Drop <HfBenefitBar /> on any page; override `items` for custom copy.
function HfBenefitBar({ items, duration = 36, style = {} }) {
  const list = items || [
    'Livrare în siguranță', 'Ambalaj sigur', 'Rezistent la mașina de spălat',
    '26 colecții complete', 'Consultanță dedicată', 'Răspuns în 24h',
    'Restock previzibil', 'Producători europeni',
  ];
  return (
    <section style={{ borderBottom: `1px solid ${HF.line}`, background: HF.paper2, padding: '15px 0', ...style }}>
      <HfMarquee duration={duration}>
        {list.map((b, i) => (
          <span key={i} style={{ display: 'inline-flex', alignItems: 'center' }}>
            <span style={{
              fontFamily: hfBody, fontSize: 12, fontWeight: 600,
              letterSpacing: '0.20em', textTransform: 'uppercase',
              color: HF.ink2, whiteSpace: 'nowrap',
            }}>{b}</span>
            <span aria-hidden style={{ color: 'var(--accent)', fontSize: 20, lineHeight: 1, margin: '0 24px', fontWeight: 700 }}>·</span>
          </span>
        ))}
      </HfMarquee>
    </section>
  );
}

// ── HfBannerCarousel — rotating banners: auto-slide + manual swipe/drag
// (pointer events, mouse + touch), NO arrows, subtle "loading dot"
// indicators — the active dot is a pill that fills with accent over the
// slide interval. slides: [{ img, eyebrow, title, text, ctas: [{label, href, variant}] }]
function HfBannerCarousel({ slides = [], interval = 6500 }) {
  const n = slides.length;
  const [idx, setIdx] = React.useState(0);
  const [drag, setDrag] = React.useState(0);
  const dragRef = React.useRef(null);
  const movedRef = React.useRef(false);
  const wrapRef = React.useRef(null);
  const [paused, setPaused] = React.useState(false);
  const reduced = typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches;

  // Autoplay — resets whenever idx changes (manual swipe = full new interval).
  React.useEffect(() => {
    if (n < 2 || paused || reduced) return undefined;
    const t = setInterval(() => setIdx(i => (i + 1) % n), interval);
    return () => clearInterval(t);
  }, [n, paused, interval, idx, reduced]);

  const onDown = (e) => {
    dragRef.current = { x: e.clientX };
    movedRef.current = false;
    setPaused(true);
    try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) {}
  };
  const onMove = (e) => {
    if (!dragRef.current) return;
    const dx = e.clientX - dragRef.current.x;
    if (Math.abs(dx) > 8) movedRef.current = true;
    setDrag(dx);
  };
  const onUp = (e) => {
    if (!dragRef.current) return;
    const dx = e.clientX - dragRef.current.x;
    dragRef.current = null;
    setDrag(0); setPaused(false);
    const w = wrapRef.current ? wrapRef.current.clientWidth : 1200;
    if (dx < -w * 0.10) setIdx(i => (i + 1) % n);
    else if (dx > w * 0.10) setIdx(i => (i - 1 + n) % n);
  };

  if (!n) return null;
  return (
    <div>
      <div ref={wrapRef}
        onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerCancel={onUp}
        onDragStart={(e) => e.preventDefault()}
        onClickCapture={(e) => { if (movedRef.current) { e.preventDefault(); e.stopPropagation(); movedRef.current = false; } }}
        style={{ overflow: 'hidden', touchAction: 'pan-y', cursor: n > 1 ? 'grab' : 'default', border: `1px solid ${HF.line}` }}>
        <div data-hf-banner-track="" style={{
          display: 'flex',
          transform: `translateX(calc(${-idx * 100}% + ${drag}px))`,
          transition: drag !== 0 ? 'none' : 'transform 620ms cubic-bezier(0.2,0.6,0.2,1)',
        }}>
          {slides.map((s, i) => (
            <div key={i} style={{ flex: '0 0 100%', minWidth: 0 }} aria-hidden={i !== idx}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.15fr', alignItems: 'stretch' }}>
                <div style={{
                  padding: '52px 56px', background: HF.paper,
                  display: 'flex', flexDirection: 'column', justifyContent: 'center',
                  borderRight: `1px solid ${HF.line}`,
                }}>
                  {s.eyebrow && <HfEyebrow num={'0' + (i + 1)}>{s.eyebrow}</HfEyebrow>}
                  <HfH2 style={{ fontSize: 52, marginBottom: 18 }}>{s.title}</HfH2>
                  <HfText dim style={{ maxWidth: 480, fontSize: 16, marginBottom: 30 }}>{s.text}</HfText>
                  <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
                    {(s.ctas || []).map((c, j) => (
                      <HfBtn key={j} variant={c.variant || 'outline'} size="md" arrow href={c.href}>{c.label}</HfBtn>
                    ))}
                  </div>
                </div>
                <HfImg src={s.img} alt={s.alt || ''} h="100%" fill style={{ minHeight: 440 }} />
              </div>
            </div>
          ))}
        </div>
      </div>
      {n > 1 && (
        <div style={{ display: 'flex', gap: 9, justifyContent: 'center', marginTop: 22 }}>
          {slides.map((_, i) => (
            <button key={i} onClick={() => setIdx(i)} aria-label={`Banner ${i + 1} din ${n}`} style={{
              width: i === idx ? 38 : 8, height: 8, borderRadius: 99, padding: 0,
              border: 'none', cursor: 'pointer', overflow: 'hidden',
              background: i === idx ? HF.paper3 : HF.line2,
              transition: 'width 260ms ease',
            }}>
              {i === idx && (
                <span key={'fill-' + idx} style={{
                  display: 'block', width: '100%', height: '100%',
                  background: 'var(--accent)', transformOrigin: 'left center',
                  animation: reduced ? 'none' : `hf-dotfill ${interval}ms linear forwards`,
                  animationPlayState: paused ? 'paused' : 'running',
                }}></span>
              )}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ── HfChoiceGroup — single-choice "check buttons" (înlocuiește dropdown-ul
// de Tip locație pe formularul de cerere ofertă): butoane toggle cu bifă.
function HfChoiceGroup({ label, options = [], value, required, style = {} }) {
  const [val, setVal] = React.useState(value || options[0]);
  return (
    <div style={style}>
      <div style={{
        fontFamily: hfBody, fontSize: 11, fontWeight: 600,
        letterSpacing: '0.16em', textTransform: 'uppercase',
        color: HF.ink2, marginBottom: 10,
      }}>
        {label}{required && <span style={{ color: 'var(--accent)', marginLeft: 4 }}>*</span>}
      </div>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
        {options.map(o => {
          const on = o === val;
          return (
            <button key={o} type="button" onClick={() => setVal(o)} aria-pressed={on} style={{
              display: 'inline-flex', alignItems: 'center', gap: 10,
              padding: '11px 16px', cursor: 'pointer',
              fontFamily: hfBody, fontSize: 14, fontWeight: on ? 600 : 500,
              color: HF.ink, background: HF.paper,
              border: on ? `1.5px solid ${HF.ink}` : `1px solid ${HF.line2}`,
              transition: 'border-color 160ms, background 160ms',
            }}>
              <span aria-hidden style={{
                width: 16, height: 16, flex: '0 0 auto',
                border: on ? `1.5px solid ${HF.ink}` : `1.5px solid ${HF.line2}`,
                background: on ? 'var(--accent)' : 'transparent',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {on && (
                  <svg width="10" height="10" viewBox="0 0 10 10">
                    <path d="M1.8 5.2 L4.2 7.6 L8.4 2.6" stroke={HF.ink} strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                )}
              </span>
              <span>{o}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ── HfRfqForm — reusable form module (light or dark version)
function HfRfqForm({ segment, segmentValue, extraField, suggestions, dark, compact }) {
  const bg = dark ? 'transparent' : HF.paper;
  const fg = dark ? '#fff' : HF.ink;
  return (
    <div style={{
      background: bg, padding: compact ? 28 : 40,
      border: dark ? '1px solid rgba(255,255,255,0.18)' : `1px solid ${HF.ink}`,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
        <h3 style={{
          fontFamily: hfDisplay, fontSize: 32, fontWeight: 500,
          margin: 0, color: fg, letterSpacing: '-0.005em',
        }}>Cerere ofertă</h3>
        <span style={{ fontFamily: hfBody, fontSize: 12, fontWeight: 600, letterSpacing: '0.16em', textTransform: 'uppercase', color: dark ? 'rgba(255,255,255,0.55)' : HF.ink2 }}>răspuns &lt; 24h</span>
      </div>
      <p style={{
        fontFamily: hfBody, fontSize: 14,
        color: dark ? 'rgba(255,255,255,0.55)' : HF.ink2,
        margin: '0 0 26px', lineHeight: 1.55,
      }}>
        Tip locație pre-selectat: <strong style={{ color: 'var(--accent)' }}>{segment}</strong>. Câteva detalii și revenim cu 2-3 colecții potrivite.
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 22, columnGap: 28 }}>
        <HfField dark={dark} label="Nume firmă / locație" required hint="ex: Restaurant Doi Cocoși" />
        <HfField dark={dark} label="Tip locație" required value={segment} />
        <HfField dark={dark} label="Oraș" required hint="București" />
        <HfField dark={dark} label="Persoană contact" required hint="Maria Popescu" />
        <HfField dark={dark} label="Telefon" required hint="07XX XXX XXX" />
        <HfField dark={dark} label="Email" hint="opțional" />
        <HfField dark={dark} label="Colecții de interes" hint="GENESIS Terre · IRIS Bleu nuit" style={{ gridColumn: '1 / -1' }} />
        <HfField dark={dark} label={segmentValue.label} hint={segmentValue.hint} style={{ gridColumn: '1 / -1' }} />
        {extraField && <HfField dark={dark} label={extraField.label} hint={extraField.hint} style={{ gridColumn: '1 / -1' }} />}
      </div>
      <div style={{ marginTop: 22 }}>
        <HfTextarea dark={dark} label="Mesaj · detalii cerere" hint="ex: căutăm o colecție pentru deschiderea unui bistro în zona Floreasca, 38 locuri…" />
      </div>
      <div style={{ marginTop: 28, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 20, flexWrap: 'wrap' }}>
        <div style={{ fontFamily: hfBody, fontSize: 12, color: dark ? 'rgba(255,255,255,0.55)' : HF.ink2, maxWidth: 340, lineHeight: 1.5 }}>
          Trimițând cererea, sunteți de acord cu prelucrarea datelor în scopul ofertării.
        </div>
        <HfBtn variant="accent" size="lg" arrow>Trimite cererea</HfBtn>
      </div>
      {suggestions && (
        <div style={{
          marginTop: 28, padding: '14px 18px',
          background: dark ? 'rgba(255,255,255,0.05)' : HF.paper2,
          fontFamily: hfBody, fontSize: 13,
          color: dark ? 'rgba(255,255,255,0.78)' : HF.ink,
        }}>
          <strong style={{ color: 'var(--accent)' }}>Sugestii pentru tine:</strong> {suggestions}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  HF, hfDisplay, hfBody, HFRoutes, HF_HOVER,
  HfEyebrow, HfH1, HfH2, HfH3, HfLede, HfText,
  HfBtn, HfField, HfTextarea, HfImg, HfSwatch, HfSpec,
  HfHeader, HfFooter, HfPreFooter, HfPage, HfDivider,
  HfCollectionCard, HfStat, HfRfqForm, HfGallery,
  HfIcon, HfHoverImg, HfSaveBtn,
  HF_HORECA_STATS, HfClosingVista,
  HfMarquee, HfBenefitBar, HfBannerCarousel, HfChoiceGroup,
  hfWishlistGet, hfWishlistToggle, hfWishlistCount,
  hfSlug, hfRfqHref, HfWhatsAppFab,
});
