// Wave Logger — Today screen
// Tokens from the brief, refined slightly for hi-fi polish.

const wl = {
  // base
  bg:        '#FBFDFC',
  bgWarm:    '#F6FAF9',
  card:      '#FFFFFF',
  ink:       '#1C3A36',
  ink2:      '#3E6E66',
  ink3:      '#8AA8A2',
  // brand
  teal:      '#2A9D8F',
  tealDeep:  '#1E7E72',
  tealSoft:  '#DDEEEA',
  tealTint:  '#EEF7F4',
  hairline:  '#E6EEEC',
  // night/evening accent
  moonCream: '#FEF3D8',
  moonInk:   '#B8923A',
  // mascot
  seed:      '#AFCFBE',
  board:     '#FAAD32',
  wave:      '#74A7DC',
  waveDeep:  '#4187CA',
  cream:     '#FEF9F4',
  // warning
  danger:    '#C2675B',
};

// ─── Icons ────────────────────────────────────────────────────
const Ico = {
  upload: (c = wl.ink2) => (
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
      <path d="M5 17v.5A2.5 2.5 0 0 0 7.5 20h9a2.5 2.5 0 0 0 2.5-2.5V17"
            stroke={c} strokeWidth="1.7" strokeLinecap="round"/>
      <path d="M12 15V5m0 0l-3.3 3.3M12 5l3.3 3.3"
            stroke={c} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  cloud: (c = wl.ink2) => (
    <svg width="22" height="16" viewBox="0 0 24 18" fill="none">
      <path d="M7 16h10.5A4.5 4.5 0 0 0 18 7.05 6 6 0 0 0 6.2 7.4 4 4 0 0 0 7 16z"
            stroke={c} strokeWidth="1.6" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
  github: (c = wl.ink2) => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill={c}>
      <path d="M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.1.79-.25.79-.56 0-.28-.01-1.02-.02-2-3.2.7-3.87-1.54-3.87-1.54-.52-1.33-1.28-1.69-1.28-1.69-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.69 0-1.26.45-2.28 1.18-3.09-.12-.29-.51-1.46.11-3.04 0 0 .97-.31 3.17 1.18a11 11 0 0 1 5.78 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.58.23 2.75.11 3.04.74.81 1.18 1.83 1.18 3.09 0 4.42-2.69 5.39-5.26 5.68.41.35.78 1.05.78 2.12 0 1.53-.01 2.76-.01 3.14 0 .31.21.67.8.55C20.21 21.38 23.5 17.07 23.5 12 23.5 5.65 18.35.5 12 .5z"/>
    </svg>
  ),
  moon: (c = wl.moonInk, fill = wl.moonCream) => (
    <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
      <path d="M16.5 12.5A7 7 0 1 1 7.5 3.5a5.6 5.6 0 0 0 9 9z"
            fill={fill} stroke={c} strokeWidth="1.4" strokeLinejoin="round"/>
    </svg>
  ),
  chevDown: (c = wl.ink3) => (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M3 5.5l4 3.5 4-3.5" stroke={c} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  check: (c = wl.teal) => (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M2.5 7.5l3 3 6-7" stroke={c} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  plus: (c = wl.ink2) => (
    <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
      <path d="M10 4v12M4 10h12" stroke={c} strokeWidth="1.8" strokeLinecap="round"/>
    </svg>
  ),
  arrowUp: (c = '#fff') => (
    <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
      <path d="M10 16V5m0 0l-4 4M10 5l4 4" stroke={c} strokeWidth="2.1" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  link: (c = wl.ink2) => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
      <path d="M6.5 9.5l3-3M9 5l1-1a2.8 2.8 0 1 1 4 4l-1 1M7 11l-1 1a2.8 2.8 0 1 1-4-4l1-1"
            stroke={c} strokeWidth="1.5" strokeLinecap="round"/>
    </svg>
  ),
  tag: (c = wl.ink2) => (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
      <path d="M2 8.6V3a1 1 0 0 1 1-1h5.6a1 1 0 0 1 .7.3l5.1 5.1a1 1 0 0 1 0 1.4l-5.6 5.6a1 1 0 0 1-1.4 0L2.3 9.3A1 1 0 0 1 2 8.6z"
            stroke={c} strokeWidth="1.5" strokeLinejoin="round"/>
      <circle cx="5.5" cy="5.5" r="1" fill={c}/>
    </svg>
  ),
  bed: (c = wl.ink2) => (
    <svg width="18" height="18" viewBox="0 0 20 16" fill="none">
      <path d="M2 11V3M2 11h16v-3a2 2 0 0 0-2-2H9v5M18 11v3" stroke={c} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
      <circle cx="5.5" cy="7.5" r="1.5" fill={c}/>
    </svg>
  ),
  nap: (c = wl.ink2) => (
    <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
      <path d="M3 14a7 7 0 0 1 14 0H3z" stroke={c} strokeWidth="1.6" strokeLinejoin="round"/>
      <path d="M9 5.5l2-2.5 2 2.5" stroke={c} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),
  spark: (c = wl.teal) => (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M7 1.5l1.2 3.3L11.5 6 8.2 7.2 7 10.5 5.8 7.2 2.5 6l3.3-1.2L7 1.5z" fill={c}/>
    </svg>
  ),
  list: (c = wl.ink2) => (
    <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
      <rect x="3" y="5" width="2.5" height="2.5" rx="0.6" stroke={c} strokeWidth="1.5"/>
      <rect x="3" y="12.5" width="2.5" height="2.5" rx="0.6" stroke={c} strokeWidth="1.5"/>
      <path d="M8.5 6.25h9M8.5 13.75h9" stroke={c} strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  ),
  sparkles: (c = wl.ink2) => (
    <svg width="20" height="20" viewBox="0 0 22 22" fill="none">
      <path d="M9 3l1.5 4.2L14.7 8.7 10.5 10.2 9 14.4 7.5 10.2 3.3 8.7 7.5 7.2 9 3z"
            stroke={c} strokeWidth="1.5" strokeLinejoin="round" fill="none"/>
      <path d="M16.5 13.2l.7 1.9 1.9.7-1.9.7-.7 1.9-.7-1.9-1.9-.7 1.9-.7.7-1.9z"
            stroke={c} strokeWidth="1.3" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
  waves: (c = wl.ink2) => (
    <svg width="22" height="16" viewBox="0 0 24 18" fill="none">
      <path d="M2 6.5c2-2 4-2 6 0s4 2 6 0 4-2 6 0 2 0 2 0"
            stroke={c} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
      <path d="M2 12c2-2 4-2 6 0s4 2 6 0 4-2 6 0 2 0 2 0"
            stroke={c} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
    </svg>
  ),
};

// ─── Tab bar icons ────────────────────────────────────────────
const TabIcon = {
  today: (active) => (
    // wave + seedling
    <svg width="26" height="26" viewBox="0 0 28 28" fill="none">
      <path d="M2 19c2.5-3 5.5-3 8 0s5.5 3 8 0 5.5-3 8 0v6H2v-6z"
            fill={active ? wl.wave : 'none'} stroke={active ? wl.waveDeep : wl.ink3} strokeWidth="1.6" strokeLinejoin="round"/>
      <path d="M14 17V11" stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6" strokeLinecap="round"/>
      <path d="M14 11c-2 0-3.5-1.2-3.5-3 2 0 3.5 1.2 3.5 3z" fill={active ? wl.seed : 'none'} stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.4"/>
      <path d="M14 11c2 0 3.5-1.2 3.5-3-2 0-3.5 1.2-3.5 3z" fill={active ? wl.seed : 'none'} stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.4"/>
    </svg>
  ),
  records: (active) => (
    // calendar-ish stacked log
    <svg width="26" height="26" viewBox="0 0 28 28" fill="none">
      <rect x="4" y="6" width="20" height="18" rx="3" stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6"/>
      <path d="M4 11h20" stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6"/>
      <path d="M9 4v4M19 4v4" stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6" strokeLinecap="round"/>
      <circle cx="10" cy="16" r="1.2" fill={active ? wl.teal : wl.ink3}/>
      <circle cx="14" cy="16" r="1.2" fill={active ? wl.teal : wl.ink3}/>
      <circle cx="18" cy="16" r="1.2" fill={active ? wl.teal : wl.ink3}/>
      <circle cx="10" cy="20" r="1.2" fill={active ? wl.teal : wl.ink3}/>
      <circle cx="14" cy="20" r="1.2" fill={active ? wl.teal : wl.ink3}/>
    </svg>
  ),
  settings: (active) => (
    <svg width="26" height="26" viewBox="0 0 28 28" fill="none">
      <circle cx="14" cy="14" r="3" stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6"/>
      <path d="M14 3v3M14 22v3M3 14h3M22 14h3M6.3 6.3l2.1 2.1M19.6 19.6l2.1 2.1M21.7 6.3l-2.1 2.1M8.4 19.6l-2.1 2.1"
            stroke={active ? wl.tealDeep : wl.ink3} strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  ),
};

// ─── Mascot — tiny inline SVG for inline use (small sizes) ────
function Mascot({ size = 44, mood = 'neutral' }) {
  // mood: neutral, calm (eyes closed), tiny
  const eyes = mood === 'calm'
    ? <><path d="M19 26c1-1 3-1 4 0M29 26c1-1 3-1 4 0" stroke="#192a48" strokeWidth="1.6" strokeLinecap="round" fill="none"/></>
    : <><circle cx="21" cy="26" r="1.6" fill="#192a48"/><circle cx="31" cy="26" r="1.6" fill="#192a48"/></>;
  return (
    <svg width={size} height={size} viewBox="0 0 52 52" fill="none">
      {/* leaves */}
      <path d="M26 12c-2-2.5-5-3-6-2 0 2 1.6 4.6 4 5" fill={wl.seed}/>
      <path d="M26 12c2-2.5 5-3 6-2 0 2-1.6 4.6-4 5" fill={wl.seed}/>
      <path d="M26 18V11" stroke={wl.tealDeep} strokeWidth="1.4" strokeLinecap="round"/>
      {/* body */}
      <ellipse cx="26" cy="29" rx="11" ry="12" fill={wl.seed}/>
      {eyes}
      {/* board */}
      <ellipse cx="26" cy="42" rx="14" ry="3" fill={wl.board}/>
    </svg>
  );
}

// ─── Status bar (iOS-ish, simple) ──────────────────────────────
function StatusBar({ time = '21:14', dark = false }) {
  const c = dark ? '#fff' : '#000';
  return (
    <div style={{
      height: 54, padding: '14px 28px 0', display: 'flex',
      alignItems: 'center', justifyContent: 'space-between',
      fontFamily: '-apple-system, "SF Pro", system-ui',
    }}>
      <span style={{ fontSize: 17, fontWeight: 600, color: c, letterSpacing: '-0.2px' }}>{time}</span>
      <div style={{ width: 110, height: 30, background: '#000', borderRadius: 18 }}/>
      <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
        <svg width="18" height="11" viewBox="0 0 18 11"><rect x="0" y="7" width="3" height="4" rx=".6" fill={c}/><rect x="4.5" y="4.5" width="3" height="6.5" rx=".6" fill={c}/><rect x="9" y="2" width="3" height="9" rx=".6" fill={c}/><rect x="13.5" y="0" width="3" height="11" rx=".6" fill={c}/></svg>
        <svg width="16" height="11" viewBox="0 0 16 11"><path d="M8 3.2c2.1 0 4 .85 5.4 2.2l1-1A8 8 0 0 0 8 1.5 8 8 0 0 0 1.6 4.4l1 1A7.5 7.5 0 0 1 8 3.2z" fill={c}/><path d="M8 6.4c1.3 0 2.4.5 3.3 1.4l1-1A6 6 0 0 0 8 4.8a6 6 0 0 0-4.3 2l1 1A4.5 4.5 0 0 1 8 6.4z" fill={c}/><circle cx="8" cy="9.7" r="1.3" fill={c}/></svg>
        <svg width="26" height="12" viewBox="0 0 26 12"><rect x=".5" y=".5" width="22" height="11" rx="3" fill="none" stroke={c} strokeOpacity=".4"/><rect x="2" y="2" width="19" height="8" rx="1.6" fill={c}/><path d="M24 4v4c.8-.3 1.5-1.3 1.5-2s-.7-1.7-1.5-2z" fill={c} fillOpacity=".5"/></svg>
      </div>
    </div>
  );
}

// ─── Header: date + 정리 button (+ optional 올리기) ───────────
function Header({ date = '5월 22일 (금)', evening = false, showUpload = true }) {
  return (
    <div style={{
      padding: '6px 16px 12px', display: 'flex', alignItems: 'center',
      gap: 8, justifyContent: 'space-between',
    }}>
      {/* left: 올리기 */}
      <div style={{ width: 96, display: 'flex', alignItems: 'center' }}>
        {showUpload && (
          <button style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '8px 12px', background: 'transparent', border: 'none',
            color: wl.ink2, fontSize: 13.5, fontWeight: 500,
            borderRadius: 999, cursor: 'pointer',
            whiteSpace: 'nowrap',
          }}>
            {Ico.github(wl.ink2)}
            <span>올리기</span>
          </button>
        )}
      </div>
      {/* center: date */}
      <div style={{
        flex: 1, textAlign: 'center', fontSize: 17, fontWeight: 700,
        color: wl.ink, letterSpacing: '-0.3px', whiteSpace: 'nowrap',
      }}>{date}</div>
      {/* right: 정리 */}
      <div style={{ width: 96, display: 'flex', justifyContent: 'flex-end' }}>
        <button style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          padding: evening ? '7px 13px' : '8px 12px',
          background: evening ? wl.moonCream : 'transparent',
          border: evening ? `1px solid #F2DFA6` : 'none',
          color: evening ? wl.moonInk : wl.ink2,
          fontSize: 13.5, fontWeight: evening ? 700 : 500,
          borderRadius: 999, cursor: 'pointer',
          whiteSpace: 'nowrap',
          boxShadow: evening ? '0 1px 0 rgba(184,146,58,0.06)' : 'none',
        }}>
          {Ico.waves(evening ? wl.moonInk : wl.ink2)}
          <span>정리</span>
        </button>
      </div>
    </div>
  );
}

