// screens-profile.jsx — orders history, profile/rewards, notifications

// ─── Orders history screen ─────────────────────────────────────────
function OrdersScreen({ app }) {
  const [filter, setFilter] = React.useState('all');
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    const t = setTimeout(() => setLoading(false), 500);
    return () => clearTimeout(t);
  }, []);

  // Add the active order in progress, if any
  const activeRow = app.activeOrder && !PAST_ORDERS.find(o => o.id === app.activeOrder.id)
    ? [{
        id: app.activeOrder.id,
        restaurantId: app.activeOrder.restaurantId,
        date: 'Just now',
        total: app.activeOrder.total,
        status: 'in_progress',
        items: app.activeOrder.items.length,
      }]
    : [];

  const orders = [...activeRow, ...PAST_ORDERS];

  const filtered = orders.filter(o => {
    if (filter === 'all') return true;
    if (filter === 'active') return o.status === 'in_progress';
    if (filter === 'delivered') return o.status === 'delivered';
    if (filter === 'cancelled') return o.status === 'cancelled' || o.status === 'refunded';
    return true;
  });

  return (
    <Screen>
      <AppHeader onProfile={() => app.nav('profile')} onBell={() => app.nav('notifications')} initials={PROFILE.initials}/>

      <div style={{ padding: '8px 20px 14px' }}>
        <Eyebrow>Your orders</Eyebrow>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 28, letterSpacing: '-0.01em', marginTop: 6 }}>The trail so far.</div>
      </div>

      {/* Filter chips */}
      <Chips items={['All', 'Active', 'Delivered', 'Cancelled']} active={['All','Active','Delivered','Cancelled'][['all','active','delivered','cancelled'].indexOf(filter)]} onChange={(c) => setFilter(c.toLowerCase())}/>

      <RateNudge app={app}/>

      <div style={{ padding: '18px 20px max(132px, calc(env(safe-area-inset-bottom, 0px) + 132px))', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {loading
          ? [0,1,2].map(i => <OrderRowSkeleton key={i}/>)
          : filtered.length === 0
            ? <EmptyState title="No orders to show" body="Filter empty? Pick a different one, or place your first order."/>
            : filtered.map(o => <OrderRow key={o.id} order={o} app={app}/>)
        }
      </div>
    </Screen>
  );
}

// ─── Rate nudge — unrated delivered orders ──────────────────────
function RateNudge({ app }) {
  const reviewedIds = new Set(MY_REVIEWS.map(rv => rv.restaurantId));
  const [dismissed, setDismissed] = React.useState(false);
  const [rateOrder, setRateOrder] = React.useState(null);
  const [rated, setRated] = React.useState(() => new Set());
  const [stars, setStars] = React.useState(0);
  const unrated = PAST_ORDERS.find(o => o.status === 'delivered' && !reviewedIds.has(o.restaurantId) && !rated.has(o.id));
  if (dismissed || !unrated) return null;
  const r = RESTAURANT_LOOKUP[unrated.restaurantId];
  return (
    <>
      <div style={{ margin: '14px 20px 0', padding: '13px 15px', borderRadius: 16, background: 'linear-gradient(125deg,#3A1F11 0%,#1B120D 100%)', color: 'var(--dust-cream)', display: 'flex', alignItems: 'center', gap: 12, position: 'relative', overflow: 'hidden' }}>
        <div style={{ position: 'absolute', right: -14, bottom: -16, opacity: 0.25 }}><Bull size={72}/></div>
        <div style={{ width: 38, height: 38, borderRadius: 11, background: 'rgba(242,140,27,0.16)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Ico.star c="var(--sun-orange)" s={18}/></div>
        <div style={{ flex: 1, minWidth: 0, position: 'relative' }}>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 13 }}>How was {r?.name}?</div>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 11, color: '#C9B7AA', marginTop: 2 }}>Rate your {unrated.date} ride · +100 XP</div>
        </div>
        <button onClick={() => { setStars(0); setRateOrder(unrated); }} style={{ background: 'var(--brand-orange)', color: '#fff', border: 'none', padding: '8px 14px', borderRadius: 10, fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 12, cursor: 'pointer', boxShadow: 'var(--shadow-orange)', flexShrink: 0 }}>Rate</button>
        <button onClick={() => setDismissed(true)} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 4, display: 'flex', flexShrink: 0 }}><Ico.x c="#9F8979" s={14}/></button>
      </div>
      <BottomSheet open={!!rateOrder} onClose={() => setRateOrder(null)} title={r ? `Rate ${r.name}` : 'Rate your ride'}>
        <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--warm-stone)', lineHeight: 1.5 }}>Your {unrated.date} order · {unrated.items} items · £{unrated.total.toFixed(2)}. Honest takes help the kitchen and the next hungry wrangler.</div>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'center', padding: '6px 0' }}>
            {[1,2,3,4,5].map(n => (
              <button key={n} onClick={() => setStars(n)} style={{ background: 'transparent', border: 'none', cursor: 'pointer', padding: 4, transform: stars >= n ? 'scale(1.1)' : 'scale(1)', transition: 'transform 180ms var(--ease-out)' }}>
                <Ico.star c={stars >= n ? 'var(--sun-orange)' : 'var(--soft-line)'} s={34}/>
              </button>
            ))}
          </div>
          <Button kind="accent" full size="lg" disabled={stars === 0} onClick={() => {
            setRated(s => new Set([...s, rateOrder.id]));
            setRateOrder(null);
            app.toast('+100 XP — review roped in', 'success');
          }}>Submit · +100 XP</Button>
        </div>
      </BottomSheet>
    </>
  );
}

