// Desktop layout — sidebar nav + multi-column content
// Hosted inside a ChromeWindow on the design canvas.

// Lightweight global search · indexes guests, vendors, tasks, budget categories.
// Cmd/Ctrl-K focuses. Selecting a result navigates to the relevant tab.
function DesktopSidebarSearch({ onNavigate }) {
  const inputRef = React.useRef(null);
  const [q, setQ] = React.useState('');
  const [focused, setFocused] = React.useState(false);
  const guests = useGuests();
  const vendors = useVendors();
  const { active: tasks } = useTasks();
  const budget = useBudget();

  // ⌘K / Ctrl-K focus
  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        inputRef.current && inputRef.current.focus();
      }
      if (e.key === 'Escape' && document.activeElement === inputRef.current) {
        setQ(''); inputRef.current.blur();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const results = React.useMemo(() => {
    const needle = q.trim().toLowerCase();
    if (!needle) return [];
    const hits = [];
    (guests.all || []).forEach(g => {
      if ((g.name || '').toLowerCase().includes(needle))
        hits.push({ kind: 'Guest', label: g.name, sub: g.group || '', tab: 'guests' });
    });
    (vendors.all || []).forEach(v => {
      if ((v.name || '').toLowerCase().includes(needle))
        hits.push({ kind: 'Vendor', label: v.name, sub: v.category || v.status || '', tab: 'vendors' });
    });
    (tasks || []).forEach(t => {
      if ((t.label || t.title || '').toLowerCase().includes(needle))
        hits.push({ kind: 'Task', label: t.label || t.title, sub: t.due || '', tab: 'home' });
    });
    (budget.categories || []).forEach(c => {
      if ((c.label || c.name || '').toLowerCase().includes(needle))
        hits.push({ kind: 'Budget', label: c.label || c.name, sub: c.subtitle || '', tab: 'budget' });
    });
    return hits.slice(0, 8);
  }, [q, guests.all, vendors.all, tasks, budget.categories]);

  return (
    <div style={{ position: 'relative', marginBottom: 18 }}>
      <div style={{
        background: '#fffdf7', borderRadius: 10,
        border: `0.5px solid ${focused ? W.clay : W.line}`,
        display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px',
        transition: 'border-color 120ms ease',
      }}>
        <Icon name="search" size={14} color={W.muted}/>
        <input
          ref={inputRef}
          value={q}
          onChange={(e) => setQ(e.target.value)}
          onFocus={() => setFocused(true)}
          onBlur={() => setTimeout(() => setFocused(false), 120)}
          placeholder="Search"
          style={{
            flex: 1, border: 'none', outline: 'none', background: 'transparent',
            fontFamily: FONT_UI, fontSize: 13, color: W.ink, padding: 0,
          }}
        />
        <div style={{
          fontFamily: FONT_MONO, fontSize: 10.5, color: W.muted,
          padding: '1px 5px', borderRadius: 4, background: '#ece2cd',
        }}>⌘K</div>
      </div>

      {focused && q.trim() && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 6px)', left: 0, right: 0,
          background: '#fffdf7', borderRadius: 10, border: `0.5px solid ${W.line}`,
          boxShadow: '0 16px 40px -16px rgba(29,24,18,0.18)',
          zIndex: 50, padding: 6, maxHeight: 360, overflowY: 'auto',
        }}>
          {results.length === 0 ? (
            <div style={{
              padding: '12px 10px', fontFamily: FONT_UI, fontSize: 12.5,
              color: W.muted,
            }}>No matches.</div>
          ) : results.map((r, i) => (
            <button
              key={i}
              onMouseDown={() => { onNavigate && onNavigate(r.tab); setQ(''); }}
              style={{
                display: 'flex', width: '100%', textAlign: 'left',
                padding: '8px 10px', gap: 10, alignItems: 'center',
                background: 'transparent', border: 'none', cursor: 'pointer',
                borderRadius: 6,
              }}
              onMouseEnter={(e) => (e.currentTarget.style.background = '#f4eedf')}
              onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
            >
              <div style={{
                fontFamily: FONT_MONO, fontSize: 9, color: W.muted,
                background: '#ece2cd', padding: '2px 5px', borderRadius: 4,
                textTransform: 'uppercase', letterSpacing: 0.5, minWidth: 46,
                textAlign: 'center',
              }}>{r.kind}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontFamily: FONT_UI, fontSize: 13, color: W.ink,
                  whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                }}>{r.label}</div>
                {r.sub && (
                  <div style={{
                    fontFamily: FONT_UI, fontSize: 11, color: W.muted, marginTop: 2,
                  }}>{r.sub}</div>
                )}
              </div>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// Live "last synced" timestamp for the sidebar. Reads from localStorage and
// listens for the wos-synced / wos-sync-failed events dispatched by sync-bridge.
function SyncStamp() {
  const [state, setState] = React.useState(() => ({
    ts: Number(localStorage.getItem('weddingos.lastSyncedAt') || 0),
    error: false,
  }));
  React.useEffect(() => {
    const onOk    = (e) => setState({ ts: e.detail.ts, error: false });
    const onFail  = ()  => setState(s => ({ ...s, error: true }));
    window.addEventListener('wos-synced', onOk);
    window.addEventListener('wos-sync-failed', onFail);
    // tick every 15s so "5m ago" updates without manual refresh
    const id = setInterval(() => setState(s => ({ ...s })), 15000);
    return () => {
      window.removeEventListener('wos-synced', onOk);
      window.removeEventListener('wos-sync-failed', onFail);
      clearInterval(id);
    };
  }, []);
  const label = (() => {
    if (state.error) return 'Sync error · retrying';
    if (!state.ts)   return 'Not synced yet';
    const s = Math.floor((Date.now() - state.ts) / 1000);
    if (s < 5)   return 'Synced · just now';
    if (s < 60)  return `Synced · ${s}s ago`;
    if (s < 3600) return `Synced · ${Math.floor(s/60)}m ago`;
    if (s < 86400) return `Synced · ${Math.floor(s/3600)}h ago`;
    return `Synced · ${Math.floor(s/86400)}d ago`;
  })();
  return (
    <div style={{
      fontFamily: FONT_UI, fontSize: 11,
      color: state.error ? '#a05030' : W.muted,
    }}>{label}</div>
  );
}

// Dark wedding-context card · rendered in the sidebar on every screen
// EXCEPT the dashboard (which has its own large version of the same).
// Matches the design canvas's sidebar wedding card.
function DesktopWeddingCard({ wedding }) {
  const couple = wedding.couple || wedding.brides || wedding.groom || 'Your wedding';
  const date = wedding.dateLabel || '';
  const city = wedding.cityShort || wedding.city || '';
  const days = wedding.daysUntil;
  return (
    <div style={{
      margin: '0 4px 16px',
      padding: '18px 18px 16px',
      background: 'radial-gradient(120% 90% at 15% 0%, #2c241b 0%, #1d1812 70%)',
      borderRadius: 14,
      color: '#fbf6ea',
      boxShadow: '0 8px 24px -14px rgba(29,24,18,0.5)',
    }}>
      <div style={{
        fontFamily: FONT_UI, fontSize: 9.5, fontWeight: 600,
        letterSpacing: 1.8, textTransform: 'uppercase',
        color: 'rgba(251,246,234,0.55)',
      }}>The wedding of</div>
      <div style={{
        fontFamily: FONT_DISPLAY, fontSize: 20, fontWeight: 500,
        color: '#fbf6ea', marginTop: 4, lineHeight: 1.15,
        letterSpacing: -0.1,
      }}>{(() => {
        const parts = couple.split(' & ');
        if (parts.length !== 2) return couple;
        return (
          <>
            {parts[0]}
            <span style={{ fontStyle: 'italic', padding: '0 4px', opacity: 0.85 }}>&</span>
            {parts[1]}
          </>
        );
      })()}</div>
      {/* Days counter */}
      {days != null && (
        <div style={{ marginTop: 14, display: 'flex', alignItems: 'baseline', gap: 6 }}>
          <div style={{
            fontFamily: FONT_DISPLAY, fontSize: 30, fontWeight: 500,
            color: '#fbf6ea', letterSpacing: -0.5, lineHeight: 1,
          }}>{days}</div>
          <div style={{
            fontFamily: FONT_DISPLAY, fontSize: 13, fontStyle: 'italic',
            color: 'rgba(251,246,234,0.75)', marginLeft: 2,
          }}>days</div>
          <div style={{
            fontFamily: FONT_UI, fontSize: 9.5, fontWeight: 600,
            letterSpacing: 1.6, textTransform: 'uppercase',
            color: 'rgba(251,246,234,0.45)', marginLeft: 6,
          }}>to go</div>
        </div>
      )}
      {(date || city) && (
        <div style={{
          marginTop: 12,
          fontFamily: FONT_UI, fontSize: 11,
          color: 'rgba(251,246,234,0.7)',
          letterSpacing: 0.1, lineHeight: 1.45,
        }}>
          {date}{date && city ? ' · ' : ''}{city}
        </div>
      )}
    </div>
  );
}

function DesktopSidebar({ active, onChange }) {
  const wedding = useWedding();
  const headerLabel = (wedding.brides || wedding.groom)
    ? `${wedding.brides || ''}${wedding.brides && wedding.groom ? ' & ' : ''}${wedding.groom || ''}${
        wedding.daysUntil != null ? ` · ${wedding.daysUntil} days` : ''
      }`
    : 'Set up your wedding';
  const groups = [
    {
      label: 'Plan',
      items: [
        { id: 'home',    label: 'Today',    icon: 'home' },
        { id: 'budget',  label: 'Budget',   icon: 'wallet' },
        { id: 'guests',  label: 'Guests',   icon: 'users' },
        { id: 'seating', label: 'Seating',  icon: 'rings' },
        { id: 'cal',     label: 'Calendar', icon: 'calendar' },
      ],
    },
    {
      label: 'Story',
      items: [
        { id: 'mood',    label: 'Moodboard',     icon: 'sparkle' },
        { id: 'party',   label: 'Wedding Party', icon: 'heart' },
      ],
    },
    {
      label: 'Manage',
      items: [
        { id: 'vendors',  label: 'Vendors',     icon: 'flag' },
        { id: 'dayof',    label: 'Wedding Day', icon: 'rings' },
        { id: 'export',   label: 'Reports',     icon: 'sparkle' },
        { id: 'settings', label: 'Settings',    icon: 'check' },
      ],
    },
  ];
  return (
    <div style={{
      width: 248, flexShrink: 0,
      background: '#f4eedf',
      borderRight: `0.5px solid ${W.line}`,
      display: 'flex', flexDirection: 'column',
      padding: '20px 14px',
    }}>
      {/* Brand */}
      <div style={{ padding: '4px 10px 14px' }}>
        <div style={{
          fontFamily: FONT_DISPLAY, fontStyle: 'italic', fontSize: 22,
          color: W.ink, letterSpacing: 0.3, lineHeight: 1,
        }}>weddingos</div>
        <div style={{
          fontFamily: FONT_UI, fontSize: 11, color: W.muted, marginTop: 6,
          letterSpacing: 0.2,
        }}>{headerLabel}</div>
      </div>

      {/* Wedding card · shown on every screen EXCEPT the dashboard,
          which already has the large hero of the same content. */}
      {active !== 'home' && (wedding.brides || wedding.groom) && (
        <DesktopWeddingCard wedding={wedding}/>
      )}

      {/* Search */}
      <DesktopSidebarSearch onNavigate={onChange}/>

      {/* Groups */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16, flex: 1 }}>
        {groups.map(g => (
          <div key={g.label}>
            <div style={{
              fontFamily: FONT_UI, fontSize: 10, fontWeight: 600,
              letterSpacing: 1.4, textTransform: 'uppercase', color: W.muted,
              padding: '0 10px 8px',
            }}>{g.label}</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              {g.items.map(item => {
                const isActive = item.id === active;
                return (
                  <button key={item.id}
                    onClick={() => onChange(item.id)}
                    style={{
                      display: 'flex', alignItems: 'center', gap: 10,
                      padding: '8px 10px', borderRadius: 8,
                      background: isActive ? W.card : 'transparent',
                      border: 'none', cursor: 'pointer',
                      fontFamily: FONT_UI, fontSize: 13.5, fontWeight: isActive ? 600 : 500,
                      color: isActive ? W.ink : W.ink2,
                      textAlign: 'left',
                      boxShadow: isActive ? '0 1px 2px rgba(60,40,20,0.04)' : 'none',
                    }}>
                    <Icon name={item.icon} size={16} color={isActive ? W.clayDeep : W.muted}
                      strokeWidth={isActive ? 1.7 : 1.5}/>
                    <span>{item.label}</span>
                  </button>
                );
              })}
            </div>
          </div>
        ))}
      </div>

      {/* Profile */}
      <div style={{
        marginTop: 16, padding: '10px 10px', borderRadius: 10,
        background: '#fffdf7', border: `0.5px solid ${W.line}`,
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <div style={{
          width: 32, height: 32, borderRadius: 999,
          background: W.clay, color: '#fbf6ea',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: FONT_DISPLAY, fontSize: 14, fontWeight: 500,
        }}>{(wedding.brides || wedding.groom || '·').slice(0, 1).toUpperCase()}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            fontFamily: FONT_UI, fontSize: 13, fontWeight: 500, color: W.ink,
            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
          }}>{wedding.brides || wedding.groom || 'You'}</div>
          <SyncStamp/>
        </div>
        <Icon name="chevronD" size={14} color={W.muted}/>
      </div>
    </div>
  );
}

