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

// ============ V1: WASHI MINIMALISTE — version peaufinée ============

const useStore = () => {
  const [state, setState] = useState(window.sushiStore.state);
  useEffect(() => window.sushiStore.subscribe(setState), []);
  return state;
};

// Inject keyframes once
if (typeof document !== 'undefined' && !document.getElementById('washi-anim')) {
  const s = document.createElement('style');
  s.id = 'washi-anim';
  s.textContent = `
    @keyframes washi-fadein {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }
    @keyframes washi-stamp {
      0% { transform: scale(2.4) rotate(-30deg); opacity: 0; }
      40% { transform: scale(0.9) rotate(-3deg); opacity: 1; }
      60% { transform: scale(1.05) rotate(-3deg); }
      100% { transform: scale(1) rotate(-3deg); opacity: 1; }
    }
    @keyframes washi-pulse {
      0%, 100% { transform: scale(1); }
      50% { transform: scale(1.1); }
    }
    @keyframes washi-spin {
      from { transform: rotate(-3deg); }
      to { transform: rotate(357deg); }
    }
    @keyframes washi-bounce {
      0% { transform: scale(0.6); opacity: 0; }
      60% { transform: scale(1.15); opacity: 1; }
      100% { transform: scale(1); }
    }
    @keyframes washi-confetti {
      0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
      100% { transform: translate(var(--tx), var(--ty)) rotate(var(--tr)); opacity: 0; }
    }
    @keyframes washi-slidein {
      from { opacity: 0; transform: translateX(-8px); }
      to { opacity: 1; transform: translateX(0); }
    }
    .washi-item {
      animation: washi-fadein .35s cubic-bezier(.2,.7,.2,1) both;
    }
    .washi-stamp-anim {
      animation: washi-stamp .7s cubic-bezier(.3,1.5,.4,1) both;
    }
    .washi-stamp-spin:hover {
      animation: washi-spin 1.2s cubic-bezier(.3,.7,.3,1);
    }
    .washi-qty-pop {
      animation: washi-bounce .35s cubic-bezier(.3,1.5,.4,1);
    }
    .washi-pill-in {
      animation: washi-slidein .3s cubic-bezier(.2,.7,.2,1) both;
    }
  `;
  document.head.appendChild(s);
}

function Hanko({ size = 44, char = '寿', rotate = -3, onClick, animate = false, spinOnHover = true }) {
  return (
    <div
      onClick={onClick}
      className={[animate ? 'washi-stamp-anim' : '', spinOnHover ? 'washi-stamp-spin' : ''].join(' ')}
      style={{
        width: size, height: size, borderRadius: 6,
        background: '#c9342a',
        color: '#f6efe0',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: '"Noto Serif JP", serif', fontWeight: 700,
        fontSize: size * 0.55,
        transform: `rotate(${rotate}deg)`,
        boxShadow: 'inset 0 0 0 2px #c9342a, inset 0 0 0 3px #f6efe0, inset 0 0 0 5px #c9342a',
        letterSpacing: '-0.05em',
        cursor: onClick ? 'pointer' : 'default',
        flex: '0 0 auto',
      }}>{char}</div>
  );
}

function WashiTexture() {
  return (
    <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', opacity: 0.5 }}>
      <defs>
        <filter id="washi-noise">
          <feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" />
          <feColorMatrix values="0 0 0 0 0.55  0 0 0 0 0.45  0 0 0 0 0.32  0 0 0 0.08 0" />
        </filter>
      </defs>
      <rect width="100%" height="100%" filter="url(#washi-noise)" />
    </svg>
  );
}