function OrderRow({ order, app }) {
  const r = RESTAURANT_LOOKUP[order.restaurantId];
  const [receiptOpen, setReceiptOpen] = React.useState(false);
  if (!r) return null;
  const statusBadge = order.status === 'in_progress'
    ? <StatusPill kind="orange">Live</StatusPill>
    : order.status === 'delivered'
      ? <StatusPill kind="live" dot={false}>Delivered</StatusPill>
      : order.status === 'cancelled'
        ? <StatusPill kind="red" dot={false}>Cancelled</StatusPill>
        : <StatusPill kind="gray" dot={false}>{order.status}</StatusPill>;

  return (
    <>
    <div data-lasso="order-history-template" onClick={() => {
      if (order.status === 'in_progress') app.nav('tracking');
      else setReceiptOpen(true);
    }} style={{
      display: 'flex', gap: 12, padding: 14, background: 'var(--bg-surface)', borderRadius: 18,
      border: '1.5px solid var(--soft-line)', cursor: 'pointer', alignItems: 'center',
    }}>
      <div data-field="restaurant-logo" style={{ width: 48, height: 48, borderRadius: 14, overflow: 'hidden', flexShrink: 0 }}>
        <FoodPh height={48} hue={r.hue || 'orange'} radius={14}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
          <div data-field="restaurant-name" style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14.5, color: 'var(--fg-primary)' }}>{r.name}</div>
          <div data-field="order-total" style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 14, color: 'var(--fg-primary)' }}>£{order.total.toFixed(2)}</div>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 4, gap: 8 }}>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)' }}>
            <span data-field="order-date">{order.date}</span> · {order.items} {order.items === 1 ? 'item' : 'items'}
          </div>
          <div data-field="order-status">{statusBadge}</div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 8, paddingTop: 8, borderTop: '1px solid var(--soft-line)' }}>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--warm-stone)' }}>#{order.id}</div>
          {order.status === 'in_progress' ? (
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11, color: 'var(--brand-orange)' }}>Track →</div>
          ) : order.status === 'delivered' ? (
            <button onClick={(e) => { e.stopPropagation(); app.openRestaurant(order.restaurantId); }} style={{
              background: 'var(--bg-warm)', color: 'var(--horse-brown)', border: 'none', padding: '6px 12px',
              borderRadius: 10, fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11, cursor: 'pointer',
            }}>Reorder</button>
          ) : (
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11, color: 'var(--warm-stone)' }}>View →</div>
          )}
        </div>
      </div>
    </div>
    <ReceiptSheet open={receiptOpen} onClose={() => setReceiptOpen(false)} order={order} app={app}/>
    </>
  );
}

// ─── Receipt sheet — full itemised receipt for a past order ───────
function ReceiptSheet({ open, onClose, order, app }) {
  const r = RESTAURANT_LOOKUP[order.restaurantId];
  const d = PAST_ORDER_DETAILS[order.id];
  if (!d || !r) return <BottomSheet open={false} onClose={onClose}/>;
  const subtotal = d.items.reduce((s, i) => s + i.price * i.qty, 0);
  const dashed = { borderTop: '1.5px dashed var(--soft-line)', margin: '4px 0' };
  return (
    <BottomSheet open={open} onClose={onClose} title="Receipt" maxHeight="90%">
      <div style={{ padding: '0 20px 28px' }}>
        {/* Receipt card — ticket look */}
        <div data-receipt-paper style={{ background: '#fff', borderRadius: 18, padding: '20px 18px', boxShadow: 'var(--shadow-md)', position: 'relative' }}>
          {/* header */}
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', gap: 6, paddingBottom: 14 }}>
            <div style={{ width: 46, height: 46, borderRadius: 14, overflow: 'hidden' }}><FoodPh height={46} hue={r.hue || 'orange'} radius={14}/></div>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 18, color: 'var(--fg-primary)' }}>{r.name}</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--warm-stone)' }}>#{order.id} · {d.time}</div>
            {d.refunded
              ? <StatusPill kind="red" dot={false}>Refunded</StatusPill>
              : <StatusPill kind="live" dot={false}>Delivered</StatusPill>}
          </div>
          <div style={dashed}/>
          {/* items */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '12px 0' }}>
            {d.items.map((it, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
                <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 12, color: 'var(--brand-orange)', width: 22, flexShrink: 0 }}>{it.qty}×</span>
                <span style={{ flex: 1, fontFamily: 'var(--font-body)', fontSize: 13.5, color: 'var(--fg-primary)' }}>{it.name}</span>
                <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 13, color: 'var(--fg-primary)' }}>£{(it.price * it.qty).toFixed(2)}</span>
              </div>
            ))}
          </div>
          <div style={dashed}/>
          {/* totals */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, padding: '12px 0' }}>
            <SummaryLine label="Subtotal" value={`£${subtotal.toFixed(2)}`}/>
            <SummaryLine label="Delivery fee" value={d.fee > 0 ? `£${d.fee.toFixed(2)}` : 'Free'}/>
            {d.tip > 0 && <SummaryLine label="Rider tip" value={`£${d.tip.toFixed(2)}`}/>}
            {d.discount > 0 && (
              <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--live-green)' }}>{d.discountLabel}</span>
                <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 13, color: 'var(--live-green)' }}>−£{d.discount.toFixed(2)}</span>
              </div>
            )}
            <SummaryLine label={d.refunded ? 'Refunded' : 'Total'} value={`£${order.total.toFixed(2)}`} bold/>
          </div>
          <div style={dashed}/>
          {/* meta */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, paddingTop: 12 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Ico.card c="var(--horse-brown)" s={14}/>
              <span style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)' }}>{d.card}</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Ico.pin c="var(--horse-brown)" s={14}/>
              <span style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)' }}>{d.address}</span>
            </div>
            {d.rider && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Ico.ride c="var(--horse-brown)" s={14}/>
                <span style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)' }}>Delivered by {d.rider}</span>
              </div>
            )}
            {d.xp > 0 && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Ico.badge c="var(--brand-orange)" s={14}/>
                <span style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)' }}>Earned <strong style={{ color: 'var(--brand-orange)' }}>+{d.xp} XP</strong> on this ride</span>
              </div>
            )}
            {d.note && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--delayed-red)', lineHeight: 1.4 }}>{d.note}</div>}
          </div>
          {/* torn edge */}
          <div aria-hidden="true" style={{ position: 'absolute', left: 8, right: 8, bottom: -5, height: 10, background: 'radial-gradient(circle at 6px 0, transparent 5px, #fff 5.5px)', backgroundSize: '14px 10px', backgroundRepeat: 'repeat-x' }}></div>
        </div>
        <div style={{ display: 'flex', gap: 10, marginTop: 20 }}>
          <Button kind="ghost" full onClick={() => { try { navigator.clipboard && navigator.clipboard.writeText(order.id); } catch (e) {} app.toast('Receipt copied for expenses', 'success'); }}>Copy receipt</Button>
          {!d.refunded && <Button kind="accent" full onClick={() => { onClose(); app.openRestaurant(order.restaurantId); }}>Reorder</Button>}
        </div>
      </div>
    </BottomSheet>
  );
}

function SummaryLine({ label, value, bold }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between' }}>
      <span style={{ fontFamily: 'var(--font-body)', fontSize: bold ? 14 : 13, color: bold ? 'var(--fg-primary)' : 'var(--warm-stone)', fontWeight: bold ? 700 : 400 }}>{label}</span>
      <span style={{ fontFamily: 'var(--font-display)', fontWeight: bold ? 900 : 700, fontSize: bold ? 16 : 13, color: 'var(--fg-primary)' }}>{value}</span>
    </div>
  );
}