function DesktopHeader({ title, subtitle, note, action }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '28px 36px 22px', borderBottom: `0.5px solid ${W.lineSoft}`,
    }}>
      <div>
        <div style={{
          fontFamily: FONT_UI, fontSize: 11, fontWeight: 600,
          letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
        }}>{subtitle}</div>
        <div style={{
          fontFamily: FONT_DISPLAY, fontSize: 30, fontWeight: 500,
          color: W.ink, letterSpacing: -0.4, lineHeight: 1, marginTop: 4,
        }}>{title}</div>
        {note && (
          <div style={{
            fontFamily: FONT_DISPLAY, fontStyle: 'italic', fontSize: 15,
            color: W.ink2, marginTop: 8, maxWidth: 540, lineHeight: 1.4,
          }}>{note}</div>
        )}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <button onClick={() => printAllReports()} style={{
          fontFamily: FONT_UI, fontSize: 13, fontWeight: 500, color: W.ink2,
          background: W.card, border: `0.5px solid ${W.line}`,
          padding: '8px 14px', borderRadius: 999, cursor: 'pointer',
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          <Icon name="sparkle" size={14} color={W.muted}/>
          Print pack
        </button>
        {action && (
          <button onClick={action.onClick} style={{
            fontFamily: FONT_UI, fontSize: 13, fontWeight: 500, color: W.bg,
            background: W.ink, border: 'none',
            padding: '8px 14px', borderRadius: 999, cursor: 'pointer',
            display: 'flex', alignItems: 'center', gap: 6,
          }}>
            <Icon name={action.icon || 'plus'} size={14} color={W.bg}/>
            {action.label}
          </button>
        )}
      </div>
    </div>
  );
}