function Confetti({ trigger }) {
  const [pieces, setPieces] = useState([]);
  useEffect(() => {
    if (!trigger) return;
    const newPieces = Array.from({ length: 28 }, (_, i) => ({
      id: trigger + '-' + i,
      tx: (Math.random() - 0.5) * 360,
      ty: -120 - Math.random() * 200,
      tr: (Math.random() - 0.5) * 720,
      delay: Math.random() * 100,
      char: ['寿', '✦', '●', '◆'][Math.floor(Math.random() * 4)],
      color: ['#c9342a', '#1a1410', '#d4a574', '#7a8a5c'][Math.floor(Math.random() * 4)],
      size: 10 + Math.random() * 10,
    }));
    setPieces(newPieces);
    const t = setTimeout(() => setPieces([]), 1400);
    return () => clearTimeout(t);
  }, [trigger]);
  if (pieces.length === 0) return null;
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 200,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {pieces.map(p => (
        <div key={p.id} style={{
          position: 'absolute',
          fontFamily: p.char === '寿' ? '"Noto Serif JP", serif' : 'inherit',
          fontSize: p.size, color: p.color, fontWeight: 700,
          animation: `washi-confetti 1.2s cubic-bezier(.3,.5,.6,1) ${p.delay}ms both`,
          '--tx': p.tx + 'px',
          '--ty': p.ty + 'px',
          '--tr': p.tr + 'deg',
        }}>{p.char}</div>
      ))}
    </div>
  );
}