function OrderRowSkeleton() {
  return (
    <div style={{ display: 'flex', gap: 12, padding: 14, background: 'var(--bg-surface)', borderRadius: 18, alignItems: 'center' }}>
      <Skeleton w={48} h={48} r={14}/>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 6 }}>
        <Skeleton w="60%" h={14}/>
        <Skeleton w="80%" h={11}/>
      </div>
    </div>
  );
}

// ─── Profile / rewards screen ───────────────────────────────────────
function ProfileScreen({ app }) {
  const liveXp = app.xp != null ? app.xp : PROFILE.xp_points;
  const p = { ...PROFILE,
    xp_points: liveXp,
    xp_to_next: Math.max(0, PROFILE.xp_total_next - liveXp),
    streak_current: app.streak != null ? app.streak : PROFILE.streak_current,
    total_orders: app.ordersCount != null ? app.ordersCount : PROFILE.total_orders,
  };
  const xpProgress = (p.xp_points / p.xp_total_next) * 100;
  const [sheet, setSheet] = React.useState(null); // 'addresses' | 'payments' | 'notifs' | 'receipts'

  // ── Signed-out state — auth entry point ─────────────────────
  if (!app.authed) {
    return (
      <Screen>
        <div style={{ background: 'var(--dark-chocolate)', color: 'var(--dust-cream)', padding: '12px 20px 26px', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', right: -20, top: -10, opacity: 0.4 }}><Bull size={150}/></div>
          <div style={{ position: 'relative', marginBottom: 6 }}><Wordmark size={18}/></div>
          <div data-customer-session-status="signed-out" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, marginTop: 12, padding: '6px 11px', borderRadius: 999, background: 'rgba(255,255,255,0.07)', border: '1.5px solid rgba(255,255,255,0.1)', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11.5, color: '#B6A595' }}>
            <span style={{ width: 7, height: 7, borderRadius: '50%', background: '#9C8A7C' }}/> Signed out
          </div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 24, lineHeight: 1.1, marginTop: 12, position: 'relative' }}>Saddle up, partner.</div>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: '#9F8979', marginTop: 7, maxWidth: 280, position: 'relative' }}>Sign in to see your orders, Trail points, streaks and rewards.</div>
        </div>
        <div data-customer-auth-entry="" style={{ padding: '20px 20px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
          <Button kind="accent" full size="lg" onClick={() => { app.setRedirectAfterAuth('profile'); app.nav('auth'); }}>Sign in</Button>
          <Button kind="ghost" full onClick={() => { app.setRedirectAfterAuth('profile'); app.nav('auth'); }}>Create an account</Button>
        </div>
        <div style={{ padding: '18px 20px max(132px, calc(env(safe-area-inset-bottom, 0px) + 132px))', fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)', textAlign: 'center', lineHeight: 1.5 }}>
          Checkout, rewards and Lucky Strike need an account — browsing the trail doesn't.
        </div>
      </Screen>
    );
  }

  return (
    <Screen>
      {/* Dark hero */}
      <div style={{
        background: 'var(--dark-chocolate)', color: 'var(--dust-cream)',
        padding: '12px 20px 28px', position: 'relative', overflow: 'hidden',
      }}>
        <div style={{ position: 'absolute', right: -20, top: -10, opacity: 0.4 }}>
          <Bull size={150}/>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 18, position: 'relative' }}>
          <Wordmark size={18}/>
          <button onClick={() => app.nav('notifications')} style={{
            width: 40, height: 40, borderRadius: 14, border: '1.5px solid rgba(255,255,255,0.08)',
            background: 'rgba(255,255,255,0.04)', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', cursor: 'pointer',
          }}>
            <Ico.bell c="var(--dust-cream)" s={18}/>
            <span style={{ position: 'absolute', top: 7, right: 7, width: 8, height: 8, borderRadius: '50%', background: 'var(--brand-orange)', border: '2px solid var(--dark-chocolate)' }}/>
          </button>
        </div>

        <div style={{ display: 'flex', gap: 14, alignItems: 'center', position: 'relative' }}>
          <div style={{
            width: 64, height: 64, borderRadius: '50%',
            background: 'linear-gradient(135deg,#F28C1B,#D85A14)', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 22,
            border: '3px solid var(--dust-cream)',
          }}>{p.initials}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div data-field="display-name" style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 20, lineHeight: 1.1 }}>{p.display_name}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 4 }}>
              <Ico.badge c="var(--brand-orange)" s={14}/>
              <span data-field="rank-label" style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 12, color: 'var(--brand-orange)', letterSpacing: '0.06em', textTransform: 'uppercase' }}>{p.rank_label}</span>
            </div>
          </div>
        </div>

        {/* XP bar */}
        <div style={{ marginTop: 18, position: 'relative' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#9F8979' }}>
              <span data-field="xp-points">{p.xp_points.toLocaleString()}</span> XP
            </div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: '#9F8979' }}>
              <span data-field="xp-to-next">{p.xp_to_next}</span> to Trail Boss
            </div>
          </div>
          <div style={{ height: 8, borderRadius: 4, background: 'rgba(255,255,255,0.08)', overflow: 'hidden' }}>
            <div data-lasso="xp-bar-fill" style={{
              height: '100%', width: `${xpProgress}%`,
              background: 'linear-gradient(90deg,#F28C1B,#D85A14)',
              transition: 'width 600ms var(--ease-out)',
            }}/>
          </div>
        </div>

        {/* Stat row */}
        <div style={{ display: 'flex', gap: 8, marginTop: 18 }}>
          <DarkStat value={<span data-field="total-orders">{p.total_orders}</span>} label="Orders"/>
          <DarkStat value={<>£<span data-field="total-spend">{p.total_spend.toFixed(0)}</span></>} label="Spent"/>
          <DarkStat value={<><Ico.flame c="var(--brand-orange)" s={14}/><span data-field="streak-current">{p.streak_current}</span></>} label="Streak"/>
          <DarkStat value={<>£<span data-field="wallet-balance">{app.walletBalance.toFixed(2)}</span></>} label="Wallet"/>
        </div>
      </div>

      <div style={{ flex: 1, overflow: 'auto', padding: '20px 0 max(132px, calc(env(safe-area-inset-bottom, 0px) + 132px))', display: 'flex', flexDirection: 'column', gap: 24 }}>

        {/* Rewards shortcut — the deep gamification lives on the Rewards tab */}
        <div style={{ padding: '0 20px' }}>
          <div onClick={() => app.replaceTo('rewards')} style={{
            display: 'flex', alignItems: 'center', gap: 12, padding: '13px 15px', borderRadius: 18, cursor: 'pointer',
            background: 'linear-gradient(125deg,#3A1F11 0%,#1B120D 100%)', color: 'var(--dust-cream)', position: 'relative', overflow: 'hidden',
          }}>
            <div style={{ position: 'absolute', right: -12, bottom: -16, opacity: 0.3 }}><Bull size={76}/></div>
            <div style={{ width: 40, height: 40, borderRadius: 12, background: 'rgba(242,140,27,0.16)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Ico.trophy c="var(--sun-orange)" s={19}/></div>
            <div style={{ flex: 1, position: 'relative' }}>
              <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 14 }}>Challenges, badges & the posse</div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: '#C9B7AA', marginTop: 2 }}>{p.challenges.length} live challenges · {p.badge_count} badges · gift wallet credit</div>
            </div>
            <Ico.chev c="var(--brand-orange)" s={16}/>
          </div>
        </div>

        {/* Recent orders */}
        <div>
          <SectionTitle eyebrow="Recent orders" title="Last few rides" action="View all" onAction={() => app.nav('orders')}/>
          <div data-lasso="recent-orders" style={{ padding: '0 20px', display: 'flex', flexDirection: 'column', gap: 10 }}>
            {PAST_ORDERS.slice(0, 2).map(o => <OrderRow key={o.id} order={o} app={app}/>)}
          </div>
        </div>

        {/* Account list */}
        <div>
          <SectionTitle title="Account"/>
          <div style={{ padding: '0 20px', display: 'flex', flexDirection: 'column', gap: 2 }}>
            <ProfileRow icon={<Ico.pin c="var(--horse-brown)" s={18}/>} label="Saved addresses" sub={`${ADDRESSES.length} saved`} onClick={() => setSheet('addresses')}/>
            <ProfileRow icon={<Ico.card c="var(--horse-brown)" s={18}/>} label="Payment methods" sub="Visa · 4242" onClick={() => setSheet('payments')}/>
            <ProfileRow icon={<Ico.bell c="var(--horse-brown)" s={18}/>} label="Notifications" sub="On — order updates, promos" onClick={() => setSheet('notifs')}/>
            <ProfileRow icon={<Ico.receipt c="var(--horse-brown)" s={18}/>} label="Past receipts" sub={`${PAST_ORDERS.length} receipts`} onClick={() => setSheet('receipts')}/>
            <ProfileRow icon={<Ico.ride c="var(--brand-orange)" s={18}/>} label="Trail Journal" sub="Your story so far, ride by ride" onClick={() => setSheet('journal')}/>
            <ProfileRow icon={<Ico.star c="var(--sun-orange)" s={18}/>} label="Your reviews" sub={`${MY_REVIEWS.length} posted · ${MY_REVIEWS.reduce((s, rv) => s + rv.helpful, 0)} found them helpful`} onClick={() => setSheet('reviews')}/>
          </div>
        </div>

        {/* Session status + sign out */}
        <div style={{ padding: '8px 20px 0' }}>
          <div data-customer-session-status="signed-in" style={{ display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'center', marginBottom: 10, fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)' }}>
            <span style={{ width: 7, height: 7, borderRadius: '50%', background: 'var(--live-green, #2E8B4E)' }}/>
            Signed in as <strong style={{ fontFamily: 'var(--font-display)', color: 'var(--fg-primary)' }}>{p.display_name}</strong>
          </div>
          <Button kind="ghost" full onClick={() => { app.setAuthed(false); app.toast('Signed out', 'info'); app.nav('home'); }}>Sign out</Button>
        </div>
      </div>

      <AddressesSheet open={sheet === 'addresses'} onClose={() => setSheet(null)} app={app}/>
      <PaymentsSheet open={sheet === 'payments'} onClose={() => setSheet(null)} app={app}/>
      <NotifPrefsSheet open={sheet === 'notifs'} onClose={() => setSheet(null)} app={app}/>
      <ReceiptsListSheet open={sheet === 'receipts'} onClose={() => setSheet(null)} app={app}/>
      <MyReviewsSheet open={sheet === 'reviews'} onClose={() => setSheet(null)} app={app}/>
      <TrailJournalSheet open={sheet === 'journal'} onClose={() => setSheet(null)} app={app}/>
    </Screen>
  );
}