// ─── Tracker summary strip (thin, tap=expand) ─────────────────
function TrackerStrip({ expanded = false, sleep = '7h', nap = '30분', checks = '2/3' }) {
  return (
    <div style={{
      margin: '0 16px',
      borderTop: `1px solid ${wl.hairline}`,
      borderBottom: `1px solid ${wl.hairline}`,
      padding: '10px 4px',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      fontSize: 13.5, color: wl.ink2,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ color: wl.ink3, fontSize: 12, fontWeight: 500 }}>수면</span>
          <span style={{ fontWeight: 600, color: wl.ink }}>{sleep}</span>
        </span>
        <span style={{ color: wl.hairline }}>·</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ color: wl.ink3, fontSize: 12, fontWeight: 500 }}>낮잠</span>
          <span style={{ fontWeight: 600, color: wl.ink }}>{nap}</span>
        </span>
        <span style={{ color: wl.hairline }}>·</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          {Ico.check(wl.teal)}
          <span style={{ fontWeight: 600, color: wl.ink }}>{checks}</span>
        </span>
      </div>
      <button style={{
        background: 'transparent', border: 'none', padding: 4, cursor: 'pointer',
        transform: expanded ? 'rotate(180deg)' : 'rotate(0)',
        transition: 'transform .2s',
      }}>{Ico.chevDown()}</button>
    </div>
  );
}

// ─── Expanded tracker — BOTTOM SHEET (overlay) ────────────────
// Layout matches user spec: 수면 (취침/기상 wheels) · 낮잠 (toggle+chips/wheel)
// · custom trackers (체크 / 숫자(단위) / 척도 1~5).

function PencilIco({ c = wl.ink3 }) {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
      <path d="M2 12l2.4-.7L11.3 4.4a1.2 1.2 0 0 0 0-1.7l-.5-.5a1.2 1.2 0 0 0-1.7 0L2.2 9.1 1.5 12l.5.5z"
            stroke={c} strokeWidth="1.2" strokeLinejoin="round" fill="none"/>
    </svg>
  );
}

// Wheel picker — visual only (one barrel column)
function WheelCol({ items, value, w = 56 }) {
  // items: array of strings; we render 5 visible rows with value centered
  const idx = items.indexOf(value);
  const before = [items[idx - 2], items[idx - 1]].filter(Boolean);
  const after = [items[idx + 1], items[idx + 2]].filter(Boolean);
  const Row = (txt, op) => (
    <div style={{
      height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: 22, fontVariantNumeric: 'tabular-nums', color: wl.ink, opacity: op,
      fontFamily: '-apple-system, "SF Pro Display", system-ui', fontWeight: 500,
    }}>{txt}</div>
  );
  return (
    <div style={{
      width: w, height: 36 * 5,
      background: '#fff', position: 'relative',
      maskImage: 'linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%)',
      WebkitMaskImage: 'linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%)',
    }}>
      {Row(before[0] || '', 0.18)}
      {Row(before[1] || '', 0.4)}
      {Row(value, 1)}
      {Row(after[0] || '', 0.4)}
      {Row(after[1] || '', 0.18)}
    </div>
  );
}

function WheelTimePicker({ h = '23', m = '30' }) {
  const hours = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0'));
  const mins = ['00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55'];
  return (
    <div style={{
      margin: '10px 16px 6px', borderRadius: 14, overflow: 'hidden',
      background: '#FAFCFB', border: `1px solid ${wl.hairline}`,
      position: 'relative',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '6px 0',
    }}>
      {/* selection band */}
      <div style={{
        position: 'absolute', left: 12, right: 12, top: '50%',
        transform: 'translateY(-50%)', height: 36,
        background: wl.tealTint, borderRadius: 8, pointerEvents: 'none',
        border: `1px solid ${wl.tealSoft}`,
      }}/>
      <WheelCol items={hours} value={h}/>
      <div style={{ fontSize: 22, color: wl.ink2, padding: '0 6px', fontWeight: 600 }}>:</div>
      <WheelCol items={mins} value={m}/>
    </div>
  );
}

function SectionTitle({ children, right }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
      padding: '14px 18px 6px',
    }}>
      <span style={{ fontSize: 15, fontWeight: 700, color: wl.ink, letterSpacing: '-0.2px' }}>{children}</span>
      {right && <span style={{ fontSize: 11.5, color: wl.ink3, letterSpacing: '0.2px' }}>{right}</span>}
    </div>
  );
}

function PickRow({ label, value, last, onTap, opening }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '13px 18px',
      borderBottom: last ? 'none' : `1px solid ${wl.hairline}`,
      cursor: 'pointer',
      background: opening ? wl.tealTint : 'transparent',
    }}>
      <span style={{ fontSize: 15, color: wl.ink, fontWeight: 500 }}>{label}</span>
      <span style={{
        fontSize: 15, color: value ? wl.ink : wl.ink3,
        fontWeight: value ? 600 : 400,
        fontVariantNumeric: 'tabular-nums',
      }}>{value || '눌러서 맞추기'}</span>
    </div>
  );
}

function NapChips({ selected = '30' }) {
  const chips = ['15', '30', '45', '60', '90'];
  return (
    <div style={{
      padding: '10px 16px 14px',
      display: 'flex', gap: 8, justifyContent: 'space-between',
    }}>
      {chips.map(c => {
        const a = c === selected;
        return (
          <button key={c} style={{
            flex: 1, padding: '9px 0',
            background: a ? wl.tealTint : '#fff',
            border: `1px solid ${a ? wl.teal : wl.hairline}`,
            color: a ? wl.tealDeep : wl.ink2,
            fontSize: 14, fontWeight: a ? 700 : 500,
            borderRadius: 999, cursor: 'pointer',
            fontVariantNumeric: 'tabular-nums',
          }}>{c}분</button>
        );
      })}
    </div>
  );
}

function Toggle({ on }) {
  return (
    <div style={{
      width: 46, height: 28, borderRadius: 999,
      background: on ? wl.teal : '#D8DDDB',
      position: 'relative', transition: 'background .2s',
      boxShadow: on ? 'inset 0 1px 2px rgba(0,0,0,0.1)' : 'inset 0 1px 2px rgba(0,0,0,0.08)',
    }}>
      <div style={{
        position: 'absolute', top: 2, left: on ? 20 : 2,
        width: 24, height: 24, borderRadius: 99, background: '#fff',
        boxShadow: '0 1px 3px rgba(0,0,0,0.18)',
        transition: 'left .2s',
      }}/>
    </div>
  );
}

