/* global React */
const { useState: useStateSearch, useEffect: useEffectSearch, useRef: useRefSearch } = React;

/* =============================================================
   ASPACE — Immersive Search
   - Cinematic centered reveal (no dropdown, no standard modal)
   - Spring-eased capsule that emerges into focus
   - Editorial result cards with thumbnail + category
   - Ambient: backdrop blur, storyline pulse, particles
   ============================================================= */

const SEARCH_INDEX = [
  // STUDIOS
  { kind: 'Studio',     title: 'North Light Studio',         meta: 'Daylight · 84 m² · Private',     thumb: 'northLight',   tag: 'studios' },
  { kind: 'Studio',     title: 'Black Box',                   meta: 'Cyclorama · 62 m² · Production', thumb: 'blackBox',     tag: 'studios' },
  { kind: 'Studio',     title: 'Atelier 04',                  meta: 'Studio space · 48 m² · Maker',   thumb: 'atelier',      tag: 'studios' },
  { kind: 'Studio',     title: 'The Loft',                    meta: 'Mezzanine · 110 m² · Flex',      thumb: 'loft',         tag: 'studios' },
  { kind: 'Studio',     title: 'Greenroom',                   meta: 'Stage room · 70 m² · Hybrid',    thumb: 'greenroom',    tag: 'studios' },
  { kind: 'Studio',     title: 'Concrete Hall',               meta: 'Industrial · 240 m² · Event',    thumb: 'concrete',     tag: 'studios' },
  // PRODUCTIONS
  { kind: 'Production', title: 'Photography day rate',        meta: 'Half / full day · Crew + lights',thumb: 'photo',        tag: 'productions' },
  { kind: 'Production', title: 'Video shoot package',         meta: 'Up to 6 hr · Cyc + grip',        thumb: 'video',        tag: 'productions' },
  { kind: 'Production', title: 'Cyclorama booking',           meta: 'Black or white · Lighting',      thumb: 'cyc',          tag: 'productions' },
  // JOURNAL
  { kind: 'Journal',    title: 'Inside ASPACE — May notes',   meta: 'Long read · 8 min',              thumb: 'journal',      tag: 'journal' },
  { kind: 'Journal',    title: 'A studio you can actually live in', meta: 'Field essay · 12 min',     thumb: 'journal2',     tag: 'journal' },
  // WORKSHOPS
  { kind: 'Workshop',   title: 'Light & shadow — open class', meta: 'Thu evenings · Limited 8',       thumb: 'workshop',     tag: 'workshops' },
  { kind: 'Workshop',   title: 'Print club',                  meta: 'Monthly · Riso + screen',        thumb: 'print',        tag: 'workshops' },
  // AI
  { kind: 'AI',         title: 'Ask ASPACE AI — find a fit',  meta: 'Concierge · Live',               thumb: 'ai',           tag: 'ai' },
  { kind: 'AI',         title: 'Let AI plan your shoot day',  meta: 'Concierge · Live',               thumb: 'ai',           tag: 'ai' },
];

const PROMPTS = [
  'a private studio with daylight…',
  'a cyclorama for a video shoot…',
  'something I can rent monthly…',
  'space for a workshop of 8…',
  'find a creative base in Amsterdam…',
];

/* ----- thumbnail SVGs ----- */
// Temporary photo placeholders — distribute the three mockups across the
// search-result kinds so each card reads with a different studio mood.
const THUMB_MOCKUP = {
  northLight: '/site/uploads/mockup1.png',
  blackBox:   '/site/uploads/mockup2.png',
  atelier:    '/site/uploads/mockup3.png',
  loft:       '/site/uploads/mockup1.png',
  greenroom:  '/site/uploads/mockup3.png',
  concrete:   '/site/uploads/mockup2.png',
  photo:      '/site/uploads/mockup1.png',
  video:      '/site/uploads/mockup2.png',
  cyc:        '/site/uploads/mockup2.png',
  journal:    '/site/uploads/mockup1.png',
  journal2:   '/site/uploads/mockup3.png',
  workshop:   '/site/uploads/mockup3.png',
  print:      '/site/uploads/mockup3.png',
  ai:         '/site/uploads/mockup2.png',
  darkroom:   '/site/uploads/mockup3.png',
};
function mockupForThumb(kind) { return THUMB_MOCKUP[kind] || '/site/uploads/mockup2.png'; }