// ─── My reviews sheet ────────────────────────────────────────────
function MyReviewsSheet({ open, onClose, app }) {
  const [editing, setEditing] = React.useState(null); // review id
  const [draftText, setDraftText] = React.useState('');
  const [draftStars, setDraftStars] = React.useState(5);
  const [overrides, setOverrides] = React.useState({}); // id -> {text, rating}
  const startEdit = (rv) => {
    const cur = overrides[rv.id] || rv;
    setEditing(rv.id); setDraftText(cur.text); setDraftStars(cur.rating);
  };
  const saveEdit = (id) => {
    setOverrides(o => ({ ...o, [id]: { text: draftText.trim(), rating: draftStars } }));
    setEditing(null);
    app.toast('Review updated — the kitchen will see it', 'success');
  };
  return (
    <BottomSheet open={open} onClose={onClose} title="Your reviews">
      <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {MY_REVIEWS.map(rvRaw => {
          const rv = { ...rvRaw, ...(overrides[rvRaw.id] || {}) };
          const r = RESTAURANT_LOOKUP[rv.restaurantId];
          const isEditing = editing === rv.id;
          return (
            <div key={rv.id} style={{ background: 'var(--bg-surface)', border: '1.5px solid ' + (isEditing ? 'var(--brand-orange)' : 'var(--soft-line)'), borderRadius: 16, padding: 14, transition: 'border-color 200ms' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{ width: 36, height: 36, borderRadius: 11, overflow: 'hidden', flexShrink: 0 }}><FoodPh height={36} hue={r?.hue || 'orange'} radius={11}/></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13.5, color: 'var(--fg-primary)' }}>{r?.name}</div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }}>
                    {[1,2,3,4,5].map(n => (
                      isEditing
                        ? <button key={n} onClick={() => setDraftStars(n)} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 1, display: 'flex' }}>
                            <Ico.star c={draftStars >= n ? 'var(--sun-orange)' : 'var(--soft-line)'} s={16}/>
                          </button>
                        : <Ico.star key={n} c={rv.rating >= n ? 'var(--sun-orange)' : 'var(--soft-line)'} s={12}/>
                    ))}
                    {!isEditing && <span style={{ fontFamily: 'var(--font-body)', fontSize: 11, color: 'var(--warm-stone)', marginLeft: 4 }}>{rv.date}</span>}
                  </div>
                </div>
                {rv.photo && !isEditing && <Pill bg="var(--bg-warm)" fg="var(--horse-brown)" style={{ fontSize: 10 }}>With photo</Pill>}
              </div>
              {isEditing ? (
                <>
                  <textarea
                    value={draftText}
                    onChange={e => setDraftText(e.target.value)}
                    rows={3}
                    autoFocus
                    style={{ width: '100%', boxSizing: 'border-box', marginTop: 10, padding: 12, borderRadius: 12, border: '1.5px solid var(--soft-line)', resize: 'none', fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--fg-primary)', outline: 'none', background: 'var(--bg-app)', lineHeight: 1.5 }}></textarea>
                  <div style={{ display: 'flex', gap: 8, marginTop: 10 }}>
                    <Button kind="ghost" size="sm" onClick={() => setEditing(null)}>Cancel</Button>
                    <div style={{ flex: 1 }}><Button kind="accent" size="sm" full disabled={!draftText.trim()} onClick={() => saveEdit(rv.id)}>Save review</Button></div>
                  </div>
                </>
              ) : (
                <>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--fg-primary)', lineHeight: 1.5, marginTop: 10 }}>“{rv.text}”</div>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 10, paddingTop: 10, borderTop: '1px solid var(--soft-line)' }}>
                    <span style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)' }}>{rv.helpful} wranglers found this helpful</span>
                    <div style={{ display: 'flex', gap: 12 }}>
                      <button onClick={() => startEdit(rv)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11.5, color: 'var(--brand-orange)' }}>Edit</button>
                      <button onClick={() => { onClose(); app.openRestaurant(rv.restaurantId); }} style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11.5, color: 'var(--horse-brown)' }}>Order again →</button>
                    </div>
                  </div>
                </>
              )}
            </div>
          );
        })}
      </div>
    </BottomSheet>
  );
}

