// Mella — Public Queue page (mobile-first, themeable)
// Anchored on the pet-portrait ICP register: art-led, editorial, conversational.
// Shared foundation lives in mella-kit.jsx.

const { useState, useEffect } = React;

// Shared design kit — theme, painted art, phone shell, form bits, bottom sheet.
const { hexToRgba, ACCENTS, TONES, FONTS, MONO, PALS, ART, resolveTheme, Painting, Field, inp, ta, PhoneShell } = window;

/* -------------------------------------------------------- state vocabulary */
function stateConfig(state) {
  switch (state) {
    case 'fresh':   return { open:5, live:true,  big:'5 of 5 slots open', sub:'books just reopened, wide open', cta:'Request a slot', kind:'request', tone:'go' };
    case 'limited': return { open:1, live:true,  big:'1 slot left', sub:'closing soon, booking into July', cta:'Request the last slot', kind:'request', tone:'go' };
    case 'closed':  return { open:0, live:false, big:'Slots closed', sub:'waitlist open, reopening in August', cta:'Join the waitlist', kind:'waitlist', tone:'rest' };
    case 'full':    return { open:0, live:false, big:'Fully booked', sub:'next batch opens late August', cta:'Join the waitlist', kind:'waitlist', tone:'rest' };
    default:        return { open:2, live:true,  big:'2 of 5 slots open', sub:'booking into July', cta:'Request a slot', kind:'request', tone:'go' };
  }
}

const QUEUE = [
  { n:'01', name:'Maple',          meta:'memorial, Saint Bernard',    status:'painting',          pct:0.72, art:ART.stbHead },
  { n:'02', name:'Bodhi',          meta:'Leonberger, 11×14',          status:'sketch',            pct:0.24, art:ART.leonberger },
  { n:'03', name:'Otto',           meta:'Maltese, 8×10',              status:'awaiting approval', pct:0.92, art:ART.terrierUp },
  { n:'04', name:'Juniper',        meta:'scruffy terrier, 9×12',      status:'painting',          pct:0.50, art:ART.affen },
  { n:'05', name:'Daisy',          meta:'Saint Bernard pup, 11×14',   status:'ready to ship',     pct:1.0,  art:ART.stbPup },
];
const STATUS_TINT = {
  'painting':          (c) => c.a,
  'sketch':            (c) => c.faint,
  'awaiting approval': () => '#B05536',
  'ready to ship':     () => '#5C6536',
};
const PIECES = [
  { name:'Maple', meta:'oil, 16×20', art:ART.stbHead },
  { name:'Otto',  meta:'oil, 8×10',  art:ART.terrierUp },
  { name:'Pepper & Beans', meta:'oil, 18×24', art:ART.twoBorzois },
];
// The full portfolio behind "see all". One entry per real painting.
const GALLERY = [
  { name:'Maple',          meta:'oil, 16×20, 2024', art:ART.stbHead,     tall:true },
  { name:'Juniper',        meta:'oil, 9×12, 2024',  art:ART.affen },
  { name:'Otto',           meta:'oil, 8×10, 2024',  art:ART.terrierUp,   tall:true },
  { name:'Daisy',          meta:'oil, 11×14, 2024', art:ART.stbPup,      tall:true },
  { name:'Pepper & Beans', meta:'oil, 18×24, 2023', art:ART.twoBorzois },
  { name:'The barn litter',meta:'oil, 16×20, 2023', art:ART.litterBarn },
  { name:'Scout & Rhett',  meta:'oil, 20×16, 2023', art:ART.twoPointers },
  { name:'The doorway six',meta:'oil, 24×30, 2022', art:ART.litterDoor },
];

/* ------------------------------------------------------------ masonry grid */
// Balanced masonry: places each piece into the currently-shortest column so the
// columns end roughly level — fixes the ragged bottoms CSS multi-column gives.
// Uses the known art ratio (tile height ∝ 1/ratio) plus a small caption
// allowance, so it lays out correctly before any image loads.
function Masonry({ items, columns, gap = 10, style, renderItem }) {
  const cols = Array.from({ length: columns }, () => []);
  const heights = new Array(columns).fill(0);
  items.forEach((it, i) => {
    let m = 0;
    for (let k = 1; k < columns; k++) if (heights[k] < heights[m]) m = k;
    cols[m].push({ it, i });
    heights[m] += 1 / ((it.art && it.art.ratio) || 1) + 0.2; // +caption row
  });
  return (
    <div style={{ display:'flex', gap, alignItems:'flex-start', ...style }}>
      {cols.map((col, ci) => (
        <div key={ci} style={{ flex:1, minWidth:0, display:'flex', flexDirection:'column', gap }}>
          {col.map(({ it, i }) => <React.Fragment key={i}>{renderItem(it, i)}</React.Fragment>)}
        </div>
      ))}
    </div>
  );
}