function NameEntry({ onSubmit }) {
  const state = useStore();
  const [name, setName] = useState('');
  const others = Object.values(state.users || {});
  return (
    <div style={{
      position: 'absolute', inset: 0, display: 'flex',
      alignItems: 'center', justifyContent: 'center',
      background: '#f6efe0', overflow: 'hidden', zIndex: 100,
    }}>
      <WashiTexture />
      <div style={{ position: 'relative', textAlign: 'center', padding: '0 32px', width: '100%', maxWidth: 340 }}>
        <div style={{
          fontFamily: '"Noto Serif JP", serif', fontSize: 90, color: '#1a1410',
          letterSpacing: '0.1em', lineHeight: 1, marginBottom: 8,
          animation: 'washi-bounce .6s cubic-bezier(.3,1.5,.4,1) both',
        }}>寿司</div>
        <div style={{
          fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
          fontSize: 18, color: '#5a4a3a', letterSpacing: '0.3em',
          marginBottom: 4, textTransform: 'uppercase',
        }}>Itadakimasu</div>
        <div style={{
          width: 40, height: 1, background: '#c9342a', margin: '20px auto 28px',
        }} />
        <div style={{
          fontFamily: '"Cormorant Garamond", serif', fontSize: 22, color: '#1a1410',
          marginBottom: 24, fontWeight: 500,
        }}>Comment t'appelles-tu&nbsp;?</div>
        <input
          autoFocus
          value={name}
          onChange={e => setName(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && name.trim() && onSubmit(name)}
          placeholder="prénom"
          style={{
            width: '100%', padding: '14px 16px',
            border: 'none', borderBottom: '1.5px solid #1a1410',
            background: 'transparent', textAlign: 'center',
            fontFamily: '"Cormorant Garamond", serif', fontSize: 22,
            color: '#1a1410', outline: 'none', letterSpacing: '0.05em',
          }}
        />
        <button
          onClick={() => name.trim() && onSubmit(name)}
          disabled={!name.trim()}
          style={{
            marginTop: 32, padding: '14px 40px',
            background: name.trim() ? '#1a1410' : '#a89a8a',
            color: '#f6efe0', border: 'none', borderRadius: 0,
            fontFamily: '"Cormorant Garamond", serif', fontSize: 16,
            letterSpacing: '0.3em', textTransform: 'uppercase',
            cursor: name.trim() ? 'pointer' : 'not-allowed',
            transition: 'all .2s',
          }}>Entrer</button>

        {others.length > 0 && (
          <div style={{ marginTop: 36 }}>
            <div style={{
              fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
              fontSize: 12, color: '#5a4a3a', letterSpacing: '0.25em',
              textTransform: 'uppercase', marginBottom: 10,
            }}>— Déjà à table —</div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', justifyContent: 'center' }}>
              {others.map(u => (
                <div key={u.name} className="washi-pill-in" style={{
                  display: 'inline-flex', alignItems: 'center', gap: 6,
                  padding: '4px 10px', border: '1px solid #1a1410',
                  fontFamily: '"Cormorant Garamond", serif', fontSize: 13,
                }}>
                  <span style={{ width: 6, height: 6, borderRadius: 999, background: u.color }} />
                  {u.name}
                </div>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* Signature footer */}
      <div style={{
        position: 'absolute', bottom: 24, left: 0, right: 0,
        textAlign: 'center', pointerEvents: 'none',
      }}>
        <div style={{
          fontFamily: '"Noto Serif JP", serif', fontSize: 14,
          color: '#1a1410', letterSpacing: '0.1em', marginBottom: 4, opacity: 0.7,
        }}>月</div>
        <div style={{
          fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
          fontSize: 11, color: '#5a4a3a',
          letterSpacing: '0.3em', textTransform: 'uppercase', opacity: 0.7,
        }}>Moon AI Corp</div>
      </div>
    </div>
  );
}

function CategoryNav({ active, onPick }) {
  const cats = window.CATEGORIES;
  return (
    <div style={{
      display: 'flex', gap: 0, overflowX: 'auto',
      borderBottom: '1px solid #1a1410',
      borderTop: '1px solid #1a1410',
      background: '#f6efe0',
      scrollbarWidth: 'none', flex: '0 0 auto',
    }}>
      {cats.map((c, i) => (
        <button key={c.id} onClick={() => onPick(c.id)} style={{
          flex: '0 0 auto', padding: '12px 18px',
          background: active === c.id ? '#1a1410' : 'transparent',
          color: active === c.id ? '#f6efe0' : '#1a1410',
          border: 'none',
          borderRight: i < cats.length - 1 ? '1px solid #1a1410' : 'none',
          fontFamily: '"Noto Serif JP", serif',
          cursor: 'pointer', textAlign: 'center',
          minWidth: 90, transition: 'all .25s',
        }}>
          <div style={{ fontSize: 18, lineHeight: 1, marginBottom: 4 }}>{c.kanji}</div>
          <div style={{
            fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
            fontSize: 11, letterSpacing: '0.15em', opacity: 0.85,
          }}>{c.romaji}</div>
        </button>
      ))}
    </div>
  );
}

function MenuItem({ item, qty, orderers, currentUser, onInc, onDec, search }) {
  const others = orderers.filter(o => o.name !== currentUser);
  const [popKey, setPopKey] = useState(0);
  const prevQty = useRef(qty);
  useEffect(() => {
    if (qty !== prevQty.current) {
      setPopKey(k => k + 1);
      prevQty.current = qty;
    }
  }, [qty]);

  // Highlight matching search
  const renderName = () => {
    if (!search) return item.nom;
    const idx = item.nom.toLowerCase().indexOf(search.toLowerCase());
    if (idx === -1) return item.nom;
    return (
      <>
        {item.nom.slice(0, idx)}
        <mark style={{ background: '#c9342a', color: '#f6efe0', padding: '0 2px' }}>
          {item.nom.slice(idx, idx + search.length)}
        </mark>
        {item.nom.slice(idx + search.length)}
      </>
    );
  };

  return (
    <div className="washi-item" style={{
      display: 'flex', alignItems: 'flex-start',
      padding: '20px 0',
      borderBottom: '1px dashed rgba(26,20,16,0.25)',
      gap: 16, position: 'relative',
    }}>
      <div style={{
        flex: '0 0 36px',
        fontFamily: '"Cormorant Garamond", serif',
        fontSize: 28, color: '#1a1410', fontWeight: 500,
        lineHeight: 1, paddingTop: 4,
      }}>
        {String(item.num).padStart(2, '0')}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontFamily: '"Cormorant Garamond", serif',
          fontSize: 19, color: '#1a1410', lineHeight: 1.25,
          fontWeight: 500,
        }}>{renderName()}</div>
        {item.sub && <div style={{
          fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
          fontSize: 13, color: '#5a4a3a', marginTop: 2,
          letterSpacing: '0.05em',
        }}>— {item.sub}</div>}
        {others.length > 0 && (
          <div style={{ display: 'flex', gap: 4, marginTop: 8, flexWrap: 'wrap' }}>
            {others.map(o => (
              <div key={o.name} className="washi-pill-in" style={{
                display: 'inline-flex', alignItems: 'center', gap: 4,
                padding: '2px 8px', borderRadius: 999,
                background: 'rgba(26,20,16,0.06)',
                fontFamily: '"Cormorant Garamond", serif',
                fontSize: 12, color: '#1a1410',
                letterSpacing: '0.03em',
              }}>
                <span style={{
                  width: 6, height: 6, borderRadius: 999, background: o.color,
                }} />
                {o.name} ×{o.qty}
              </div>
            ))}
          </div>
        )}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 0, flex: '0 0 auto' }}>
        {qty > 0 ? (
          <>
            <button onClick={onDec} style={qtyBtnStyle('left')}>−</button>
            <div key={popKey} className="washi-qty-pop" style={{
              width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: '#1a1410', color: '#f6efe0',
              fontFamily: '"Cormorant Garamond", serif', fontSize: 18, fontWeight: 600,
            }}>{qty}</div>
            <button onClick={onInc} style={qtyBtnStyle('right')}>+</button>
          </>
        ) : (
          <button onClick={onInc} style={{
            width: 36, height: 36, border: '1px solid #1a1410',
            background: 'transparent', color: '#1a1410',
            fontFamily: '"Cormorant Garamond", serif', fontSize: 22,
            cursor: 'pointer', transition: 'all .15s',
          }}
            onMouseEnter={e => { e.currentTarget.style.background = '#1a1410'; e.currentTarget.style.color = '#f6efe0'; }}
            onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = '#1a1410'; }}
          >+</button>
        )}
      </div>
    </div>
  );
}

