// kataleya-screens.jsx — The five screens. Pure presentation, no routing.

// ── BRIDGE — arrival ritual ─────────────────────────────────────────────
function BridgeScreen({ phase, daysSober, onEnter, gapFraction, ringSize }) {
  const theme = window.PHASE_THEME[phase];
  const rgba = window.rgba;
  const [phraseKey, setPhraseKey] = React.useState(0);

  const phrasePools = {
    dawn:       ['the garden wakes.\nso do you.', 'morning again.\nyou made it here.'],
    day:        ['you are present.\nthat is enough.', 'the work continues.\nso do you.'],
    goldenHour: ['the threshold.\nhold.', 'this feeling has a lifespan.\noutlast it.'],
    night:      ['the garden is open.\neven now.', '2am always ends.', 'rest is not surrender.\nit is preparation.'],
  };
  const phrases = phrasePools[phase];
  const phrase = phrases[phraseKey % phrases.length];

  React.useEffect(() => { setPhraseKey(k => k + 1); }, [phase]);

  return (
    <div style={{
      position: 'absolute', inset: 0, background: '#050508',
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      justifyContent: 'center', overflow: 'hidden',
    }}>
      <Atmosphere phase={phase} />
      <HudCorners phase={phase} opacity={0.32} inset={22} />

      <div style={{
        position: 'absolute', top: 70,
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 10, letterSpacing: 4, textTransform: 'uppercase',
        color: rgba(theme.rgb, 0.35),
      }}>◈ {theme.ouro}</div>

      {/* Ring composition */}
      <div style={{
        position: 'relative', width: ringSize, height: ringSize,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        transform: 'perspective(600px) rotateX(-12deg)',
      }}>
        <OuroborosRing size={ringSize} phase={phase} gapFraction={gapFraction} cycleCount={daysSober} />
        {/* hollow */}
        <div style={{
          position: 'absolute',
          width: ringSize * 0.42, height: ringSize * 0.42,
          borderRadius: '50%',
          background: 'rgba(5,5,8,0.62)',
          border: `1px solid ${rgba(theme.rgb, 0.1)}`,
        }} />
        {/* butterfly */}
        <div style={{ position: 'absolute', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <ButterflyDNA size={ringSize * 0.34} phase={phase} />
        </div>
      </div>

      {/* system status */}
      <div style={{
        marginTop: 18,
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 9, letterSpacing: 2.5,
        color: rgba(theme.rgb, 0.25),
        animation: 'fadeInSlow 2s ease-out 2.5s both',
      }}>sys · nominal · {theme.ouro}</div>

      {/* garden phrase */}
      <div key={phraseKey} style={{
        marginTop: 22, padding: '0 40px', maxWidth: 320,
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 15, lineHeight: '24px', letterSpacing: 0.3,
        fontStyle: 'italic', textAlign: 'center', whiteSpace: 'pre-line',
        color: rgba(theme.rgb, 0.72),
      }}>
        <Typewriter key={phraseKey + '-' + phase} text={phrase} speed={32} jitter={16} />
      </div>

      {/* enter button */}
      <button
        onClick={onEnter}
        style={{
          marginTop: 30, padding: '13px 52px',
          background: rgba(theme.rgb, 0.05),
          border: `1px solid ${rgba(theme.rgb, 0.28)}`,
          borderTop: `1.5px solid ${rgba(theme.rgb, 0.5)}`,
          borderRadius: 4,
          boxShadow: `0 0 14px ${rgba(theme.rgb, 0.28)}`,
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 12, letterSpacing: 3, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.85),
          cursor: 'pointer',
          animation: 'fadeInSlow 1s ease-out 3.2s both',
        }}>enter</button>

      {/* wordmark */}
      <div style={{
        position: 'absolute', bottom: 48,
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 11, letterSpacing: 6, textTransform: 'lowercase',
        color: rgba(theme.rgb, 0.16),
        animation: 'fadeInSlow 2s ease-out 4s both',
      }}>kataleya</div>
    </div>
  );
}

// ── ROOM — the orb owns the canvas ──────────────────────────────────────
function RoomScreen({ phase, daysSober, userName, onTapOrb, onSwipeLeft, onSwipeUp, onLongPress, gapFraction, ringSize, bpm, transmutationScars }) {
  const theme = window.PHASE_THEME[phase];
  const rgba = window.rgba;
  const [pressed, setPressed] = React.useState(false);
  const [dragStart, setDragStart] = React.useState(null);
  const longPressRef = React.useRef(null);

  const presenceByState = {
    dawn:       'the garden wakes. so do you.',
    day:        "i'm here.",
    goldenHour: 'the threshold. hold.',
    night:      "i don't sleep.",
  };
  const greetByPhase = {
    dawn: 'good morning', day: 'good afternoon', goldenHour: 'good evening', night: "i'm here."
  };

  const handleDown = (e) => {
    const t = e.touches ? e.touches[0] : e;
    setDragStart({ x: t.clientX, y: t.clientY, at: Date.now() });
    setPressed(true);
    longPressRef.current = setTimeout(() => {
      onLongPress && onLongPress();
      longPressRef.current = null;
    }, 900);
  };
  const handleUp = (e) => {
    setPressed(false);
    if (longPressRef.current) {
      clearTimeout(longPressRef.current);
      longPressRef.current = null;
      if (dragStart) {
        const t = e.changedTouches ? e.changedTouches[0] : e;
        const dx = t.clientX - dragStart.x;
        const dy = t.clientY - dragStart.y;
        const dur = Date.now() - dragStart.at;
        if (dy < -60 && Math.abs(dy) > Math.abs(dx)) onSwipeUp && onSwipeUp();
        else if (dx < -60 && Math.abs(dx) > Math.abs(dy)) onSwipeLeft && onSwipeLeft();
        else if (Math.abs(dx) < 10 && Math.abs(dy) < 10 && dur < 500) onTapOrb && onTapOrb();
      }
    }
    setDragStart(null);
  };

  return (
    <div
      onMouseDown={handleDown} onMouseUp={handleUp} onMouseLeave={() => { setPressed(false); if (longPressRef.current) { clearTimeout(longPressRef.current); longPressRef.current = null; } }}
      onTouchStart={handleDown} onTouchEnd={handleUp}
      style={{
        position: 'absolute', inset: 0, background: '#050508',
        display: 'flex', flexDirection: 'column', alignItems: 'center',
        justifyContent: 'center', overflow: 'hidden', cursor: 'pointer',
        userSelect: 'none',
      }}>
      <Atmosphere phase={phase} />

      {/* phase whisper top-left */}
      <div style={{
        position: 'absolute', top: 70, left: 24,
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 9, letterSpacing: 3, textTransform: 'lowercase',
        color: rgba(theme.rgb, 0.35),
      }}>{theme.displayName}</div>

      {/* composition */}
      <div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: -40 }}>
        <div style={{
          position: 'absolute', display: 'flex', alignItems: 'center', justifyContent: 'center',
          transform: 'perspective(700px) rotateX(-10deg)',
        }}>
          <OuroborosRing size={ringSize} phase={phase} gapFraction={gapFraction} cycleCount={daysSober} transmutationScars={transmutationScars} />
        </div>
        <SphereOrb size={Math.floor(ringSize * 0.58)} phase={phase} pressed={pressed} bpm={bpm} />
      </div>

      {/* presence */}
      <div style={{ marginTop: 28, textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 10, letterSpacing: 1.5, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.45),
        }}>{greetByPhase[phase]}{userName ? `, ${userName.toLowerCase()}` : ''}</div>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 15, letterSpacing: 0.5, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.72),
          textShadow: `0 0 12px ${rgba(theme.rgb, 0.25)}`,
        }}>{presenceByState[phase]}</div>
      </div>

      {/* day count */}
      {daysSober > 0 && (
        <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
          <div style={{
            fontFamily: '"Courier Prime", ui-monospace, monospace',
            fontSize: 40, lineHeight: '44px', letterSpacing: -1,
            color: rgba(theme.rgb, 0.85),
          }}>{daysSober}</div>
          <div style={{
            fontFamily: '"Courier Prime", ui-monospace, monospace',
            fontSize: 9, letterSpacing: 3, textTransform: 'lowercase',
            color: rgba(theme.rgb, 0.3),
          }}>{daysSober === 1 ? 'day' : 'days'}</div>
          <MercuryLine phase={phase} width={44} />
        </div>
      )}

      {/* gesture hints */}
      <div style={{
        position: 'absolute', bottom: 48,
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
      }}>
        {['swipe up · memory', 'swipe left · talk', 'hold · sanctuary'].map(h => (
          <div key={h} style={{
            fontFamily: '"Courier Prime", ui-monospace, monospace',
            fontSize: 8, letterSpacing: 2, textTransform: 'lowercase',
            color: rgba(theme.rgb, 0.18),
          }}>{h}</div>
        ))}
      </div>
    </div>
  );
}

