/* global React, AuroraMark, CDial, COrb, CHoldButton, CSeg, CGlass,
   UScreen, UTabBar, URow, UDropdownRow, UTimeScroller, UEditHeader, USleepGoal, fmt, sleepGoal, chevR, U_TOK */
// Canonical Aurora screens — single source of truth, rendered by BOTH the Unified
// router (Aurora App - Unified.html) and the Combined canvas (Aurora App - Combined.html).
// Screens never render the footer tab bar; the wrapper supplies it for tab-level screens.

const { useState: uState, useEffect: uEffect, useRef: uRef } = React;
const K = U_TOK;
const { C_BG, C_FIRE, C_MORN, C_CORAL, C_INDIGO, C_GREEN, C_GOLD, C_TEXT, C_DIM, C_MUTED, C_CARD } = K;

const moonIcon = <svg width="20" height="20" viewBox="0 0 24 24"><path d="M20 14.5 A8 8 0 1 1 11 4 a6.5 6.5 0 0 0 9 10.5z" fill={C_INDIGO}/></svg>;
const bellIcon = <svg width="20" height="20" viewBox="0 0 24 24"><path d="M12 2 a6 6 0 0 0 -6 6 v5 l-2 3 h16 l-2 -3 v-5 a6 6 0 0 0 -6 -6z M10 19 a2 2 0 0 0 4 0z" fill={C_CORAL}/></svg>;

// flat row inside the grouped Bedtime/Alarm summary card (no own background)
const URowFlat = ({ icon, label, value, border, onClick }) => {
  const [p, setP] = uState(false);
  return (
    <div onClick={onClick}
      onMouseDown={() => setP(true)} onMouseUp={() => setP(false)} onMouseLeave={() => setP(false)} onTouchStart={() => setP(true)} onTouchEnd={() => setP(false)}
      style={{ display: 'flex', alignItems: 'center', gap: 13, padding: '14px 18px', borderBottom: border ? '1px solid rgba(255,255,255,0.06)' : 'none', background: p ? 'rgba(255,255,255,0.06)' : 'transparent', transition: 'background 0.12s', userSelect: 'none', cursor: onClick ? 'pointer' : 'default' }}>
      {icon}
      <span style={{ fontSize: 15, fontWeight: 500 }}>{label}</span>
      <span style={{ flex: 1 }}/>
      <span style={{ fontSize: 19, fontWeight: 500, letterSpacing: '-0.01em' }}>{value}</span>
      {chevR()}
    </div>
  );
};

// ════════ WAKE — main · alarm dial + multiple alarms ════════
const dayLetters = ['M','T','W','T','F','S','S'];
const summarize = (days = []) => {
  const n = days.filter(Boolean).length;
  if (n === 0) return 'Once';
  if (n === 7) return 'Every day';
  if (days[0]&&days[1]&&days[2]&&days[3]&&days[4]&&!days[5]&&!days[6]) return 'Weekdays';
  if (!days[0]&&!days[1]&&!days[2]&&!days[3]&&!days[4]&&days[5]&&days[6]) return 'Weekends';
  return null;
};

const UAlarmRow = ({ a, selected, onSelect, onToggle, onEdit, onDelete, canDelete }) => (
  <div onClick={onSelect} style={{ background: selected ? 'rgba(255,122,89,0.12)' : C_CARD, border: selected ? `1px solid ${C_CORAL}66` : '1px solid rgba(255,255,255,0.06)', borderRadius: 16, padding: '13px 16px', cursor: 'pointer', transition: 'background 0.15s, border-color 0.15s', userSelect: 'none' }}>
    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontSize: 30, fontWeight: 600, letterSpacing: '-0.03em', color: a.enabled ? C_TEXT : 'rgba(232,230,240,0.4)', fontVariantNumeric: 'tabular-nums' }}>{fmt(a)}</span>
          <span style={{ fontSize: 12, opacity: a.enabled ? 0.55 : 0.3 }}>{a.label}</span>
        </div>
        <div style={{ display: 'flex', gap: 5, marginTop: 6 }}>
          {dayLetters.map((d, i) => (
            <span key={i} style={{ fontSize: 10.5, fontWeight: 600, width: 15, textAlign: 'center', color: a.days[i] ? (a.enabled ? C_CORAL : 'rgba(255,122,89,0.45)') : 'rgba(232,230,240,0.22)' }}>{d}</span>
          ))}
        </div>
      </div>
      <div onClick={(e) => { e.stopPropagation(); onToggle(); }} style={{ width: 42, height: 25, borderRadius: 13, background: a.enabled ? C_CORAL : 'rgba(255,255,255,0.15)', position: 'relative', transition: 'background 0.2s', flex: '0 0 auto', cursor: 'pointer' }}>
        <div style={{ position: 'absolute', top: 2.5, left: a.enabled ? 20 : 2.5, width: 20, height: 20, borderRadius: '50%', background: '#fff', transition: 'left 0.2s cubic-bezier(0.4,0,0.2,1)' }}/>
      </div>
    </div>
    {selected && (
      <div style={{ display: 'flex', gap: 18, marginTop: 12, paddingTop: 11, borderTop: '1px solid rgba(255,255,255,0.08)' }}>
        <button onClick={(e) => { e.stopPropagation(); onEdit(); }} style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', color: C_TEXT, fontSize: 12.5, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6, padding: 0 }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M4 20h4L18 10l-4-4L4 16v4z" stroke={C_TEXT} strokeWidth="2" strokeLinejoin="round"/></svg>
          Edit details
        </button>
        <span style={{ flex: 1 }}/>
        {canDelete && (
          <button onClick={(e) => { e.stopPropagation(); onDelete(); }} style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', color: 'rgba(232,230,240,0.5)', fontSize: 12.5, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6, padding: 0 }}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M5 7h14M10 7V5h4v2M6 7l1 13h10l1-13" stroke="rgba(232,230,240,0.5)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
            Delete
          </button>
        )}
      </div>
    )}
  </div>
);

const UWakeHome = ({ alarms, selectedIndex, onSelect, onToggle, onAdd, onDelete, onDialChange, onEdit }) => (
  <UScreen bg={C_BG}>
    <div style={{ padding: '16px 28px 0' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
        <AuroraMark size={28} tone="invert"/>
        <div style={{ fontSize: 25, fontWeight: 600, letterSpacing: '-0.02em' }}>Aurora</div>
      </div>
    </div>

    <div style={{ display: 'grid', placeItems: 'center', padding: '12px 0 6px' }}>
      <CDial size={196} alarms={alarms} selectedIndex={selectedIndex} onChange={onDialChange}/>
    </div>

    <div className="aurScroll" style={{ padding: '6px 20px 0', display: 'flex', flexDirection: 'column', gap: 9, overflowY: 'auto' }}>
      {alarms.map((a, i) => (
        <UAlarmRow key={a.id} a={a} selected={i === selectedIndex}
          onSelect={() => onSelect(i)} onToggle={() => onToggle(i)} onEdit={() => onEdit(i)}
          onDelete={() => onDelete(i)} canDelete={alarms.length > 1}/>
      ))}
      <button onClick={onAdd} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '12px', borderRadius: 14, background: 'transparent', border: '1px dashed rgba(255,255,255,0.2)', color: C_CORAL, fontFamily: 'inherit', fontSize: 13, fontWeight: 600, cursor: 'pointer' }}>
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none"><path d="M12 5v14M5 12h14" stroke={C_CORAL} strokeWidth="2" strokeLinecap="round"/></svg>
        Add alarm
      </button>
    </div>
  </UScreen>
);