function CustomRow({ name, kind, value, unit, last }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '13px 18px', gap: 12,
      borderBottom: last ? 'none' : `1px solid ${wl.hairline}`,
    }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 1, minWidth: 0 }}>
        <span style={{ fontSize: 15, color: wl.ink, fontWeight: 500 }}>{name}</span>
        {unit && <span style={{ fontSize: 11, color: wl.ink3 }}>{unit}</span>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        {kind === 'check' && (
          <div style={{
            width: 24, height: 24, borderRadius: 7,
            background: value ? wl.teal : '#fff',
            border: `1.5px solid ${value ? wl.teal : wl.hairline}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {value && <svg width="12" height="12" viewBox="0 0 12 12"><path d="M2 6.5l2.5 2.5 5.5-6" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/></svg>}
          </div>
        )}
        {kind === 'number' && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <button style={{
              width: 34, height: 30, borderRadius: 9,
              background: '#fff', border: `1px solid ${wl.hairline}`,
              color: wl.teal, fontSize: 18, fontWeight: 600, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>−</button>
            <span style={{
              minWidth: 26, textAlign: 'center', fontSize: 17, fontWeight: 600,
              color: value > 0 ? wl.ink : wl.ink3, fontVariantNumeric: 'tabular-nums',
            }}>{value}</span>
            <button style={{
              width: 34, height: 30, borderRadius: 9,
              background: '#fff', border: `1px solid ${wl.hairline}`,
              color: wl.teal, fontSize: 18, fontWeight: 600, cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>+</button>
          </div>
        )}
        {kind === 'scale' && (
          <div style={{ display: 'flex', gap: 6 }}>
            {[1,2,3,4,5].map(n => {
              const on = value && n <= value;
              return (
                <div key={n} style={{
                  width: 28, height: 28, borderRadius: 99,
                  background: on ? wl.tealTint : '#fff',
                  border: `1px solid ${on ? wl.teal : wl.hairline}`,
                  color: on ? wl.tealDeep : wl.ink3,
                  fontSize: 13, fontWeight: 600,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>{n}</div>
              );
            })}
          </div>
        )}
        <PencilIco/>
      </div>
    </div>
  );
}

function TrackerSheet({ napOn = false, napDuration = '30', showWheel = false }) {
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, top: 0,
      maxHeight: '84%',
      background: '#FBFDFC', borderRadius: '0 0 24px 24px',
      boxShadow: '0 18px 40px rgba(0,0,0,0.18)',
      display: 'flex', flexDirection: 'column',
      overflow: 'hidden',
      paddingTop: 54, /* clear status bar */
    }}>
      {/* header */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '10px 18px 4px',
      }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontSize: 17, fontWeight: 700, color: wl.ink, letterSpacing: '-0.3px' }}>오늘의 트래커</span>
          <span style={{ fontSize: 12, color: wl.ink3 }}>5월 22일 (금)</span>
        </div>
        <button style={{
          background: 'transparent', border: 'none', padding: 4, cursor: 'pointer',
          fontSize: 13, color: wl.tealDeep, fontWeight: 600,
          display: 'inline-flex', alignItems: 'center', gap: 4,
        }}>
          닫기
        </button>
      </div>

      <div style={{ overflowY: 'auto', flex: 1, paddingBottom: 8 }}>
        {/* ─── 잠 그룹 (수면 + 낮잠) — collapsible header + 한 흐름의 subGroup ─── */}
        <div style={{ padding: '8px 14px 4px' }}>
          <div style={{
            background: '#fff', border: `1px solid ${wl.hairline}`,
            borderRadius: 18, overflow: 'hidden',
            boxShadow: '0 1px 0 rgba(28,58,54,0.02)',
          }}>
            {/* group header — chevron toggle */}
            <div style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: '12px 16px 10px',
              borderBottom: `1px solid ${wl.hairline}`,
              background: '#F7FBF9',
              cursor: 'pointer',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                {Ico.bed(wl.tealDeep)}
                <span style={{ fontSize: 14, fontWeight: 700, color: wl.ink, letterSpacing: '-0.2px' }}>잠</span>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ fontSize: 11.5, color: wl.ink3 }}>
                  {napOn ? `수면 7h · 낮잠 ${napDuration}분` : '수면 7h · 낮잠 —'}
                </span>
                <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden>
                  <path d="M3 5l4 4 4-4" stroke={wl.ink3} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
              </div>
            </div>

            {/* unified subGroup — 수면(취침/기상) + 낮잠 토글이 한 흐름으로 */}
            <div>
              <PickRow label="취침" value="23:30" opening={showWheel}/>
              {showWheel && <WheelTimePicker h="23" m="30"/>}
              <PickRow label="기상" value="06:40"/>

              {/* 낮잠 토글 — 단순 한 줄 행 (라벨 + Switch) */}
              <div style={{
                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                padding: '13px 18px',
                borderBottom: napOn ? `1px solid ${wl.hairline}` : 'none',
              }}>
                <span style={{ fontSize: 15, color: wl.ink, fontWeight: 500 }}>낮잠</span>
                <Toggle on={napOn}/>
              </div>
              {napOn && <NapChips selected={napDuration}/>}
            </div>
          </div>
        </div>

        {/* ─── 항목 그룹 (체크/숫자/척도) — 잠과 동일한 카드 + 헤더 ─── */}
        <div style={{ padding: '8px 14px 4px' }}>
          <div style={{
            background: '#fff', border: `1px solid ${wl.hairline}`,
            borderRadius: 18, overflow: 'hidden',
            boxShadow: '0 1px 0 rgba(28,58,54,0.02)',
          }}>
            {/* group header */}
            <div style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: '12px 16px 10px',
              borderBottom: `1px solid ${wl.hairline}`,
              background: '#F7FBF9',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                {Ico.list(wl.tealDeep)}
                <span style={{ fontSize: 14, fontWeight: 700, color: wl.ink, letterSpacing: '-0.2px' }}>항목</span>
              </div>
              <span style={{ fontSize: 11.5, color: wl.ink3 }}>3 / 4 완료</span>
            </div>
            <CustomRow name="독서" kind="number" value={12} unit="페이지"/>
            <CustomRow name="컨디션" kind="scale" value={3}/>
            <CustomRow name="영양제" kind="check" value={true}/>
            <CustomRow name="피아노 연습" kind="check" value={false} last/>
          </div>
        </div>

        <div style={{ height: 18 }}/>
      </div>

      {/* close affordance — chevron up at bottom edge */}
    </div>
  );
}

// ─── Settings → 트래커 편집 (bottom sheet) ────────────────────
function EditorChip({ active, children, color = wl.tealDeep }) {
  return (
    <button style={{
      padding: '6px 12px', borderRadius: 999,
      background: active ? wl.tealTint : '#fff',
      border: `1px solid ${active ? color : wl.hairline}`,
      color: active ? color : wl.ink2,
      fontSize: 12.5, fontWeight: active ? 700 : 500,
      cursor: 'pointer', letterSpacing: '-0.1px',
    }}>{children}</button>
  );
}

function DayChip({ active, children }) {
  return (
    <span style={{
      width: 26, height: 26, borderRadius: 99,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      background: active ? wl.teal : '#fff',
      border: `1px solid ${active ? wl.teal : wl.hairline}`,
      color: active ? '#fff' : wl.ink2,
      fontSize: 12, fontWeight: active ? 700 : 500,
    }}>{children}</span>
  );
}

function EditorItem({ name, kind, unit, days = 'all', highlight }) {
  return (
    <div style={{
      background: highlight ? '#F7FBF9' : '#fff',
      border: `1px solid ${highlight ? '#CFE4DC' : wl.hairline}`,
      borderRadius: 14, padding: 12, display: 'flex', flexDirection: 'column', gap: 10,
    }}>
      {/* name + reorder + delete */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ color: wl.ink3, cursor: 'grab', display: 'flex', flexDirection: 'column', gap: 2 }}>
          <svg width="14" height="6" viewBox="0 0 14 6"><circle cx="3" cy="3" r="1" fill={wl.ink3}/><circle cx="7" cy="3" r="1" fill={wl.ink3}/><circle cx="11" cy="3" r="1" fill={wl.ink3}/></svg>
          <svg width="14" height="6" viewBox="0 0 14 6"><circle cx="3" cy="3" r="1" fill={wl.ink3}/><circle cx="7" cy="3" r="1" fill={wl.ink3}/><circle cx="11" cy="3" r="1" fill={wl.ink3}/></svg>
        </div>
        <div style={{
          flex: 1, background: '#fff', border: `1px solid ${wl.hairline}`,
          borderRadius: 9, padding: '8px 12px',
          fontSize: 14.5, fontWeight: 600, color: wl.ink,
        }}>{name}</div>
        <button style={{
          width: 30, height: 30, borderRadius: 8,
          background: 'transparent', border: 'none', cursor: 'pointer',
          color: wl.ink3, display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
            <path d="M2.5 4.5h11M6.5 4.5V3a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v1.5M4 4.5L4.6 13a1 1 0 0 0 1 .9h4.8a1 1 0 0 0 1-.9L12 4.5"
                  stroke="#C2675B" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      </div>

      {/* kind row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontSize: 11.5, color: wl.ink3, fontWeight: 600, width: 30, letterSpacing: '0.3px' }}>종류</span>
        <div style={{ display: 'flex', gap: 6, flex: 1 }}>
          <EditorChip active={kind === 'check'}>체크</EditorChip>
          <EditorChip active={kind === 'number'}>숫자</EditorChip>
          <EditorChip active={kind === 'scale'}>척도 1~5</EditorChip>
        </div>
        {kind === 'number' && (
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '4px 10px 4px 8px', background: '#fff',
            border: `1px solid ${wl.hairline}`, borderRadius: 8,
          }}>
            <span style={{ fontSize: 10.5, color: wl.ink3, fontWeight: 600 }}>단위</span>
            <span style={{ fontSize: 13, color: wl.ink, fontWeight: 600 }}>{unit}</span>
          </div>
        )}
      </div>

      {/* days row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontSize: 11.5, color: wl.ink3, fontWeight: 600, width: 30, letterSpacing: '0.3px' }}>요일</span>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <EditorChip active={days === 'all'}>매일</EditorChip>
          {['일','월','화','수','목','금','토'].map((d,i) => (
            <DayChip key={i} active={days === 'all' || (Array.isArray(days) && days.includes(i))}>{d}</DayChip>
          ))}
        </div>
      </div>
    </div>
  );
}

function TrackerEditorSheet() {
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      height: '92%',
      background: '#FBFDFC', borderRadius: '24px 24px 0 0',
      boxShadow: '0 -12px 40px rgba(0,0,0,0.22)',
      display: 'flex', flexDirection: 'column',
      overflow: 'hidden',
    }}>
      {/* drag handle */}
      <div style={{ padding: '10px 0 4px', display: 'flex', justifyContent: 'center' }}>
        <div style={{ width: 36, height: 4, background: '#E2E8E6', borderRadius: 99 }}/>
      </div>
      <div style={{ padding: '8px 20px 4px' }}>
        <div style={{ fontSize: 18, fontWeight: 700, color: wl.ink, letterSpacing: '-0.3px' }}>
          트래커 편집
        </div>
        <div style={{ fontSize: 12.5, color: wl.ink3, marginTop: 4, lineHeight: 1.5 }}>
          매일 트래커에서 기록할 항목들. 순서를 잡고 종류와 요일을 설정해요.
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '12px 14px 16px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        <EditorItem name="운동" kind="scale" days="all"/>
        <EditorItem name="물" kind="number" unit="잔" days="all" highlight/>
        <EditorItem name="컨디션" kind="scale" days="all"/>
        <EditorItem name="영양제" kind="check" days="all"/>
        <EditorItem name="피아노 연습" kind="check" days={[1,3,5]}/>

        <button style={{
          margin: '4px 0', padding: '14px 12px',
          background: '#fff', border: `1.5px dashed ${wl.tealSoft}`,
          borderRadius: 14, color: wl.tealDeep, fontSize: 14, fontWeight: 600,
          cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M7 2v10M2 7h10" stroke={wl.tealDeep} strokeWidth="1.8" strokeLinecap="round"/></svg>
          트래커 추가
        </button>

        <div style={{
          marginTop: 6, padding: '12px 14px',
          background: wl.tealTint, border: `1px solid ${wl.tealSoft}`, borderRadius: 12,
          fontSize: 12, color: wl.tealDeep, lineHeight: 1.6,
        }}>
          저장 위치 · 옵시디언 일일노트 frontmatter<br/>
          <span style={{ fontFamily: 'ui-monospace, SFMono-Regular, monospace', fontSize: 11.5, color: wl.ink2 }}>
            trackers: {'{'} 물: 6, 운동: 3, 영양제: true {'}'}
          </span>
        </div>
      </div>
      {/* footer CTA */}
      <div style={{
        padding: '10px 16px 22px',
        background: '#fff', borderTop: `1px solid ${wl.hairline}`,
      }}>
        <div style={{
          background: wl.teal, color: '#fff', textAlign: 'center',
          padding: '14px 0', borderRadius: 14,
          fontWeight: 700, fontSize: 15, letterSpacing: '-0.1px',
          boxShadow: '0 4px 12px rgba(42,157,143,0.25)',
        }}>완료</div>
      </div>
    </div>
  );
}

// ─── Filter chips row (below tracker) ─────────────────────────
function FilterChips({ active = 'all', evening = false }) {
  const chips = [
    { id: 'all',     label: '전체',     color: wl.tealDeep, bg: '#fff', activeBg: wl.tealSoft, activeBorder: '#B7DDD3' },
    { id: 'record',  label: '기록',     color: tagColors.record,  bg: '#fff', activeBg: '#DDEEEA',  activeBorder: '#B7DDD3' },
    { id: 'tracker', label: '트래커',   color: tagColors.tracker, bg: '#fff', activeBg: '#E0ECF8',  activeBorder: '#BFD7EE' },
    { id: 'cleanup', label: '하루정리', color: tagColors.cleanup, bg: '#fff', activeBg: '#FBEEDB',  activeBorder: '#EBD3A9' },
  ];
  return (
    <div style={{
      padding: '10px 16px 12px',
      display: 'flex', gap: 8, overflowX: 'auto',
      borderBottom: `1px solid ${wl.hairline}`,
      background: evening ? 'transparent' : 'transparent',
    }}>
      {chips.map(c => {
        const a = c.id === active;
        return (
          <button key={c.id} style={{
            display: 'inline-flex', alignItems: 'center', gap: 5,
            padding: '6px 13px',
            background: a ? c.activeBg : c.bg,
            border: `1px solid ${a ? c.activeBorder : wl.hairline}`,
            color: a ? c.color : wl.ink2,
            fontSize: 13, fontWeight: a ? 700 : 500,
            borderRadius: 999, cursor: 'pointer',
            whiteSpace: 'nowrap',
            letterSpacing: '-0.1px',
          }}>
            {/* tiny color dot for category, hidden for 전체 */}
            {c.id !== 'all' && (
              <span style={{
                width: 6, height: 6, borderRadius: 99,
                background: c.color,
                opacity: a ? 1 : 0.6,
              }}/>
            )}
            {c.label}
          </button>
        );
      })}
    </div>
  );
}

// ─── Stream day separator ─────────────────────────────────────
function DaySep({ label = '오늘' }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      gap: 8, padding: '14px 0 6px',
    }}>
      <Dots/>
      <span style={{
        fontSize: 11.5, color: wl.ink3, letterSpacing: '0.8px',
        fontWeight: 600, textTransform: 'uppercase',
      }}>{label}</span>
      <Dots/>
    </div>
  );
}
function Dots() {
  return (
    <div style={{ display: 'flex', gap: 3 }}>
      <span style={{ width: 3, height: 3, borderRadius: 99, background: wl.ink3, opacity: 0.4 }}/>
      <span style={{ width: 3, height: 3, borderRadius: 99, background: wl.ink3, opacity: 0.4 }}/>
      <span style={{ width: 3, height: 3, borderRadius: 99, background: wl.ink3, opacity: 0.4 }}/>
    </div>
  );
}

// Tag color palette — user-defined tags + system categories
const tagColors = {
  default:  wl.tealDeep,
  // categories
  record:   '#1E7E72',     // 기록
  tracker:  '#3F86C9',     // 트래커
  cleanup:  '#C28A4B',     // 하루정리
  // common user tags
  '#기쁨':   '#8B6FB8',     // soft purple
  '#감사':   '#C99459',
  '#차분':   '#3F86C9',
  '#배운것': '#1E7E72',
  '#해낸것': '#1E7E72',
  '#성장':   '#4F9F76',
  '#시드닝': '#D89149',     // warm orange (project-y)
};
function tagColor(tag) {
  if (!tag) return tagColors.default;
  if (tagColors[tag]) return tagColors[tag];
  return tagColors.default;
}

// ─── Chat bubble (own message — right-aligned) ────────────────
function Bubble({ time, tag, tagKind, children }) {
  const tc = tagKind ? tagColors[tagKind] : tagColor(tag);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4, padding: '10px 16px 4px' }}>
      <div style={{ fontSize: 11, color: wl.ink3, paddingRight: 4 }}>{time}</div>
      <div style={{
        maxWidth: '78%', background: wl.tealSoft, color: wl.ink,
        padding: '10px 14px', borderRadius: '18px 18px 4px 18px',
        fontSize: 15, lineHeight: 1.5, letterSpacing: '-0.1px',
        boxShadow: '0 1px 0 rgba(30,126,114,0.04)',
      }}>
        {tag && <div style={{
          fontSize: 12.5, color: tc, fontWeight: 700,
          marginBottom: 3, letterSpacing: '-0.1px',
        }}>{tag}</div>}
        {children}
      </div>
    </div>
  );
}

// ─── Link embed inside a bubble (richer) ──────────────────────
function LinkBubble({ time, tag, tagKind, comment, title, source, thumb }) {
  const tc = tagKind ? tagColors[tagKind] : tagColor(tag);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4, padding: '10px 16px 4px' }}>
      <div style={{ fontSize: 11, color: wl.ink3, paddingRight: 4 }}>{time}</div>
      <div style={{
        maxWidth: '80%', background: wl.tealSoft, color: wl.ink,
        padding: '10px 12px 12px', borderRadius: '18px 18px 4px 18px',
        display: 'flex', flexDirection: 'column', gap: 8,
      }}>
        {tag && <div style={{
          fontSize: 12.5, color: tc, fontWeight: 700,
          padding: '0 2px', letterSpacing: '-0.1px',
        }}>{tag}</div>}
        {comment && <div style={{ fontSize: 15, padding: '0 2px', lineHeight: 1.4 }}>{comment}</div>}
        <div style={{
          background: '#fff', borderRadius: 12, padding: 10,
          display: 'flex', gap: 10, alignItems: 'center',
          boxShadow: '0 1px 0 rgba(30,126,114,0.04)',
        }}>
          {/* thumbnail — abstract wave illustration */}
          <div style={{
            width: 44, height: 44, borderRadius: 9, flexShrink: 0,
            background: `linear-gradient(160deg, #BFD8F4 0%, ${wl.wave} 60%, ${wl.waveDeep} 100%)`,
            position: 'relative', overflow: 'hidden',
          }}>
            <svg width="44" height="44" viewBox="0 0 44 44" style={{ position: 'absolute', inset: 0 }}>
              <path d="M0 30 Q11 22 22 30 T44 30 V44 H0 Z" fill="rgba(255,255,255,0.4)"/>
              <path d="M0 36 Q11 30 22 36 T44 36 V44 H0 Z" fill="#fff" opacity="0.7"/>
              <circle cx="32" cy="12" r="5" fill="#FFF4D6"/>
            </svg>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{
              fontSize: 13.5, fontWeight: 600, color: wl.ink, lineHeight: 1.3,
              overflow: 'hidden', textOverflow: 'ellipsis',
              display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical',
            }}>{title}</div>
            <div style={{ fontSize: 11.5, color: wl.ink3, marginTop: 2, display: 'flex', alignItems: 'center', gap: 4 }}>
              {Ico.link(wl.ink3)} <span>{source}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Empty-stream prompt with mascot ──────────────────────────
function EmptyPrompt({ mood = 'neutral', title = '오늘 첫 줄을 남겨볼까요?', sub = '떠오른 생각 · 본 영상 · 한 문장…', image }) {
  return (
    <div style={{
      flex: 1, display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      padding: '24px 24px 40px', gap: 14, textAlign: 'center',
    }}>
      {image ? (
        <div style={{ width: 220, height: 220, position: 'relative' }}>
          <div style={{
            position: 'absolute', inset: -10, borderRadius: '50%',
            background: 'radial-gradient(circle, rgba(42,157,143,0.06) 0%, transparent 70%)',
          }}/>
          <img src={image} alt="" style={{
            position: 'relative', width: '100%', height: '100%',
            objectFit: 'contain',
          }}/>
        </div>
      ) : (
        <div style={{ width: 88, height: 88, position: 'relative' }}>
          <div style={{
            position: 'absolute', inset: -6, borderRadius: '50%',
            background: 'radial-gradient(circle, rgba(42,157,143,0.07) 0%, transparent 70%)',
          }}/>
          <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Mascot size={88} mood={mood}/>
          </div>
        </div>
      )}
      <div style={{ fontSize: 16, fontWeight: 700, color: wl.ink, letterSpacing: '-0.3px' }}>{title}</div>
      <div style={{ fontSize: 13.5, color: wl.ink3 }}>{sub}</div>
    </div>
  );
}

// ─── Input bar ────────────────────────────────────────────────
function InputBar({ value = '메시지 입력…', focused = false, cursor = false }) {
  const showCursor = focused || cursor;
  const showSend = focused && !cursor; // send active only when text exists
  return (
    <div style={{
      padding: '8px 12px 12px',
      display: 'flex', alignItems: 'center', gap: 8,
      background: wl.bg,
    }}>
      <button style={{
        width: 36, height: 36, borderRadius: 99,
        background: 'transparent', border: 'none',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        cursor: 'pointer',
        color: wl.teal,
      }}>
        <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
          <path d="M11 4v14M4 11h14" stroke={wl.teal} strokeWidth="2" strokeLinecap="round"/>
        </svg>
      </button>
      <div style={{
        flex: 1, height: 38, borderRadius: 999,
        background: '#fff', border: `1px solid ${wl.hairline}`,
        display: 'flex', alignItems: 'center', padding: '0 16px',
        fontSize: 14.5, color: wl.ink3,
      }}>
        {showCursor && <span style={{
          marginRight: 1, width: 1.5, height: 18, background: wl.teal,
          animation: 'wl-blink 1.1s steps(2) infinite',
        }}/>}
        <span>{value}</span>
      </div>
      <button style={{
        width: 36, height: 36, borderRadius: 99,
        background: showSend ? wl.teal : wl.tealSoft,
        border: 'none', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        cursor: 'pointer',
        boxShadow: showSend ? '0 4px 10px rgba(42,157,143,0.3)' : 'none',
      }}>{Ico.arrowUp(showSend ? '#fff' : wl.ink3)}</button>
    </div>
  );
}

// ─── Tab bar ──────────────────────────────────────────────────
function TabBar({ active = 'today' }) {
  const Tab = ({ id, label, icon }) => {
    const a = active === id;
    return (
      <div style={{
        flex: 1, display: 'flex', flexDirection: 'column',
        alignItems: 'center', gap: 3, padding: '6px 0 2px',
      }}>
        {icon(a)}
        <span style={{
          fontSize: 11, fontWeight: a ? 700 : 500,
          color: a ? wl.tealDeep : wl.ink3, letterSpacing: '-0.1px',
        }}>{label}</span>
      </div>
    );
  };
  return (
    <div style={{
      borderTop: `1px solid ${wl.hairline}`, background: '#fff',
      paddingBottom: 26, display: 'flex',
    }}>
      <Tab id="today" label="오늘" icon={TabIcon.today}/>
      <Tab id="records" label="기록" icon={TabIcon.records}/>
      <Tab id="settings" label="설정" icon={TabIcon.settings}/>
    </div>
  );
}

// ─── + 시트 (compose panel + Korean keyboard) ─────────────────
// No dim, no overlay — it sits inline above the input bar and pushes
// up the keyboard. Recent tag chips, free-form tag input, and a
// link/source line.

function ComposePanel() {
  const recent = [
    { t: '#독서',      color: tagColors.default },
    { t: '#운동',      color: tagColors.default },
    { t: '#영양제',    color: tagColors.default },
    { t: '#피아노연습', color: tagColors.default },
    { t: '#시드닝',    color: '#D89149' },
    { t: '#기쁨',      color: '#8B6FB8' },
    { t: '#배운것',    color: wl.tealDeep },
  ];
  return (
    <div style={{
      background: wl.bg,
      padding: '10px 0 0',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* recent tag chips — horizontally scrollable */}
      <div style={{
        display: 'flex', gap: 8, padding: '4px 16px 12px',
        overflowX: 'auto', WebkitMaskImage: 'linear-gradient(90deg, #000 92%, transparent 100%)',
        maskImage: 'linear-gradient(90deg, #000 92%, transparent 100%)',
      }}>
        {recent.map(({ t, color }) => (
          <button key={t} style={{
            padding: '7px 14px', borderRadius: 999,
            background: '#fff', border: `1px solid ${wl.hairline}`,
            color, fontSize: 14, fontWeight: 600,
            cursor: 'pointer', whiteSpace: 'nowrap', flexShrink: 0,
            letterSpacing: '-0.1px',
          }}>{t}</button>
        ))}
      </div>

      {/* # 직접 태그 입력 */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 18px',
        borderTop: `1px solid ${wl.hairline}`,
        background: '#fff',
      }}>
        <span style={{
          width: 22, height: 22, borderRadius: 6,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          color: wl.tealDeep, fontSize: 16, fontWeight: 700,
        }}>#</span>
        <span style={{
          flex: 1, fontSize: 14.5, color: wl.ink3, fontWeight: 400,
        }}>직접 태그 입력</span>
      </div>

      {/* 링크/출처 입력 */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '12px 18px',
        borderTop: `1px solid ${wl.hairline}`,
        background: '#fff',
      }}>
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
          <path d="M6.5 9.5l3-3M9 5l1-1a2.8 2.8 0 1 1 4 4l-1 1M7 11l-1 1a2.8 2.8 0 1 1-4-4l1-1"
                stroke={wl.ink3} strokeWidth="1.5" strokeLinecap="round"/>
        </svg>
        <span style={{
          flex: 1, fontSize: 14.5, color: wl.ink3, fontWeight: 400,
        }}>링크(주소 붙여넣기) 또는 출처(책·영상 제목)</span>
      </div>
    </div>
  );
}

// ─── iOS Korean keyboard ──────────────────────────────────────
function Keyboard() {
  const r1 = ['ㅂ','ㅈ','ㄷ','ㄱ','ㅅ','ㅛ','ㅕ','ㅑ','ㅐ','ㅔ'];
  const r2 = ['ㅁ','ㄴ','ㅇ','ㄹ','ㅎ','ㅗ','ㅓ','ㅏ','ㅣ'];
  const r3 = ['ㅋ','ㅌ','ㅊ','ㅍ','ㅠ','ㅜ','ㅡ'];

  const Key = ({ ch, w = 32, bg = '#fff', big = false, children }) => (
    <div style={{
      width: w, height: 42, borderRadius: 5,
      background: bg, boxShadow: bg === '#fff' ? '0 1px 0 rgba(0,0,0,0.18)' : '0 1px 0 rgba(0,0,0,0.10)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: big ? 13 : 18, fontWeight: 400, color: '#000',
      fontFamily: '-apple-system, "SF Pro", system-ui',
      flexShrink: 0,
    }}>{children ?? ch}</div>
  );

  const Suggest = ({ t, mid }) => (
    <div style={{
      flex: 1, padding: '8px 0', display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: 16, color: '#000', borderLeft: mid ? '1px solid rgba(0,0,0,0.18)' : 'none',
      borderRight: mid ? '1px solid rgba(0,0,0,0.18)' : 'none',
    }}>{t}</div>
  );

  return (
    <div style={{
      background: '#D1D4DA',
      padding: '0 0 18px',
      fontFamily: '-apple-system, "SF Pro", "Apple SD Gothic Neo", system-ui',
    }}>
      {/* suggestion strip */}
      <div style={{ display: 'flex', padding: '2px 0' }}>
        <Suggest t="나"/>
        <Suggest t="아" mid/>
        <Suggest t="나는"/>
      </div>

      {/* row 1 */}
      <div style={{ display: 'flex', justifyContent: 'center', gap: 3, padding: '3px 3px' }}>
        {r1.map(ch => <Key key={ch} ch={ch}/>)}
      </div>
      {/* row 2 (offset, 9 keys) */}
      <div style={{ display: 'flex', justifyContent: 'center', gap: 3, padding: '3px 3px' }}>
        {r2.map(ch => <Key key={ch} ch={ch}/>)}
      </div>
      {/* row 3 — shift + letters + backspace */}
      <div style={{ display: 'flex', justifyContent: 'center', gap: 3, padding: '3px 3px', alignItems: 'center' }}>
        <Key w={42} big>
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <path d="M3 8l4-4 4 4M5 8v3h4V8" stroke="#000" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </Key>
        {r3.map(ch => <Key key={ch} ch={ch}/>)}
        <Key w={42} big>
          <svg width="20" height="14" viewBox="0 0 22 16" fill="none">
            <path d="M7 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H7L1 8 7 2z" stroke="#000" strokeWidth="1.3"/>
            <path d="M10.5 6L15 10M15 6l-4.5 4" stroke="#000" strokeWidth="1.3" strokeLinecap="round"/>
          </svg>
        </Key>
      </div>
      {/* bottom row */}
      <div style={{ display: 'flex', justifyContent: 'center', gap: 3, padding: '3px 3px', alignItems: 'center' }}>
        <Key w={42} big>123</Key>
        <Key w={42} big>
          <svg width="20" height="20" viewBox="0 0 22 22" fill="none">
            <circle cx="11" cy="11" r="9" stroke="#000" strokeWidth="1.3"/>
            <circle cx="8" cy="9" r="0.9" fill="#000"/>
            <circle cx="14" cy="9" r="0.9" fill="#000"/>
            <path d="M7.5 13.5c1 1.4 2.2 2.1 3.5 2.1s2.5-.7 3.5-2.1" stroke="#000" strokeWidth="1.2" strokeLinecap="round" fill="none"/>
          </svg>
        </Key>
        <Key w={160} big>
          <span style={{ position: 'relative', width: '100%', textAlign: 'center' }}>
            <span style={{ position: 'absolute', right: 12, top: 0, fontSize: 11, color: '#7C7F86' }}>한</span>
          </span>
        </Key>
        <Key w={42} big>
          {/* dot ... actually emoji */}
        </Key>
        <Key w={66} big>
          <svg width="18" height="14" viewBox="0 0 20 16" fill="none">
            <path d="M14 2v6H4M4 8l3-3M4 8l3 3" stroke="#000" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </Key>
      </div>
      {/* globe + mic strip */}
      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '8px 14px 0' }}>
        <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
          <circle cx="11" cy="11" r="9" stroke="#000" strokeWidth="1.2"/>
          <ellipse cx="11" cy="11" rx="4" ry="9" stroke="#000" strokeWidth="1.2"/>
          <path d="M2 11h18M3.5 6h15M3.5 16h15" stroke="#000" strokeWidth="1.2"/>
        </svg>
        <svg width="20" height="22" viewBox="0 0 20 22" fill="none">
          <rect x="7" y="2" width="6" height="11" rx="3" stroke="#000" strokeWidth="1.3"/>
          <path d="M4 11a6 6 0 0 0 12 0M10 17v3M7 20h6" stroke="#000" strokeWidth="1.3" strokeLinecap="round"/>
        </svg>
      </div>
    </div>
  );
}