// ─── Account sheets ──────────────────────────────────────────────
function AddressesSheet({ open, onClose, app }) {
  const [defId, setDefId] = React.useState((ADDRESSES.find(a => a.default) || ADDRESSES[0]).id);
  return (
    <BottomSheet open={open} onClose={onClose} title="Saved addresses">
      <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {ADDRESSES.map(a => {
          const on = a.id === defId;
          return (
            <button key={a.id} onClick={() => { setDefId(a.id); app.toast(`${a.label} set as default`, 'success'); }} style={{
              display: 'flex', alignItems: 'flex-start', gap: 12, padding: 14, borderRadius: 14, cursor: 'pointer', textAlign: 'left',
              background: on ? 'var(--bg-warm)' : 'var(--bg-surface)', border: '1.5px solid ' + (on ? 'var(--brand-orange)' : 'var(--soft-line)'),
            }}>
              <div style={{ width: 36, height: 36, borderRadius: 10, background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                {a.label === 'Home' ? <Ico.home c="var(--brand-orange)" s={18}/> : <Ico.pin c="var(--brand-orange)" s={18}/>}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14, color: 'var(--fg-primary)' }}>{a.label}</span>
                  {on && <Pill bg="var(--brand-orange)" fg="#fff" style={{ fontSize: 9 }}>Default</Pill>}
                </div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)', marginTop: 2 }}>{a.line1}{a.line2 ? `, ${a.line2}` : ''}, {a.city} {a.postcode}</div>
                {a.notes && <div style={{ fontFamily: 'var(--font-body)', fontSize: 11, color: 'var(--warm-stone)', marginTop: 4, fontStyle: 'italic' }}>“{a.notes}”</div>}
              </div>
            </button>
          );
        })}
        <button onClick={() => app.toast('Add address — drop a pin coming soon', 'info')} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: 13, borderRadius: 14, border: '1.5px dashed var(--horse-brown)', background: 'transparent', cursor: 'pointer', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13, color: 'var(--horse-brown)' }}>
          <Ico.plus c="var(--horse-brown)" s={16}/> Add new address
        </button>
      </div>
    </BottomSheet>
  );
}

function PaymentsSheet({ open, onClose, app }) {
  const [defId, setDefId] = React.useState('visa');
  const [topupOpen, setTopupOpen] = React.useState(false);
  const methods = [
    { id: 'visa', label: 'Visa ···· 4242', sub: 'Expires 09/27', icon: <Ico.card c="var(--fg-primary)" s={18}/> },
    { id: 'apple', label: 'Apple Pay', sub: 'jordan@lasso.io', icon: <Ico.lock c="var(--fg-primary)" s={18}/> },
    { id: 'google', label: 'Google Pay', sub: 'Linked account', icon: <Ico.google s={18}/> },
  ];
  return (
    <BottomSheet open={open} onClose={onClose} title="Payment methods">
      <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {/* Wallet first */}
        <div className="lv-wallet-glow" style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 14, borderRadius: 14, background: 'var(--dark-chocolate)', color: 'var(--dust-cream)' }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: 'rgba(242,140,27,0.16)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Ico.wallet c="var(--sun-orange)" s={18}/></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14 }}>Lasso wallet</div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: '#9F8979' }}>Applies first at checkout</div>
          </div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 16 }}>£{app.walletBalance.toFixed(2)}</div>
          <button onClick={() => setTopupOpen(v => !v)} style={{ background: 'var(--brand-orange)', color: '#fff', border: 'none', padding: '8px 13px', borderRadius: 10, fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 12, cursor: 'pointer', boxShadow: 'var(--shadow-orange)' }}>Top up</button>
        </div>
        {topupOpen && (
          <div style={{ display: 'flex', gap: 8, padding: '2px 0 4px', animation: 'lasso-slide-up 220ms var(--ease-out)' }}>
            {[10, 20, 50].map(a => (
              <button key={a} onClick={() => { app.topUpWallet(a); setTopupOpen(false); app.toast(`£${a} added — wallet now £${(app.walletBalance + a).toFixed(2)}`, 'success'); }} style={{
                flex: 1, padding: '12px 4px', borderRadius: 12, cursor: 'pointer',
                background: 'var(--bg-warm)', border: '1.5px dashed var(--brand-orange)',
                fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 14, color: 'var(--brand-orange)',
              }}>+£{a}</button>
            ))}
          </div>
        )}
        {methods.map(m => {
          const on = m.id === defId;
          return (
            <button key={m.id} onClick={() => { setDefId(m.id); app.toast(`${m.label} set as default`, 'success'); }} style={{
              display: 'flex', alignItems: 'center', gap: 12, padding: 14, borderRadius: 14, cursor: 'pointer', textAlign: 'left',
              background: on ? 'var(--bg-warm)' : 'var(--bg-surface)', border: '1.5px solid ' + (on ? 'var(--brand-orange)' : 'var(--soft-line)'),
            }}>
              <div style={{ width: 36, height: 36, borderRadius: 10, background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{m.icon}</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14, color: 'var(--fg-primary)' }}>{m.label}</div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)', marginTop: 2 }}>{m.sub}</div>
              </div>
              {on && <Pill bg="var(--brand-orange)" fg="#fff" style={{ fontSize: 9 }}>Default</Pill>}
            </button>
          );
        })}
        <button onClick={() => app.toast('Add card — secure form coming soon', 'info')} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: 13, borderRadius: 14, border: '1.5px dashed var(--horse-brown)', background: 'transparent', cursor: 'pointer', fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13, color: 'var(--horse-brown)' }}>
          <Ico.plus c="var(--horse-brown)" s={16}/> Add card
        </button>
      </div>
    </BottomSheet>
  );
}