function ThumbSVG({ kind, blue }) {
  const B = blue || '#00C2FF';
  const ink = '#0A0A0B';
  const cream = '#F4F2EC';
  switch (kind) {
    case 'northLight': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#E9E6DC"/>
        <rect x="20" y="20" width="64" height="100" fill="#fff"/>
        <rect x="92" y="20" width="64" height="100" fill="#fff"/>
        <line x1="20" y1="40" x2="156" y2="40" stroke="#0A0A0B" strokeOpacity="0.18"/>
        <line x1="20" y1="60" x2="156" y2="60" stroke="#0A0A0B" strokeOpacity="0.18"/>
        <line x1="20" y1="80" x2="156" y2="80" stroke="#0A0A0B" strokeOpacity="0.18"/>
        <line x1="52" y1="20" x2="52" y2="120" stroke="#0A0A0B" strokeOpacity="0.18"/>
        <line x1="124" y1="20" x2="124" y2="120" stroke="#0A0A0B" strokeOpacity="0.18"/>
        <circle cx="170" cy="36" r="4" fill={B}/>
      </svg>
    );
    case 'blackBox': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill={ink}/>
        <path d="M0 90 Q100 60 200 90 L200 140 L0 140 Z" fill="#1a1a1c"/>
        <circle cx="160" cy="32" r="14" fill={B} opacity="0.6"/>
        <circle cx="160" cy="32" r="6" fill={B}/>
      </svg>
    );
    case 'atelier': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#D6CFBE"/>
        <rect x="0" y="84" width="200" height="56" fill="#B9AF98"/>
        <rect x="40" y="40" width="60" height="80" fill="#fff" stroke={ink} strokeWidth="1"/>
        <rect x="120" y="60" width="50" height="60" fill={ink}/>
      </svg>
    );
    case 'loft': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#E2DDCF"/>
        <path d="M0 0 L200 0 L160 60 L40 60 Z" fill="#CDC5B2"/>
        <rect x="20" y="60" width="160" height="80" fill="#F4F2EC"/>
        <line x1="60" y1="60" x2="60" y2="140" stroke={ink} strokeOpacity="0.15"/>
        <line x1="140" y1="60" x2="140" y2="140" stroke={ink} strokeOpacity="0.15"/>
      </svg>
    );
    case 'greenroom': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#1F2A22"/>
        <rect x="40" y="50" width="120" height="60" fill="#2C3E32"/>
        <circle cx="100" cy="80" r="18" fill={B} opacity="0.4"/>
        <circle cx="100" cy="80" r="8" fill="#F4F2EC"/>
      </svg>
    );
    case 'concrete': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#9C9489"/>
        <rect x="0" y="100" width="200" height="40" fill="#7E776D"/>
        <line x1="0" y1="100" x2="200" y2="100" stroke={ink} strokeOpacity="0.3"/>
        <line x1="60" y1="0" x2="60" y2="100" stroke={ink} strokeOpacity="0.15"/>
        <line x1="140" y1="0" x2="140" y2="100" stroke={ink} strokeOpacity="0.15"/>
      </svg>
    );
    case 'photo': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill={cream}/>
        <rect x="50" y="40" width="100" height="60" rx="8" fill={ink}/>
        <circle cx="100" cy="70" r="18" fill="#1f1f21" stroke={B} strokeWidth="2"/>
        <circle cx="100" cy="70" r="8" fill={B}/>
      </svg>
    );
    case 'video': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill={ink}/>
        <polygon points="80,50 80,90 120,70" fill={B}/>
        <circle cx="100" cy="70" r="36" fill="none" stroke={B} strokeOpacity="0.4" strokeWidth="1"/>
      </svg>
    );
    case 'cyc': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#fff"/>
        <path d="M0 90 Q100 64 200 90 L200 140 L0 140 Z" fill="#fff" stroke={ink} strokeOpacity="0.15"/>
        <circle cx="160" cy="34" r="10" fill={B}/>
      </svg>
    );
    case 'journal':
    case 'journal2': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill={cream}/>
        <rect x="20" y="22" width="120" height="3" fill={ink}/>
        <rect x="20" y="34" width="160" height="2" fill={ink} opacity="0.5"/>
        <rect x="20" y="42" width="140" height="2" fill={ink} opacity="0.5"/>
        <rect x="20" y="50" width="150" height="2" fill={ink} opacity="0.5"/>
        <rect x="20" y="78" width="160" height="50" fill={ink}/>
      </svg>
    );
    case 'workshop': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#EAE3D2"/>
        <circle cx="60"  cy="80" r="14" fill={ink}/>
        <circle cx="100" cy="80" r="14" fill={ink}/>
        <circle cx="140" cy="80" r="14" fill={ink}/>
        <line x1="40" y1="100" x2="160" y2="100" stroke={ink} strokeOpacity="0.5"/>
      </svg>
    );
    case 'print': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill="#FFD3C6"/>
        <rect x="30" y="30" width="60" height="80" fill={B}/>
        <rect x="80" y="50" width="60" height="80" fill={ink} opacity="0.85"/>
        <rect x="130" y="40" width="40" height="80" fill="#fff"/>
      </svg>
    );
    case 'ai': return (
      <svg viewBox="0 0 200 140" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%' }}>
        <rect width="200" height="140" fill={ink}/>
        <circle cx="100" cy="70" r="38" fill="none" stroke={B} strokeWidth="1" opacity="0.5"/>
        <circle cx="100" cy="70" r="22" fill="none" stroke={B} strokeWidth="1" opacity="0.7"/>
        <circle cx="100" cy="70" r="8" fill={B}/>
      </svg>
    );
    default: return <svg viewBox="0 0 200 140"><rect width="200" height="140" fill="#ddd"/></svg>;
  }
}