/* ============================================================= the page === */
function QueuePage({ t }) {
  const c = resolveTheme(t);
  const { wide } = window.useViewport();
  const cfg = stateConfig(t.state);
  const names = !!t.showNames; // public page anonymizes by default; names are opt-in
  const sub = (t.statusNote && t.statusNote.trim()) ? t.statusNote : cfg.sub; // editable free-text primitive
  const working = QUEUE.slice(0, Math.max(0, 5 - cfg.open));
  const [sheet, setSheet] = useState(false);
  const [gallery, setGallery] = useState(false);
  const depositPct = t.depositPct || 50;   // from the artist's payment settings, not hardcoded
  const [tiers, setTiers] = useState(false);
  useEffect(() => { setTiers(t.showTiers); }, [t.showTiers]);

  const head = (size, extra) => ({
    fontFamily: c.f.head, fontWeight: c.f.hw, letterSpacing: c.f.kern,
    lineHeight: 1.04, color: c.text, margin: 0, fontSize: size, ...extra,
  });
  const eyebrow = {
    fontFamily: MONO, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase',
    color: c.faint, fontWeight: 500,
  };
  const pad = wide
    ? { padding: '0 22px', maxWidth: 640, marginLeft: 'auto', marginRight: 'auto' }
    : { padding: '0 22px' };
  const restDot = cfg.tone === 'rest';
  const dotColor = restDot ? c.faint : c.a;

  return (
    <div style={{ fontFamily: c.f.body, color: c.text, background: c.bg, position:'relative' }}>

      {/* ---------- HERO: art first ---------- */}
      <div style={{ position:'relative' }}>
        <Painting pal={ART.twoPointers.pal} src={ART.twoPointers.src} pos="center 20%" radius={0} style={{ height: wide ? 240 : 168, width:'100%' }} />
        <div style={{ position:'absolute', inset:0, background:`linear-gradient(180deg, ${hexToRgba(c.bg,0)} 40%, ${hexToRgba(c.bg,0.55)} 78%, ${c.bg} 100%)` }} />
      </div>

      <div style={{ ...pad, marginTop: -42, position:'relative' }}>
        <div style={{ display:'flex', alignItems:'flex-end', gap:14 }}>
          <Painting pal={ART.leonberger.pal} src={ART.leonberger.src} pos={ART.leonberger.pos} radius={'50%'} style={{
            width:76, height:76, flexShrink:0, border:`3px solid ${c.bg}`, boxShadow:`0 6px 16px ${hexToRgba('#000', c.dark?0.5:0.18)}`,
          }} />
          <div style={{ paddingBottom: 6 }}>
            <div style={{ ...eyebrow, color: c.a, marginBottom: 5, whiteSpace:'nowrap' }}>Oil portraits</div>
          </div>
        </div>

        <h1 style={head(40 * c.f.big + 8, { marginTop: 14 })}>Iris Sandoval</h1>
        <p style={{ margin:'9px 0 0', fontSize: 15.5, lineHeight: 1.5, color: c.soft, maxWidth: wide ? 'none' : '30ch', whiteSpace: wide ? 'nowrap' : 'normal' }}>
          Hand-painted portraits of your pet, in oil on canvas, from your favorite photo.
        </p>
        <div style={{ ...eyebrow, marginTop: 12, color: c.faint, display:'flex', gap:8, alignItems:'center' }}>
          <span>Portland, OR</span><span>est. 2016</span>
        </div>

        {/* status line — the one line */}
        <div style={{
          marginTop: 18, background: c.surface, border:`1px solid ${c.rule}`, borderRadius: 12,
          padding: '14px 16px', boxShadow:`0 1px 0 ${hexToRgba('#000',c.dark?0.3:0.02)}`,
        }}>
          <div style={{ display:'flex', alignItems:'flex-start', gap:10 }}>
            <span style={{ position:'relative', width:9, height:9, marginTop:8, flexShrink:0 }}>
              <span style={{ position:'absolute', inset:0, borderRadius:'50%', background:dotColor }} />
              {cfg.live && <span style={{ position:'absolute', inset:-4, borderRadius:'50%', border:`1.5px solid ${hexToRgba(dotColor,0.4)}`, animation:'mq-pulse 2.4s ease-out infinite' }} />}
            </span>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={ t.statusSerif
                ? { fontFamily:c.f.head, fontWeight:c.f.hw, fontSize: 22, lineHeight:1.12, letterSpacing:c.f.kern, color:c.text }
                : { fontFamily:c.f.body, fontWeight:500, fontSize: 20, lineHeight:1.15, letterSpacing:'-0.01em', color:c.text } }>{cfg.big}</div>
              <div style={{ marginTop: 4, fontSize: 13.5, color: c.muted }}>{sub}</div>
            </div>
          </div>
          {/* the wedge: auto-update, never hand-typed */}
          <div style={{ marginLeft: 19, marginTop: 9, ...eyebrow, fontSize: 9.5, color: c.faint, display:'flex', alignItems:'center', gap:6 }}>
            <span style={{ width:5, height:5, borderRadius:'50%', background: cfg.live ? c.a : c.faint }} />
            updates itself, last change 4 min ago
          </div>
        </div>
      </div>

      {/* ---------- LIVE QUEUE: transparency ---------- */}
      <section style={{ ...pad, marginTop: 34 }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline' }}>
          <span style={eyebrow}>The queue</span>
          <span style={{ ...eyebrow, color: c.faint }}>{5 - cfg.open} working, {cfg.open} open</span>
        </div>
        {/* slot meter */}
        <div style={{ display:'flex', gap:6, marginTop: 12 }}>
          {[0,1,2,3,4].map(i => {
            const filled = i < (5 - cfg.open);
            return <div key={i} style={{
              flex:1, height:7, borderRadius:99,
              background: filled ? c.a : 'transparent',
              border: filled ? 'none' : `1.5px dashed ${c.rule}`,
              opacity: filled ? (1 - i*0.08) : 1,
            }} />;
          })}
        </div>

        {/* current work, numbered = where you'd land */}
        <div style={{ marginTop: 16, display:'flex', flexDirection:'column', gap:10 }}>
          {working.length === 0 && cfg.open > 0 && (
            <div style={{ textAlign:'center', padding:'18px 16px', border:`1px dashed ${c.rule}`, borderRadius:12, background:c.sunk }}>
              <div style={{ fontFamily:c.f.body, fontWeight:500, fontSize:15, letterSpacing:'-0.005em', color:c.text }}>No one's ahead of you.</div>
              <div style={{ fontSize:13, color:c.muted, marginTop:3 }}>Books just opened. Yours could be the first piece in the batch.</div>
            </div>
          )}
          {working.map(item => {
            const tint = STATUS_TINT[item.status](c);
            return (
              <div key={item.n} style={{
                display:'flex', alignItems:'center', gap:12,
                background:c.surface, border:`1px solid ${c.rule}`, borderRadius:12, padding:'10px 12px',
              }}>
                {names ? (
                  <Painting pal={item.art.pal} src={item.art.src} pos={item.art.pos} radius={8} style={{ width:46, height:46, flexShrink:0 }} />
                ) : (
                  <div style={{ width:46, height:46, flexShrink:0, borderRadius:8, background:c.sunk, border:`1px solid ${c.rule}`, display:'flex', alignItems:'center', justifyContent:'center', fontFamily:MONO, fontSize:13, color:c.faint }}>{item.n}</div>
                )}
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontFamily:c.f.body, fontWeight:500, fontSize:15, letterSpacing:'-0.005em', color:c.text, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
                    {names && <span style={{ fontFamily:MONO, fontSize:10, color:c.faint, marginRight:7 }}>{item.n}</span>}
                    {names ? item.name : ('Slot ' + item.n)}
                  </div>
                  <div style={{ fontSize:11.5, color:c.muted, marginTop:1 }}>{names ? item.meta : 'in the studio'}</div>
                </div>
                <span style={{
                  fontFamily:MONO, fontSize:9, letterSpacing:'0.08em', textTransform:'uppercase',
                  color: tint, background: hexToRgba(tint, c.dark?0.22:0.12), borderRadius:99, padding:'4px 9px', whiteSpace:'nowrap', flexShrink:0,
                }}>{item.status}</span>
              </div>
            );
          })}
          {/* the open slot — your turn */}
          {cfg.open > 0 ? (
            <button onClick={() => setSheet(true)} style={{
              display:'flex', alignItems:'center', gap:12, textAlign:'left', cursor:'pointer',
              background:'transparent', border:`1.5px dashed ${hexToRgba(c.a,0.55)}`, borderRadius:12, padding:'12px', fontFamily:c.f.body,
            }}>
              <div style={{ width:46, height:46, flexShrink:0, borderRadius:8, border:`1.5px dashed ${c.rule}`,
                display:'flex', alignItems:'center', justifyContent:'center', color:c.a, fontSize:22, lineHeight:1 }}>+</div>
              <div style={{ flex:1 }}>
                <div style={{ fontFamily:c.f.body, fontWeight:500, fontSize:15, letterSpacing:'-0.005em', color:c.text }}>An open slot. Yours.</div>
                <div style={{ fontSize:11.5, color:c.muted, marginTop:1 }}>next to start, about 2 to 3 weeks</div>
              </div>
              <span style={{ color:c.a, fontSize:18 }}>→</span>
            </button>
          ) : (
            <div style={{ textAlign:'center', padding:'14px', border:`1px solid ${c.rule}`, borderRadius:12, background:c.sunk }}>
              <div style={{ fontSize:13.5, color:c.soft }}>The book is closed for now. <span style={{ color:c.a }}>Join the waitlist</span> and you'll be first to hear.</div>
            </div>
          )}
        </div>
      </section>

      {/* ---------- PORTFOLIO: bigger, earlier ---------- */}
      <section style={{ marginTop: 38 }}>
        <div style={{ ...pad, display:'flex', justifyContent:'space-between', alignItems:'baseline' }}>
          <span style={eyebrow}>Recent work</span>
          <button onClick={() => setGallery(true)} style={{ ...eyebrow, color:c.a, background:'none', border:'none', cursor:'pointer', padding:0 }}>see all {GALLERY.length} →</button>
        </div>
        <Masonry items={PIECES} columns={wide ? 3 : 2} gap={10} style={{ ...pad, marginTop: 12 }}
          renderItem={(p) => (
            <div>
              <Painting pal={p.art.pal} src={p.art.src} pos={p.art.pos} radius={10} style={{ width:'100%', aspectRatio: '4 / 5' }} />
              <div style={{ display:'flex', justifyContent:'space-between', marginTop:6, alignItems:'baseline' }}>
                <span style={{ fontFamily:c.f.body, fontWeight:500, fontSize:14, letterSpacing:'-0.005em', color:c.text }}>{p.name}</span>
                <span style={{ fontFamily:MONO, fontSize:9.5, color:c.faint }}>{p.meta}</span>
              </div>
            </div>
          )} />
      </section>

      {/* ---------- SOFT PRICING ---------- */}
      <section style={{ ...pad, marginTop: 26 }}>
        <div style={{ background:c.sunk, border:`1px solid ${c.rule}`, borderRadius:14, padding:'18px 18px 16px' }}>
          <span style={eyebrow}>Commissions</span>
          <div style={{ marginTop: 8, display:'flex', alignItems:'baseline', gap:8, flexWrap:'wrap' }}>
            <span style={head(28 * c.f.big + 6)}>Starting at $260</span>
          </div>
          <p style={{ margin:'8px 0 0', fontSize: 14, lineHeight:1.55, color:c.soft }}>
            Every piece is quoted by hand. Size, number of pets, and detail all matter. Tell me what you have in mind and I'll send a price.
          </p>
          <button onClick={() => setTiers(v => !v)} style={{
            marginTop: 12, background:'transparent', border:'none', cursor:'pointer', padding:0,
            fontFamily:MONO, fontSize:10.5, letterSpacing:'0.06em', color:c.a, display:'flex', alignItems:'center', gap:6,
          }}>
            {tiers ? 'Hide typical sizes' : 'See typical sizes'} <span style={{ transform: tiers?'rotate(180deg)':'none', transition:'transform .2s' }}>⌄</span>
          </button>
          {tiers && (
            <div style={{ marginTop: 12, borderTop:`1px solid ${c.rule}`, paddingTop: 12, display:'flex', flexDirection:'column', gap:9 }}>
              {[['8 × 10', 'single pet', 'from $260'], ['11 × 14', 'single pet', 'from $340'], ['11 × 14', 'two pets', 'from $440'], ['16 × 20', 'statement piece', 'from $620']].map((r,i) => (
                <div key={i} style={{ display:'flex', alignItems:'baseline', gap:8 }}>
                  <span style={{ fontFamily:MONO, fontSize:12, color:c.text, width:64 }}>{r[0]}</span>
                  <span style={{ fontSize:13, color:c.muted, flex:1 }}>{r[1]}</span>
                  <span style={{ fontFamily:MONO, fontSize:12, color:c.a }}>{r[2]}</span>
                </div>
              ))}
              <div style={{ fontSize:12, color:c.faint, marginTop:2 }}>{depositPct}% deposit to start, balance when it ships.</div>
            </div>
          )}
        </div>
      </section>

      {/* ---------- QUIET TRUST ROW ---------- */}
      <section style={{ ...pad, marginTop: 28 }}>
        <div style={{ display:'flex', flexDirection:'column', gap:0, borderTop:`1px solid ${c.rule}` }}>
          {[
            ['Painted by hand', 'No AI, ever. No NFTs. Real oil on real canvas, yours to keep.'],
            ['Pay in two steps', `${depositPct}% deposit to start, balance when it ships. Secure checkout via Stripe.`],
            ['You see every step', 'A private link with work-in-progress photos. Approve before it ships.'],
          ].map((r,i) => (
            <div key={i} style={{ display:'flex', gap:13, padding:'15px 0', borderBottom:`1px solid ${c.rule}` }}>
              <span style={{ fontFamily:MONO, fontSize:11, color:c.a, marginTop:2 }}>{String(i+1).padStart(2,'0')}</span>
              <div>
                <div style={{ fontFamily:c.f.body, fontWeight:600, fontSize:15, letterSpacing:'-0.01em', color:c.text }}>{r[0]}</div>
                <div style={{ fontSize:13, color:c.muted, marginTop:2, lineHeight:1.5 }}>{r[1]}</div>
              </div>
            </div>
          ))}
        </div>
      </section>

      {/* ---------- FOOTER ---------- */}
      <footer style={{ ...pad, marginTop: 22, paddingBottom: 120, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
        <span style={{ fontFamily:MONO, fontSize:10, color:c.faint, letterSpacing:'0.04em' }}>iris @ mella.studio</span>
        <span style={{ fontFamily:"'Instrument Serif', serif", fontSize:17, color:c.faint }}>
          on mella<span style={{ color:c.a }}>.</span>
        </span>
      </footer>

      {/* ---------- STICKY ACTION BAR ---------- */}
      <div style={{
        position:'sticky', bottom:0, padding:'12px 18px calc(12px + env(safe-area-inset-bottom))',
        background: hexToRgba(c.bg, 0.86), backdropFilter:'blur(12px)', borderTop:`1px solid ${c.rule}`,
        display:'flex', alignItems:'center', gap:12,
      }}>
        <div style={{ lineHeight:1.1 }}>
          <div style={{ fontFamily:MONO, fontSize:9, letterSpacing:'0.1em', textTransform:'uppercase', color:c.faint }}>{restDot ? 'Waitlist' : 'From'}</div>
          <div style={{ fontFamily:c.f.body, fontWeight:700, fontSize:18, color:c.text, letterSpacing:'-0.02em' }}>{restDot ? 'open' : '$260'}</div>
        </div>
        <button onClick={() => setSheet(true)} style={{
          flex:1, background:c.a, color:c.aOn, border:'none', borderRadius:11, padding:'15px',
          fontFamily:c.f.body, fontSize:15, fontWeight:600, letterSpacing:'0.01em', cursor:'pointer',
          display:'flex', alignItems:'center', justifyContent:'center', gap:8,
          boxShadow:`0 8px 22px -8px ${hexToRgba(c.a,0.6)}`,
        }}>{cfg.cta} <span style={{ fontSize:17 }}>→</span></button>
      </div>

      {sheet && <IntakeSheet c={c} cfg={cfg} onClose={() => setSheet(false)} />}
      {gallery && <GallerySheet c={c} onClose={() => setGallery(false)} />}
    </div>
  );
}

/* ------------------------------------------------------ portfolio gallery */
function GallerySheet({ c, onClose }) {
  const [focus, setFocus] = useState(null);
  const { BottomSheet } = window;
  const eyebrow = { fontFamily: MONO, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: c.faint, fontWeight: 500 };
  return (
    <BottomSheet c={c} onClose={onClose}>
      {focus === null ? (
        <React.Fragment>
          <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between', marginBottom:14 }}>
            <div>
              <div style={{ ...eyebrow, color:c.a }}>Iris Sandoval</div>
              <div style={{ fontFamily:c.f.head, fontWeight:c.f.hw, fontSize:24, letterSpacing:c.f.kern, color:c.text, marginTop:2 }}>The full portfolio</div>
            </div>
            <span onClick={onClose} style={{ cursor:'pointer', color:c.faint, fontSize:22 }}>×</span>
          </div>
          <Masonry items={GALLERY} columns={2} gap={10}
            renderItem={(p, i) => (
              <div onClick={() => setFocus(i)} style={{ cursor:'pointer' }}>
                <Painting pal={p.art.pal} src={p.art.src} pos={p.art.pos} radius={10} style={{ width:'100%', aspectRatio: String(p.art.ratio) }} />
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginTop:6 }}>
                  <span style={{ fontFamily:c.f.body, fontWeight:500, fontSize:14, letterSpacing:'-0.005em', color:c.text }}>{p.name}</span>
                  <span style={{ fontFamily:MONO, fontSize:9, color:c.faint }}>{p.meta}</span>
                </div>
              </div>
            )} />
        </React.Fragment>
      ) : (
        <React.Fragment>
          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:14 }}>
            <button onClick={() => setFocus(null)} style={{ ...eyebrow, color:c.a, background:'none', border:'none', cursor:'pointer', padding:0 }}>← all work</button>
            <span onClick={onClose} style={{ cursor:'pointer', color:c.faint, fontSize:22 }}>×</span>
          </div>
          <Painting pal={GALLERY[focus].art.pal} src={GALLERY[focus].art.src} pos={GALLERY[focus].art.pos} radius={12} style={{ width:'100%', aspectRatio: String(GALLERY[focus].art.ratio) }} />
          <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between', marginTop:12 }}>
            <span style={{ fontFamily:c.f.body, fontWeight:600, fontSize:20, letterSpacing:'-0.01em', color:c.text }}>{GALLERY[focus].name}</span>
            <span style={{ fontFamily:MONO, fontSize:11, color:c.faint }}>{GALLERY[focus].meta}</span>
          </div>
          <p style={{ fontSize:13, color:c.muted, lineHeight:1.5, margin:'8px 0 0' }}>A hand-painted commission. Want one like this? Close this and request a slot.</p>
        </React.Fragment>
      )}
    </BottomSheet>
  );
}