// ─── Desktop Dashboard ─────────────────────────────────────────

function DesktopDashboard({ onNav }) {
  const wedding = useWedding();
  const { active: activeTasks, toggleTask, addTask, updateTask } = useTasks();
  const g = useGuests();
  const b = useBudget();
  const v = useVendors();
  const signals = usePlanningSignals();
  const confidence = usePlanningConfidence();
  const readiness = useReadinessScore();
  const [editingTask, setEditingTask] = React.useState(null);
  const todayLabel = new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
  const submitTask = (v) => {
    if (editingTask === 'new') addTask(v);
    else updateTask(editingTask.id, v);
    setEditingTask(null);
  };
  return (
    <div style={{ background: W.bg, minHeight: '100%', position: 'relative' }}>
      <DesktopHeader
        subtitle={todayLabel}
        title={`Good morning, ${wedding.brides}.`}
        note={confidence}
        action={{
          label: 'New task',
          icon: 'plus',
          onClick: () => setEditingTask('new'),
        }}
      />

      <div style={{ padding: '28px 36px 40px' }}>
        {/* Hero + stats row */}
        <div style={{
          display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 18, marginBottom: 18,
        }}>
          {/* Hero countdown */}
          <Card style={{
            padding: 0, overflow: 'hidden', background: W.cardDeep,
            color: '#f5efe2', border: 'none',
            boxShadow: '0 16px 40px -20px rgba(29,24,18,0.45)',
          }}>
            <div style={{ position: 'relative', padding: '28px 32px' }}>
              <div style={{
                position: 'absolute', inset: 0, pointerEvents: 'none',
                background: 'radial-gradient(120% 80% at 100% 0%, rgba(199,155,145,0.18), transparent 60%), radial-gradient(80% 60% at 0% 100%, rgba(168,122,79,0.20), transparent 60%)',
              }}/>
              <div style={{ position: 'relative' }}>
                <div style={{
                  fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                  letterSpacing: 1.8, textTransform: 'uppercase',
                  color: 'rgba(245,239,226,0.55)',
                }}>The Wedding of</div>
                <div style={{
                  fontFamily: FONT_DISPLAY, fontSize: 36, fontWeight: 500,
                  marginTop: 6, letterSpacing: -0.2, lineHeight: 1.05,
                }}>
                  {wedding.brides} <span style={{ fontStyle: 'italic', opacity: 0.85 }}>&amp;</span> {wedding.groom}
                </div>

                <div style={{
                  marginTop: 28, display: 'flex', alignItems: 'flex-end', gap: 22,
                }}>
                  <div style={{
                    fontFamily: FONT_DISPLAY, fontSize: 144, fontWeight: 400,
                    lineHeight: 0.82, letterSpacing: -6,
                  }}>{wedding.daysUntil}</div>
                  <div style={{ paddingBottom: 18 }}>
                    <div style={{
                      fontFamily: FONT_UI, fontSize: 11, fontWeight: 600,
                      letterSpacing: 1.6, textTransform: 'uppercase',
                      color: 'rgba(245,239,226,0.65)',
                    }}>Days until</div>
                    <div style={{
                      fontFamily: FONT_DISPLAY, fontStyle: 'italic',
                      fontSize: 26, marginTop: 4,
                    }}>{wedding.dateLabel}</div>
                  </div>
                </div>

                <div style={{
                  marginTop: 24, paddingTop: 18,
                  borderTop: '0.5px solid rgba(245,239,226,0.15)',
                  display: 'flex', alignItems: 'center', gap: 24,
                  fontFamily: FONT_UI, fontSize: 13,
                  color: 'rgba(245,239,226,0.75)',
                }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <Icon name="leaf" size={14} color="rgba(245,239,226,0.6)" strokeWidth={1.4}/>
                    {wedding.city}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <Icon name="calendar" size={14} color="rgba(245,239,226,0.6)" strokeWidth={1.4}/>
                    Ceremony · {wedding.timeLabel}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <Icon name="users" size={14} color="rgba(245,239,226,0.6)" strokeWidth={1.4}/>

                  </div>
                </div>
              </div>
            </div>
          </Card>

          {/* Stats column */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <DStat
              label="Budget Health"
              value={b.remaining >= 0 ? fmtK(b.remaining) : `−${fmtK(Math.abs(b.remaining))}`}
              sub={b.remaining >= 0 ? `of ${fmtK(b.total)} remaining` : 'over plan'}
              ring={b.total ? Math.min(1, b.spent / b.total) : 0}
              color={b.remaining < 0 ? W.red : W.clay} />
            <DStat label="RSVP Responses"    value={`${g.attending}/${Math.max(g.total, 1)}`}  sub={g.pending > 0 ? `${g.pending} still pending` : 'All in'}     ring={g.total ? g.attending/g.total : 0} color={W.sage} />
            <DStat label="Planning Readiness" value={`${readiness.score}%`}    sub="Across 5 signals"            ring={readiness.score/100} color={W.rose} />
          </div>
        </div>

        {/* Lower grid: Needs you + Right column */}
        <div style={{
          display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 18,
        }}>
          {/* Needs you */}
          <Card style={{ padding: 24 }}>
            <div style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
              marginBottom: 18,
            }}>
              <div>
                <div style={{
                  fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                  letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
                }}>This week</div>
                <div style={{
                  fontFamily: FONT_DISPLAY, fontSize: 24, fontWeight: 500,
                  color: W.ink, letterSpacing: -0.2, marginTop: 2,
                }}>Needs attention</div>
              </div>
              <div style={{
                fontFamily: FONT_UI, fontSize: 12.5, color: W.clay, fontWeight: 500,
              }}>See all 5</div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {signals.slice(0, 4).map(s => (
                <SignalCard key={s.id} signal={s}/>
              ))}
            </div>
          </Card>

          {/* This week strip + alerts */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
            <Card style={{ padding: 22 }}>
              <div style={{
                fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
                marginBottom: 16,
              }}>This week</div>
              <WeekStrip/>
            </Card>

            <Card style={{ padding: 22 }}>
              <div style={{
                fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
                marginBottom: 12,
              }}>Watch list</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {signals.length === 0 ? (
                  <div style={{
                    fontFamily: FONT_DISPLAY, fontStyle: 'italic', fontSize: 14, color: W.muted,
                  }}>Nothing on the watch list. Beautifully on track.</div>
                ) : signals.slice(0, 3).map(s => {
                  const dot = s.severity === 'urgent' ? W.red
                            : s.severity === 'warning' ? W.amber
                            : W.sage;
                  return (
                    <div key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                      <div style={{ width: 8, height: 8, borderRadius: 999, background: dot, flexShrink: 0 }}/>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{
                          fontFamily: FONT_UI, fontSize: 13.5, color: W.ink, fontWeight: 500,
                          whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                        }}>{s.title}</div>
                        {s.detail && (
                          <div style={{
                            fontFamily: FONT_UI, fontSize: 11.5, color: W.muted, marginTop: 2,
                            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                          }}>{s.detail}</div>
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </Card>
          </div>
        </div>

        {/* Your to-dos */}
        <div style={{ marginTop: 22 }}>
          <Card style={{ padding: 24 }}>
            <div style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
              marginBottom: 18,
            }}>
              <div>
                <div style={{
                  fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                  letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
                }}>Personal</div>
                <div style={{
                  fontFamily: FONT_DISPLAY, fontSize: 24, fontWeight: 500,
                  color: W.ink, letterSpacing: -0.2, marginTop: 2,
                }}>Your to-dos</div>
              </div>
              <button
                onClick={() => setEditingTask('new')}
                style={{
                  fontFamily: FONT_UI, fontSize: 12.5, color: W.clay, fontWeight: 500,
                  background: 'transparent', border: 'none', cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', gap: 4,
                }}>
                <Icon name="plus" size={12} color={W.clay} strokeWidth={1.8}/> Add task
              </button>
            </div>
            <div style={{
              display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8,
            }}>
              {activeTasks.slice(0, 6).map(t => (
                <TaskCard key={t.id} task={t}
                  onToggle={() => toggleTask(t.id)}
                  onEdit={() => setEditingTask(t)}/>
              ))}
            </div>
          </Card>
        </div>

        {/* Vendor payments row */}
        <div style={{ marginTop: 22 }}>
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
            marginBottom: 14,
          }}>
            <div>
              <div style={{
                fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
                letterSpacing: 1.6, textTransform: 'uppercase', color: W.muted,
              }}>Vendors</div>
              <div style={{
                fontFamily: FONT_DISPLAY, fontSize: 24, fontWeight: 500,
                color: W.ink, letterSpacing: -0.2, marginTop: 2,
              }}>Payments</div>
            </div>
            <button
              onClick={() => onNav && onNav('vendors')}
              style={{
                fontFamily: FONT_UI, fontSize: 12.5, color: W.clay, fontWeight: 500,
                background: 'transparent', border: 'none', cursor: 'pointer',
                padding: '4px 8px', borderRadius: 6,
              }}
              onMouseEnter={(e) => (e.currentTarget.style.background = 'rgba(168,122,79,0.08)')}
              onMouseLeave={(e) => (e.currentTarget.style.background = 'transparent')}
            >Manage →</button>
          </div>
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12,
          }}>
            {(() => {
              // Sort by urgency: due > booked > paid > researching · then take 4.
              const order = { due: 0, partial: 1, booked: 2, paid: 3, researching: 4 };
              const top4 = [...(v.all || [])]
                .sort((a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9))
                .slice(0, 4);
              if (top4.length === 0) {
                return (
                  <div style={{
                    gridColumn: 'span 4', padding: '20px 0', textAlign: 'center',
                    fontFamily: FONT_DISPLAY, fontStyle: 'italic', fontSize: 15,
                    color: W.muted,
                  }}>
                    No vendors yet · add your first one from Vendors.
                  </div>
                );
              }
              const toneFor = (s) =>
                s === 'due' ? 'amber'
                : s === 'partial' ? 'clay'
                : s === 'booked' ? 'sage'
                : s === 'paid' ? 'neutral'
                : 'neutral';
              const statusLabel = (vd) => {
                if (vd.next) return vd.next;
                if (vd.status === 'paid') return 'Paid';
                if (vd.status === 'booked') return 'Booked';
                if (vd.status === 'researching') return 'Researching';
                return 'Open';
              };
              return top4.map((vd, i) => (
                <VendorChip
                  key={vd.id || i}
                  name={vd.name}
                  status={statusLabel(vd)}
                  amount={Math.max(0, (vd.total || 0) - (vd.paid || 0))}
                  tone={toneFor(vd.status)}
                />
              ));
            })()}
          </div>
        </div>
      </div>

      {editingTask && (
        <FormSheet
          title={editingTask === 'new' ? 'Add a task' : 'Edit task'}
          eyebrow={editingTask === 'new' ? 'New' : 'Edit'}
          fields={taskFields(wedding.brides, wedding.groom)}
          initial={editingTask === 'new' ? {} : editingTask}
          submitLabel={editingTask === 'new' ? 'Add' : 'Save'}
          onClose={() => setEditingTask(null)}
          onSubmit={submitTask}
          onDelete={editingTask !== 'new' ? () => {
            updateTask(editingTask.id, { dismissed: true });
            setEditingTask(null);
          } : null}
        />
      )}
    </div>
  );
}