// ════════ WAKE SOUND SHEET ════════
const SOUND_PRESETS = [
  { id: 'birds',   label: 'Birds at dawn',  desc: 'Gentle nature ambience' },
  { id: 'chimes',  label: 'Gentle chimes',  desc: 'Soft and melodic' },
  { id: 'tide',    label: 'Rising tide',    desc: 'Ocean waves, slow build' },
  { id: 'piano',   label: 'Soft piano',     desc: 'Calm & minimal' },
  { id: 'marimba', label: 'Marimba',        desc: 'Warm, hard to sleep through' },
  { id: 'classic', label: 'Classic ring',   desc: 'Traditional alarm tone' },
  { id: 'digital', label: 'Digital pulse',  desc: 'Sharp and effective' },
];

const LIBRARY_MOCK = [
  { id: 'l1', title: 'Morning Mood',        artist: 'Edvard Grieg' },
  { id: 'l2', title: 'Here Comes the Sun',  artist: 'The Beatles' },
  { id: 'l3', title: 'Walking on Sunshine', artist: 'Katrina & The Waves' },
  { id: 'l4', title: 'Lovely Day',          artist: 'Bill Withers' },
  { id: 'l5', title: 'Good Day Sunshine',   artist: 'The Beatles' },
  { id: 'l6', title: 'Aqua',                artist: 'Boards of Canada' },
];