/* ----------------------------------------------- conversational intake --- */
function IntakeSheet({ c, cfg, onClose }) {
  const [sent, setSent] = useState(false);
  const waitlist = cfg.kind === 'waitlist';
  const { BottomSheet } = window;
  return (
    <BottomSheet c={c} onClose={onClose}>
      {sent ? (
        <div style={{ textAlign:'center', padding:'18px 6px 8px' }}>
          <div style={{ width:54, height:54, borderRadius:'50%', background:c.aSoft, color:c.a, display:'flex', alignItems:'center', justifyContent:'center', fontSize:26, margin:'0 auto 16px' }}>✓</div>
          <h3 style={{ fontFamily:c.f.head, fontWeight:c.f.hw, fontSize:26, letterSpacing:c.f.kern, color:c.text, margin:0 }}>
            {waitlist ? "You're on the list." : 'Got it, thank you.'}
          </h3>
          <p style={{ fontSize:14.5, color:c.muted, lineHeight:1.55, margin:'10px auto 0', maxWidth:'30ch' }}>
            {waitlist
              ? "I'll email you the moment a slot opens up. No spam, promise."
              : "I'll read this and email you a quote within a few days. Talk soon!"}
          </p>
          <button onClick={onClose} style={{ marginTop:22, background:c.a, color:c.aOn, border:'none', borderRadius:11, padding:'14px 26px', fontFamily:c.f.body, fontSize:15, fontWeight:600, cursor:'pointer' }}>Done</button>
        </div>
      ) : (
        <React.Fragment>
          <div style={{ fontFamily:MONO, fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:c.a }}>
            {waitlist ? 'Join the waitlist' : 'Request a slot'}
          </div>
          <h3 style={{ fontFamily:c.f.body, fontWeight:600, fontSize:24, letterSpacing:'-0.015em', color:c.text, margin:'8px 0 0' }}>
            {waitlist ? 'I’ll save you a spot.' : 'Tell me about your pet.'}
          </h3>
          <p style={{ fontSize:14, color:c.muted, lineHeight:1.5, margin:'8px 0 18px' }}>
            {waitlist
              ? 'Leave your email and a note. You’ll be first in line when the book reopens.'
              : 'No fussy dropdowns. Just tell me what you’re imagining, and I’ll take it from there.'}
          </p>

          {!waitlist && (
            <Field c={c} label="Your pet, in your words">
              <textarea rows={3} placeholder="Biscuit was our golden. I'd love an 11×14 from this beach photo…" style={ta(c)} />
            </Field>
          )}
          <div style={{ display:'flex', gap:10 }}>
            <Field c={c} label="Name" flex><input placeholder="First name" style={inp(c)} /></Field>
            <Field c={c} label="Email" flex><input placeholder="you@email.com" style={inp(c)} /></Field>
          </div>
          {!waitlist && (
            <Field c={c} label="A reference photo, optional">
              <div style={{ border:`1.5px dashed ${c.rule}`, borderRadius:12, padding:'18px', textAlign:'center', color:c.faint, fontSize:13, background:c.sunk }}>
                <span style={{ color:c.a, fontSize:18, display:'block', marginBottom:4 }}>↑</span>
                Drag a photo here, or tap to add
              </div>
            </Field>
          )}

          <button onClick={() => setSent(true)} style={{
            marginTop: 8, width:'100%', background:c.a, color:c.aOn, border:'none', borderRadius:12, padding:'16px',
            fontFamily:c.f.body, fontSize:15.5, fontWeight:600, cursor:'pointer', display:'flex', justifyContent:'center', alignItems:'center', gap:8,
          }}>{waitlist ? 'Join the waitlist' : 'Send my request'} <span style={{ fontSize:17 }}>→</span></button>
          <p style={{ textAlign:'center', fontSize:11.5, color:c.faint, margin:'12px 0 0' }}>
            Goes straight to Iris, usually a reply within a few days
          </p>
        </React.Fragment>
      )}
    </BottomSheet>
  );
}