// ─── 정리 confirm dialog ──────────────────────────────────────
function CleanupDialog() {
  return (
    <>
      <div style={{
        position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.32)',
        backdropFilter: 'blur(2px)',
      }}/>
      <div style={{
        position: 'absolute', left: 24, right: 24, top: '50%',
        transform: 'translateY(-50%)',
        background: '#fff', borderRadius: 22, padding: '20px 18px 16px',
        boxShadow: '0 20px 50px rgba(0,0,0,0.18)',
        display: 'flex', flexDirection: 'column', gap: 12, alignItems: 'center',
      }}>
        <div style={{ width: 56, height: 56, borderRadius: 16, background: wl.moonCream, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <svg width="34" height="22" viewBox="0 0 24 18" fill="none">
            <path d="M2 6.5c2-2 4-2 6 0s4 2 6 0 4-2 6 0 2 0 2 0"
                  stroke={wl.moonInk} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
            <path d="M2 12c2-2 4-2 6 0s4 2 6 0 4-2 6 0 2 0 2 0"
                  stroke={wl.moonInk} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
          </svg>
        </div>
        <div style={{ fontSize: 17, fontWeight: 700, color: wl.ink, textAlign: 'center', letterSpacing: '-0.3px' }}>
          오늘의 항해를 정리할까요?
        </div>
        <div style={{ fontSize: 13.5, color: wl.ink2, textAlign: 'center', lineHeight: 1.5, padding: '0 4px' }}>
          지금까지의 기록을 GitHub에 안전하게 백업해요.<br/>
          오늘 화면은 비워지지만, [기록]에서 다시 볼 수 있어요.
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8, width: '100%', marginTop: 6 }}>
          <button style={{
            background: wl.teal, color: '#fff', border: 'none',
            padding: '13px 0', borderRadius: 14, fontSize: 15, fontWeight: 700,
            cursor: 'pointer',
            boxShadow: '0 4px 12px rgba(42,157,143,0.25)',
          }}>네, 올릴게요</button>
          <button style={{
            background: 'transparent', color: wl.ink2, border: 'none',
            padding: '10px 0', fontSize: 14, fontWeight: 500,
            cursor: 'pointer',
          }}>조금 더 쓸게요</button>
        </div>
      </div>
    </>
  );
}