function WakeSoundSheet({ current, onClose, onChange }) {
  const [selected, setSelected] = uState(current);
  const [tab, setTab]           = uState('presets');
  const [playing, setPlaying]   = uState(null);
  const [ytUrl, setYtUrl]       = uState('');
  const [ytPhase, setYtPhase]   = uState('idle'); // idle | loading | done
  const [libQuery, setLibQuery] = uState('');

  const filtered = LIBRARY_MOCK.filter(t =>
    !libQuery ||
    t.title.toLowerCase().includes(libQuery.toLowerCase()) ||
    t.artist.toLowerCase().includes(libQuery.toLowerCase())
  );

  const doImport = () => {
    if (!ytUrl.trim() || ytPhase === 'loading') return;
    setYtPhase('loading');
    setTimeout(() => { setYtPhase('done'); setSelected('Custom · YouTube'); }, 2600);
  };

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 220 }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.55)', animation: 'sheetScrim 0.2s ease' }}/>
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, background: 'rgba(16,14,24,0.98)', backdropFilter: 'blur(28px)', borderTopLeftRadius: 28, borderTopRightRadius: 28, border: '1px solid rgba(255,255,255,0.1)', borderBottom: 'none', maxHeight: '86%', display: 'flex', flexDirection: 'column', animation: 'sheetUp 0.26s cubic-bezier(0.2,0.9,0.3,1)' }}>

        {/* Handle + header */}
        <div style={{ padding: '10px 18px 0', flexShrink: 0 }}>
          <div style={{ width: 38, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.22)', margin: '0 auto 14px' }}/>
          <div style={{ display: 'flex', alignItems: 'center', marginBottom: 14 }}>
            <span style={{ flex: 1, fontSize: 17, fontWeight: 600, color: C_TEXT }}>Wake sound</span>
            <button onClick={() => { onChange(selected); onClose(); }} style={{ background: C_CORAL, border: 'none', borderRadius: 10, padding: '8px 20px', color: '#fff', fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>Done</button>
          </div>
          {/* Tab bar */}
          <div style={{ display: 'flex', background: 'rgba(255,255,255,0.06)', borderRadius: 12, padding: 3, gap: 2, marginBottom: 2 }}>
            {[{ id: 'presets', label: 'Presets' }, { id: 'youtube', label: 'YouTube' }, { id: 'library', label: 'Library' }].map(t => (
              <button key={t.id} onClick={() => setTab(t.id)} style={{ flex: 1, padding: '8px 0', borderRadius: 10, border: 'none', fontFamily: 'inherit', fontSize: 13, fontWeight: tab === t.id ? 600 : 400, cursor: 'pointer', background: tab === t.id ? 'rgba(255,255,255,0.13)' : 'transparent', color: tab === t.id ? C_TEXT : C_DIM, transition: 'background 0.15s' }}>
                {t.label}
              </button>
            ))}
          </div>
        </div>

        {/* Scrollable content */}
        <div className="aurScroll" style={{ flex: 1, overflowY: 'auto', padding: '12px 14px 28px' }}>

          {/* ── PRESETS ── */}
          {tab === 'presets' && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              {SOUND_PRESETS.map(p => {
                const on = selected === p.label;
                return (
                  <div key={p.id} onClick={() => setSelected(p.label)}
                    style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderRadius: 14, background: on ? 'rgba(255,122,89,0.14)' : 'transparent', cursor: 'pointer', transition: 'background 0.15s', userSelect: 'none' }}>
                    <button onClick={(e) => { e.stopPropagation(); setPlaying(playing === p.id ? null : p.id); }}
                      style={{ width: 36, height: 36, borderRadius: '50%', background: 'rgba(255,255,255,0.09)', border: '1px solid rgba(255,255,255,0.1)', display: 'grid', placeItems: 'center', cursor: 'pointer', flex: '0 0 auto' }}>
                      {playing === p.id
                        ? <svg width="10" height="10" viewBox="0 0 24 24"><rect x="5" y="4" width="5" height="16" fill={C_CORAL}/><rect x="14" y="4" width="5" height="16" fill={C_CORAL}/></svg>
                        : <svg width="10" height="10" viewBox="0 0 24 24"><path d="M5 3l14 9-14 9V3z" fill={C_TEXT}/></svg>}
                    </button>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 15, fontWeight: on ? 600 : 400, color: C_TEXT }}>{p.label}</div>
                      <div style={{ fontSize: 12, opacity: 0.42, marginTop: 2 }}>{p.desc}</div>
                    </div>
                    {on && <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke={C_CORAL} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                  </div>
                );
              })}
            </div>
          )}

          {/* ── YOUTUBE ── */}
          {tab === 'youtube' && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div style={{ fontSize: 13, color: C_DIM, lineHeight: 1.65 }}>
                Paste a YouTube URL — the audio is extracted and saved locally on your device, so it plays even offline.
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                <input value={ytUrl} onChange={(e) => { setYtUrl(e.target.value); setYtPhase('idle'); }}
                  placeholder="https://youtube.com/watch?v=…"
                  style={{ flex: 1, background: 'rgba(255,255,255,0.08)', border: `1px solid ${ytPhase === 'done' ? C_GREEN : 'rgba(255,255,255,0.14)'}`, borderRadius: 12, padding: '12px 14px', color: C_TEXT, fontSize: 13, fontFamily: 'inherit', outline: 'none', transition: 'border-color 0.3s' }}/>
                <button onClick={doImport} style={{ background: ytPhase === 'done' ? C_GREEN : C_CORAL, border: 'none', borderRadius: 12, padding: '0 20px', color: '#fff', fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', opacity: ytUrl.trim() ? 1 : 0.45, transition: 'background 0.3s, opacity 0.2s', flexShrink: 0 }}>
                  {ytPhase === 'loading' ? '…' : ytPhase === 'done' ? '✓' : 'Import'}
                </button>
              </div>
              {ytPhase === 'loading' && (
                <div style={{ background: 'rgba(255,255,255,0.05)', borderRadius: 14, padding: '14px 16px' }}>
                  <div style={{ fontSize: 13, opacity: 0.65, marginBottom: 10 }}>Extracting audio…</div>
                  <div style={{ height: 4, background: 'rgba(255,255,255,0.08)', borderRadius: 2, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: '70%', background: C_CORAL, borderRadius: 2, animation: 'beam 1.1s ease-in-out infinite' }}/>
                  </div>
                </div>
              )}
              {ytPhase === 'done' && (
                <div style={{ background: 'rgba(95,219,167,0.1)', border: `1px solid rgba(95,219,167,0.28)`, borderRadius: 14, padding: '14px 16px' }}>
                  <div style={{ fontSize: 13, color: C_GREEN, fontWeight: 600 }}>✓ Audio saved to device</div>
                  <div style={{ fontSize: 12, opacity: 0.6, marginTop: 4, lineHeight: 1.55 }}>Plays at alarm time even without an internet connection.</div>
                </div>
              )}
              <div style={{ background: 'rgba(255,255,255,0.04)', borderRadius: 12, padding: '12px 14px' }}>
                <div style={{ fontSize: 11, opacity: 0.38, lineHeight: 1.65 }}>Only audio is extracted — no video is stored. Aurora never shares your URL. The audio file lives entirely on your device.</div>
              </div>
            </div>
          )}

          {/* ── LIBRARY ── */}
          {tab === 'library' && (
            <div>
              <div style={{ position: 'relative', marginBottom: 12 }}>
                <input value={libQuery} onChange={(e) => setLibQuery(e.target.value)} placeholder="Search music library"
                  style={{ width: '100%', background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 12, padding: '11px 14px 11px 40px', color: C_TEXT, fontSize: 14, fontFamily: 'inherit', outline: 'none', boxSizing: 'border-box' }}/>
                <svg style={{ position: 'absolute', left: 13, top: '50%', transform: 'translateY(-50%)', opacity: 0.35, pointerEvents: 'none' }} width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="7" stroke={C_TEXT} strokeWidth="2"/><path d="M16.5 16.5l4 4" stroke={C_TEXT} strokeWidth="2" strokeLinecap="round"/></svg>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                {filtered.map(t => {
                  const on = selected === t.title;
                  return (
                    <div key={t.id} onClick={() => setSelected(t.title)}
                      style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px', borderRadius: 12, background: on ? 'rgba(255,122,89,0.14)' : 'transparent', cursor: 'pointer', transition: 'background 0.15s', userSelect: 'none' }}>
                      <div style={{ width: 42, height: 42, borderRadius: 8, background: 'rgba(255,255,255,0.07)', border: '1px solid rgba(255,255,255,0.08)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                        <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="3" fill={C_CORAL} opacity="0.65"/><circle cx="12" cy="12" r="8" stroke={C_DIM} strokeWidth="1"/><circle cx="12" cy="12" r="11" stroke={C_MUTED} strokeWidth="0.5"/></svg>
                      </div>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 15, fontWeight: on ? 600 : 400, color: C_TEXT }}>{t.title}</div>
                        <div style={{ fontSize: 12, opacity: 0.42, marginTop: 2 }}>{t.artist}</div>
                      </div>
                      {on && <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke={C_CORAL} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                    </div>
                  );
                })}
                {filtered.length === 0 && <div style={{ textAlign: 'center', padding: '28px 0', fontSize: 13, opacity: 0.35 }}>No tracks found</div>}
              </div>
              <div style={{ marginTop: 16, fontSize: 11, opacity: 0.35, lineHeight: 1.65 }}>Sourced from your device library. Streaming services are not supported — download tracks first.</div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ════════ VOLUME SLIDER ════════
function VolumeSlider({ value, onChange }) {
  const trackRef = uRef(null);
  const [dragging, setDragging] = uState(false);

  const fromX = (clientX) => {
    if (!trackRef.current) return;
    const rect = trackRef.current.getBoundingClientRect();
    const pct = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
    onChange(Math.round(pct * 100));
  };

  return (
    <div style={{ background: C_CARD, borderRadius: 14, padding: '14px 16px 18px', border: '1px solid rgba(255,255,255,0.05)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <path d="M3 9v6h4l5 5V4L7 9H3z" stroke={value > 0 ? C_TEXT : C_MUTED} strokeWidth="2" strokeLinejoin="round" fill={value > 0 ? 'rgba(255,255,255,0.08)' : 'none'}/>
          {value > 25 && <path d="M16 8a5 5 0 0 1 0 8" stroke={C_CORAL} strokeWidth="2" strokeLinecap="round"/>}
          {value > 60 && <path d="M19 5a9 9 0 0 1 0 14" stroke={C_CORAL} strokeWidth="2" strokeLinecap="round" opacity="0.6"/>}
        </svg>
        <span style={{ flex: 1, fontSize: 15, fontWeight: 500 }}>Volume</span>
        <span style={{ fontSize: 14, opacity: 0.55, fontVariantNumeric: 'tabular-nums', minWidth: 38, textAlign: 'right' }}>{value}%</span>
      </div>
      <div
        ref={trackRef}
        style={{ position: 'relative', height: 28, cursor: 'pointer', userSelect: 'none', touchAction: 'none', display: 'flex', alignItems: 'center' }}
        onMouseDown={(e) => { setDragging(true); fromX(e.clientX); }}
        onMouseMove={(e) => dragging && fromX(e.clientX)}
        onMouseUp={() => setDragging(false)}
        onMouseLeave={() => setDragging(false)}
        onTouchStart={(e) => { e.preventDefault(); setDragging(true); fromX(e.touches[0].clientX); }}
        onTouchMove={(e) => { e.preventDefault(); fromX(e.touches[0].clientX); }}
        onTouchEnd={() => setDragging(false)}
      >
        <div style={{ position: 'absolute', left: 0, right: 0, height: 5, background: 'rgba(255,255,255,0.1)', borderRadius: 3 }}>
          <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: `${value}%`, background: `linear-gradient(to right, ${C_INDIGO}, ${C_CORAL})`, borderRadius: 3 }}/>
        </div>
        <div style={{ position: 'absolute', left: `${value}%`, transform: 'translateX(-50%)', width: 22, height: 22, borderRadius: '50%', background: '#fff', boxShadow: `0 2px 7px rgba(0,0,0,0.45), 0 0 0 3px ${C_CORAL}2a`, transition: dragging ? 'none' : 'left 0.04s' }}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 11, opacity: 0.3 }}>
        <span>Silent</span><span>Max</span>
      </div>
    </div>
  );
}

// ════════ ALARM — edit (per-alarm: time, name, days, wake method, sound, volume) ════════
const UAlarmEdit = ({ alarm, update, onBack }) => {
  const conv = alarm.method === 'Conversation';
  const toggleDay = (i) => { const nd = alarm.days.slice(); nd[i] = !nd[i]; update({ days: nd }); };
  const [showSoundSheet, setShowSoundSheet] = uState(false);
  return (
    <UScreen bg={C_BG} padBottom={28}>
      <div style={{ padding: '10px 20px 4px', display: 'flex', alignItems: 'center' }}>
        <button onClick={onBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'grid', placeItems: 'center' }}>
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M15 5l-7 7 7 7" stroke={C_TEXT} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
        <span style={{ flex: 1, textAlign: 'center', fontSize: 18, fontWeight: 600 }}>Edit alarm</span>
        <span style={{ width: 24 }}/>
      </div>
      <UTimeScroller hour={alarm.h} min={alarm.m} setHour={(h) => update({ h })} setMin={(m) => update({ m })}/>
      <div className="aurScroll" style={{ padding: '8px 16px 0', display: 'flex', flexDirection: 'column', gap: 10, overflowY: 'auto' }}>
        {/* Name */}
        <div style={{ background: C_CARD, borderRadius: 14, padding: '13px 16px', border: '1px solid rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ fontSize: 15, fontWeight: 500 }}>Name</span>
          <input value={alarm.label} onChange={(e) => update({ label: e.target.value })} placeholder="Alarm" maxLength={24}
            style={{ flex: 1, textAlign: 'right', background: 'none', border: 'none', color: C_TEXT, fontFamily: 'inherit', fontSize: 15, outline: 'none' }}/>
        </div>
        {/* Repeat days */}
        <div style={{ background: C_CARD, borderRadius: 14, padding: '14px 16px', border: '1px solid rgba(255,255,255,0.05)' }}>
          <div style={{ display: 'flex', alignItems: 'center', marginBottom: 12 }}>
            <span style={{ flex: 1, fontSize: 15, fontWeight: 500 }}>Repeat</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            {dayLetters.map((d, i) => {
              const on = alarm.days[i];
              return <div key={i} onClick={() => toggleDay(i)} style={{ width: 36, height: 36, borderRadius: '50%', display: 'grid', placeItems: 'center', cursor: 'pointer', background: on ? C_CORAL : 'rgba(255,255,255,0.06)', color: on ? '#fff' : C_MUTED, fontSize: 13, fontWeight: 600, userSelect: 'none', transition: 'background 0.15s, color 0.15s' }}>{d}</div>;
            })}
          </div>
        </div>
        {/* Wake method */}
        <div style={{ background: C_CARD, borderRadius: 14, padding: '14px 16px', border: '1px solid rgba(255,255,255,0.05)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
            <span style={{ flex: 1, fontSize: 15, fontWeight: 500 }}>Wake method</span>
            <span style={{ fontSize: 10, letterSpacing: '0.12em', color: conv ? C_CORAL : C_GREEN, fontWeight: 600 }}>{conv ? 'NO EASY OFF' : 'SHARED-ROOM OK'}</span>
          </div>
          <CSeg options={['Conversation','Agent only']} value={alarm.method} onChange={(m) => update({ method: m })}/>
          <div style={{ fontSize: 12, opacity: 0.62, lineHeight: 1.5, marginTop: 10 }}>
            {conv ? 'Aurora asks; you answer out loud to wake. The stop button is deliberately hard — no dismissing on autopilot.' : "Aurora speaks your brief, no reply needed. Hold to stop. Best when you can't talk out loud."}
          </div>
        </div>
        {/* Wake sound — opens full sheet */}
        <div onClick={() => setShowSoundSheet(true)}
          style={{ background: C_CARD, borderRadius: 14, padding: '14px 16px', border: '1px solid rgba(255,255,255,0.05)', display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer', userSelect: 'none' }}>
          <span style={{ flex: 1, fontSize: 15, fontWeight: 500 }}>Wake sound</span>
          <span style={{ fontSize: 14, opacity: 0.52, maxWidth: 160, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{alarm.wakeSound}</span>
          {chevR()}
        </div>
        {/* Volume */}
        <VolumeSlider value={alarm.volume ?? 70} onChange={(v) => update({ volume: v })}/>
        {/* Gradual ramp */}
        <URow label="Gradual volume ramp" sub="Starts at 20%, rises over 60 s" toggle on={alarm.gradualVolume ?? true} onClick={() => update({ gradualVolume: !(alarm.gradualVolume ?? true) })}/>
        {/* Vibration */}
        <URow label="Vibration" toggle on={alarm.vibration} onClick={() => update({ vibration: !alarm.vibration })}/>
      </div>
      {showSoundSheet && <WakeSoundSheet current={alarm.wakeSound} onClose={() => setShowSoundSheet(false)} onChange={(v) => update({ wakeSound: v })}/>}
    </UScreen>
  );
};

// ════════ FIRES · CONVERSATION ════════
//   speaking → listening (you answer) → offer (Aurora asks to plan the day).
//   During the talk, the only escape is "Hold 5s to silence" → switches to agent-only.
//   Once you're confirmed awake, two buttons: Plan my day / Not now.
const UFiresTalk = ({ alarm, onPlan, onDismiss, onSilence }) => {
  const [phase, setPhase] = uState('speaking'); // speaking | listening | offer
  uEffect(() => {
    const t1 = setTimeout(() => setPhase('listening'), 2400);
    const t2 = setTimeout(() => setPhase('offer'), 5200);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, []);
  const speaking = phase === 'speaking';
  const offer = phase === 'offer';
  return (
    <UScreen bg={C_FIRE} color="#fff" padBottom={0}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', padding: '10px 28px 28px' }}>
        <div style={{ textAlign: 'center', marginTop: 8 }}>
          <div style={{ fontSize: 10, letterSpacing: '0.25em', opacity: 0.75 }}>GOOD MORNING, ALEX</div>
          <div style={{ fontSize: 72, fontWeight: 200, letterSpacing: '-0.04em', lineHeight: 1.05, marginTop: 6 }}>{fmt(alarm)}</div>
          <div style={{ fontSize: 13, opacity: 0.75, marginTop: 2 }}>Tuesday · 14 May · 14°</div>
        </div>

        <div style={{ marginTop: 22 }}>
          <COrb size={104} speaking={speaking} settledLabel="AURORA · LISTENING" settledDot={C_GREEN}/>
        </div>

        {/* exchange */}
        <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 7 }}>
          <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
            <div style={{ maxWidth: '85%', padding: '9px 13px', borderRadius: 15, borderBottomLeftRadius: 4, fontSize: 13, lineHeight: 1.4, background: 'rgba(255,255,255,0.13)', backdropFilter: 'blur(16px)' }}>Morning. Standup with Sara at 9:30 — how are you feeling?</div>
          </div>
          <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
            <div style={{ maxWidth: '85%', padding: '9px 13px', borderRadius: 15, borderBottomRightRadius: 4, fontSize: 13, lineHeight: 1.4, background: 'rgba(255,122,89,0.34)', backdropFilter: 'blur(16px)', opacity: speaking ? 0 : 1, transition: 'opacity 0.5s' }}>Awake-ish. Coffee, please.</div>
          </div>
          {offer && (
            <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
              <div style={{ maxWidth: '85%', padding: '9px 13px', borderRadius: 15, borderBottomLeftRadius: 4, fontSize: 13, lineHeight: 1.4, background: 'rgba(255,255,255,0.13)', backdropFilter: 'blur(16px)', animation: 'sheetScrim 0.4s ease' }}>Good — you're up. Want me to plan your day?</div>
            </div>
          )}
        </div>

        {/* bottom control */}
        <div style={{ marginTop: 'auto' }}>
          {offer ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <button onClick={onPlan} style={{ width: '100%', height: 60, borderRadius: 999, background: '#ff7a59', border: 'none', color: '#fff', fontFamily: 'inherit', fontSize: 16, fontWeight: 600, cursor: 'pointer' }}>Plan my day</button>
              <button onClick={onDismiss} style={{ width: '100%', height: 50, borderRadius: 999, background: 'transparent', border: '1px solid rgba(255,255,255,0.25)', color: '#fff', fontFamily: 'inherit', fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>Not now</button>
            </div>
          ) : (
            <CHoldButton small label="Can't talk right now? Hold 5s to silence" holdingLabel="Switching to silent…" doneLabel="Silent mode" duration={5000} onDone={onSilence}/>
          )}
        </div>
      </div>
    </UScreen>
  );
};

// ════════ FIRES · AGENT ONLY ════════
const UFiresAgent = ({ alarm, onStop }) => {
  const [phase, setPhase] = uState('speaking');
  uEffect(() => { const t = setTimeout(() => setPhase('settled'), 3600); return () => clearTimeout(t); }, []);
  const speaking = phase === 'speaking';
  return (
    <UScreen bg={C_FIRE} color="#fff" padBottom={0}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', padding: '10px 28px 28px' }}>
        <div style={{ textAlign: 'center', marginTop: 8 }}>
          <div style={{ fontSize: 10, letterSpacing: '0.25em', opacity: 0.75 }}>GOOD MORNING, ALEX</div>
          <div style={{ fontSize: 72, fontWeight: 200, letterSpacing: '-0.04em', lineHeight: 1.05, marginTop: 6 }}>{fmt(alarm)}</div>
          <div style={{ fontSize: 13, opacity: 0.75, marginTop: 2 }}>Tuesday · 14 May · 14°</div>
        </div>
        <div style={{ marginTop: 22 }}>
          <COrb size={104} speaking={speaking} settledLabel="BRIEF READ" settledDot={C_GREEN}/>
        </div>
        <div style={{ marginTop: 20, padding: '16px 18px', background: 'rgba(255,255,255,0.1)', backdropFilter: 'blur(20px)', borderRadius: 18, border: '1px solid rgba(255,255,255,0.14)' }}>
          <div style={{ fontSize: 15, lineHeight: 1.55 }}>A clear morning, 14°. Standup with Sara at 9:30 — three hours are yours first. The Go release-candidate cleared overnight, nothing breaking.</div>
        </div>
        <div style={{ marginTop: 'auto', paddingTop: 24 }}>
          <CHoldButton primary label="Hold to stop" holdingLabel="Keep holding…" doneLabel="Alarm off" duration={1400} onDone={onStop}/>
        </div>
      </div>
    </UScreen>
  );
};

// dispatcher: conversation unless agent-only (or silence override flips it to agent-only)
const UFires = ({ method, alarm, onPlan, onDismiss, onStop }) => {
  const [forcedAgent, setForcedAgent] = uState(false);
  if (method === 'Conversation' && !forcedAgent) {
    return <UFiresTalk alarm={alarm} onPlan={onPlan} onDismiss={onDismiss} onSilence={() => setForcedAgent(true)}/>;
  }
  return <UFiresAgent alarm={alarm} onStop={onStop}/>;
};

// ════════ PLAN day ════════
const UPlan = ({ onDone }) => {
  const [phase, setPhase] = uState('speaking');
  const [saved, setSaved] = uState(false);
  uEffect(() => { const t = setTimeout(() => setPhase('listening'), 2400); return () => clearTimeout(t); }, []);
  const speaking = phase === 'speaking';
  return (
    <UScreen bg={C_MORN} padBottom={28}>
      <div style={{ padding: '10px 24px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <button onClick={onDone} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, display: 'grid', placeItems: 'center' }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none"><path d="M15 5l-7 7 7 7" stroke={C_TEXT} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
        <span style={{ flex: 1, fontSize: 15, fontWeight: 500, textAlign: 'center' }}>Planning Tuesday</span>
        <span style={{ width: 22 }}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'center', padding: '8px 0' }}>
        <CGlass style={{ padding: '6px 16px 6px 6px', display: 'flex', alignItems: 'center', gap: 4 }}>
          <COrb size={30} speaking={speaking} label={false}/>
          <span style={{ fontSize: 12, fontWeight: 600, color: speaking ? C_CORAL : C_GREEN, letterSpacing: '0.08em' }}>{speaking ? 'SPEAKING' : 'LISTENING'}</span>
        </CGlass>
      </div>
      <div style={{ padding: '8px 24px 0' }}>
        <CGlass style={{ padding: '13px 18px', marginBottom: 8 }}>
          <div style={{ fontSize: 10, opacity: 0.5, letterSpacing: '0.15em', marginBottom: 4 }}>AURORA</div>
          <div style={{ fontSize: 14, lineHeight: 1.55 }}>"I see standup at 9:30 and the rebrand review at 2. Block 10–12 for design?"</div>
        </CGlass>
        <CGlass style={{ padding: '13px 18px' }}>
          <div style={{ fontSize: 10, opacity: 0.5, letterSpacing: '0.15em', marginBottom: 4 }}>YOU</div>
          <div style={{ fontSize: 14, lineHeight: 1.55, fontStyle: 'italic', opacity: 0.85 }}>"9:45 to 12. Coffee after the call."</div>
        </CGlass>
      </div>
      <div style={{ padding: '16px 24px 0', flex: 1 }}>
        <div style={{ fontSize: 10, opacity: 0.45, letterSpacing: '0.18em', marginBottom: 10 }}>YOUR DAY</div>
        <CGlass style={{ padding: '4px 16px' }}>
          {[{ t: '9:30', l: 'Standup with Sara' },{ t: '9:45', l: 'Coffee', n: true },{ t: '10:00', l: 'Rebrand · design', n: true },{ t: '14:00', l: 'Rebrand review' }].map((e, i, arr) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '11px 0', borderBottom: i === arr.length-1 ? 'none' : '1px solid rgba(255,255,255,0.08)' }}>
              <span style={{ fontSize: 13, fontWeight: 600, width: 42, color: e.n ? C_CORAL : C_TEXT, fontVariantNumeric: 'tabular-nums' }}>{e.t}</span>
              <span style={{ flex: 1, fontSize: 14, opacity: e.n ? 1 : 0.85 }}>{e.l}</span>
              {e.n && <span style={{ fontSize: 9, letterSpacing: '0.15em', padding: '2px 6px', borderRadius: 4, background: C_CORAL, color: '#fff', fontWeight: 600 }}>NEW</span>}
            </div>
          ))}
        </CGlass>
      </div>
      <div style={{ padding: '12px 24px 0' }}>
        <button onClick={() => { setSaved(true); setTimeout(onDone, 700); }} style={{ width: '100%', padding: '14px', borderRadius: 999, background: saved ? C_GREEN : C_CORAL, color: '#fff', border: 'none', fontSize: 14, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, transition: 'background 0.25s' }}>
          {saved && <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
          {saved ? 'Saved to calendar' : 'Save to calendar'}
        </button>
      </div>
    </UScreen>
  );
};

// ════════ MEMORY ════════
const CAT_SEED = [
  { name: 'Projects',  tag: 'PROJECT',  color: C_CORAL },
  { name: 'People',    tag: 'PEOPLE',   color: '#9aa4f2' },
  { name: 'Goals',     tag: 'GOAL',     color: C_GREEN },
  { name: 'Health',    tag: 'HEALTH',   color: C_GOLD },
  { name: 'Interests', tag: 'INTEREST', color: 'oklch(0.74 0.13 48)' },
];
const MEM_SEED = [
  { id: 1, cat: 'Projects',  label: 'Kitchen renovation',    detail: 'Cabinets ordered. Next: book the electrician.' },
  { id: 2, cat: 'People',    label: 'Sara',                  detail: 'Project collaborator. Weekly standup at 9:30.' },
  { id: 3, cat: 'Goals',     label: 'Run 4×/week',           detail: 'Currently averaging 3.' },
  { id: 4, cat: 'Health',    label: 'Morning energy',        detail: 'Best around 9:30.' },
  { id: 5, cat: 'Interests', label: 'History of computing',  detail: '70s–90s personal computing era. Early Apple, Xerox PARC, hacker culture.' },
  { id: 6, cat: 'Interests', label: 'Specialty coffee',      detail: 'Pour-over preferred. Favourites: Ethiopian Yirgacheffe, Kenyan SL28.' },
  { id: 7, cat: 'Interests', label: 'Architecture & cities', detail: 'Particularly Scandinavian modernism and Japanese urbanism.' },
];
const TODAY_SEED = ['Moved design block to 9:45–12 after standup','Coffee after the Sara call','Review confirmed for 14:00','Felt low-energy late afternoon yesterday'];
const NEW_CAT_COLORS = ['oklch(0.74 0.13 200)','oklch(0.74 0.13 45)','oklch(0.74 0.13 320)','oklch(0.74 0.13 265)','oklch(0.74 0.13 150)'];

const memFieldStyle = { width: '100%', background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 12, padding: '11px 14px', color: '#fff', fontSize: 15, fontFamily: 'inherit', outline: 'none', resize: 'none' };
const memCapStyle = { fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', opacity: 0.5, fontWeight: 600, margin: '0 0 7px 2px' };
const memRemoveBtn = { background: 'rgba(255,255,255,0.08)', border: 'none', borderRadius: '50%', width: 22, height: 22, color: 'rgba(255,255,255,0.7)', fontSize: 16, lineHeight: 1, cursor: 'pointer', fontFamily: 'inherit', flex: '0 0 auto', display: 'grid', placeItems: 'center' };
const pencil = <svg width="15" height="15" viewBox="0 0 24 24" fill="none"><path d="M4 20h4l10-10-4-4L4 16v4z" stroke="rgba(255,255,255,0.55)" strokeWidth="1.8" strokeLinejoin="round"/><path d="M14 6l4 4" stroke="rgba(255,255,255,0.55)" strokeWidth="1.8"/></svg>;

// ── Bottom-sheet editor for a single memory ──
const MemEditSheet = ({ target, cats, onClose, onSave, onRemove, onAddCat }) => {
  const isAdd = !target.id;
  const [label, setLabel] = uState(target.label || '');
  const [detail, setDetail] = uState(target.detail || '');
  const [cat, setCat] = uState(target.cat || cats[0].name);
  const [adding, setAdding] = uState(false);
  const [newName, setNewName] = uState('');
  const nextColor = NEW_CAT_COLORS[Math.max(0, cats.length - CAT_SEED.length) % NEW_CAT_COLORS.length];
  const confirmCat = () => {
    const n = newName.trim();
    if (!n) { setAdding(false); return; }
    if (!cats.some(c => c.name.toLowerCase() === n.toLowerCase())) onAddCat({ name: n, tag: n.toUpperCase(), color: nextColor });
    setCat(n); setAdding(false); setNewName('');
  };
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 200 }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', animation: 'sheetScrim 0.2s ease' }}/>
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, background: 'rgba(26,23,32,0.98)', backdropFilter: 'blur(24px)', borderTopLeftRadius: 26, borderTopRightRadius: 26, border: '1px solid rgba(255,255,255,0.1)', borderBottom: 'none', padding: '10px 18px 26px', maxHeight: '90%', overflowY: 'auto', animation: 'sheetUp 0.26s cubic-bezier(0.2,0.9,0.3,1)' }}>
        <div style={{ width: 38, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.25)', margin: '4px auto 14px' }}/>
        <div style={{ fontSize: 12, letterSpacing: '0.14em', color: 'rgba(232,230,240,0.5)', fontWeight: 600, padding: '0 2px 14px', textTransform: 'uppercase' }}>{isAdd ? 'New memory' : 'Edit memory'}</div>
        <div style={{ marginBottom: 14 }}>
          <div style={memCapStyle}>Label</div>
          <input value={label} onChange={e => setLabel(e.target.value)} placeholder="e.g. Kitchen renovation" style={memFieldStyle}/>
        </div>
        <div style={{ marginBottom: 14 }}>
          <div style={memCapStyle}>Detail</div>
          <textarea value={detail} onChange={e => setDetail(e.target.value)} rows={3} placeholder="What should Aurora remember?" style={{ ...memFieldStyle, lineHeight: 1.45 }}/>
        </div>
        <div style={{ marginBottom: 20 }}>
          <div style={memCapStyle}>Category</div>
          <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap' }}>
            {cats.map(c => {
              const on = c.name === cat;
              return <button key={c.name} onClick={() => setCat(c.name)} style={{ padding: '7px 13px', borderRadius: 999, fontSize: 13, fontWeight: on ? 600 : 500, cursor: 'pointer', fontFamily: 'inherit', background: on ? c.color + '30' : 'rgba(255,255,255,0.06)', color: on ? c.color : 'rgba(232,230,240,0.72)', border: on ? `1px solid ${c.color}66` : '1px solid rgba(255,255,255,0.1)' }}>{c.name}</button>;
            })}
            {!adding && <button onClick={() => setAdding(true)} style={{ padding: '7px 13px', borderRadius: 999, fontSize: 13, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit', background: 'transparent', color: 'rgba(232,230,240,0.6)', border: '1px dashed rgba(255,255,255,0.22)' }}>+ New category</button>}
          </div>
          {adding && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10 }}>
              <span style={{ width: 14, height: 14, borderRadius: '50%', background: nextColor, flex: '0 0 auto' }}/>
              <input autoFocus value={newName} onChange={e => setNewName(e.target.value)} onKeyDown={e => e.key === 'Enter' && confirmCat()} placeholder="Category name" style={{ ...memFieldStyle, padding: '9px 12px', fontSize: 14 }}/>
              <button onClick={confirmCat} style={{ background: C_CORAL, border: 'none', borderRadius: 10, padding: '9px 14px', color: '#fff', fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>Add</button>
            </div>
          )}
        </div>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
          <button onClick={() => onSave({ label: label.trim() || 'Untitled', detail: detail.trim(), cat })} style={{ flex: 1, background: C_CORAL, border: 'none', borderRadius: 14, padding: '15px 0', color: '#fff', fontSize: 16, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>{isAdd ? 'Add memory' : 'Save'}</button>
          {!isAdd && <button onClick={onRemove} style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 14, padding: '15px 18px', color: '#ff9a8a', fontSize: 15, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit' }}>Remove</button>}
        </div>
      </div>
    </div>
  );
};

// ── Conversation with Aurora — chat / talk to add what she knows ──
const CHAT_SEED = [
  { who: 'aurora', text: 'Morning, Alex. Tell me what\u2019s on your mind \u2014 a project, a goal, someone you\u2019re seeing. I\u2019ll keep it in mind for your wake-ups.' },
];
const CHAT_ACKS = [
  'Got it \u2014 I\u2019ll keep that in mind.',
  'Noted. I\u2019ve added that to what I know about you.',
  'Thanks for telling me. I\u2019ll bring it up when it matters.',
  'Understood. That\u2019s saved for your mornings.',
];
const VOICE_SAMPLES = [
  'I\u2019ve got a rebrand review Thursday \u2014 keep me sharp this week.',
  'I want to start running before work, maybe three mornings.',
  'Remind me Sara likes our standups at 9:30.',
];

const micIcon = (c, s = 18) => <svg width={s} height={s} viewBox="0 0 24 24" fill="none"><rect x="9" y="3" width="6" height="11" rx="3" stroke={c} strokeWidth="2"/><path d="M5 11a7 7 0 0 0 14 0" stroke={c} strokeWidth="2" strokeLinecap="round"/><line x1="12" y1="18" x2="12" y2="21" stroke={c} strokeWidth="2" strokeLinecap="round"/></svg>;
const sendIcon = <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M12 19V6M6 12l6-6 6 6" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>;

const ChatOrb = ({ size = 30, speaking }) => (
  <div style={{ width: size, height: size, borderRadius: '50%', flex: '0 0 auto', display: 'grid', placeItems: 'center',
    background: `radial-gradient(circle at 35% 32%, ${C_CORAL}, ${C_CORAL}66 58%, transparent 78%)`,
    boxShadow: speaking ? `0 0 14px ${C_CORAL}aa` : 'none',
    animation: speaking ? 'beam 1.3s ease-in-out infinite' : 'breathe 4s ease-in-out infinite' }}>
    <AuroraMark size={Math.round(size * 0.5)} tone="ink"/>
  </div>
);

const MemChatSheet = ({ convo, setConvo, onRemember, onClose }) => {
  const [text, setText] = uState('');
  const [listening, setListening] = uState(false);
  const scrollRef = uRef(null);
  const timerRef = uRef(null);

  uEffect(() => { const el = scrollRef.current; if (el) el.scrollTop = el.scrollHeight; }, [convo, listening]);
  uEffect(() => () => clearTimeout(timerRef.current), []);

  const send = (raw) => {
    const t = (raw == null ? text : raw).trim();
    if (!t) return;
    setText('');
    setListening(false);
    setConvo(c => [...c, { who: 'me', text: t }]);
    timerRef.current = setTimeout(() => {
      onRemember(t);
      setConvo(c => [...c, { who: 'aurora', text: CHAT_ACKS[Math.floor(Math.random() * CHAT_ACKS.length)], saved: true }]);
    }, 700);
  };

  const startVoice = () => {
    setListening(true);
    timerRef.current = setTimeout(() => {
      setListening(false);
      setText(VOICE_SAMPLES[Math.floor(Math.random() * VOICE_SAMPLES.length)]);
    }, 2200);
  };

  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 200 }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.5)', animation: 'sheetScrim 0.2s ease' }}/>
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: '88%', background: 'rgba(26,23,32,0.98)', backdropFilter: 'blur(24px)', borderTopLeftRadius: 26, borderTopRightRadius: 26, border: '1px solid rgba(255,255,255,0.1)', borderBottom: 'none', display: 'flex', flexDirection: 'column', animation: 'sheetUp 0.26s cubic-bezier(0.2,0.9,0.3,1)', color: C_TEXT }}>
        <div style={{ width: 38, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.25)', margin: '8px auto 10px', flex: '0 0 auto' }}/>
        {/* header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '2px 18px 14px', borderBottom: '1px solid rgba(255,255,255,0.07)', flex: '0 0 auto' }}>
          <ChatOrb size={32} speaking={listening}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 15.5, fontWeight: 600 }}>Aurora</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 2 }}>
              <span style={{ width: 5, height: 5, borderRadius: '50%', background: listening ? C_CORAL : C_GREEN }}/>
              <span style={{ fontSize: 11.5, opacity: 0.6 }}>{listening ? 'Listening\u2026' : 'Tell me anything to remember'}</span>
            </div>
          </div>
          <button onClick={onClose} style={{ background: 'rgba(255,255,255,0.07)', border: 'none', borderRadius: '50%', width: 30, height: 30, color: 'rgba(255,255,255,0.7)', fontSize: 18, lineHeight: 1, cursor: 'pointer', fontFamily: 'inherit', display: 'grid', placeItems: 'center', flex: '0 0 auto' }}>×</button>
        </div>
        {/* thread */}
        <div ref={scrollRef} className="aurScroll" style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '18px 18px 8px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {convo.map((m, i) => m.who === 'aurora' ? (
            <div key={i} style={{ display: 'flex', gap: 9, alignItems: 'flex-end', maxWidth: '86%' }}>
              <ChatOrb size={24}/>
              <div style={{ minWidth: 0 }}>
                <div style={{ background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '16px 16px 16px 5px', padding: '10px 13px', fontSize: 13.5, lineHeight: 1.5 }}>{m.text}</div>
                {m.saved && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 5, margin: '6px 0 0 4px', fontSize: 11, color: C_GREEN, fontWeight: 500 }}>
                    <svg width="13" height="13" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke={C_GREEN} strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    Saved to memory
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div key={i} style={{ alignSelf: 'flex-end', maxWidth: '82%', background: C_CORAL, borderRadius: '16px 16px 5px 16px', padding: '10px 13px', fontSize: 13.5, lineHeight: 1.5, color: '#fff' }}>{m.text}</div>
          ))}
        </div>
        {/* composer */}
        <div style={{ padding: '12px 14px', paddingBottom: 18, borderTop: '1px solid rgba(255,255,255,0.07)', flex: '0 0 auto' }}>
          {listening ? (
            <div onClick={() => setListening(false)} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'rgba(255,122,89,0.14)', border: `1px solid ${C_CORAL}55`, borderRadius: 999, padding: '12px 18px', cursor: 'pointer' }}>
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 18 }}>
                {[0, 1, 2, 3, 4].map(i => <span key={i} style={{ width: 3, height: 18, borderRadius: 2, background: C_CORAL, transformOrigin: 'bottom', animation: `eq 0.9s ease-in-out ${i * 0.12}s infinite` }}/>)}
              </div>
              <span style={{ flex: 1, fontSize: 13.5, color: C_CORAL, fontWeight: 500 }}>Listening… tap to stop</span>
            </div>
          ) : (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div style={{ flex: 1, display: 'flex', alignItems: 'center', background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 999, padding: '4px 6px 4px 16px' }}>
                <input value={text} onChange={e => setText(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') send(); }} placeholder="Message Aurora…" style={{ flex: 1, minWidth: 0, background: 'none', border: 'none', color: '#fff', fontSize: 14, fontFamily: 'inherit', outline: 'none', padding: '8px 0' }}/>
                {!text.trim() && (
                  <button onClick={startVoice} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 6, display: 'grid', placeItems: 'center', flex: '0 0 auto' }}>{micIcon('rgba(255,255,255,0.6)')}</button>
                )}
              </div>
              <button onClick={() => send()} disabled={!text.trim()} style={{ width: 40, height: 40, borderRadius: '50%', border: 'none', flex: '0 0 auto', cursor: text.trim() ? 'pointer' : 'default', background: text.trim() ? C_CORAL : 'rgba(255,255,255,0.08)', display: 'grid', placeItems: 'center', opacity: text.trim() ? 1 : 0.5, transition: 'background 0.15s, opacity 0.15s' }}>{sendIcon}</button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

const UMemory = () => {
  const [filter, setFilter] = uState('All');
  const [open, setOpen] = uState(false);
  const [editing, setEditing] = uState(false);
  const [cats, setCats] = uState(CAT_SEED);
  const [mem, setMem] = uState(MEM_SEED);
  const [today, setToday] = uState(TODAY_SEED);
  const [sheet, setSheet] = uState(null);
  const [chat, setChat] = uState(false);
  const [convo, setConvo] = uState(CHAT_SEED);
  const remember = (t) => setToday(ts => [t, ...ts]);

  const catOf = (name) => cats.find(c => c.name === name) || { tag: (name || '').toUpperCase(), color: 'rgba(232,230,240,0.5)' };
  const chips = [{ l: 'All', n: mem.length }, ...cats.map(c => ({ l: c.name, n: mem.filter(m => m.cat === c.name).length }))];
  const cards = filter === 'All' ? mem : mem.filter(c => c.cat === filter);
  const expanded = open || editing;

  const addCat = (c) => setCats(cs => cs.some(x => x.name.toLowerCase() === c.name.toLowerCase()) ? cs : [...cs, c]);
  const saveMem = (patch) => {
    setMem(ms => sheet.id ? ms.map(m => m.id === sheet.id ? { ...m, ...patch } : m) : [...ms, { id: Date.now(), ...patch }]);
    setSheet(null);
  };
  const removeMem = () => { setMem(ms => ms.filter(m => m.id !== sheet.id)); setSheet(null); };

  return (
    <UScreen bg={C_MORN}>
      <div style={{ padding: '16px 28px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div style={{ fontSize: 32, fontWeight: 400, letterSpacing: '-0.025em' }}>Memory</div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 6 }}>
          <button onClick={() => setEditing(e => !e)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', fontSize: 14, fontWeight: editing ? 600 : 500, color: editing ? '#fff' : 'rgba(255,255,255,0.75)', padding: 0 }}>{editing ? 'Done' : 'Edit'}</button>
          <AuroraMark size={24} tone="invert"/>
        </div>
      </div>
      <div onClick={() => setChat(true)} style={{ margin: '14px 24px 0', display: 'flex', alignItems: 'center', gap: 13, padding: '13px 14px 13px 15px', borderRadius: 18, background: 'linear-gradient(135deg, rgba(255,122,89,0.16), rgba(255,255,255,0.05))', border: '1px solid rgba(255,255,255,0.14)', backdropFilter: 'blur(24px)', WebkitBackdropFilter: 'blur(24px)', cursor: 'pointer', userSelect: 'none' }}>
        <ChatOrb size={34}/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14.5, fontWeight: 600, color: '#fff' }}>Talk to Aurora</div>
          <div style={{ fontSize: 12, opacity: 0.6, marginTop: 1 }}>Tell her about your projects, goals…</div>
        </div>
        <div style={{ width: 34, height: 34, borderRadius: '50%', background: 'rgba(255,255,255,0.1)', display: 'grid', placeItems: 'center', flex: '0 0 auto' }}>{micIcon('#fff', 16)}</div>
      </div>
      <div style={{ margin: '12px 24px 0' }}>
        <CGlass style={{ padding: '12px 16px', background: 'rgba(255,255,255,0.035)' }}>
          <div onClick={() => !editing && setOpen(!open)} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: editing ? 'default' : 'pointer', userSelect: 'none' }}>
            <div style={{ width: 6, height: 6, borderRadius: '50%', background: C_CORAL }}/>
            <span style={{ flex: 1, fontSize: 13, fontWeight: 500 }}>What Aurora remembers from today</span>
            <span style={{ fontSize: 12, opacity: 0.5 }}>{today.length} notes</span>
            {!editing && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" style={{ transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}><path d="M6 9l6 6 6-6" stroke={C_TEXT} strokeOpacity="0.5" strokeWidth="2" strokeLinecap="round"/></svg>}
          </div>
          <div className="aurScroll" style={{ maxHeight: expanded ? 340 : 0, overflowX: 'hidden', overflowY: expanded ? 'auto' : 'hidden', transition: 'max-height 0.3s ease, margin-top 0.3s', marginTop: expanded ? 12 : 0 }}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 9, borderTop: '1px solid rgba(255,255,255,0.1)', paddingTop: 12 }}>
              {today.map((t, i) => editing ? (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ color: C_CORAL }}>·</span>
                  <input value={t} onChange={e => setToday(ts => ts.map((x, j) => j === i ? e.target.value : x))} style={{ flex: 1, background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 9, padding: '7px 10px', color: '#fff', fontSize: 12.5, fontFamily: 'inherit', outline: 'none' }}/>
                  <button onClick={() => setToday(ts => ts.filter((_, j) => j !== i))} style={memRemoveBtn}>×</button>
                </div>
              ) : (
                <div key={i} style={{ display: 'flex', gap: 9, fontSize: 12.5, lineHeight: 1.45, opacity: 0.8 }}><span style={{ color: C_CORAL }}>·</span><span style={{ flex: 1 }}>{t}</span></div>
              ))}
              {editing && <button onClick={() => setToday(ts => [...ts, ''])} style={{ background: 'none', border: 'none', color: C_CORAL, fontSize: 12.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left', padding: '2px 0 0 17px' }}>+ Add note</button>}
            </div>
          </div>
        </CGlass>
      </div>
      <div style={{ padding: '18px 24px 6px', display: 'flex', gap: 6, flexWrap: 'wrap' }}>
        {chips.map((c, i) => {
          const on = c.l === filter;
          return <div key={i} onClick={() => setFilter(c.l)} style={{ padding: '6px 12px', borderRadius: 999, fontSize: 12, fontWeight: 500, cursor: 'pointer', background: on ? C_CORAL : 'rgba(255,255,255,0.06)', color: on ? '#fff' : 'rgba(232,230,240,0.7)', border: on ? 'none' : '1px solid rgba(255,255,255,0.1)', whiteSpace: 'nowrap', transition: 'background 0.15s, color 0.15s', userSelect: 'none' }}>{c.l} · {c.n}</div>;
        })}
      </div>
      <div className="aurScroll" style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '12px 24px 8px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {cards.map((card) => {
          const c = catOf(card.cat);
          return (
            <CGlass key={card.id} style={{ padding: '13px 18px', cursor: editing ? 'pointer' : 'default' }}>
              <div onClick={editing ? () => setSheet(card) : undefined} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                    <span style={{ fontSize: 9, letterSpacing: '0.18em', padding: '2px 7px', borderRadius: 4, background: c.color+'30', color: c.color, fontWeight: 700 }}>{c.tag}</span>
                    <span style={{ fontSize: 14, fontWeight: 500 }}>{card.label}</span>
                  </div>
                  <div style={{ fontSize: 12, opacity: 0.6, lineHeight: 1.5 }}>{card.detail}</div>
                </div>
                {editing && <span style={{ flex: '0 0 auto', display: 'grid', placeItems: 'center' }}>{pencil}</span>}
              </div>
            </CGlass>
          );
        })}
        {cards.length === 0 && <div style={{ textAlign: 'center', fontSize: 13, opacity: 0.45, padding: '24px 0' }}>No memories in this category yet.</div>}
        {editing && <button onClick={() => setSheet({ cat: filter !== 'All' ? filter : cats[0].name })} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '13px 18px', borderRadius: 16, border: '1px dashed rgba(255,255,255,0.25)', background: 'rgba(255,255,255,0.03)', color: 'rgba(255,255,255,0.82)', fontSize: 14, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit' }}>+ Add memory</button>}
      </div>
      {sheet && <MemEditSheet target={sheet} cats={cats} onClose={() => setSheet(null)} onSave={saveMem} onRemove={removeMem} onAddCat={addCat}/>}
      {chat && <MemChatSheet convo={convo} setConvo={setConvo} onRemember={remember} onClose={() => setChat(false)}/>}
    </UScreen>
  );
};