/* ============================================================ app + tweaks */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "teal",
  "tone": "warm",
  "type": "editorial",
  "state": "open",
  "showTiers": false,
  "showNames": false,
  "statusNote": "",
  "depositPct": 50,
  "statusSerif": false
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  return (
    <React.Fragment>
      <PhoneShell t={t} url="mella.studio/iris"><QueuePage t={t} /></PhoneShell>
      <TweaksPanel title="Tweaks">
        <TweakSection label="The artist's brand" />
        <TweakColor label="Accent" value={ACCENTS[t.accent]}
          options={Object.values(ACCENTS)}
          onChange={(v) => setTweak('accent', Object.keys(ACCENTS).find(k => ACCENTS[k] === v) || 'teal')} />
        <TweakRadio label="Background" value={t.tone} options={['warm','paper','dusk']}
          onChange={(v) => setTweak('tone', v)} />
        <TweakSelect label="Type" value={t.type}
          options={[['editorial','Editorial serif'],['classic','Classic serif'],['clean','Clean sans']]}
          onChange={(v) => setTweak('type', v)} />
        <TweakSection label="Queue state" />
        <TweakSlider label="Deposit %" min={0} max={100} step={5} value={t.depositPct || 50}
          onChange={(v) => setTweak('depositPct', v)} />
        <TweakSelect label="Status" value={t.state}
          options={[['fresh','Wide open, 5 of 5'],['open','Open, 2 of 5'],['limited','Limited, 1 left'],['closed','Closed + waitlist'],['full','Fully booked']]}
          onChange={(v) => setTweak('state', v)} />
        <TweakText label="Status note (artist-editable)" value={t.statusNote}
          placeholder="booking into July" onChange={(v) => setTweak('statusNote', v)} />
        <TweakToggle label="Show client names (opt-in)" value={t.showNames}
          onChange={(v) => setTweak('showNames', v)} />
        <TweakToggle label="Show price tiers by default" value={t.showTiers}
          onChange={(v) => setTweak('showTiers', v)} />
        <TweakToggle label="Status title in serif" value={t.statusSerif}
          onChange={(v) => setTweak('statusSerif', v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