// ── CONVERSATION — CBT as dialogue, one question per screen ────────────
function ConversationScreen({ phase, onBack }) {
  const theme = window.PHASE_THEME[phase];
  const rgba = window.rgba;
  const [step, setStep] = React.useState(0);
  const [answers, setAnswers] = React.useState({});
  const [textInput, setTextInput] = React.useState('');

  // Inference: phase=night + high restlessness → mood_check slow gentle
  const script = [
    { type: 'intro', text: phase === 'night'
        ? "hey.\nit's late. you're here.\nthat's enough."
        : "okay. one thing at a time." },
    { type: 'text', prompt: "what's it saying?", placeholder: 'let it out…', key: 'thought' },
    { type: 'scale', prompt: 'how loud is it?', min: 1, max: 10, key: 'intensity' },
    { type: 'select', prompt: 'and the weather inside?',
      options: ['storm', 'fog', 'still water', 'first light'], key: 'mood' },
    { type: 'close', text: "i've got this. it's safer here.\nthe garden remembers." },
  ];
  const s = script[step];

  const answer = (val) => {
    setAnswers(a => ({ ...a, [s.key]: val }));
    setTextInput('');
    setStep(i => Math.min(i + 1, script.length - 1));
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, background: '#050508',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <Atmosphere phase={phase} />

      {/* header */}
      <div style={{
        position: 'absolute', top: 58, left: 0, right: 0,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        padding: '0 22px', zIndex: 10,
      }}>
        <button onClick={onBack} style={{
          background: 'transparent', border: 'none',
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 10, letterSpacing: 2, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.4), cursor: 'pointer', padding: 4,
        }}>← room</button>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 9, letterSpacing: 3, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.3),
        }}>{step + 1} / {script.length}</div>
      </div>

      {/* progress mercury */}
      <div style={{
        position: 'absolute', top: 82, left: 22, right: 22, height: 1,
        background: rgba(theme.rgb, 0.08),
      }}>
        <div style={{
          width: `${((step + 1) / script.length) * 100}%`, height: '100%',
          background: `linear-gradient(90deg, transparent, ${rgba(theme.rgb, 0.7)})`,
          transition: 'width 600ms cubic-bezier(.4,0,.2,1)',
        }} />
      </div>

      {/* question/content — centered */}
      <div key={step} style={{
        flex: 1, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center',
        padding: '0 32px', animation: 'softFade 800ms ease-out',
      }}>
        {(s.type === 'intro' || s.type === 'close') && (
          <div style={{
            fontFamily: '"Courier Prime", ui-monospace, monospace',
            fontSize: 19, lineHeight: '30px', letterSpacing: 0.3,
            textAlign: 'center', whiteSpace: 'pre-line',
            color: rgba(theme.rgb, 0.82),
          }}>
            <Typewriter key={step} text={s.text} speed={38} jitter={14} />
          </div>
        )}

        {s.type === 'text' && (
          <>
            <div style={{
              fontFamily: '"Courier Prime", ui-monospace, monospace',
              fontSize: 18, letterSpacing: 0.3, textAlign: 'center',
              color: rgba(theme.rgb, 0.8), marginBottom: 28,
            }}>
              <Typewriter key={step} text={s.prompt} speed={38} jitter={14} />
            </div>
            <textarea
              value={textInput}
              onChange={(e) => setTextInput(e.target.value)}
              placeholder={s.placeholder}
              style={{
                width: '100%', minHeight: 90, resize: 'none',
                background: 'transparent',
                border: `1px solid ${rgba(theme.rgb, 0.18)}`,
                borderRadius: 4, padding: 12,
                fontFamily: '"Courier Prime", ui-monospace, monospace',
                fontSize: 14, lineHeight: '22px',
                color: rgba(theme.rgb, 0.9),
                outline: 'none',
              }} />
          </>
        )}

        {s.type === 'scale' && (
          <>
            <div style={{
              fontFamily: '"Courier Prime", ui-monospace, monospace',
              fontSize: 18, letterSpacing: 0.3, textAlign: 'center',
              color: rgba(theme.rgb, 0.8), marginBottom: 28,
            }}>
              <Typewriter key={step} text={s.prompt} speed={38} jitter={14} />
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', justifyContent: 'center', maxWidth: 280 }}>
              {Array.from({ length: s.max }).map((_, i) => (
                <button key={i} onClick={() => answer(i + 1)} style={{
                  width: 38, height: 38, borderRadius: 19,
                  background: 'transparent',
                  border: `1px solid ${rgba(theme.rgb, 0.22)}`,
                  fontFamily: '"Courier Prime", ui-monospace, monospace',
                  fontSize: 13, color: rgba(theme.rgb, 0.7),
                  cursor: 'pointer',
                }}>{i + 1}</button>
              ))}
            </div>
          </>
        )}

        {s.type === 'select' && (
          <>
            <div style={{
              fontFamily: '"Courier Prime", ui-monospace, monospace',
              fontSize: 18, letterSpacing: 0.3, textAlign: 'center',
              color: rgba(theme.rgb, 0.8), marginBottom: 28,
            }}>
              <Typewriter key={step} text={s.prompt} speed={38} jitter={14} />
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10, width: '100%', maxWidth: 260 }}>
              {s.options.map(opt => (
                <button key={opt} onClick={() => answer(opt)} style={{
                  padding: '12px 16px',
                  background: rgba(theme.rgb, 0.04),
                  border: `1px solid ${rgba(theme.rgb, 0.2)}`,
                  borderRadius: 4,
                  fontFamily: '"Courier Prime", ui-monospace, monospace',
                  fontSize: 13, letterSpacing: 0.5,
                  textTransform: 'lowercase', textAlign: 'left',
                  color: rgba(theme.rgb, 0.75),
                  cursor: 'pointer',
                }}>{opt}</button>
              ))}
            </div>
          </>
        )}
      </div>

      {/* next / done button */}
      <div style={{ padding: '0 32px 60px', display: 'flex', justifyContent: 'center' }}>
        {(s.type === 'intro' || s.type === 'text') && (
          <button
            onClick={() => s.type === 'text' ? answer(textInput) : setStep(i => i + 1)}
            disabled={s.type === 'text' && !textInput.trim()}
            style={{
              padding: '11px 42px',
              background: rgba(theme.rgb, 0.06),
              border: `1px solid ${rgba(theme.rgb, 0.28)}`,
              borderTop: `1.5px solid ${rgba(theme.rgb, 0.5)}`,
              borderRadius: 4,
              fontFamily: '"Courier Prime", ui-monospace, monospace',
              fontSize: 11, letterSpacing: 2.5, textTransform: 'lowercase',
              color: rgba(theme.rgb, 0.85),
              opacity: (s.type === 'text' && !textInput.trim()) ? 0.3 : 1,
              cursor: 'pointer',
            }}>{s.type === 'intro' ? 'begin' : 'next'}</button>
        )}
        {s.type === 'close' && (
          <button onClick={onBack} style={{
            padding: '11px 42px',
            background: rgba(theme.rgb, 0.06),
            border: `1px solid ${rgba(theme.rgb, 0.28)}`,
            borderTop: `1.5px solid ${rgba(theme.rgb, 0.5)}`,
            borderRadius: 4,
            fontFamily: '"Courier Prime", ui-monospace, monospace',
            fontSize: 11, letterSpacing: 2.5, textTransform: 'lowercase',
            color: rgba(theme.rgb, 0.85), cursor: 'pointer',
          }}>return</button>
        )}
      </div>
    </div>
  );
}