/* ----- Search trigger — same Apple-glass system as Menu / Let's talk.
        Icon-only at rest, expands to reveal "SEARCH" label on hover. ----- */
function SearchTrigger({ onClick }) {
  const t = (window.useT && window.useT()) || ((k) => k);
  const [hover, setHover] = useStateSearch(false);

  // Shared glass tokens (mirrored from site-header-menu.jsx).
  const GBG  = 'linear-gradient(180deg, rgba(20,22,28,0.55) 0%, rgba(10,10,11,0.42) 100%)';
  const GBGH = 'linear-gradient(180deg, rgba(28,30,38,0.62) 0%, rgba(14,14,16,0.50) 100%)';
  const GSH  = '0 1px 0 rgba(255,255,255,0.12) inset, 0 -1px 0 rgba(0,0,0,0.35) inset, 0 12px 28px -16px rgba(0,0,0,0.45), 0 0 36px rgba(0,194,255,0.06)';
  const GSHH = '0 1px 0 rgba(255,255,255,0.16) inset, 0 -1px 0 rgba(0,0,0,0.40) inset, 0 18px 42px -20px rgba(0,0,0,0.55), 0 0 56px rgba(0,194,255,0.10)';

  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      aria-label={t('search.triggerAria')}
      className="aspace-search-trigger"
      style={{
        all: 'unset',
        cursor: 'pointer',
        position: 'relative',
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        height: 44,
        width: hover ? 124 : 44,
        padding: 0,
        borderRadius: 999,
        background: hover ? GBGH : GBG,
        backdropFilter: 'blur(18px) saturate(140%)',
        WebkitBackdropFilter: 'blur(18px) saturate(140%)',
        border: hover ? '1px solid rgba(255,255,255,0.22)' : '1px solid rgba(255,255,255,0.14)',
        color: '#fff',
        fontFamily: "'Inter Tight', sans-serif",
        fontSize: 11, fontWeight: 500, letterSpacing: '0.20em', textTransform: 'uppercase',
        transform: hover ? 'translateY(-1px)' : 'translateY(0)',
        transition: 'transform 420ms cubic-bezier(0.22,1,0.36,1), width 520ms cubic-bezier(0.22,1,0.36,1), background 320ms ease, border-color 320ms ease, box-shadow 420ms ease',
        boxShadow: hover ? GSHH : GSH,
        whiteSpace: 'nowrap',
        overflow: 'hidden',
      }}
    >
      {/* expanding label */}
      <span aria-hidden={!hover} style={{
        position: 'absolute', left: 18, top: '50%',
        transform: `translateY(-50%) translateX(${hover ? 0 : -8}px)`,
        opacity: hover ? 0.9 : 0,
        transition: 'opacity 320ms ease 60ms, transform 480ms cubic-bezier(0.22,1,0.36,1) 60ms',
        pointerEvents: 'none',
      }}>{t('search.triggerLabel')}</span>
      {/* search glyph — fixed on right edge, no rotation */}
      <span aria-hidden="true" style={{
        position: 'absolute', right: 13, top: '50%',
        transform: 'translateY(-50%)',
        display: 'inline-flex',
      }}>
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
          <circle cx="10" cy="10" r="6.4"/>
          <path d="M14.8 14.8L20 20"/>
        </svg>
      </span>
    </button>
  );
}