function NotifPrefsSheet({ open, onClose, app }) {
  const [prefs, setPrefs] = React.useState({ orders: true, promos: true, rewards: true, sms: false });
  const rows = [
    { id: 'orders', label: 'Order updates', sub: 'Rider assigned, on the way, delivered' },
    { id: 'promos', label: 'Promos & offers', sub: 'Deals from kitchens you follow' },
    { id: 'rewards', label: 'Rewards & XP', sub: 'Challenges, badges, streak reminders' },
    { id: 'sms', label: 'SMS backup', sub: 'Text me if a push doesn’t land' },
  ];
  return (
    <BottomSheet open={open} onClose={onClose} title="Notifications">
      <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {rows.map(rw => {
          const on = prefs[rw.id];
          return (
            <button key={rw.id} onClick={() => setPrefs(p => ({ ...p, [rw.id]: !p[rw.id] }))} style={{
              display: 'flex', alignItems: 'center', gap: 12, padding: 14, borderRadius: 14, cursor: 'pointer', textAlign: 'left',
              background: 'var(--bg-surface)', border: '1.5px solid var(--soft-line)',
            }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14, color: 'var(--fg-primary)' }}>{rw.label}</div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)', marginTop: 2 }}>{rw.sub}</div>
              </div>
              <div style={{ width: 42, height: 25, borderRadius: 13, flexShrink: 0, position: 'relative', background: on ? 'var(--brand-orange)' : 'var(--soft-line)', transition: 'background 200ms' }}>
                <div style={{ position: 'absolute', top: 2.5, left: on ? 19.5 : 2.5, width: 20, height: 20, borderRadius: '50%', background: '#fff', transition: 'left 200ms var(--ease-out)', boxShadow: '0 1px 3px rgba(0,0,0,0.25)' }}/>
              </div>
            </button>
          );
        })}
        <div style={{ marginTop: 8 }}>
          <Button kind="primary" full onClick={() => { onClose(); app.toast('Notification preferences saved', 'success'); }}>Save preferences</Button>
        </div>
      </div>
    </BottomSheet>
  );
}

function ReceiptsListSheet({ open, onClose, app }) {
  const [openReceipt, setOpenReceipt] = React.useState(null);
  return (
    <>
      <BottomSheet open={open && !openReceipt} onClose={onClose} title="Past receipts">
        <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 8 }}>
          {PAST_ORDERS.map(o => {
            const r = RESTAURANT_LOOKUP[o.restaurantId];
            return (
              <button key={o.id} onClick={() => setOpenReceipt(o)} style={{
                display: 'flex', alignItems: 'center', gap: 12, padding: 13, borderRadius: 14, cursor: 'pointer', textAlign: 'left',
                background: 'var(--bg-surface)', border: '1.5px solid var(--soft-line)',
              }}>
                <div style={{ width: 38, height: 38, borderRadius: 11, overflow: 'hidden', flexShrink: 0 }}><FoodPh height={38} hue={r?.hue || 'orange'} radius={11}/></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13.5, color: 'var(--fg-primary)' }}>{r?.name}</div>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)', marginTop: 2 }}>{o.date} · #{o.id}</div>
                </div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 14, color: o.status === 'cancelled' ? 'var(--warm-stone)' : 'var(--fg-primary)' }}>£{o.total.toFixed(2)}</div>
                <Ico.chev c="var(--warm-stone)" s={15}/>
              </button>
            );
          })}
        </div>
      </BottomSheet>
      {openReceipt && <ReceiptSheet open={!!openReceipt} onClose={() => setOpenReceipt(null)} order={openReceipt} app={app}/>}
    </>
  );
}