// ── RIVER — memory as flow, days as color ───────────────────────────────
function RiverScreen({ phase, daysSober, onBack }) {
  const theme = window.PHASE_THEME[phase];
  const rgba = window.rgba;

  // Generate a plausible river of past events
  const events = [];
  const now = new Date();
  const moodByDay = [7, 8, 4, 6, 7, 3, 5, 8, 9, 6, 7, 4];
  const labels = {
    mood: 'logged the weather inside',
    urge: 'sat with an urge',
    journal: 'named a hard thought',
    breathe: 'breathed 4-7-8',
    ground: 'five things. four things.',
  };
  const types = ['mood', 'urge', 'journal', 'breathe', 'ground'];
  for (let d = 0; d < 12; d++) {
    const mood = moodByDay[d] || 5;
    const dayEvents = [];
    const count = d === 0 ? 3 : (d < 3 ? 2 : 1);
    for (let i = 0; i < count; i++) {
      dayEvents.push({
        type: types[(d * 3 + i) % types.length],
        label: labels[types[(d * 3 + i) % types.length]],
        hour: [22, 14, 8, 19, 3][(d * 3 + i) % 5],
      });
    }
    events.push({ dayOffset: d, mood, events: dayEvents });
  }

  // mood → hue
  const moodColor = (m) => {
    if (m <= 3) return '138,95,224';   // violet — void
    if (m <= 5) return '255,107,53';   // amber
    if (m <= 7) return '0,212,170';    // cyan
    return '0,236,196';                // bright cyan
  };

  const dayName = (off) => {
    if (off === 0) return 'today';
    if (off === 1) return 'yesterday';
    const d = new Date(now); d.setDate(d.getDate() - off);
    return d.toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase();
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, background: '#050508',
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <Atmosphere phase={phase} />

      {/* header */}
      <div style={{
        position: 'absolute', top: 58, left: 0, right: 0,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        padding: '0 22px', zIndex: 10,
      }}>
        <button onClick={onBack} style={{
          background: 'transparent', border: 'none',
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 10, letterSpacing: 2, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.4), cursor: 'pointer', padding: 4,
        }}>↓ room</button>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 9, letterSpacing: 3, textTransform: 'uppercase',
          color: rgba(theme.rgb, 0.3),
        }}>◈ river</div>
      </div>

      {/* narration */}
      <div style={{
        marginTop: 100, padding: '0 28px', textAlign: 'left',
      }}>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 11, letterSpacing: 2, textTransform: 'lowercase',
          color: rgba(theme.rgb, 0.35), marginBottom: 6,
        }}>continuous</div>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 15, lineHeight: '24px', letterSpacing: 0.3,
          color: rgba(theme.rgb, 0.75), fontStyle: 'italic',
        }}>three days ago you sat with a hard thought.<br/>you named it. that was brave.</div>
      </div>

      {/* flow */}
      <div style={{
        flex: 1, overflow: 'auto', marginTop: 22,
        padding: '0 28px 60px', position: 'relative',
      }}>
        {/* river line (left edge) */}
        <div style={{
          position: 'absolute', left: 34, top: 0, bottom: 40, width: 1,
          background: `linear-gradient(180deg, transparent 0%, ${rgba(theme.rgb, 0.25)} 8%, ${rgba(theme.rgb, 0.12)} 100%)`,
        }} />

        {events.map((day, di) => {
          const mc = moodColor(day.mood);
          return (
            <div key={di} style={{ position: 'relative', paddingLeft: 24, marginBottom: 28 }}>
              {/* day dot */}
              <div style={{
                position: 'absolute', left: 1, top: 8,
                width: 13, height: 13, borderRadius: '50%',
                background: rgba(mc, 0.35),
                boxShadow: `0 0 10px ${rgba(mc, 0.5)}, inset 0 0 0 1px ${rgba(mc, 0.7)}`,
              }} />
              {/* day label */}
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 6 }}>
                <div style={{
                  fontFamily: '"Courier Prime", ui-monospace, monospace',
                  fontSize: 12, letterSpacing: 1, textTransform: 'lowercase',
                  color: rgba(mc, 0.85),
                }}>{dayName(day.dayOffset)}</div>
                <div style={{
                  fontFamily: '"Courier Prime", ui-monospace, monospace',
                  fontSize: 9, letterSpacing: 2, textTransform: 'lowercase',
                  color: rgba(theme.rgb, 0.3),
                }}>mood · {day.mood}/10</div>
              </div>
              {/* events */}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                {day.events.map((ev, ei) => (
                  <div key={ei} style={{
                    display: 'flex', alignItems: 'baseline', gap: 10,
                  }}>
                    <div style={{
                      fontFamily: '"Courier Prime", ui-monospace, monospace',
                      fontSize: 10, letterSpacing: 1,
                      color: rgba(theme.rgb, 0.35), minWidth: 32,
                    }}>{String(ev.hour).padStart(2, '0')}:00</div>
                    <div style={{
                      fontFamily: '"Courier Prime", ui-monospace, monospace',
                      fontSize: 13, letterSpacing: 0.3, textTransform: 'lowercase',
                      color: rgba(theme.rgb, 0.7),
                    }}>{ev.label}</div>
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── COVER — 2am lung ────────────────────────────────────────────────────
function CoverScreen({ onReturn }) {
  const rgba = window.rgba;
  const coverRgb = '0,236,228'; // cyan monochrome, per spec
  const [phraseIdx, setPhraseIdx] = React.useState(0);
  const holdStart = React.useRef(null);
  const holdTimer = React.useRef(null);
  const [holding, setHolding] = React.useState(false);
  const [progress, setProgress] = React.useState(0);

  const phrases = [
    "you're not alone.",
    "breathe. just the next one.",
    "this will pass.",
    "i see you.",
    "2am always ends.",
  ];

  const handleTap = (e) => {
    // only cycle if wasn't a hold
    if (holdStart.current && Date.now() - holdStart.current < 500) {
      setPhraseIdx(i => (i + 1) % phrases.length);
    }
  };

  const handleDown = () => {
    holdStart.current = Date.now();
    setHolding(true);
    let p = 0;
    holdTimer.current = setInterval(() => {
      p += 33;
      setProgress(Math.min(p / 3000, 1));
      if (p >= 3000) {
        clearInterval(holdTimer.current);
        holdTimer.current = null;
        setHolding(false);
        setProgress(0);
        onReturn && onReturn();
      }
    }, 33);
  };
  const handleUp = () => {
    const dur = holdStart.current ? Date.now() - holdStart.current : 0;
    if (holdTimer.current) {
      clearInterval(holdTimer.current);
      holdTimer.current = null;
    }
    setHolding(false);
    setProgress(0);
    if (dur < 400) {
      setPhraseIdx(i => (i + 1) % phrases.length);
    }
    holdStart.current = null;
  };

  return (
    <div
      onMouseDown={handleDown} onMouseUp={handleUp} onMouseLeave={handleUp}
      onTouchStart={handleDown} onTouchEnd={handleUp}
      style={{
        position: 'absolute', inset: 0, background: '#000',
        display: 'flex', flexDirection: 'column', alignItems: 'center',
        justifyContent: 'center', overflow: 'hidden', cursor: 'pointer',
        userSelect: 'none',
      }}>
      {/* rain particles */}
      {Array.from({ length: 24 }).map((_, i) => (
        <div key={i} style={{
          position: 'absolute',
          left: `${(i * 37) % 100}%`,
          top: `${(i * 53) % 100}%`,
          width: 1, height: 14,
          background: `linear-gradient(180deg, transparent, ${rgba(coverRgb, 0.4)}, transparent)`,
          animation: `rainDrop ${3 + (i % 4)}s linear infinite`,
          animationDelay: `${(i * 0.2) % 3}s`,
        }} />
      ))}

      {/* butterfly (inverse pulse to orb) */}
      <div style={{ position: 'absolute', width: 160, height: 160, display: 'flex', alignItems: 'center', justifyContent: 'center', animation: 'butterflyInv 4s ease-in-out infinite' }}>
        <ButterflyDNA size={120} phase="night" inverse />
      </div>

      {/* emergency orb */}
      <div style={{ animation: 'emergencyPulse 4s ease-in-out infinite' }}>
        <SphereOrb size={180} phase="night" bpm={45} />
      </div>

      {/* phrase */}
      <div style={{
        marginTop: 48, padding: '0 40px',
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: 17, letterSpacing: 0.3, textAlign: 'center',
        color: rgba(coverRgb, 0.75),
        textShadow: `0 0 14px ${rgba(coverRgb, 0.4)}`,
      }}>{phrases[phraseIdx]}</div>

      {/* tap hint */}
      <div style={{
        position: 'absolute', bottom: 60,
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
      }}>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 9, letterSpacing: 2, textTransform: 'lowercase',
          color: rgba(coverRgb, 0.3),
        }}>tap · next breath</div>
        <div style={{
          fontFamily: '"Courier Prime", ui-monospace, monospace',
          fontSize: 9, letterSpacing: 2, textTransform: 'lowercase',
          color: rgba(coverRgb, 0.3),
        }}>hold 3s · return</div>
        {/* hold progress */}
        <div style={{ width: 80, height: 1, background: rgba(coverRgb, 0.15), marginTop: 4 }}>
          <div style={{
            width: `${progress * 100}%`, height: '100%',
            background: rgba(coverRgb, 0.7),
            transition: 'width 33ms linear',
          }} />
        </div>
      </div>
    </div>
  );
}

// ── PHYSICIAN MODE — the raw data layer ─────────────────────────────────
// Not part of the garden. Not discoverable. Two-finger spiral on device,
// hold `p` on web. Caduceus emerges, mercury flows, the numbers appear.
// Designed to feel like peeling back the poetry.
function PhysicianMode({ phase, daysSober, bpm, transmutationScars, onDismiss }) {
  const theme = window.PHASE_THEME[phase];
  const rgba = window.rgba;
  // Mock but plausible telemetry (all on-device, never transmitted)
  const restlessness = React.useMemo(() => 0.23 + Math.random() * 0.3, []);
  const topTriggers = [
    { label: 'late · solitary',    count: 11, wave: [3,4,2,5,7,6,8,9] },
    { label: 'resentment · work',  count:  7, wave: [2,3,5,4,3,6,5,4] },
    { label: 'boredom · sunday',   count:  4, wave: [1,2,2,3,2,3,4,3] },
  ];
  const weekly = {
    moodAvg: 6.3,
    worksheets: 9,
    urgesSat: 4,
    urgesHeld: 6,
    transmutations: transmutationScars,
    surfacedAt: ['03:12', '02:48', '14:04', '22:10'],
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 100,
      background: 'rgba(5,5,8,0.92)',
      backdropFilter: 'blur(8px)',
      WebkitBackdropFilter: 'blur(8px)',
      display: 'flex', flexDirection: 'column',
      padding: '58px 22px 40px',
      overflow: 'auto', animation: 'softFade 500ms ease-out',
    }}>
      {/* Caduceus — spine with two helix strands */}
      <div style={{ position: 'absolute', right: 22, top: 100, width: 36, height: 220, opacity: 0.55, pointerEvents: 'none' }}>
        <svg width="36" height="220" viewBox="0 0 36 220">
          <line x1="18" y1="10" x2="18" y2="210" stroke={theme.accent} strokeWidth="0.8" opacity="0.5" />
          {Array.from({ length: 28 }).map((_, i) => {
            const t = i / 27;
            const y = 12 + t * 196;
            const off = Math.sin(t * Math.PI * 4) * 10;
            const op = 0.35 + Math.abs(Math.sin(t * Math.PI * 4)) * 0.4;
            return <circle key={i} cx={18 + off} cy={y} r="1.4" fill={theme.accent} opacity={op} />;
          })}
          {Array.from({ length: 28 }).map((_, i) => {
            const t = i / 27;
            const y = 12 + t * 196;
            const off = -Math.sin(t * Math.PI * 4) * 10;
            const op = 0.35 + Math.abs(Math.sin(t * Math.PI * 4)) * 0.4;
            return <circle key={'b'+i} cx={18 + off} cy={y} r="1.4" fill={theme.accent} opacity={op} />;
          })}
          {/* wings at top */}
          <path d="M 18 14 Q 6 6, 2 14 Q 10 12, 18 20 Q 26 12, 34 14 Q 30 6, 18 14 Z"
            fill="none" stroke={theme.accent} strokeWidth="0.8" opacity="0.6" />
        </svg>
      </div>

      {/* header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
        <div style={{
          fontSize: 10, letterSpacing: 3, textTransform: 'uppercase',
          color: rgba(theme.rgb, 0.9),
        }}>◈ physician mode</div>
        <button onClick={onDismiss} style={{
          background: 'transparent', border: 'none', cursor: 'pointer',
          fontFamily: 'inherit', fontSize: 10, letterSpacing: 2,
          color: rgba(theme.rgb, 0.4),
        }}>close</button>
      </div>
      <div style={{
        fontSize: 9, letterSpacing: 2, textTransform: 'lowercase',
        color: rgba(theme.rgb, 0.35), marginBottom: 24,
        fontStyle: 'italic',
      }}>the garden, in numbers. on-device only.</div>

      {/* hero stat */}
      <div style={{ marginBottom: 22 }}>
        <div style={{ fontSize: 9, letterSpacing: 2.5, color: rgba(theme.rgb, 0.45) }}>continuous · sober</div>
        <div style={{ fontSize: 52, lineHeight: '56px', color: rgba(theme.rgb, 0.95), letterSpacing: -1 }}>
          {daysSober}<span style={{ fontSize: 18, letterSpacing: 2, color: rgba(theme.rgb, 0.4), marginLeft: 8 }}>days</span>
        </div>
      </div>

      {/* vitals strip */}
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
        gap: 1, background: rgba(theme.rgb, 0.15), padding: 1,
        marginBottom: 22,
      }}>
        {[
          { label: 'bpm',         val: bpm,   unit: '' },
          { label: 'restless',    val: restlessness.toFixed(2), unit: 'rms' },
          { label: 'phase',       val: theme.ouro, unit: '' },
        ].map(v => (
          <div key={v.label} style={{ background: '#050508', padding: '10px 8px' }}>
            <div style={{ fontSize: 8, letterSpacing: 2, color: rgba(theme.rgb, 0.4), textTransform: 'uppercase' }}>{v.label}</div>
            <div style={{ fontSize: 16, color: rgba(theme.rgb, 0.9), marginTop: 2 }}>{v.val}<span style={{ fontSize: 9, marginLeft: 3, color: rgba(theme.rgb, 0.5) }}>{v.unit}</span></div>
          </div>
        ))}
      </div>

      {/* triggers */}
      <div style={{ fontSize: 9, letterSpacing: 2.5, color: rgba(theme.rgb, 0.45), marginBottom: 10 }}>top triggers · 30d</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 22 }}>
        {topTriggers.map((tr, i) => (
          <div key={i} style={{
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '8px 10px',
            borderLeft: `1px solid ${rgba(theme.rgb, 0.4)}`,
            background: rgba(theme.rgb, 0.03),
          }}>
            <div style={{ flex: 1, fontSize: 12, color: rgba(theme.rgb, 0.8), letterSpacing: 0.5 }}>{tr.label}</div>
            {/* sparkline */}
            <svg width="60" height="16" viewBox="0 0 60 16">
              <polyline
                points={tr.wave.map((v, j) => `${j * 8},${16 - v * 1.6}`).join(' ')}
                fill="none" stroke={theme.accent} strokeWidth="1" opacity="0.7" />
            </svg>
            <div style={{ fontSize: 13, color: rgba(theme.rgb, 0.95), minWidth: 20, textAlign: 'right' }}>{tr.count}</div>
          </div>
        ))}
      </div>

      {/* weekly */}
      <div style={{ fontSize: 9, letterSpacing: 2.5, color: rgba(theme.rgb, 0.45), marginBottom: 10 }}>weekly summary</div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1, background: rgba(theme.rgb, 0.15), padding: 1, marginBottom: 22 }}>
        {[
          ['mood avg', `${weekly.moodAvg} / 10`],
          ['worksheets', weekly.worksheets],
          ['urges · sat with', weekly.urgesSat],
          ['urges · held', weekly.urgesHeld],
          ['transmutations', weekly.transmutations],
          ['surfaced at', weekly.surfacedAt.slice(0,2).join(' · ')],
        ].map(([k, v]) => (
          <div key={k} style={{ background: '#050508', padding: '10px 8px' }}>
            <div style={{ fontSize: 8, letterSpacing: 2, color: rgba(theme.rgb, 0.4), textTransform: 'uppercase' }}>{k}</div>
            <div style={{ fontSize: 13, color: rgba(theme.rgb, 0.85), marginTop: 2 }}>{v}</div>
          </div>
        ))}
      </div>

      <div style={{
        fontSize: 9, letterSpacing: 2, color: rgba(theme.rgb, 0.3),
        textTransform: 'lowercase', fontStyle: 'italic', textAlign: 'center',
        marginTop: 'auto', paddingTop: 20,
      }}>nothing here leaves the device. hold anywhere to dismiss.</div>
    </div>
  );
}

Object.assign(window, { BridgeScreen, RoomScreen, ConversationScreen, RiverScreen, CoverScreen, PhysicianMode });