/* ----- main overlay ----- */
function SearchOverlay({ open, onClose, blue }) {
  const tx = (window.useT && window.useT()) || ((k) => k);
  // Localized data — prompts, category labels, kind names, and the index.
  const PROMPTS_T = tx('search.prompts') || PROMPTS;
  const KINDS_T = tx('search.kinds') || {};
  const INDEX_T = (tx('search.index') || []).map((row, i) => ({
    ...SEARCH_INDEX[i],
    title: row.title,
    meta: row.meta,
  }));
  const SEARCH_DATA = INDEX_T.length === SEARCH_INDEX.length ? INDEX_T : SEARCH_INDEX;
  const kindLabel = (k) => {
    const map = { Studio: KINDS_T.studio, Production: KINDS_T.production, Journal: KINDS_T.journal, Workshop: KINDS_T.workshop, AI: KINDS_T.ai };
    return map[k] || k;
  };
  const [q, setQ] = useStateSearch('');
  const [activePromptIdx, setActivePromptIdx] = useStateSearch(0);
  const [hoverIdx, setHoverIdx] = useStateSearch(-1);
  const inputRef = useRefSearch(null);
  const fieldRef = useRefSearch(null);
  const [mounted, setMounted] = useStateSearch(false);

  // Mount on open with one frame delay so transition runs
  useEffectSearch(() => {
    if (open) {
      setMounted(true);
      const t = setTimeout(() => inputRef.current?.focus(), 380);
      return () => clearTimeout(t);
    } else {
      const t = setTimeout(() => setMounted(false), 520);
      return () => clearTimeout(t);
    }
  }, [open]);

  // Cycle placeholders when idle and empty
  useEffectSearch(() => {
    if (!open || q) return;
    const t = setInterval(() => setActivePromptIdx(i => (i + 1) % PROMPTS_T.length), 2600);
    return () => clearInterval(t);
  }, [open, q]);

  // Esc + body lock
  useEffectSearch(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.documentElement.style.overflow = 'hidden';
    document.body.style.overflow = 'hidden';
    if (window.lenis && typeof window.lenis.stop === 'function') window.lenis.stop();
    return () => {
      window.removeEventListener('keydown', onKey);
      // Always reset (never restore stale 'hidden' from chained overlays).
      document.documentElement.style.overflow = '';
      document.body.style.overflow = '';
      if (window.lenis && typeof window.lenis.start === 'function') window.lenis.start();
    };
  }, [open, onClose]);

  // Filter
  const norm = q.trim().toLowerCase();
  const results = norm
    ? SEARCH_DATA.filter(it => (it.title + ' ' + it.kind + ' ' + it.meta).toLowerCase().includes(norm)).slice(0, 8)
    : SEARCH_DATA.slice(0, 8);

  // Group categories present
  const categories = tx('search.categories') || [];

  // Magnetic field
  const [fieldMagnet, setFieldMagnet] = useStateSearch({ x: 0, y: 0 });
  const onFieldMove = (e) => {
    const el = fieldRef.current; if (!el) return;
    const r = el.getBoundingClientRect();
    setFieldMagnet({
      x: (e.clientX - (r.left + r.width/2)) * 0.018,
      y: (e.clientY - (r.top + r.height/2)) * 0.020,
    });
  };

  if (!mounted) return null;

  const bgB = blue || '#00C2FF';

  return (
    <React.Fragment>
      {/* Ambient backdrop — soft dim + blur with a centered electric halo */}
      <div
        onClick={onClose}
        aria-hidden="true"
        style={{
          position: 'fixed', inset: 0, zIndex: 9700,
          background: 'radial-gradient(60% 50% at 50% 38%, rgba(0,194,255,0.10), rgba(10,10,11,0.55) 60%, rgba(10,10,11,0.72))',
          backdropFilter: 'blur(18px) saturate(120%)',
          WebkitBackdropFilter: 'blur(18px) saturate(120%)',
          opacity: open ? 1 : 0,
          transition: 'opacity 600ms cubic-bezier(0.22,1,0.36,1)',
        }}
      />

      {/* Floating ambient particles */}
      <div aria-hidden="true" style={{
        position: 'fixed', inset: 0, zIndex: 9701, pointerEvents: 'none',
        opacity: open ? 1 : 0,
        transition: 'opacity 800ms ease 120ms',
      }}>
        {[...Array(14)].map((_, i) => {
          const left = (i * 73) % 100;
          const top = (i * 41 + 7) % 100;
          const size = 2 + (i % 3);
          const dur = 6 + (i % 5);
          return (
            <span key={i} style={{
              position: 'absolute',
              left: `${left}%`, top: `${top}%`,
              width: size, height: size, borderRadius: '50%',
              background: i % 4 === 0 ? bgB : 'rgba(255,255,255,0.7)',
              boxShadow: i % 4 === 0 ? `0 0 ${size*4}px ${bgB}` : 'none',
              opacity: 0.55,
              animation: `searchFloat ${dur}s ease-in-out ${i * 0.3}s infinite alternate`,
            }}/>
          );
        })}
      </div>

      {/* Content stage */}
      <div
        aria-hidden={!open}
        style={{
          position: 'fixed', inset: 0, zIndex: 9710,
          display: 'flex', flexDirection: 'column', alignItems: 'center',
          padding: 'clamp(80px, 10vh, 140px) clamp(20px, 4vw, 64px) 40px',
          pointerEvents: open ? 'auto' : 'none',
          overflowY: 'auto',
        }}
        onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      >
        {/* Eyebrow */}
        <div className="aspace-eyebrow" style={{
          color: 'rgba(255,255,255,0.5)', marginBottom: 18,
          letterSpacing: '0.32em',
          opacity: open ? 1 : 0,
          transform: open ? 'translateY(0)' : 'translateY(-12px)',
          transition: 'opacity 600ms ease 220ms, transform 600ms cubic-bezier(0.22,1,0.36,1) 220ms',
        }}>
          {tx('search.eyebrow')}
        </div>

        {/* Hero search field */}
        <div
          ref={fieldRef}
          onMouseMove={onFieldMove}
          onMouseLeave={() => setFieldMagnet({ x: 0, y: 0 })}
          style={{
            width: '100%',
            maxWidth: 880,
            position: 'relative',
            transform: open
              ? `translate(${fieldMagnet.x}px, ${fieldMagnet.y}px) scale(1)`
              : 'translate(0, 24px) scale(0.94)',
            opacity: open ? 1 : 0,
            transition: 'transform 720ms cubic-bezier(0.22,1.2,0.36,1) 80ms, opacity 540ms ease 80ms',
          }}
        >
          {/* breathing halo */}
          <div aria-hidden="true" style={{
            position: 'absolute', inset: -22,
            borderRadius: 999,
            background: `radial-gradient(60% 80% at 50% 50%, ${bgB}33, transparent 70%)`,
            filter: 'blur(20px)',
            animation: 'searchHaloBreath 4.6s ease-in-out infinite',
            pointerEvents: 'none',
          }}/>

          {/* outer rim glow */}
          <div aria-hidden="true" style={{
            position: 'absolute', inset: -1,
            borderRadius: 999,
            background: `linear-gradient(120deg, transparent, ${bgB}55, transparent 60%)`,
            opacity: 0.6,
            pointerEvents: 'none',
          }}/>

          <div style={{
            position: 'relative',
            display: 'flex', alignItems: 'center', gap: 18,
            padding: 'clamp(14px, 2vw, 18px) clamp(18px, 3vw, 28px)',
            borderRadius: 999,
            background: 'rgba(244,242,236,0.92)',
            backdropFilter: 'blur(28px) saturate(160%)',
            WebkitBackdropFilter: 'blur(28px) saturate(160%)',
            border: `1px solid rgba(255,255,255,0.6)`,
            boxShadow: `
              0 30px 80px rgba(0,0,0,0.35),
              0 0 0 1px rgba(10,10,11,0.05),
              inset 0 1px 0 rgba(255,255,255,0.8),
              0 0 60px rgba(0,194,255,0.18)
            `,
          }}>
            {/* Left rotating glyph */}
            <span aria-hidden="true" style={{
              flexShrink: 0,
              width: 44, height: 44, borderRadius: '50%',
              background: '#0A0A0B', color: '#fff',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              animation: 'searchGlyphSpin 14s linear infinite',
            }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
                <circle cx="10" cy="10" r="6"/>
                <path d="M14.6 14.6L20 20"/>
              </svg>
            </span>

            {/* The input */}
            <div style={{ flex: 1, position: 'relative', minWidth: 0 }}>
              <input
                ref={inputRef}
                value={q}
                onChange={(e) => setQ(e.target.value)}
                placeholder=""
                style={{
                  all: 'unset',
                  display: 'block',
                  width: '100%',
                  fontFamily: "'Inter Tight', sans-serif",
                  fontWeight: 500,
                  fontSize: 'clamp(22px, 3.4vw, 38px)',
                  letterSpacing: '-0.01em',
                  lineHeight: 1.1,
                  color: '#0A0A0B',
                  caretColor: bgB,
                }}
              />
              {/* cycling editorial placeholder */}
              {!q && (
                <div aria-hidden="true" style={{
                  position: 'absolute', inset: 0,
                  display: 'flex', alignItems: 'center',
                  pointerEvents: 'none',
                  fontFamily: "'Inter Tight', sans-serif",
                  fontWeight: 500,
                  fontSize: 'clamp(22px, 3.4vw, 38px)',
                  letterSpacing: '-0.01em',
                  color: 'rgba(10,10,11,0.32)',
                  whiteSpace: 'nowrap',
                  overflow: 'hidden',
                }}>
                  <span style={{ position: 'relative', display: 'inline-block', minHeight: '1.1em', flex: 1 }}>
                    {PROMPTS_T.map((p, i) => (
                      <span key={p} style={{
                        position: i === 0 ? 'relative' : 'absolute',
                        left: 0, top: 0, whiteSpace: 'nowrap',
                        opacity: i === activePromptIdx ? 1 : 0,
                        transform: i === activePromptIdx ? 'translateY(0)' : 'translateY(8px)',
                        transition: 'opacity 600ms cubic-bezier(0.22,1,0.36,1), transform 600ms cubic-bezier(0.22,1,0.36,1)',
                        color: 'rgba(10,10,11,0.42)',
                      }}>{p}</span>
                    ))}
                  </span>
                </div>
              )}
            </div>

          </div>

          {/* Sub line under input */}
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            marginTop: 14, padding: '0 6px',
            color: 'rgba(255,255,255,0.55)',
            fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase',
          }}>
            <span>{q ? `${results.length} ${tx('search.subline.matches') || 'matches'}` : (tx('search.subline.idle') || 'Quiet index · curated')}</span>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: bgB, boxShadow: `0 0 8px ${bgB}` }}/>
              {tx('search.subline.live')}
            </span>
          </div>
        </div>

        {/* Categories chips */}
        <div style={{
          display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'center',
          marginTop: 32, maxWidth: 880, width: '100%',
          opacity: open ? 1 : 0,
          transform: open ? 'translateY(0)' : 'translateY(12px)',
          transition: 'opacity 540ms ease 320ms, transform 600ms cubic-bezier(0.22,1,0.36,1) 320ms',
        }}>
          {categories.map((c) => {
            const has = results.some(r => r.tag === c.id);
            return (
              <span key={c.id} style={{
                padding: '8px 14px',
                borderRadius: 999,
                fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase',
                background: has ? 'rgba(255,255,255,0.10)' : 'rgba(255,255,255,0.04)',
                border: `1px solid ${has ? 'rgba(255,255,255,0.18)' : 'rgba(255,255,255,0.06)'}`,
                color: has ? 'rgba(255,255,255,0.92)' : 'rgba(255,255,255,0.32)',
                fontFamily: "'Inter Tight', sans-serif",
                display: 'inline-flex', alignItems: 'center', gap: 8,
              }}>
                {has && <span style={{ width: 5, height: 5, borderRadius: '50%', background: bgB, boxShadow: `0 0 6px ${bgB}` }}/>}
                {c.label}
                <span style={{ opacity: 0.5 }}>{results.filter(r => r.tag === c.id).length}</span>
              </span>
            );
          })}
        </div>

        {/* Result cards */}
        <div style={{
          width: '100%', maxWidth: 1080,
          marginTop: 36,
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))',
          gap: 16,
        }}>
          {results.map((r, i) => {
            const active = hoverIdx === i;
            return (
              <a
                key={r.title}
                href={r.tag === 'studios' ? 'ASPACE Studios.html' : r.tag === 'journal' ? '#' : r.tag === 'ai' ? '#' : 'ASPACE Studios.html'}
                onMouseEnter={() => setHoverIdx(i)}
                onMouseLeave={() => setHoverIdx(-1)}
                onClick={onClose}
                style={{
                  position: 'relative',
                  display: 'block',
                  borderRadius: 22,
                  overflow: 'hidden',
                  background: 'rgba(244,242,236,0.06)',
                  border: '1px solid rgba(255,255,255,0.10)',
                  backdropFilter: 'blur(14px)',
                  WebkitBackdropFilter: 'blur(14px)',
                  textDecoration: 'none', color: 'inherit',
                  transform: open
                    ? (active ? 'translateY(-4px)' : 'translateY(0)')
                    : 'translateY(20px)',
                  opacity: open ? 1 : 0,
                  transition: `transform 540ms cubic-bezier(0.22,1.2,0.36,1) ${380 + i * 40}ms, opacity 460ms ease ${380 + i * 40}ms, box-shadow 360ms ease, background 320ms ease`,
                  boxShadow: active
                    ? `0 18px 50px -10px rgba(0,0,0,0.5), 0 0 0 1px rgba(0,194,255,0.4), 0 0 24px ${bgB}55`
                    : `0 8px 24px -10px rgba(0,0,0,0.35)`,
                }}
              >
                {/* Thumbnail */}
                <div style={{
                  position: 'relative',
                  aspectRatio: '16 / 9',
                  background: '#0A0A0B',
                  overflow: 'hidden',
                }}>
                  <div style={{
                    position: 'absolute', inset: 0,
                    transform: active ? 'scale(1.06)' : 'scale(1)',
                    transition: 'transform 720ms cubic-bezier(0.22,1,0.36,1)',
                  }}>
                    <img
                      src={mockupForThumb(r.thumb)}
                      alt=""
                      loading="lazy"
                      style={{
                        position: 'absolute', inset: 0,
                        width: '100%', height: '100%',
                        objectFit: 'cover', display: 'block',
                      }}
                    />
                    {/* subtle dark overlay so the chip + arrow stay readable */}
                    <div aria-hidden="true" style={{
                      position: 'absolute', inset: 0,
                      background: 'linear-gradient(to bottom, rgba(0,0,0,0.20) 0%, rgba(0,0,0,0.0) 35%, rgba(0,0,0,0.0) 65%, rgba(0,0,0,0.45) 100%)',
                    }}/>
                  </div>
                  {/* category chip */}
                  <span style={{
                    position: 'absolute', top: 12, left: 12,
                    padding: '5px 10px',
                    borderRadius: 999,
                    fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase',
                    background: 'rgba(10,10,11,0.7)',
                    color: '#fff',
                    backdropFilter: 'blur(6px)',
                    border: '1px solid rgba(255,255,255,0.15)',
                  }}>{kindLabel(r.kind)}</span>
                  {/* arrow */}
                  <span style={{
                    position: 'absolute', bottom: 12, right: 12,
                    width: 36, height: 36, borderRadius: '50%',
                    background: active ? bgB : 'rgba(255,255,255,0.94)',
                    color: '#0A0A0B',
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    transform: active ? 'translate(0,0) rotate(-45deg)' : 'translate(0,0) rotate(0)',
                    transition: 'transform 460ms cubic-bezier(0.22,1.2,0.36,1), background 320ms ease',
                  }}>
                    <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
                  </span>
                </div>
                {/* meta */}
                <div style={{ padding: '14px 16px 18px' }}>
                  <div style={{
                    fontFamily: "'Inter Tight', sans-serif",
                    fontWeight: 500,
                    fontSize: 17,
                    color: '#fff',
                    letterSpacing: '-0.005em',
                  }}>{r.title}</div>
                  <div style={{ marginTop: 4, color: 'rgba(255,255,255,0.55)', fontSize: 12 }}>{r.meta}</div>
                </div>
              </a>
            );
          })}
        </div>

        {/* Bottom hint */}
        <div style={{
          marginTop: 32, marginBottom: 12,
          color: 'rgba(255,255,255,0.42)',
          fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase',
          opacity: open ? 1 : 0,
          transition: 'opacity 540ms ease 600ms',
        }}>
          {tx('search.bottomHint.prefix')} <kbd style={{ padding: '4px 8px', borderRadius: 6, background: 'rgba(255,255,255,0.10)', color: '#fff', margin: '0 4px' }}>{tx('search.bottomHint.esc')}</kbd>
          {' '}{tx('search.bottomHint.suffix')} <a href="#" onClick={(e) => { e.preventDefault(); onClose(); window.dispatchEvent(new CustomEvent('aspace:openAI')); }} style={{ color: bgB }}>{tx('search.bottomHint.aiLink')}</a>
        </div>
      </div>

      {/* Keyframes */}
      <style>{`
        @keyframes searchHaloBreath {
          0%, 100% { transform: scale(1); opacity: 0.7; }
          50%      { transform: scale(1.06); opacity: 1; }
        }
        @keyframes searchGlyphSpin {
          to { transform: rotate(360deg); }
        }
        @keyframes searchFloat {
          from { transform: translate(0, 0); }
          to   { transform: translate(8px, -16px); }
        }
      `}</style>
    </React.Fragment>
  );
}

window.SearchTrigger = SearchTrigger;
window.SearchOverlay = SearchOverlay;