// ─── Rewards + restaurant challenge table (opened from a loyalty card) ──
function RewardsChallengeSheet({ card, onClose, app }) {
  if (!card) return <BottomSheet open={false} onClose={onClose}/>;
  const r = RESTAURANT_LOOKUP[card.restaurantId];
  const mids = Array.from(new Set([
    Math.max(1, Math.round(card.total / 2)),
    Math.max(2, card.total - 2),
    card.total,
  ])).sort((a, b) => a - b);
  const rewards = mids.map((at, i) => ({ at, reward: i === mids.length - 1 ? card.reward : (i === 0 ? 'Free drink' : 'Free side') }));
  const challenges = [
    { title: 'Order 3 weeks running', xp: 300, progress: 2, total: 3, icon: 'flame' },
    { title: `Try a new dish at ${r?.name || 'here'}`, xp: 120, progress: 0, total: 1, icon: 'star' },
    { title: 'Bring a friend along', xp: 200, progress: 1, total: 2, icon: 'star' },
  ];
  return (
    <BottomSheet open={!!card} onClose={onClose} title={card.restaurantName}>
      <div style={{ padding: '0 20px 28px', display: 'flex', flexDirection: 'column', gap: 18 }}>
        {/* Progress recap */}
        <div style={{ background: 'var(--dark-chocolate)', color: 'var(--dust-cream)', borderRadius: 16, padding: 16, position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', right: -16, top: -8, opacity: 0.35 }}><Bull size={84}/></div>
          <Eyebrow color="var(--brand-orange)">{card.cardName}</Eyebrow>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 20, marginTop: 4 }}>{card.stamps} of {card.total} stamps</div>
          <div style={{ display: 'flex', gap: 5, marginTop: 12 }}>
            {Array.from({ length: card.total }).map((_, i) => (
              <div key={i} style={{ flex: 1, height: 24, borderRadius: 7, background: i < card.stamps ? 'var(--brand-orange)' : 'rgba(255,255,255,0.08)', border: '1.5px solid ' + (i < card.stamps ? 'var(--brand-orange)' : 'rgba(255,255,255,0.12)'), display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{i < card.stamps && <Bull size={12}/>}</div>
            ))}
          </div>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: '#C9B3A0', marginTop: 10 }}>{Math.max(0, card.total - card.stamps)} more to <strong style={{ color: 'var(--dust-cream)', fontFamily: 'var(--font-display)' }}>{card.reward}</strong>.</div>
        </div>
        {/* Rewards table */}
        <div>
          <Eyebrow style={{ marginBottom: 8 }}>Rewards</Eyebrow>
          <div style={{ background: 'var(--bg-surface)', border: '1.5px solid var(--soft-line)', borderRadius: 16, overflow: 'hidden' }}>
            {rewards.map((t, i) => {
              const earned = card.stamps >= t.at;
              return (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 14px', borderTop: i > 0 ? '1px solid var(--soft-line)' : 'none' }}>
                  <div style={{ width: 34, height: 34, borderRadius: '50%', background: earned ? 'var(--brand-orange)' : 'var(--bg-warm)', color: earned ? '#fff' : 'var(--horse-brown)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 13, flexShrink: 0 }}>{t.at}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13.5, color: 'var(--fg-primary)' }}>{t.reward}</div>
                    <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)' }}>{t.at} stamps</div>
                  </div>
                  {earned
                    ? <Pill bg="rgba(46,139,78,0.14)" fg="var(--live-green)" style={{ fontSize: 10.5 }}>Unlocked</Pill>
                    : <Pill bg="var(--bg-warm)" fg="var(--warm-stone)" style={{ fontSize: 10.5 }}>{t.at - card.stamps} to go</Pill>}
                </div>
              );
            })}
          </div>
        </div>
        {/* Challenge table */}
        <div>
          <Eyebrow style={{ marginBottom: 8 }}>Challenges at {card.restaurantName}</Eyebrow>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {challenges.map((c, i) => {
              const pct = (c.progress / c.total) * 100;
              return (
                <div key={i} style={{ background: 'var(--bg-surface)', border: '1.5px solid var(--soft-line)', borderRadius: 14, padding: 13, display: 'flex', gap: 12, alignItems: 'center' }}>
                  <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--bg-warm)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{c.icon === 'flame' ? <Ico.flame c="var(--brand-orange)" s={20}/> : <Ico.star c="var(--sun-orange)" s={20}/>}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'baseline' }}>
                      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13, color: 'var(--fg-primary)' }}>{c.title}</div>
                      <Pill bg="var(--brand-orange)" fg="#fff" style={{ fontSize: 10 }}>+{c.xp} XP</Pill>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
                      <div style={{ flex: 1, height: 5, borderRadius: 3, background: 'var(--soft-line)', overflow: 'hidden' }}><div style={{ height: '100%', width: `${pct}%`, background: 'var(--brand-orange)' }}/></div>
                      <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11, color: 'var(--warm-stone)' }}>{c.progress}/{c.total}</span>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
        <Button kind="accent" full size="lg" onClick={() => { onClose(); app.toast('Let’s ride — order to earn stamps', 'success'); }}>Order to earn</Button>
      </div>
    </BottomSheet>
  );
}

function DarkStat({ value, label }) {
  return (
    <div style={{
      flex: 1, background: 'rgba(255,255,255,0.06)', border: '1.5px solid rgba(255,255,255,0.06)',
      borderRadius: 14, padding: '10px 10px',
    }}>
      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 16, color: 'var(--dust-cream)', display: 'flex', alignItems: 'center', gap: 4 }}>{value}</div>
      <div style={{ fontFamily: 'var(--font-body)', fontSize: 10, color: '#9F8979', textTransform: 'uppercase', letterSpacing: '0.08em', marginTop: 2 }}>{label}</div>
    </div>
  );
}

function ChallengeCard({ challenge: c }) {
  const pct = (c.progress / c.total) * 100;
  return (
    <div data-lasso="challenge-template" style={{
      background: 'var(--bg-surface)', borderRadius: 16, padding: 14,
      border: '1.5px solid var(--soft-line)', display: 'flex', gap: 12, alignItems: 'center',
    }}>
      <div data-field="challenge-icon" style={{
        width: 44, height: 44, borderRadius: 12, background: 'var(--bg-warm)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {c.icon === 'flame' ? <Ico.flame c="var(--brand-orange)" s={22}/> : <Ico.star c="var(--sun-orange)" s={22}/>}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
          <div data-field="challenge-title" style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13.5, color: 'var(--fg-primary)' }}>{c.title}</div>
          <Pill bg="var(--brand-orange)" fg="#fff" style={{ fontSize: 10 }}>+<span data-field="challenge-xp">{c.xp}</span> XP</Pill>
        </div>
        <div data-field="challenge-desc" style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--warm-stone)', marginTop: 2 }}>{c.desc}</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8 }}>
          <div style={{ flex: 1, height: 5, borderRadius: 3, background: 'var(--soft-line)', overflow: 'hidden' }}>
            <div data-field="challenge-progress" style={{ height: '100%', width: `${pct}%`, background: 'var(--brand-orange)', transition: 'width 320ms var(--ease-out)' }}/>
          </div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11, color: 'var(--warm-stone)' }}>{c.progress}/{c.total}</div>
          <div data-field="challenge-expires" style={{ fontFamily: 'var(--font-body)', fontSize: 10, color: 'var(--warm-stone)' }}>· {c.expires}</div>
        </div>
      </div>
    </div>
  );
}