function DStat({ label, value, sub, ring, color }) {
  return (
    <Card style={{
      flex: 1, padding: 22, display: 'flex', alignItems: 'center', gap: 20,
    }}>
      <ProgressRing value={ring} size={64} stroke={5} color={color}>
        <div style={{
          fontFamily: FONT_DISPLAY, fontSize: 18, color: W.ink,
          letterSpacing: -0.3, lineHeight: 1,
        }}>{Math.round(ring*100)}%</div>
      </ProgressRing>
      <div style={{ flex: 1 }}>
        <div style={{
          fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
          letterSpacing: 1.4, textTransform: 'uppercase', color: W.muted,
        }}>{label}</div>
        <div style={{
          fontFamily: FONT_DISPLAY, fontSize: 28, color: W.ink, letterSpacing: -0.5,
          marginTop: 4, lineHeight: 1,
        }}>{value}</div>
        <div style={{
          fontFamily: FONT_UI, fontSize: 12, color: W.muted, marginTop: 4,
        }}>{sub}</div>
      </div>
    </Card>
  );
}

// ─── Wrapped mobile screens for other desktop tabs ─────────────
// Use the mobile screen inside a centered narrow column. Premium and easy.

function DesktopWrapped({ subtitle, title, action, children }) {
  return (
    <div style={{ background: W.bg, minHeight: '100%' }}>
      <DesktopHeader subtitle={subtitle} title={title} action={action}/>
      <div style={{
        maxWidth: 720, margin: '0 auto',
        padding: '8px 0 60px',
      }}>{children}</div>
    </div>
  );
}