// ─── Toast: 정리 완료 ─────────────────────────────────────────
function DoneToast() {
  return (
    <div style={{
      position: 'absolute', left: 16, right: 16, top: 112,
      background: '#fff', borderRadius: 14,
      border: `1px solid ${wl.hairline}`,
      boxShadow: '0 6px 16px rgba(0,0,0,0.06)',
      padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 10,
    }}>
      <div style={{
        width: 28, height: 28, borderRadius: 99,
        background: wl.tealSoft, display: 'flex',
        alignItems: 'center', justifyContent: 'center',
      }}>{Ico.check(wl.tealDeep)}</div>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, color: wl.ink }}>오늘은 이미 올렸어요</div>
        <div style={{ fontSize: 12, color: wl.ink3, marginTop: 1 }}>이후 추가한 기록은 다음 올리기 때 함께 올라갈게요</div>
      </div>
    </div>
  );
}

// ─── 하루 정리 (cleanup) ──────────────────────────────────────
// In-stream block: section heading + 오늘 상태 card + editable question chips.

function SproutIco({ size = 16 }) {
  // small leaf/sprout — replaces 🌱 seedling emoji
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <path d="M8 14V7.5" stroke={wl.tealDeep} strokeWidth="1.5" strokeLinecap="round"/>
      <path d="M8 8.4c-1.7-.1-3.4-1-4-2.5-.2-.6.2-1.2.8-1.2 1.7 0 3.3 1 4 2.4.2.6-.2 1.3-.8 1.3z"
            fill={wl.seed} stroke={wl.tealDeep} strokeWidth="1" strokeLinejoin="round"/>
      <path d="M8 6.8c1.7-.1 3.4-1.1 4-2.7.2-.6-.2-1.2-.8-1.2-1.7.1-3.3 1.2-4 2.6-.2.6.2 1.3.8 1.3z"
            fill={wl.teal} stroke={wl.tealDeep} strokeWidth="1" strokeLinejoin="round"/>
    </svg>
  );
}