function BadgeCard({ badge: b, onOpen }) {
  const palette = {
    orange: { bg: 'linear-gradient(135deg,#F28C1B,#D85A14)', fg: '#fff' },
    sun: { bg: 'linear-gradient(135deg,#F4D8B0,#F28C1B)', fg: 'var(--horse-brown)' },
    gold: { bg: 'linear-gradient(135deg,#F4E1C1,#D6A63A)', fg: 'var(--horse-brown)' },
    gray: { bg: 'var(--bg-warm)', fg: 'var(--warm-stone)' },
  }[b.kind];
  return (
    <div data-lasso="badge-template" onClick={onOpen} role={onOpen ? 'button' : undefined} style={{
      width: 100, flexShrink: 0, padding: 10, borderRadius: 16,
      background: 'var(--bg-surface)', border: '1.5px solid var(--soft-line)',
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
      opacity: b.earned ? 1 : 0.5, cursor: onOpen ? 'pointer' : 'default',
    }}>
      <div style={{
        width: 50, height: 50, borderRadius: '50%',
        background: palette.bg, display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <Ico.badge c={palette.fg} s={26}/>
      </div>
      <div style={{ textAlign: 'center' }}>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11, color: 'var(--fg-primary)', lineHeight: 1.2 }}>{b.name}</div>
        <div style={{ fontFamily: 'var(--font-body)', fontSize: 9.5, color: 'var(--warm-stone)', marginTop: 2, lineHeight: 1.3 }}>{b.desc}</div>
      </div>
    </div>
  );
}

function LoyaltyCard({ card: l, onOpen }) {
  const r = RESTAURANT_LOOKUP[l.restaurantId];
  return (
    <div data-lasso="loyalty-card-template" onClick={onOpen} style={{
      background: 'var(--dark-chocolate)', color: 'var(--dust-cream)', borderRadius: 18,
      padding: 16, display: 'flex', flexDirection: 'column', gap: 12, position: 'relative', overflow: 'hidden',
      cursor: onOpen ? 'pointer' : 'default',
    }}>
      <div style={{ position: 'absolute', right: -20, top: -10, opacity: 0.4 }}>
        <Bull size={80}/>
      </div>
      <div style={{ position: 'relative' }}>
        <Eyebrow color="var(--brand-orange)">{l.cardName}</Eyebrow>
        <div data-field="restaurant-name" style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 18, marginTop: 4 }}>{l.restaurantName}</div>
        <div data-field="reward-label" style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: '#9F8979', marginTop: 2 }}>{l.reward}</div>
      </div>
      <div data-lasso="stamp-slots" style={{ display: 'flex', gap: 6, marginTop: 4, position: 'relative' }}>
        {Array.from({ length: l.total }).map((_, i) => (
          <div key={i} style={{
            flex: 1, height: 28, borderRadius: 8,
            background: i < l.stamps ? 'var(--brand-orange)' : 'rgba(255,255,255,0.08)',
            border: '1.5px solid ' + (i < l.stamps ? 'var(--brand-orange)' : 'rgba(255,255,255,0.12)'),
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {i < l.stamps && <Bull size={14}/>}
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', position: 'relative' }}>
        <div data-field="stamps-count" style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 11, color: '#9F8979', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
          {l.stamps} of {l.total} stamps
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 11, color: 'var(--brand-orange)' }}>
          View rewards <Ico.chev c="var(--brand-orange)" s={13}/>
        </div>
      </div>
    </div>
  );
}

function ProfileRow({ icon, label, sub, onClick }) {
  return (
    <button onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '14px 0', border: 'none',
      background: 'transparent', cursor: 'pointer', borderBottom: '1px solid var(--soft-line)',
      textAlign: 'left', width: '100%',
    }}>
      <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--bg-warm)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {icon}
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14, color: 'var(--fg-primary)' }}>{label}</div>
        <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--warm-stone)', marginTop: 2 }}>{sub}</div>
      </div>
      <Ico.chev c="var(--warm-stone)" s={16}/>
    </button>
  );
}

// ─── Notifications panel ────────────────────────────────────────────
function NotificationsScreen({ app }) {
  const items = [
    { id: 'n1', type: 'order', title: 'Your order is on the way', sub: 'Diego picked up your Brisket Tacos · 7 min', time: 'now', icon: 'ride', unread: true },
    { id: 'n2', type: 'reward', title: 'XP earned', sub: '+250 XP for completing "Three for the trail"', time: '2h', icon: 'badge', unread: true },
    { id: 'n3', type: 'promo', title: 'Free delivery this Friday', sub: 'On orders over £20 at Rojo & Smoke', time: '1d', icon: 'ticket', unread: false },
    { id: 'n4', type: 'order', title: 'Order delivered · LSO-22087', sub: 'Cactus & Cream · Rate your experience', time: '3d', icon: 'check', unread: false },
  ];
  return (
    <Screen>
      <div style={{ padding: '12px 20px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <button onClick={() => app.back()} style={{
          width: 40, height: 40, borderRadius: 14, border: '1.5px solid var(--soft-line)',
          background: 'var(--bg-surface)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        }}><Ico.chevL c="var(--fg-primary)" s={20}/></button>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 17 }}>Notifications</div>
        <button style={{ width: 40, height: 40, borderRadius: 14, border: 'none', background: 'transparent', cursor: 'pointer' }}>
          <Ico.check c="var(--fg-primary)" s={20}/>
        </button>
      </div>

      <div style={{ flex: 1, overflow: 'auto', padding: '8px 20px 24px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {items.map(n => (
          <div key={n.id} style={{
            display: 'flex', gap: 12, padding: 14,
            background: n.unread ? 'var(--bg-warm)' : 'var(--bg-surface)',
            borderRadius: 14, border: '1.5px solid var(--soft-line)',
            alignItems: 'flex-start',
          }}>
            <div style={{ width: 36, height: 36, borderRadius: 10, background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
              {n.icon === 'ride' && <Ico.ride c="var(--brand-orange)" s={18}/>}
              {n.icon === 'badge' && <Ico.badge c="var(--brand-orange)" s={18}/>}
              {n.icon === 'ticket' && <Ico.ticket c="var(--brand-orange)" s={18}/>}
              {n.icon === 'check' && <Ico.check c="var(--live-green)" s={18}/>}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 13.5, color: 'var(--fg-primary)' }}>{n.title}</div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 11, color: 'var(--warm-stone)', flexShrink: 0 }}>{n.time}</div>
              </div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--warm-stone)', marginTop: 2, lineHeight: 1.4 }}>{n.sub}</div>
            </div>
            {n.unread && <div style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--brand-orange)', marginTop: 8, flexShrink: 0 }}/>}
          </div>
        ))}
      </div>
    </Screen>
  );
}

Object.assign(window, { OrdersScreen, ProfileScreen, NotificationsScreen, OrderRow, ReceiptSheet, ChallengeCard, BadgeCard, LoyaltyCard, RewardsChallengeSheet,
  // shared with desktop
  AddressesSheet, PaymentsSheet, NotifPrefsSheet, ReceiptsListSheet, MyReviewsSheet, DarkStat, ProfileRow, RateNudge });