// ════════ ME — profile / global settings ════════
const UMe = ({ defaultMethod, setDefaultMethod, voice, setVoice, sleepReport, setSleepReport, tagline }) => (
  <UScreen bg={C_BG}>
    <div style={{ padding: '16px 28px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
      <div style={{ fontSize: 32, fontWeight: 400, letterSpacing: '-0.025em' }}>Me</div>
      <AuroraMark size={24} tone="invert"/>
    </div>
    <div style={{ margin: '16px 24px 0', display: 'flex', alignItems: 'center', gap: 14 }}>
      <div style={{ position: 'relative', flex: '0 0 auto' }}>
        <div style={{ width: 54, height: 54, borderRadius: '50%', background: `linear-gradient(135deg, ${C_INDIGO}, ${C_CORAL})`, display: 'grid', placeItems: 'center', fontSize: 20, fontWeight: 600, color: '#fff' }}>A</div>
        <div style={{ position: 'absolute', right: -1, bottom: -1, width: 15, height: 15, borderRadius: '50%', background: C_GREEN, border: '2.5px solid #0d0f1f' }}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 18, fontWeight: 600 }}>Alex Morgan</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 3 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: C_GREEN, flex: '0 0 auto' }}/>
          <span style={{ fontSize: 12.5, opacity: 0.6 }}>Signed in · alex@morgan.co</span>
        </div>
      </div>
    </div>
    <div style={{ padding: '22px 16px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ fontSize: 10, opacity: 0.45, letterSpacing: '0.18em', padding: '0 6px 2px' }}>DEFAULTS</div>
      <UDropdownRow label="Default wake method" value={defaultMethod} options={['Conversation','Agent only']} onChange={setDefaultMethod}/>
      <UDropdownRow label="Assistant voice" value={voice} options={['Aurora — warm','Sol — bright','Luna — calm','Reed — low']} onChange={setVoice}/>
      <URow label="Weekly sleep report" sub="Sundays, 8:00" toggle on={sleepReport} onClick={() => setSleepReport(!sleepReport)}/>
    </div>
  </UScreen>
);

Object.assign(window, { UWakeHome, UAlarmEdit, UFires, UFiresTalk, UFiresAgent, UPlan, UMemory, UMe });