function MoodFace({ level, active = false, size = 32 }) {
  // level: 1 (worst) .. 5 (best). Drawn in the app's flat-line style.
  const stroke = active ? wl.tealDeep : wl.ink2;
  const fill   = active ? '#FFF' : '#FFFEF8';
  const eye    = active ? wl.tealDeep : wl.ink2;
  // mouth by level
  const mouthMap = {
    1: <path d="M9.5 19 Q14 16 18.5 19" stroke={stroke} strokeWidth="1.7" strokeLinecap="round" fill="none"/>,
    2: <path d="M10 18.2 Q14 16.6 18 18.2" stroke={stroke} strokeWidth="1.6" strokeLinecap="round" fill="none"/>,
    3: <path d="M10.5 17.5 L17.5 17.5" stroke={stroke} strokeWidth="1.6" strokeLinecap="round"/>,
    4: <path d="M10 16.5 Q14 19.3 18 16.5" stroke={stroke} strokeWidth="1.7" strokeLinecap="round" fill="none"/>,
    5: <path d="M9 15.5 Q14 20.5 19 15.5 Q14 18 9 15.5 Z" fill={stroke} stroke={stroke} strokeWidth="1.4" strokeLinejoin="round"/>,
  };
  // happy → squinty arc eyes; sad/neutral → dots
  const eyes = level >= 4 ? (
    <>
      <path d="M9 12 Q10.6 10.4 12.2 12" stroke={eye} strokeWidth="1.5" strokeLinecap="round" fill="none"/>
      <path d="M15.8 12 Q17.4 10.4 19 12" stroke={eye} strokeWidth="1.5" strokeLinecap="round" fill="none"/>
    </>
  ) : (
    <>
      <circle cx="10.6" cy="12" r="1.1" fill={eye}/>
      <circle cx="17.4" cy="12" r="1.1" fill={eye}/>
    </>
  );
  return (
    <svg width={size} height={size} viewBox="0 0 28 28" fill="none">
      <circle cx="14" cy="14" r="10.5" fill={fill} stroke={stroke} strokeWidth="1.5"/>
      {eyes}
      {mouthMap[level]}
    </svg>
  );
}

function StatusCard({ mood = null, energy = null }) {
  const Cell = ({ on, children }) => (
    <div style={{
      flex: 1, aspectRatio: '1 / 1',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      borderRadius: 12,
      background: on ? wl.tealTint : '#fff',
      border: `1.5px solid ${on ? wl.tealDeep : wl.hairline}`,
      boxShadow: on ? '0 0 0 3px rgba(42,157,143,0.08)' : 'none',
      transition: 'all .15s',
    }}>{children}</div>
  );
  return (
    <div style={{
      margin: '0 16px',
      background: '#fff', border: `1px solid ${wl.hairline}`,
      borderRadius: 18, padding: '14px 14px 16px',
      display: 'flex', flexDirection: 'column', gap: 12,
      boxShadow: '0 1px 0 rgba(28,58,54,0.02)',
    }}>
      <div style={{ fontSize: 13, fontWeight: 700, color: wl.ink, letterSpacing: '-0.1px' }}>오늘 상태</div>
      {/* 기분 */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{ width: 28, fontSize: 13, color: wl.ink2, fontWeight: 500 }}>기분</span>
        <div style={{ display: 'flex', gap: 6, flex: 1 }}>
          {[1, 2, 3, 4, 5].map(lv => (
            <Cell key={lv} on={mood === lv}>
              <MoodFace level={lv} active={mood === lv}/>
            </Cell>
          ))}
        </div>
      </div>
      {/* 활력 */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{ width: 28, fontSize: 13, color: wl.ink2, fontWeight: 500 }}>활력</span>
        <div style={{ display: 'flex', gap: 6, flex: 1 }}>
          {[1, 2, 3, 4, 5].map(n => (
            <Cell key={n} on={energy === n}>
              <span style={{
                fontSize: 16, fontWeight: energy === n ? 700 : 500,
                color: energy === n ? wl.tealDeep : wl.ink3,
                fontVariantNumeric: 'tabular-nums',
              }}>{n}</span>
            </Cell>
          ))}
        </div>
      </div>
    </div>
  );
}

function QuestionChip({ q, active = false }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'flex-start', padding: '3px 16px' }}>
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '10px 14px',
        background: active ? wl.tealTint : '#fff',
        border: `1.5px solid ${active ? wl.tealDeep : wl.hairline}`,
        borderRadius: '18px 18px 18px 6px',
        fontSize: 14.5, color: active ? wl.tealDeep : wl.ink,
        fontWeight: active ? 600 : 500,
        cursor: 'pointer', letterSpacing: '-0.1px',
        boxShadow: active ? '0 0 0 3px rgba(42,157,143,0.08)' : '0 1px 0 rgba(28,58,54,0.02)',
      }}>
        <SproutIco size={15}/>
        <span>{q}</span>
      </div>
    </div>
  );
}