// Vendors desktop screen
function DesktopVendors() {
  const vendors = useVendors();
  const [editing, setEditing] = React.useState(null);
  return (
    <div style={{ background: W.bg, minHeight: '100%', position: 'relative' }}>
      <DesktopHeader
        subtitle="Manage"
        title={vendors.all.length ? `${vendors.all.length} vendors` : 'Your vendor team'}
        action={{
          label: 'Add vendor',
          icon: 'plus',
          onClick: () => setEditing('new'),
        }}
      />
      <div style={{ padding: '24px 36px 40px' }}>
        {/* Top stats */}
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14, marginBottom: 22,
        }}>
          <VendorStat n={vendors.bookedCount}        label="Booked"        color={W.sage}/>
          <VendorStat n={vendors.counts.paid}        label="Paid in full"  color={W.clay}/>
          <VendorStat n={vendors.counts.researching} label="Researching"   color={W.faint}/>
          <VendorStat n={vendors.counts.due}         label="Due this week" color={W.amber}/>
        </div>

        {/* Vendor table or empty state */}
        {vendors.all.length === 0 ? (
          <Card style={{ padding: 48, textAlign: 'center' }}>
            <div style={{
              fontFamily: FONT_DISPLAY, fontSize: 24, color: W.ink,
              letterSpacing: -0.2, lineHeight: 1.1,
            }}>No vendors yet.</div>
            <div style={{
              fontFamily: FONT_UI, fontSize: 13.5, color: W.muted,
              marginTop: 10, lineHeight: 1.5,
            }}>Add your first vendor — venue, florist, photographer — to start tracking payments.</div>
            <button onClick={() => setEditing('new')} style={{
              marginTop: 18, padding: '11px 18px',
              background: W.ink, color: W.bg, border: 'none', borderRadius: 999,
              cursor: 'pointer',
              fontFamily: FONT_UI, fontSize: 13.5, fontWeight: 500,
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
              <Icon name="plus" size={14} color={W.bg}/>
              Add vendor
            </button>
          </Card>
        ) : (
          <Card style={{ padding: 0, overflow: 'hidden' }}>
            <div style={{
              display: 'grid',
              gridTemplateColumns: '2fr 1.2fr 1.2fr 1fr 1.5fr',
              padding: '14px 22px',
              background: '#fbf6ea',
              borderBottom: `0.5px solid ${W.lineSoft}`,
              fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
              letterSpacing: 1.4, textTransform: 'uppercase', color: W.muted,
            }}>
              <div>Vendor</div>
              <div>Contact</div>
              <div>Paid</div>
              <div>Status</div>
              <div>Next</div>
            </div>
            {vendors.all.map((v, i) => (
              <div key={v.id} onClick={() => setEditing(v)} style={{
                display: 'grid',
                gridTemplateColumns: '2fr 1.2fr 1.2fr 1fr 1.5fr',
                padding: '16px 22px',
                borderBottom: i < vendors.all.length - 1 ? `0.5px solid ${W.lineSoft}` : 'none',
                alignItems: 'center',
                fontFamily: FONT_UI, fontSize: 13.5, color: W.ink,
                cursor: 'pointer',
              }}>
                <div>
                  <div style={{ fontWeight: 500 }}>{v.name || <span style={{ color: W.muted, fontStyle: 'italic' }}>(unnamed)</span>}</div>
                  <div style={{ fontSize: 11.5, color: W.muted, marginTop: 2 }}>{v.role || '—'}</div>
                </div>
                <div style={{ color: W.ink2 }}>{v.contact || '—'}</div>
                <div style={{ fontFamily: FONT_DISPLAY, fontSize: 16, letterSpacing: -0.2 }}>
                  {v.total ? fmt$(v.paid) : '—'}
                  {v.total > 0 && (
                    <div style={{
                      fontFamily: FONT_UI, fontSize: 10.5, color: W.muted, marginTop: 1,
                    }}>of {fmt$(v.total)}</div>
                  )}
                </div>
                <div>
                  <Pill tone={
                    v.status === 'paid' ? 'sage' :
                    v.status === 'due' ? 'amber' :
                    v.status === 'partial' ? 'clay' :
                    v.status === 'booked' ? 'clay' :
                    'neutral'
                  } style={{ padding: '3px 8px', fontSize: 9.5 }}>{v.status}</Pill>
                </div>
                <div style={{ color: W.ink2, fontSize: 12.5 }}>{v.next || '—'}</div>
              </div>
            ))}
          </Card>
        )}
      </div>

      {editing && (
        <FormSheet
          title={editing === 'new' ? 'Add a vendor' : 'Edit vendor'}
          eyebrow={editing === 'new' ? 'New entry' : 'Edit'}
          fields={vendorFields()}
          initial={editing === 'new' ? {} : editing}
          submitLabel={editing === 'new' ? 'Add' : 'Save'}
          onClose={() => setEditing(null)}
          onSubmit={(values) => {
            const norm = {
              ...values,
              paid:  Number(values.paid)  || 0,
              total: Number(values.total) || 0,
            };
            if (editing === 'new') vendors.addVendor(norm);
            else vendors.updateVendor(editing.id, norm);
            setEditing(null);
          }}
          onDelete={editing !== 'new' ? () => {
            vendors.deleteVendor(editing.id);
            setEditing(null);
          } : null}
        />
      )}
    </div>
  );
}