function qtyBtnStyle(side) {
  return {
    width: 36, height: 36,
    border: '1px solid #1a1410',
    borderRight: side === 'left' ? 'none' : '1px solid #1a1410',
    borderLeft: side === 'right' ? 'none' : '1px solid #1a1410',
    background: '#f6efe0', color: '#1a1410',
    fontFamily: '"Cormorant Garamond", serif', fontSize: 20,
    cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
    transition: 'all .15s',
  };
}


function SummarySheet({ open, onClose, onReset }) {
  const state = useStore();
  const [confettiKey, setConfettiKey] = useState(0);
  const orders = state.orders;
  const allItems = window.MENU_DATA;

  const totals = {};
  const orderersByItem = {};
  Object.entries(orders).forEach(([name, ord]) => {
    Object.entries(ord).forEach(([num, q]) => {
      const n = +num;
      totals[n] = (totals[n] || 0) + q;
      if (!orderersByItem[n]) orderersByItem[n] = [];
      orderersByItem[n].push({ name, qty: q, color: state.users[name]?.color });
    });
  });
  const orderedNums = Object.keys(totals).map(Number).sort((a, b) => a - b);
  const totalCount = Object.values(totals).reduce((s, n) => s + n, 0);

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 50,
      pointerEvents: open ? 'auto' : 'none',
    }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0, background: 'rgba(26,20,16,0.4)',
        opacity: open ? 1 : 0, transition: 'opacity .25s',
      }} />
      <div style={{
        position: 'absolute', inset: '40px 0 0 0', background: '#f6efe0',
        transform: open ? 'translateY(0)' : 'translateY(100%)',
        transition: 'transform .35s cubic-bezier(.2,.7,.2,1)',
        boxShadow: '0 -8px 30px rgba(0,0,0,0.2)',
        display: 'flex', flexDirection: 'column',
        overflow: 'hidden',
      }}>
        <WashiTexture />
        <Confetti trigger={confettiKey} />
        <div style={{
          padding: '20px 24px 0', borderBottom: 'none',
          position: 'relative', background: '#f6efe0',
        }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 14 }}>
            <div>
              <div style={{
                fontFamily: '"Noto Serif JP", serif', fontSize: 24, color: '#1a1410', lineHeight: 1,
              }}>注文</div>
              <div style={{
                fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
                fontSize: 14, color: '#5a4a3a', letterSpacing: '0.2em',
                textTransform: 'uppercase', marginTop: 4,
              }}>La commande · {totalCount} pièces</div>
            </div>
            <button onClick={onClose} style={{
              width: 36, height: 36, border: '1px solid #1a1410',
              background: 'transparent', cursor: 'pointer',
              fontFamily: '"Cormorant Garamond", serif', fontSize: 20, color: '#1a1410',
            }}>×</button>
          </div>
        </div>

          <div style={{ flex: 1, overflowY: 'auto', padding: '0 24px', position: 'relative' }}>
            {orderedNums.length === 0 ? (
              <div style={{
                textAlign: 'center', padding: '60px 20px',
                fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
                fontSize: 18, color: '#5a4a3a',
              }}>Aucune commande pour l'instant</div>
            ) : orderedNums.map((num, i) => {
              const item = allItems.find(it => it.num === num);
              return (
                <div key={num} className="washi-item" style={{
                  padding: '16px 0', borderBottom: '1px dashed rgba(26,20,16,0.25)',
                  animationDelay: `${i * 30}ms`,
                }}>
                  <div style={{ display: 'flex', alignItems: 'baseline', gap: 12 }}>
                    <div style={{
                      fontFamily: '"Cormorant Garamond", serif', fontSize: 18,
                      color: '#5a4a3a', flex: '0 0 30px',
                    }}>{String(num).padStart(2, '0')}</div>
                    <div style={{ flex: 1, fontFamily: '"Cormorant Garamond", serif', fontSize: 17, color: '#1a1410', fontWeight: 500 }}>{item?.nom}</div>
                    <div style={{
                      fontFamily: '"Noto Serif JP", serif', fontSize: 22, color: '#c9342a', fontWeight: 700,
                    }}>×{totals[num]}</div>
                  </div>
                  <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 6, paddingLeft: 42 }}>
                    {orderersByItem[num].map(o => (
                      <span key={o.name} style={{
                        display: 'inline-flex', alignItems: 'center', gap: 4,
                        fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
                        fontSize: 13, color: '#1a1410',
                      }}>
                        <span style={{ width: 7, height: 7, background: o.color, borderRadius: 999 }} />
                        {o.name} ×{o.qty}
                      </span>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>

        <div style={{ padding: 20, borderTop: '1px solid #1a1410', background: '#f6efe0', position: 'relative', display: 'flex', gap: 10 }}>
          <button onClick={() => {
            if (confirm('Réinitialiser toute la commande ?')) onReset();
          }} style={{
            flex: 1, padding: '14px',
            border: '1px solid #1a1410', background: 'transparent', color: '#1a1410',
            fontFamily: '"Cormorant Garamond", serif', fontSize: 14,
            letterSpacing: '0.25em', textTransform: 'uppercase', cursor: 'pointer',
          }}>Reset</button>
          <button onClick={() => {
            setConfettiKey(k => k + 1);
            setTimeout(() => onClose(), 1200);
          }} style={{
            flex: 2, padding: '14px',
            border: '1px solid #1a1410', background: '#1a1410', color: '#f6efe0',
            fontFamily: '"Cormorant Garamond", serif', fontSize: 14,
            letterSpacing: '0.25em', textTransform: 'uppercase', cursor: 'pointer',
          }}>Itadakimasu ✦</button>
        </div>
      </div>
    </div>
  );
}

function PeopleStrip() {
  const state = useStore();
  const users = Object.values(state.users);
  if (users.length === 0) return null;
  return (
    <div style={{
      display: 'flex', gap: 6, padding: '8px 16px',
      borderBottom: '1px solid rgba(26,20,16,0.15)',
      background: '#f6efe0', overflowX: 'auto', scrollbarWidth: 'none',
      alignItems: 'center', flex: '0 0 auto',
    }}>
      <div style={{
        fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
        fontSize: 12, color: '#5a4a3a', letterSpacing: '0.2em',
        textTransform: 'uppercase', flex: '0 0 auto', marginRight: 4,
      }}>À table —</div>
      {users.map(u => {
        const isMe = u.name === state.currentUser;
        const orderCount = Object.values(state.orders[u.name] || {}).reduce((s, n) => s + n, 0);
        return (
          <div key={u.name} className="washi-pill-in" style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '4px 10px',
            background: isMe ? '#1a1410' : 'transparent',
            color: isMe ? '#f6efe0' : '#1a1410',
            border: '1px solid #1a1410',
            fontFamily: '"Cormorant Garamond", serif', fontSize: 13,
            flex: '0 0 auto',
          }}>
            <span style={{ width: 6, height: 6, borderRadius: 999, background: u.color }} />
            <span>{u.name}</span>
            {orderCount > 0 && <span style={{ opacity: 0.7, fontSize: 12 }}>·{orderCount}</span>}
          </div>
        );
      })}
    </div>
  );
}

function SearchBar({ value, onChange }) {
  return (
    <div style={{
      padding: '10px 16px', background: '#f6efe0',
      borderBottom: '1px solid rgba(26,20,16,0.15)', flex: '0 0 auto',
      display: 'flex', alignItems: 'center', gap: 10,
    }}>
      <div style={{
        fontFamily: '"Noto Serif JP", serif', fontSize: 16, color: '#5a4a3a', flex: '0 0 auto',
      }}>検</div>
      <input
        value={value}
        onChange={e => onChange(e.target.value)}
        placeholder="Rechercher un plat…"
        style={{
          flex: 1, padding: '6px 8px',
          border: 'none', borderBottom: '1px solid rgba(26,20,16,0.4)',
          background: 'transparent',
          fontFamily: '"Cormorant Garamond", serif', fontSize: 15,
          color: '#1a1410', outline: 'none',
        }}
      />
      {value && (
        <button onClick={() => onChange('')} style={{
          background: 'transparent', border: 'none', cursor: 'pointer',
          fontFamily: '"Cormorant Garamond", serif', fontSize: 18, color: '#1a1410',
        }}>×</button>
      )}
    </div>
  );
}

function WashiApp() {
  const state = useStore();
  const [activeCat, setActiveCat] = useState(window.CATEGORIES[0].id);
  const [summaryOpen, setSummaryOpen] = useState(false);
  const [search, setSearch] = useState('');
  const sectionRefs = useRef({});
  const scrollRef = useRef(null);

  const itemsByCategory = useMemo(() => {
    const map = {};
    const q = search.trim().toLowerCase();
    window.MENU_DATA.forEach(item => {
      if (q && !item.nom.toLowerCase().includes(q)) return;
      if (!map[item.cat]) map[item.cat] = [];
      map[item.cat].push(item);
    });
    return map;
  }, [search]);

  if (!state.currentUser) {
    return <NameEntry onSubmit={n => window.sushiStore.setUser(n)} />;
  }

  const myOrder = state.orders[state.currentUser] || {};
  const myCount = Object.values(myOrder).reduce((s, n) => s + n, 0);

  const handleNavPick = (catId) => {
    setActiveCat(catId);
    const el = sectionRefs.current[catId];
    if (el && scrollRef.current) {
      scrollRef.current.scrollTo({ top: el.offsetTop - 60, behavior: 'smooth' });
    }
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, background: '#f6efe0',
      fontFamily: '"Cormorant Garamond", serif',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <WashiTexture />
      {/* Header */}
      <div style={{
        padding: '14px 18px 12px', display: 'flex', alignItems: 'center',
        justifyContent: 'space-between', borderBottom: '1px solid #1a1410',
        background: '#f6efe0', position: 'relative', zIndex: 1, flex: '0 0 auto',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <Hanko size={36} char="寿" rotate={-3} animate={true} />
          <div>
            <div style={{
              fontFamily: '"Noto Serif JP", serif', fontSize: 18, color: '#1a1410',
              lineHeight: 1, letterSpacing: '0.05em',
            }}>月見</div>
            <div style={{
              fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
              fontSize: 11, color: '#5a4a3a', letterSpacing: '0.25em',
              textTransform: 'uppercase', marginTop: 2,
            }}>Tsukimi · Commande</div>
          </div>
        </div>
        <button onClick={() => window.sushiStore.leaveSession()} style={{
          padding: '6px 12px', border: '1px solid #1a1410', background: 'transparent',
          fontFamily: '"Cormorant Garamond", serif', fontSize: 12,
          color: '#1a1410', cursor: 'pointer',
          letterSpacing: '0.1em', textTransform: 'uppercase',
        }}>{state.currentUser}</button>
      </div>

      <PeopleStrip />
      <SearchBar value={search} onChange={setSearch} />
      <CategoryNav active={activeCat} onPick={handleNavPick} />

      {/* Menu list */}
      <div ref={scrollRef} style={{
        flex: 1, overflowY: 'auto', padding: '0 20px 100px',
        position: 'relative', zIndex: 1,
      }}>
        {window.CATEGORIES.map(cat => {
          const items = itemsByCategory[cat.id] || [];
          if (search && items.length === 0) return null;
          return (
            <div
              key={cat.id}
              ref={el => sectionRefs.current[cat.id] = el}
              style={{ paddingTop: 28, scrollMarginTop: 60 }}
            >
              <div style={{
                display: 'flex', alignItems: 'baseline', gap: 16,
                borderBottom: '1.5px solid #1a1410', paddingBottom: 8, marginBottom: 4,
              }}>
                <div style={{
                  fontFamily: '"Noto Serif JP", serif', fontSize: 32, color: '#1a1410',
                  fontWeight: 700, lineHeight: 1, letterSpacing: '-0.02em',
                }}>{cat.kanji}</div>
                <div style={{
                  fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
                  fontSize: 14, color: '#5a4a3a', letterSpacing: '0.25em',
                  textTransform: 'uppercase',
                }}>{cat.romaji}</div>
                <div style={{ flex: 1 }} />
                <div style={{
                  fontFamily: '"Cormorant Garamond", serif', fontSize: 13, color: '#5a4a3a',
                  fontStyle: 'italic',
                }}>{cat.label}</div>
              </div>
              {items.map(item => (
                <MenuItem
                  key={item.num}
                  item={item}
                  qty={myOrder[item.num] || 0}
                  orderers={Object.entries(state.orders).filter(([n, o]) => o[item.num]).map(([n, o]) => ({
                    name: n, qty: o[item.num], color: state.users[n]?.color || '#999'
                  }))}
                  currentUser={state.currentUser}
                  onInc={() => window.sushiStore.increment(item.num, 1)}
                  onDec={() => window.sushiStore.increment(item.num, -1)}
                  search={search}
                />
              ))}
            </div>
          );
        })}
        {search && Object.values(itemsByCategory).every(arr => arr.length === 0) && (
          <div style={{
            textAlign: 'center', padding: '60px 20px',
            fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
            fontSize: 16, color: '#5a4a3a',
          }}>Aucun plat ne correspond à « {search} »</div>
        )}

        {/* Signature footer */}
        <div style={{
          marginTop: 60, paddingTop: 24, paddingBottom: 8,
          borderTop: '1px solid rgba(26,20,16,0.15)',
          textAlign: 'center',
        }}>
          <div style={{
            fontFamily: '"Noto Serif JP", serif', fontSize: 16,
            color: '#1a1410', letterSpacing: '0.1em', marginBottom: 6,
          }}>月</div>
          <div style={{
            fontFamily: '"Cormorant Garamond", serif', fontStyle: 'italic',
            fontSize: 13, color: '#5a4a3a',
            letterSpacing: '0.25em', textTransform: 'uppercase',
          }}>Moon AI Corp</div>
          <div style={{
            width: 24, height: 1, background: 'rgba(26,20,16,0.25)',
            margin: '10px auto 0',
          }} />
        </div>
      </div>

      {/* Floating order button */}
      <button onClick={() => setSummaryOpen(true)} style={{
        position: 'absolute', bottom: 20, left: 20, right: 20,
        padding: '16px 20px',
        background: '#1a1410', color: '#f6efe0', border: 'none',
        fontFamily: '"Cormorant Garamond", serif',
        fontSize: 14, letterSpacing: '0.3em', textTransform: 'uppercase',
        cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        boxShadow: '0 4px 20px rgba(26,20,16,0.25)',
        zIndex: 10,
      }}>
        <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontFamily: '"Noto Serif JP", serif', fontSize: 18, letterSpacing: 0 }}>注文</span>
          Voir la commande
        </span>
        <span style={{
          padding: '2px 10px', background: '#c9342a', borderRadius: 0,
          fontSize: 13, fontWeight: 600,
        }}>{myCount} · table</span>
      </button>

      <SummarySheet
        open={summaryOpen}
        onClose={() => setSummaryOpen(false)}
        onReset={() => { window.sushiStore.resetAll(); setSummaryOpen(false); }}
      />
    </div>
  );
}

window.WashiApp = WashiApp;