function WrapupBlock({ mood, energy, activeQ }) {
  const questions = ['오늘 해낸 건?', '오늘 뭐 배웠어?', '오늘 성장한 점은?'];
  return (
    <div style={{ paddingTop: 6, paddingBottom: 8 }}>
      {/* section heading — wave icon ties this to the "정리" CTA in the header */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 7,
        padding: '8px 18px 10px',
      }}>
        {Ico.waves(wl.tealDeep)}
        <span style={{ fontSize: 15, fontWeight: 700, color: wl.ink, letterSpacing: '-0.2px' }}>
          하루 정리
        </span>
      </div>
      <StatusCard mood={mood} energy={energy}/>
      <div style={{ height: 12 }}/>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        {questions.map((q, i) => (
          <QuestionChip key={i} q={q} active={activeQ === i}/>
        ))}
      </div>
    </div>
  );
}

function AnswerHintBar({ q }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '8px 16px 6px',
      borderTop: `1px solid ${wl.hairline}`,
      background: wl.bg,
      fontSize: 12.5,
    }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
        <SproutIco size={13}/>
        <span style={{ color: wl.ink3 }}>답하는 중</span>
        <span style={{ color: wl.ink, fontWeight: 600 }}>· {q}</span>
      </span>
      <span style={{ color: wl.tealDeep, fontWeight: 600, fontSize: 13 }}>취소</span>
    </div>
  );
}

// ─── 하루 마무리 질문 — 편집 바텀시트 ─────────────────────────
function WrapupEditorSheet() {
  const items = [
    { tag: '해낸것', value: '오늘 해낸 건?' },
    { tag: '배운것', value: '오늘 뭐 배웠어?' },
    { tag: '성장',   value: '오늘 성장한 점은?' },
  ];
  const FieldRow = ({ tag, value, highlight }) => (
    <div style={{
      background: highlight ? '#F7FBF9' : '#fff',
      border: `1px solid ${highlight ? '#CFE4DC' : wl.hairline}`,
      borderRadius: 14, padding: 12, display: 'flex', flexDirection: 'column', gap: 10,
    }}>
      {/* drag + value-input + delete */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ color: wl.ink3, cursor: 'grab', display: 'flex', flexDirection: 'column', gap: 2 }}>
          <svg width="14" height="6" viewBox="0 0 14 6"><circle cx="3" cy="3" r="1" fill={wl.ink3}/><circle cx="7" cy="3" r="1" fill={wl.ink3}/><circle cx="11" cy="3" r="1" fill={wl.ink3}/></svg>
          <svg width="14" height="6" viewBox="0 0 14 6"><circle cx="3" cy="3" r="1" fill={wl.ink3}/><circle cx="7" cy="3" r="1" fill={wl.ink3}/><circle cx="11" cy="3" r="1" fill={wl.ink3}/></svg>
        </div>
        <div style={{
          flex: 1, background: '#fff', border: `1px solid ${wl.hairline}`,
          borderRadius: 9, padding: '8px 12px',
          fontSize: 14.5, fontWeight: 500, color: wl.ink,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8,
        }}>
          <span>{value}</span>
          <PencilIco c={wl.ink3}/>
        </div>
        <button style={{
          width: 30, height: 30, borderRadius: 8,
          background: 'transparent', border: 'none', cursor: 'pointer',
          color: wl.ink3, display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
            <path d="M2.5 4.5h11M6.5 4.5V3a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v1.5M4 4.5L4.6 13a1 1 0 0 0 1 .9h4.8a1 1 0 0 0 1-.9L12 4.5"
                  stroke="#C2675B" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      </div>

      {/* tag row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontSize: 11.5, color: wl.ink3, fontWeight: 600, width: 30, letterSpacing: '0.3px' }}>태그</span>
        <div style={{
          display: 'inline-flex', alignItems: 'baseline', gap: 3,
          padding: '5px 11px', borderRadius: 999,
          background: wl.tealTint, border: `1px solid ${wl.tealSoft}`,
        }}>
          <span style={{ color: wl.teal, fontSize: 13, fontWeight: 700 }}>#</span>
          <span style={{ color: wl.tealDeep, fontSize: 13, fontWeight: 600 }}>{tag}</span>
        </div>
      </div>
    </div>
  );

  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0, top: 200,
      background: '#fff', borderRadius: '22px 22px 0 0',
      boxShadow: '0 -8px 30px rgba(28,58,54,0.18)',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      {/* grabber */}
      <div style={{ padding: '8px 0 2px', display: 'flex', justifyContent: 'center' }}>
        <div style={{ width: 36, height: 4, borderRadius: 99, background: '#D8E2DE' }}/>
      </div>
      {/* title */}
      <div style={{ padding: '8px 20px 4px' }}>
        <div style={{ fontSize: 18, fontWeight: 700, color: wl.ink, letterSpacing: '-0.3px' }}>
          하루 마무리 질문
        </div>
        <div style={{ fontSize: 12.5, color: wl.ink3, marginTop: 4, lineHeight: 1.5 }}>
          저녁에 뜨는 질문이에요. 순서·문구·태그를 자유롭게 바꿔요.
        </div>
      </div>
      {/* list */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '12px 14px 16px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {items.map(({ tag, value }, i) => (
          <FieldRow key={i} tag={tag} value={value} highlight={i === 0}/>
        ))}
        <button style={{
          margin: '4px 0', padding: '14px 12px',
          background: '#fff', border: `1.5px dashed ${wl.tealSoft}`,
          borderRadius: 14, color: wl.tealDeep, fontSize: 14, fontWeight: 600,
          cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M7 2v10M2 7h10" stroke={wl.tealDeep} strokeWidth="1.8" strokeLinecap="round"/></svg>
          질문 추가
        </button>
      </div>
      {/* footer CTA */}
      <div style={{
        padding: '10px 16px 22px',
        background: '#fff', borderTop: `1px solid ${wl.hairline}`,
      }}>
        <div style={{
          background: wl.teal, color: '#fff', textAlign: 'center',
          padding: '14px 0', borderRadius: 14,
          fontWeight: 700, fontSize: 15, letterSpacing: '-0.1px',
          boxShadow: '0 4px 12px rgba(42,157,143,0.25)',
        }}>완료</div>
      </div>
    </div>
  );
}

// ─── Today Screen — composes everything ───────────────────────
function TodayScreen({ variant = 'default' }) {
  const W = 390, H = 844;
  const dark = false;

  // Stream content per variant
  const isEmpty = variant === 'empty' || variant === 'cleaned';
  const showTracker = variant !== 'empty';
  const trackerExpanded = variant === 'expanded' || variant === 'expanded-nap' || variant === 'expanded-wheel';
  const showEditor = variant === 'editor';
  const showPlus = variant === 'plus';
  const showDialog = variant === 'dialog';
  const showToast = variant === 'cleaned';
  const isWrapup = variant === 'wrapup' || variant === 'wrapup-answering' || variant === 'wrapup-edit';
  const wrapupAnswering = variant === 'wrapup-answering';
  const wrapupEditing = variant === 'wrapup-edit';
  const eveningTone = variant === 'evening' || variant === 'dialog' || isWrapup;
  const time = isWrapup ? '17:06' : (eveningTone ? '21:14' : (variant === 'empty' ? '07:32' : '15:47'));
  const date = (variant === 'empty' || isWrapup) ? '5월 23일 (토)' : '5월 22일 (금)';
  const sheetActive = trackerExpanded || showEditor || showPlus || showDialog || wrapupEditing;

  return (
    <div style={{
      width: W, height: H, borderRadius: 48, overflow: 'hidden',
      position: 'relative',
      background: eveningTone
        ? `linear-gradient(180deg, #F4F1EA 0%, ${wl.bg} 35%)`
        : `linear-gradient(180deg, #F4F9F7 0%, ${wl.bg} 22%)`,
      boxShadow: '0 30px 60px rgba(28,58,54,0.18), 0 0 0 1px rgba(28,58,54,0.08)',
      fontFamily: '"Pretendard", -apple-system, "SF Pro", "Apple SD Gothic Neo", system-ui',
      WebkitFontSmoothing: 'antialiased',
      color: wl.ink,
      display: 'flex', flexDirection: 'column',
    }}>
      {/* Dynamic island */}
      <div style={{
        position: 'absolute', top: 11, left: '50%', transform: 'translateX(-50%)',
        width: 122, height: 35, borderRadius: 22, background: '#000', zIndex: 30,
      }}/>

      <StatusBar time={time} dark={dark}/>

      <Header date={date} evening={eveningTone} showUpload={variant !== 'empty'}/>

      {showTracker && (
        variant === 'empty' || variant === 'cleaned'
          ? <TrackerStrip sleep="—" nap="—" checks="0/3"/>
          : isWrapup
            ? <TrackerStrip sleep="7.5h" nap="—" checks="0/1"/>
            : <TrackerStrip expanded={trackerExpanded}/>
      )}
      {showTracker && <FilterChips active="all" evening={eveningTone}/>}

      {/* Stream */}
      <div style={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
        {isEmpty ? (
          <EmptyPrompt
            mood={variant === 'cleaned' ? 'calm' : 'neutral'}
            image={variant === 'cleaned' ? 'assets/done-character.svg' : 'assets/normal-character.svg'}
            title={variant === 'cleaned' ? '오늘은 이제 가볍게.' : '오늘 첫 줄을 남겨볼까요?'}
            sub={variant === 'cleaned' ? '쉬어가도 괜찮아요. 떠오를 때 다시 와요.' : '떠오른 생각 · 본 영상 · 한 문장…'}
          />
        ) : (
          <div style={{ flex: 1, overflowY: 'auto' }}>
            <DaySep label={eveningTone ? '오늘 · 저녁' : '오늘'}/>
            {isWrapup ? (
              <>
                <Bubble time="11:42">오전 연습. 손목 풀고 시작.</Bubble>
                <Bubble time="14:18" tag="#기쁨">
                  앙상블 합주 — 마디 32~48 합이 진짜 좋았다.
                </Bubble>
                <Bubble time="17:05">
                  오늘 앙상블 갔다왔다.
                </Bubble>
              </>
            ) : variant === 'evening' ? (
              <>
                <Bubble time="07:58">
                  새벽에 한 번 깼는데 다시 잘 잤다.
                </Bubble>
                <Bubble time="09:14" tag="#차분">
                  아침에 든 생각 한 줄 — 천천히 가도 되는 날.
                </Bubble>
                <LinkBubble
                  time="00:48"
                  tag="#시드닝"
                  comment="장기요양 ERP 개발에 참고해 봐야지"
                  title="토스 PO 출신 대표가 사내 ERP와 AI 에이전트를 직접 만들고 AI 네이티브 컴퍼니로 거듭…"
                  source="folin.co"
                />
                <Bubble time="13:20" tag="#배운것">
                  급하지 않은 일은 내일로 미뤄도 무너지지 않는다.
                </Bubble>
                <Bubble time="18:42" tag="#기쁨">
                  창문 열어두고 차 한 잔.<br/>오늘 저녁은 조용했다.
                </Bubble>
                <Bubble time="20:50" tag="#하루정리" tagKind="cleanup">
                  오늘 한 줄: 천천히 가도 무너지지 않는다는 걸 다시 배움.
                </Bubble>
              </>
            ) : (
              <>
                <Bubble time="09:14">아침에 든 생각 한 줄.</Bubble>
                <Bubble time="11:02" tag="#기쁨">
                  새 프로젝트 첫 줄 적었다. 가볍게 시작.
                </Bubble>
                <LinkBubble
                  time="13:20"
                  tag="#시드닝"
                  comment="조용할 때 좋은 클래식"
                  title="쇼팽 녹턴 Op.9 No.2 — YouTube"
                  source="youtube.com"
                />
                <Bubble time="15:46" tag="#기쁨">
                  이 앱에 관한 아이디어 떠오르는 거~~
                </Bubble>
                <Bubble time="15:47" tag="#배운것">
                  마찰 줄이기 = 매일 쓰게 만드는 가장 큰 레버.
                </Bubble>
              </>
            )}
            <div style={{ height: 12 }}/>
          </div>
        )}
      </div>

      {showPlus && (
        <div style={{
          position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.34)',
          backdropFilter: 'blur(1px)', zIndex: 10,
        }}/>
      )}
      {isWrapup && !wrapupEditing && (
        <div style={{
          position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.34)',
          backdropFilter: 'blur(1px)', zIndex: 10,
        }}/>
      )}
      <div style={{
        position: (showPlus || (isWrapup && !wrapupEditing)) ? 'relative' : 'static',
        zIndex: (showPlus || (isWrapup && !wrapupEditing)) ? 20 : 'auto',
      }}>
        {showPlus && <ComposePanel/>}
        {isWrapup && !wrapupEditing && (
          <div style={{
            background: wl.bg,
            borderRadius: '22px 22px 0 0',
            boxShadow: '0 -10px 30px rgba(28,58,54,0.20)',
            paddingTop: 6,
          }}>
            {/* grabber */}
            <div style={{ padding: '6px 0 0', display: 'flex', justifyContent: 'center' }}>
              <div style={{ width: 36, height: 4, borderRadius: 99, background: '#D8E2DE' }}/>
            </div>
            <WrapupBlock
              mood={wrapupAnswering ? 3 : null}
              energy={wrapupAnswering ? 3 : null}
              activeQ={wrapupAnswering ? 1 : null}
            />
          </div>
        )}
        {wrapupAnswering && <AnswerHintBar q="오늘 해낸 건?"/>}
        <InputBar value="메시지 입력…" cursor={showPlus}/>
        {showPlus ? <Keyboard/> : <TabBar active="today"/>}
      </div>

      {/* Overlays */}
      {trackerExpanded && <>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.34)', backdropFilter: 'blur(1px)' }}/>
        <TrackerSheet
          napOn={variant !== 'expanded'}
          napDuration="30"
          showWheel={variant === 'expanded-wheel'}
        />
      </>}
      {showEditor && <>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.34)', backdropFilter: 'blur(1px)' }}/>
        <TrackerEditorSheet/>
      </>}
      {showDialog && <CleanupDialog/>}
      {showToast && <DoneToast/>}
      {wrapupEditing && <>
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(28,58,54,0.34)', backdropFilter: 'blur(1px)' }}/>
        <WrapupEditorSheet/>
      </>}

      {/* Home indicator — hidden when keyboard up */}
      {!showPlus && <div style={{
        position: 'absolute', bottom: 8, left: '50%', transform: 'translateX(-50%)',
        width: 134, height: 5, borderRadius: 99, background: 'rgba(28,58,54,0.32)',
        zIndex: 40,
      }}/>}
    </div>
  );
}