function VendorStat({ n, label, color }) {
  return (
    <Card style={{ padding: 18 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ width: 8, height: 8, borderRadius: 999, background: color }}/>
        <div style={{
          fontFamily: FONT_UI, fontSize: 10.5, fontWeight: 600,
          letterSpacing: 1.4, textTransform: 'uppercase', color: W.muted,
        }}>{label}</div>
      </div>
      <div style={{
        fontFamily: FONT_DISPLAY, fontSize: 36, color: W.ink, letterSpacing: -0.6,
        lineHeight: 1, marginTop: 8,
      }}>{n}</div>
    </Card>
  );
}

// ─── Desktop Reports ──────────────────────────────────────────

function DesktopReports() {
  const [active, setActive] = React.useState('budget');
  const reports = [
    { id: 'budget',  label: 'Budget Summary',     comp: <BudgetReport/> },
    { id: 'seating', label: 'Seating Plan',       comp: <SeatingReport/> },
    { id: 'dayof',   label: 'Day-of Timeline',    comp: <DayOfReport/> },
  ];
  const current = reports.find(r => r.id === active);
  return (
    <div style={{ background: '#e8e2d1', minHeight: '100%' }}>
      <DesktopHeader subtitle="Reports" title="Print pack"
        note="Three printable documents drawn live from your planning data. Letter size, ready for your venue, planner, and vendors."/>

      {/* Tab switcher */}
      <div style={{
        padding: '20px 36px 0',
        display: 'flex', alignItems: 'center', gap: 8,
      }}>
        {reports.map(r => {
          const isActive = r.id === active;
          return (
            <button key={r.id} onClick={() => setActive(r.id)} style={{
              background: isActive ? W.ink : W.card,
              color: isActive ? W.bg : W.ink2,
              border: isActive ? 'none' : `0.5px solid ${W.line}`,
              padding: '8px 16px', borderRadius: 999, cursor: 'pointer',
              fontFamily: FONT_UI, fontSize: 13, fontWeight: 500,
            }}>{r.label}</button>
          );
        })}
        <div style={{ flex: 1 }}/>
        <button onClick={() => printReport(active)} style={{
          background: W.card, color: W.ink2,
          border: `0.5px solid ${W.line}`,
          padding: '8px 14px', borderRadius: 999, cursor: 'pointer',
          fontFamily: FONT_UI, fontSize: 13, fontWeight: 500,
          display: 'flex', alignItems: 'center', gap: 6,
          marginRight: 6,
        }}>
          <Icon name="sparkle" size={13} color={W.muted}/>
          Print this
        </button>
        <button onClick={() => printAllReports()} style={{
          background: W.ink, color: W.bg,
          border: 'none',
          padding: '8px 14px', borderRadius: 999, cursor: 'pointer',
          fontFamily: FONT_UI, fontSize: 13, fontWeight: 500,
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          <Icon name="sparkle" size={13} color={W.bg}/>
          Print all 3
        </button>
      </div>

      {/* The page */}
      <div style={{
        padding: '24px 36px 48px',
        display: 'flex', justifyContent: 'center',
      }}>
        <div style={{ transform: 'scale(0.92)', transformOrigin: 'top center' }}>
          {current.comp}
        </div>
      </div>
    </div>
  );
}

// ─── Desktop Guests route ─────────────────────────────────────

function DesktopGuestsRoute() {
  const g = useGuests();
  const titleText = g.total === 0
    ? 'Guest list'
    : `${g.total} ${g.total === 1 ? 'guest' : 'guests'}`;
  return (
    <DesktopWrapped subtitle="Guests" title={titleText}>
      <GuestsScreen/>
    </DesktopWrapped>
  );
}

// ─── Desktop App ──────────────────────────────────────────────

function DesktopApp() {
  const [tab, setTab] = React.useState('home');

  let content;
  if (tab === 'home')    content = <DesktopDashboard onNav={setTab}/>;
  else if (tab === 'vendors') content = <DesktopVendors/>;
  else if (tab === 'budget') content = (
    <DesktopWrapped subtitle="Budget" title="$60,000 plan">
      <BudgetScreen/>
    </DesktopWrapped>
  );
  else if (tab === 'guests') content = <DesktopGuestsRoute/>;
  else if (tab === 'seating') content = (
    <DesktopWrapped subtitle="Seating" title="Floor plan">
      <SeatingScreen/>
    </DesktopWrapped>
  );
  else if (tab === 'cal') content = (
    <DesktopWrapped subtitle="Calendar" title="September 2026">
      <CalendarScreen/>
    </DesktopWrapped>
  );
  else if (tab === 'mood') content = (
    <DesktopWrapped subtitle="Story" title="Moodboard">
      <MoodboardScreen/>
    </DesktopWrapped>
  );
  else if (tab === 'party') content = (
    <DesktopWrapped subtitle="Story" title="Wedding party">
      <WeddingPartyScreen/>
    </DesktopWrapped>
  );
  else if (tab === 'dayof') content = (
    <DesktopWrapped subtitle="Day of" title="Wedding day">
      <DayOfScreen onBack={() => {}}/>
    </DesktopWrapped>
  );
  else if (tab === 'export') content = <DesktopReports/>;
  else if (tab === 'settings') content = (
    <DesktopWrapped subtitle="Manage" title="Settings">
      <SettingsScreen onBack={() => {}}/>
    </DesktopWrapped>
  );
  else content = (
    <DesktopWrapped subtitle="Coming soon" title="In progress">
      <div style={{
        padding: 80, textAlign: 'center',
        fontFamily: FONT_DISPLAY, fontStyle: 'italic',
        fontSize: 22, color: W.muted,
      }}>This view is on the way.</div>
    </DesktopWrapped>
  );

  return (
    <div style={{
      display: 'flex', height: '100%', minHeight: 760,
      background: W.bg, fontFamily: FONT_UI,
    }}>
      <DesktopSidebar active={tab} onChange={setTab}/>
      <div style={{ flex: 1, overflow: 'auto' }}>{content}</div>
    </div>
  );
}

Object.assign(window, { DesktopApp });