Object.assign(window, {
  TodayScreen, Mascot, wl, Ico,
  MoodFace, SproutIco, StatusCard,
  Bubble, LinkBubble, StatusBar, TabBar, Header, TrackerStrip,
  FilterChips, DaySep, Toggle, PencilIco,
  WrapupEditorSheet, TrackerEditorSheet,
  PickRow, WheelTimePicker, Keyboard, tagColors,
  TrackerSheet, CustomRow, NapChips,
});

// ─── Splash screens ───────────────────────────────────────────
// Two variants — minimal centered, and tagline/poetic.

function SplashWaves({ color = '#74B2E7', opacity = 1 }) {
  // Decorative SVG wave layers in the icon style
  return (
    <svg width="390" height="240" viewBox="0 0 390 240" preserveAspectRatio="none"
         style={{ position: 'absolute', left: 0, right: 0, bottom: 0, opacity, pointerEvents: 'none' }}>
      <defs>
        <linearGradient id="splash-grad" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%" stopColor="#9CC8EE"/>
          <stop offset="50%" stopColor={color}/>
          <stop offset="100%" stopColor="#5A9ED7"/>
        </linearGradient>
      </defs>
      <path d="M0 130 Q 60 100 130 130 T 260 130 T 390 120 L390 240 L0 240 Z"
            fill="url(#splash-grad)" opacity="0.35"/>
      <path d="M0 165 Q 70 135 150 165 T 290 168 T 390 160 L390 240 L0 240 Z"
            fill={color} opacity="0.55"/>
      <path d="M0 195 Q 80 170 170 195 T 320 198 T 390 195 L390 240 L0 240 Z"
            fill={color} opacity="0.85"/>
    </svg>
  );
}

function SplashScreen({ variant = 'minimal' }) {
  const W = 390, H = 844;
  const bg = variant === 'poetic'
    ? 'linear-gradient(180deg, #F0F6FA 0%, #F8FBFC 50%, #FBFDFC 100%)'
    : '#FBFDFC';

  return (
    <div style={{
      width: W, height: H, borderRadius: 48, overflow: 'hidden',
      position: 'relative', background: bg,
      boxShadow: '0 30px 60px rgba(28,58,54,0.18), 0 0 0 1px rgba(28,58,54,0.08)',
      fontFamily: '"Pretendard", -apple-system, "SF Pro", "Apple SD Gothic Neo", system-ui',
      WebkitFontSmoothing: 'antialiased',
      color: wl.ink,
      display: 'flex', flexDirection: 'column',
    }}>
      {/* Dynamic island */}
      <div style={{
        position: 'absolute', top: 11, left: '50%', transform: 'translateX(-50%)',
        width: 122, height: 35, borderRadius: 22, background: '#000', zIndex: 30,
      }}/>
      <StatusBar time="07:32" dark={false}/>

      {variant === 'minimal' && (
        <>
          {/* center icon + name */}
          <div style={{
            flex: 1, display: 'flex', flexDirection: 'column',
            alignItems: 'center', justifyContent: 'center', gap: 22,
            paddingBottom: 60,
          }}>
            <img src="assets/app-icon.svg" alt=""
                 style={{
                   width: 132, height: 132, borderRadius: 30,
                   boxShadow: '0 14px 36px rgba(65,135,202,0.20), 0 1px 0 rgba(28,58,54,0.05)',
                 }}/>
            <div style={{ textAlign: 'center', display: 'flex', flexDirection: 'column', gap: 6 }}>
              <div style={{
                fontSize: 30, fontWeight: 700, color: wl.ink,
                letterSpacing: '-0.8px',
              }}>wayvel</div>
              <div style={{
                fontSize: 14, fontWeight: 500, color: wl.ink3,
                letterSpacing: '0.4px',
              }}>파도타기</div>
            </div>
          </div>

          {/* subtle wave decoration at bottom */}
          <SplashWaves opacity={0.55}/>

          {/* tiny loading dot */}
          <div style={{
            position: 'absolute', left: 0, right: 0, bottom: 80,
            display: 'flex', justifyContent: 'center', gap: 6, zIndex: 5,
          }}>
            {[0, 1, 2].map(i => (
              <div key={i} style={{
                width: 6, height: 6, borderRadius: 99, background: wl.tealDeep,
                opacity: 0.25 + (i * 0.25),
              }}/>
            ))}
          </div>
        </>
      )}

      {variant === 'poetic' && (
        <>
          {/* top: icon */}
          <div style={{
            paddingTop: 100, display: 'flex', justifyContent: 'center',
          }}>
            <img src="assets/app-icon.svg" alt=""
                 style={{
                   width: 96, height: 96, borderRadius: 22,
                   boxShadow: '0 10px 28px rgba(65,135,202,0.18)',
                 }}/>
          </div>

          {/* center: brand quote */}
          <div style={{
            flex: 1, display: 'flex', flexDirection: 'column',
            alignItems: 'center', justifyContent: 'center',
            padding: '24px 36px 80px', gap: 18, textAlign: 'center',
          }}>
            <div style={{
              fontSize: 22, fontWeight: 500, color: wl.ink,
              lineHeight: 1.55, letterSpacing: '-0.4px',
              textWrap: 'pretty',
            }}>
              파도를 멈출 순 없지만,<br/>
              <span style={{ color: wl.tealDeep, fontWeight: 700 }}>파도 타는 법</span>을<br/>
              배울 수는 있다.
            </div>
            <div style={{
              fontSize: 12, color: wl.ink3, letterSpacing: '0.6px',
              textTransform: 'uppercase', fontWeight: 600,
            }}>— Jon Kabat-Zinn</div>
          </div>

          {/* bottom waves */}
          <SplashWaves opacity={0.9}/>

          {/* mascot peeking from waves */}
          <img src="assets/normal-character.svg" alt=""
               style={{
                 position: 'absolute', right: 30, bottom: 70,
                 width: 130, height: 130, objectFit: 'contain',
                 zIndex: 6,
                 filter: 'drop-shadow(0 4px 14px rgba(65,135,202,0.20))',
               }}/>
        </>
      )}

      {/* Home indicator */}
      <div style={{
        position: 'absolute', bottom: 8, left: '50%', transform: 'translateX(-50%)',
        width: 134, height: 5, borderRadius: 99, background: 'rgba(28,58,54,0.32)',
        zIndex: 40,
      }}/>
    </div>
  );
}

Object.assign(window, { SplashScreen });
