/* Client screens. Legal theory, Evidence, Timeline, Readiness, Court prep.
   Each screen accepts (jx, matter, variant, onNav, onOpenHandoff) and exposes
   2-3 layout variants via the `variant` prop. */

/* ============================================================
   LEGAL THEORY. A.3 deep dive on the chosen cause + alternatives
   Variants: 'cards' | 'columns' | 'narrative'
   ============================================================ */

const ClientLegalTheoryScreen = ({ jx, variant = 'cards', onConsult }) => {
  const matter = MATTERS[ACTIVE_MATTER_ID]; // Chen, NY
  const isUtah = jx === 'utah';
  const [selected, setSelected] = React.useState([matter.cause]);
  const [expanded, setExpanded] = React.useState(matter.cause);
  const j = JURISDICTIONS[jx];

  const causes = CAUSES_OF_ACTION;
  const primary = causes.find(c => c.id === matter.cause) || causes[0];
  const alts = causes.filter(c => c.id !== matter.cause);

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <JurisdictionRibbon jx={jx} onChange={() => {}}/>
      <PageHeader
        eyebrow={<>A.3 · Legal theory <JurisdictionPill jx={jx}/></>}
        title="Which legal theory fits your situation?"
        subtitle={isUtah
          ? 'Utah sandbox · options are ranked by system-suggested match. You still decide.'
          : 'Cases often have more than one. We show you the menu. You pick.'}
        right={<>
          <Segmented dense options={[
            { value: 'cards', label: 'Cards' },
            { value: 'columns', label: 'Compare' },
            { value: 'narrative', label: 'Walkthrough' },
          ]} value={variant} onChange={() => {}}/>
        </>}
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 32px' }}>
        {variant === 'cards' && (
          <CauseOfActionPicker jx={jx} selected={selected}
            onToggle={(id) => setSelected(s => s.includes(id) ? s.filter(x => x !== id) : [...s, id])}
            onConsult={onConsult}/>
        )}

        {variant === 'columns' && (
          <ColumnsCompare causes={causes} jx={jx} selected={selected} onSelect={setSelected} onConsult={onConsult}/>
        )}

        {variant === 'narrative' && (
          <NarrativeWalkthrough cause={primary} alts={alts} jx={jx} onConsult={onConsult}/>
        )}
      </div>
    </div>
  );
};

/* Compare-mode column layout */
const ColumnsCompare = ({ causes, jx, selected, onSelect, onConsult }) => {
  const isUtah = jx === 'utah';
  return (
    <div>
      <div style={{ fontSize: 12.5, color: THEME.textDim, marginBottom: 14, lineHeight: 1.5 }}>
        Side-by-side comparison. Tap a column to select that theory as your primary.
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
        {causes.map(c => {
          const a = selected.includes(c.id);
          return (
            <div key={c.id} onClick={() => onSelect([c.id])} style={{
              padding: '14px 14px', borderRadius: 12, cursor: 'pointer',
              background: a ? THEME.blueSoft : (THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)'),
              border: `1.5px solid ${a ? THEME.blue : THEME.line}`,
              display: 'flex', flexDirection: 'column', gap: 10, minHeight: 320,
            }}>
              <div>
                <div style={{ fontFamily: 'Fraunces', fontSize: 15, color: THEME.text, fontWeight: 600, lineHeight: 1.2, marginBottom: 6 }}>{c.label}</div>
                {isUtah && (
                  <div style={{ fontSize: 10, fontWeight: 700, padding: '1px 6px', borderRadius: 4, display: 'inline-block',
                    background: c.confidence > 0.7 ? 'rgba(91,167,115,0.18)' : c.confidence > 0.4 ? 'rgba(217,144,54,0.16)' : 'rgba(255,255,255,0.06)',
                    color: c.confidence > 0.7 ? THEME.success : c.confidence > 0.4 ? THEME.warn : THEME.textMute,
                    letterSpacing: 0.4 }}>
                    {Math.round(c.confidence * 100)}% MATCH
                  </div>
                )}
              </div>
              <div style={{ fontSize: 11.5, color: THEME.textDim, lineHeight: 1.5 }}>{c.plain}</div>
              <div style={{ flex: 1 }}/>
              <div>
                <div style={{ fontSize: 9.5, color: THEME.textMute, letterSpacing: 0.6, textTransform: 'uppercase', fontWeight: 600, marginBottom: 6 }}>Elements ({c.elements.filter(e => e.complete).length}/{c.elements.length})</div>
                {c.elements.map((e, i) => (
                  <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, color: e.complete ? THEME.text : THEME.textDim, padding: '2px 0' }}>
                    <div style={{ width: 8, height: 8, borderRadius: 4, background: e.complete ? THEME.success : THEME.line }}/>
                    <span style={{ flex: 1, lineHeight: 1.3 }}>{e.label}</span>
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>
      <div onClick={onConsult} style={{
        marginTop: 16, padding: '14px 18px', borderRadius: 12, cursor: 'pointer',
        background: `linear-gradient(135deg, ${THEME.blueSoft}, transparent)`,
        border: `1px solid ${THEME.blue}40`,
        display: 'flex', alignItems: 'center', gap: 12,
      }}>
        <Icon d={Icons.shield} size={16} stroke={THEME.blue}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 13, color: THEME.text, fontWeight: 600 }}>Want a 30-min consult before you commit?</div>
          <div style={{ fontSize: 11.5, color: THEME.textDim }}>Reviewing attorney reads your facts, recommends a theory. $79 flat.</div>
        </div>
        <Icon d={Icons.arrowRight} size={14} stroke={THEME.textDim}/>
      </div>
    </div>
  );
};

/* Narrative walkthrough. Single cause, deep dive */
const NarrativeWalkthrough = ({ cause, alts, jx, onConsult }) => {
  return (
    <div style={{ maxWidth: 720, display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div>
        <div style={{ fontSize: 11, color: THEME.textMute, letterSpacing: 1.4, textTransform: 'uppercase', fontWeight: 600, marginBottom: 6 }}>Your selected theory</div>
        <div style={{ fontFamily: 'Fraunces', fontSize: 32, color: THEME.text, fontWeight: 500, letterSpacing: -0.5, lineHeight: 1.1, marginBottom: 8 }}>{cause.label}</div>
        <div style={{ fontSize: 14, color: THEME.textDim, lineHeight: 1.6 }}>{cause.plain}</div>
      </div>

      <div style={{ padding: '16px 18px', borderRadius: 12, background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)', border: `1px solid ${THEME.line}`, borderLeft: `3px solid ${THEME.accent}` }}>
        <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', color: THEME.accent, marginBottom: 6 }}>Concrete example from another user</div>
        <div style={{ fontSize: 13, color: THEME.textDim, lineHeight: 1.6 }}>{cause.example}</div>
      </div>

      <div>
        <SectionLabel>What this theory typically requires</SectionLabel>
        {cause.elements.map((e, i) => (
          <div key={i} style={{
            display: 'flex', alignItems: 'flex-start', gap: 12,
            padding: '12px 14px', borderRadius: 10, marginBottom: 6,
            background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
            border: `1px solid ${THEME.line}`,
          }}>
            <div style={{
              width: 24, height: 24, borderRadius: 12, flexShrink: 0,
              background: e.complete ? 'rgba(91,167,115,0.20)' : THEME.mode === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.04)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 11, color: e.complete ? THEME.success : THEME.textMute, fontWeight: 700,
            }}>{e.complete ? <Icon d={Icons.check} size={12} stroke={THEME.success} sw={3}/> : i + 1}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, color: THEME.text, fontWeight: 600, marginBottom: 2 }}>{e.label}</div>
              <div style={{ fontSize: 11.5, color: THEME.textMute }}>
                {e.evidenceCount > 0 ? `${e.evidenceCount} of your evidence items support this` : 'No evidence linked yet. Add some on the Evidence tab.'}
              </div>
            </div>
          </div>
        ))}
        <div style={{ fontSize: 11, color: THEME.textMute, fontStyle: 'italic', marginTop: 8 }}>{cause.citations}</div>
      </div>

      <div>
        <SectionLabel>Backup theories you could plead</SectionLabel>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {alts.map(a => (
            <div key={a.id} style={{
              padding: '10px 14px', borderRadius: 9,
              background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
              border: `1px solid ${THEME.line}`,
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, color: THEME.text, fontWeight: 600 }}>{a.label}</div>
                <div style={{ fontSize: 11, color: THEME.textMute, marginTop: 1 }}>{a.plain.slice(0, 95)}…</div>
              </div>
              <div style={{ fontSize: 11, color: THEME.textDim }}>+ Add as backup</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

/* ============================================================
   EVIDENCE. A.5 binder of items mapped to elements
   Variants: 'binder' (vertical list) | 'matrix' (element × evidence grid) | 'gallery'
   ============================================================ */

const EVIDENCE_ITEMS = [
  { id: 'e1', exh: 'A', kind: 'pdf', title: 'Signed remodel agreement · 03/14/2025', desc: '4-page contract; deposit, scope, completion date.', elements: ['contract', 'breach'], date: 'Mar 14', size: '1.4 MB' },
  { id: 'e2', exh: 'B', kind: 'image', title: 'Kitchen photos · day demo stopped', desc: '7 photos showing partial demolition.', elements: ['breach'], date: 'Apr 2', size: '14 photos' },
  { id: 'e3', exh: 'C', kind: 'pdf', title: 'Bank statement · $4,200 deposit', desc: 'Wire transfer to Northbay LLC.', elements: ['contract', 'performance'], date: 'Mar 14', size: '2 pages' },
  { id: 'e4', exh: 'D', kind: 'text', title: 'Text thread with project manager', desc: '47 messages, Mar 14 – Apr 8. Includes "we\'ll be back tomorrow" promises.', elements: ['breach'], date: 'Apr 8', size: '47 msgs' },
  { id: 'e5', exh: 'E', kind: 'pdf', title: 'Bayside Renovations quote · $11,840', desc: 'Second contractor quote to complete work.', elements: ['damages'], date: 'Apr 11', size: '3 pages' },
  { id: 'e6', exh: 'F', kind: 'pdf', title: 'Bayside invoice · paid 04/22', desc: 'Final invoice from completion contractor.', elements: ['damages'], date: 'Apr 22', size: '2 pages' },
  { id: 'e7', exh: 'G', kind: 'email', title: 'Email demanding return of deposit', desc: 'Sent 4/15. No response.', elements: ['performance'], date: 'Apr 15', size: '1 email' },
  { id: 'e8', exh: 'H', kind: 'image', title: 'Building dept inspection notice', desc: 'Cited unfinished work as code violation.', elements: ['breach'], date: 'Apr 18', size: '1 photo' },
];

const ELEMENT_LABELS = {
  contract: 'Valid contract existed',
  performance: 'You performed your obligations',
  breach: 'Other party breached',
  damages: 'You suffered measurable damages',
};

const KIND_ICONS = { pdf: Icons.doc, image: Icons.eye, text: Icons.send, email: Icons.send };

const ClientEvidenceScreen = ({ jx, variant = 'binder', onUpload }) => {
  const matter = MATTERS[ACTIVE_MATTER_ID];
  const [filter, setFilter] = React.useState('all');
  const [selected, setSelected] = React.useState(null);

  const filtered = filter === 'all' ? EVIDENCE_ITEMS : EVIDENCE_ITEMS.filter(e => e.elements.includes(filter));

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <JurisdictionRibbon jx={jx} onChange={() => {}}/>
      <PageHeader
        eyebrow={<>A.5 · Evidence binder <JurisdictionPill jx={jx}/></>}
        title={<>{EVIDENCE_ITEMS.length} items · numbered as exhibits A–H</>}
        subtitle="System suggested element associations. You affirmed each one. Final say is yours."
        right={<>
          <Btn icon={Icons.upload} kind="ghost" onClick={onUpload}>Upload</Btn>
          <Btn icon={Icons.download} kind="primary">Export binder</Btn>
        </>}
      />

      <div style={{ padding: '12px 32px 8px', borderBottom: `1px solid ${THEME.line}`, display: 'flex', gap: 10, alignItems: 'center' }}>
        <FilterChips
          chips={[
            { value: 'all', label: `All · ${EVIDENCE_ITEMS.length}` },
            { value: 'contract', label: `Element 1 · contract · ${EVIDENCE_ITEMS.filter(e => e.elements.includes('contract')).length}` },
            { value: 'performance', label: `Element 2 · performance · ${EVIDENCE_ITEMS.filter(e => e.elements.includes('performance')).length}` },
            { value: 'breach', label: `Element 3 · breach · ${EVIDENCE_ITEMS.filter(e => e.elements.includes('breach')).length}` },
            { value: 'damages', label: `Element 4 · damages · ${EVIDENCE_ITEMS.filter(e => e.elements.includes('damages')).length}` },
          ]}
          value={filter} onChange={setFilter}
        />
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 32px' }}>
        {variant === 'binder' && <EvidenceBinder items={filtered} selected={selected} setSelected={setSelected}/>}
        {variant === 'matrix' && <EvidenceMatrix items={EVIDENCE_ITEMS}/>}
        {variant === 'gallery' && <EvidenceGallery items={filtered} selected={selected} setSelected={setSelected}/>}
      </div>
    </div>
  );
};

const EvidenceBinder = ({ items, selected, setSelected }) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
    {items.map(e => {
      const a = selected === e.id;
      return (
        <div key={e.id} onClick={() => setSelected(a ? null : e.id)} style={{
          padding: '12px 14px', borderRadius: 11, cursor: 'pointer',
          background: a ? THEME.blueSoft : (THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)'),
          border: `1px solid ${a ? THEME.blue : THEME.line}`,
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <div style={{
            width: 36, height: 44, borderRadius: 5, flexShrink: 0,
            background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.05)',
            border: `1px solid ${THEME.line}`,
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 2,
          }}>
            <Icon d={KIND_ICONS[e.kind] || Icons.doc} size={14} stroke={THEME.textDim}/>
            <span style={{ fontFamily: 'Fraunces', fontSize: 12, color: THEME.text, fontWeight: 600 }}>{e.exh}</span>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, color: THEME.text, fontWeight: 600, marginBottom: 3 }}>{e.title}</div>
            <div style={{ fontSize: 11.5, color: THEME.textDim, lineHeight: 1.4, marginBottom: 5 }}>{e.desc}</div>
            <div style={{ display: 'flex', gap: 5, alignItems: 'center', flexWrap: 'wrap' }}>
              {e.elements.map(el => (
                <span key={el} style={{
                  fontSize: 9.5, fontWeight: 600, padding: '1px 6px', borderRadius: 4, letterSpacing: 0.4,
                  background: 'rgba(91,167,115,0.16)', color: THEME.success,
                  border: `1px solid rgba(91,167,115,0.3)`, textTransform: 'uppercase',
                }}>→ {ELEMENT_LABELS[el]}</span>
              ))}
              <span style={{ fontSize: 10.5, color: THEME.textMute }}>· {e.date} · {e.size}</span>
            </div>
          </div>
          <Icon d={Icons.chevronRight} size={14} stroke={THEME.textMute}/>
        </div>
      );
    })}
  </div>
);

const EvidenceMatrix = ({ items }) => {
  const elements = Object.keys(ELEMENT_LABELS);
  return (
    <div>
      <div style={{ fontSize: 12, color: THEME.textDim, marginBottom: 14, lineHeight: 1.5 }}>
        Each row is an element. Each column is an exhibit. ✓ means you've linked that exhibit to that element.
      </div>
      <div style={{
        background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
        border: `1px solid ${THEME.line}`, borderRadius: 12, overflow: 'hidden',
      }}>
        <div style={{ display: 'grid', gridTemplateColumns: `220px repeat(${items.length}, 1fr)`, padding: '10px 14px', borderBottom: `1px solid ${THEME.line}`, alignItems: 'center', fontSize: 10, color: THEME.textMute, letterSpacing: 0.8, textTransform: 'uppercase', fontWeight: 700 }}>
          <div>Element</div>
          {items.map(it => (
            <div key={it.id} style={{ textAlign: 'center', fontFamily: 'Fraunces', fontSize: 13, color: THEME.text, fontWeight: 600, letterSpacing: 0 }}>{it.exh}</div>
          ))}
        </div>
        {elements.map((el, i) => {
          const matchCount = items.filter(it => it.elements.includes(el)).length;
          return (
            <div key={el} style={{
              display: 'grid', gridTemplateColumns: `220px repeat(${items.length}, 1fr)`,
              padding: '12px 14px', borderTop: i > 0 ? `1px solid ${THEME.lineSoft}` : 'none', alignItems: 'center',
            }}>
              <div>
                <div style={{ fontSize: 12.5, color: THEME.text, fontWeight: 600 }}>{ELEMENT_LABELS[el]}</div>
                <div style={{ fontSize: 10.5, color: matchCount > 0 ? THEME.success : THEME.warn, marginTop: 2, fontWeight: 600 }}>
                  {matchCount > 0 ? `${matchCount} item${matchCount > 1 ? 's' : ''} linked` : 'No evidence yet'}
                </div>
              </div>
              {items.map(it => {
                const linked = it.elements.includes(el);
                return (
                  <div key={it.id} style={{ display: 'flex', justifyContent: 'center' }}>
                    <div style={{
                      width: 26, height: 26, borderRadius: 6,
                      background: linked ? 'rgba(91,167,115,0.20)' : THEME.mode === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)',
                      border: `1px solid ${linked ? 'rgba(91,167,115,0.4)' : THEME.lineSoft}`,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                      {linked && <Icon d={Icons.check} size={13} stroke={THEME.success} sw={3}/>}
                    </div>
                  </div>
                );
              })}
            </div>
          );
        })}
      </div>
    </div>
  );
};

const EvidenceGallery = ({ items, selected, setSelected }) => (
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
    {items.map(e => {
      const a = selected === e.id;
      return (
        <div key={e.id} onClick={() => setSelected(a ? null : e.id)} style={{
          borderRadius: 12, cursor: 'pointer', overflow: 'hidden',
          background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
          border: `1.5px solid ${a ? THEME.blue : THEME.line}`,
        }}>
          <div style={{
            height: 120, background: `linear-gradient(135deg, ${THEME.blueSoft}, transparent)`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            borderBottom: `1px solid ${THEME.line}`, position: 'relative',
          }}>
            <div style={{ position: 'absolute', top: 8, left: 8, fontFamily: 'Fraunces', fontSize: 18, color: THEME.text, fontWeight: 600,
              background: THEME.mode === 'dark' ? 'rgba(0,0,0,0.4)' : 'rgba(255,255,255,0.7)',
              padding: '2px 9px', borderRadius: 6 }}>{e.exh}</div>
            <Icon d={KIND_ICONS[e.kind] || Icons.doc} size={32} stroke={THEME.textDim}/>
          </div>
          <div style={{ padding: '10px 12px' }}>
            <div style={{ fontSize: 12, color: THEME.text, fontWeight: 600, marginBottom: 3, lineHeight: 1.3 }}>{e.title}</div>
            <div style={{ fontSize: 10.5, color: THEME.textMute }}>{e.date} · {e.size}</div>
          </div>
        </div>
      );
    })}
  </div>
);

/* ============================================================
   TIMELINE. A.4 chronological timeline / case story
   Variants: 'vertical' (story flow) | 'horizontal' (gantt-ish) | 'narrative'
   ============================================================ */

const TIMELINE_EVENTS = [
  { date: 'Mar 14, 2025', kind: 'contract', label: 'Signed remodel agreement', desc: 'Contract signed at Northbay\'s office. $4,200 deposit wired same day.', linked: ['A', 'C'], tone: THEME.blue },
  { date: 'Mar 17', kind: 'work', label: 'Northbay began demolition', desc: 'Cabinets, countertops removed. Crew of 3 on-site for 2 days.', linked: ['B'], tone: THEME.blue },
  { date: 'Mar 21', kind: 'work', label: 'Crew stopped showing up', desc: 'No call, no text. Project manager said "supplier delay."', linked: ['D'], tone: THEME.warn },
  { date: 'Apr 2', kind: 'photo', label: 'Documented partial demolition', desc: '7 photos taken showing kitchen left unfinished.', linked: ['B'], tone: THEME.warn },
  { date: 'Apr 8', kind: 'comm', label: 'Last contact from Northbay', desc: 'Project manager: "we\'ll be back tomorrow." Never returned.', linked: ['D'], tone: THEME.warn },
  { date: 'Apr 11', kind: 'mitigate', label: 'Hired Bayside Renovations', desc: 'Got quote to complete work: $11,840. Mitigation evidence.', linked: ['E'], tone: THEME.blue },
  { date: 'Apr 15', kind: 'demand', label: 'Sent demand letter', desc: 'Email demanding return of deposit. No response received.', linked: ['G'], tone: THEME.danger },
  { date: 'Apr 18', kind: 'official', label: 'Building dept cited unfinished work', desc: 'Code violation issued. Strengthens damages claim.', linked: ['H'], tone: THEME.danger },
  { date: 'Apr 22', kind: 'mitigate', label: 'Bayside completed work · paid invoice', desc: 'Final cost: $11,840. Total damages: $4,200 deposit + $4,220 cost differential = $8,420.', linked: ['F'], tone: THEME.success },
  { date: 'Today · Apr 28', kind: 'now', label: 'Drafting Statement of Claim', desc: 'You are here. Filing window opens after demand letter expires.', linked: [], tone: THEME.accent },
  { date: 'Apr 16, 2026', kind: 'future', label: 'Hearing scheduled', desc: 'Kings County Civil Court · 9:30 AM · Part 38.', linked: [], tone: THEME.textMute, future: true },
];

const ClientTimelineScreen = ({ jx, variant = 'vertical' }) => {
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <JurisdictionRibbon jx={jx} onChange={() => {}}/>
      <PageHeader
        eyebrow={<>A.4 · Timeline of events <JurisdictionPill jx={jx}/></>}
        title="Tell the story chronologically. What happened, when."
        subtitle="The story you tell in court starts here. Each event can link to evidence."
        right={<Btn icon={Icons.plus} kind="primary">Add event</Btn>}
      />
      <div style={{ flex: 1, overflowY: 'auto', padding: '24px 32px' }}>
        {variant === 'vertical' && <VerticalTimeline events={TIMELINE_EVENTS}/>}
        {variant === 'horizontal' && <HorizontalTimeline events={TIMELINE_EVENTS}/>}
        {variant === 'narrative' && <NarrativeTimeline events={TIMELINE_EVENTS}/>}
      </div>
    </div>
  );
};

const VerticalTimeline = ({ events }) => (
  <div style={{ position: 'relative', maxWidth: 760 }}>
    <div style={{ position: 'absolute', left: 18, top: 6, bottom: 6, width: 1, background: THEME.line }}/>
    {events.map((e, i) => (
      <div key={i} style={{ display: 'flex', gap: 16, marginBottom: 20, position: 'relative' }}>
        <div style={{
          width: 36, height: 36, borderRadius: 18, flexShrink: 0,
          background: e.kind === 'now' ? `linear-gradient(135deg, ${THEME.blue}, ${THEME.accent})` :
            e.future ? (THEME.mode === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(255,255,255,0.7)') :
            e.tone + '24',
          border: `1.5px solid ${e.kind === 'now' ? THEME.blue : e.tone + '60'}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1,
          boxShadow: e.kind === 'now' ? `0 0 0 4px ${THEME.blueSoft}` : 'none',
        }}>
          <div style={{ width: 8, height: 8, borderRadius: 4, background: e.kind === 'now' ? '#fff' : e.tone }}/>
        </div>
        <div style={{ flex: 1, paddingTop: 4 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 3 }}>
            <span style={{ fontSize: 11, color: THEME.textMute, letterSpacing: 0.6, fontWeight: 600, textTransform: 'uppercase' }}>{e.date}</span>
            {e.kind === 'now' && <Pill tone={THEME.blue} dense>You are here</Pill>}
            {e.future && <Pill tone={THEME.textMute} soft dense>Upcoming</Pill>}
          </div>
          <div style={{ fontFamily: 'Fraunces', fontSize: 17, color: THEME.text, fontWeight: 500, letterSpacing: -0.2, marginBottom: 4 }}>{e.label}</div>
          <div style={{ fontSize: 12.5, color: THEME.textDim, lineHeight: 1.55 }}>{e.desc}</div>
          {e.linked.length > 0 && (
            <div style={{ display: 'flex', gap: 5, marginTop: 8 }}>
              {e.linked.map(ex => (
                <span key={ex} style={{
                  fontSize: 10, fontWeight: 700, padding: '2px 7px', borderRadius: 4,
                  background: 'rgba(91,167,115,0.16)', color: THEME.success,
                  border: `1px solid rgba(91,167,115,0.3)`, letterSpacing: 0.4,
                }}>EXHIBIT {ex}</span>
              ))}
            </div>
          )}
        </div>
      </div>
    ))}
  </div>
);

const HorizontalTimeline = ({ events }) => (
  <div>
    <div style={{ fontSize: 12, color: THEME.textDim, marginBottom: 16, lineHeight: 1.5 }}>
      Compressed view. Useful for spotting gaps in the timeline. Hover any event for details.
    </div>
    <div style={{ position: 'relative', height: 200, padding: '20px 0' }}>
      <div style={{ position: 'absolute', left: 0, right: 0, top: 100, height: 2, background: THEME.line }}/>
      <div style={{ display: 'flex', justifyContent: 'space-between', position: 'relative', height: '100%' }}>
        {events.map((e, i) => (
          <div key={i} style={{ position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', flex: 1 }}>
            <div style={{
              fontSize: 10, color: THEME.textMute, fontWeight: 600,
              position: 'absolute', top: i % 2 === 0 ? 10 : 'auto', bottom: i % 2 === 0 ? 'auto' : 10,
              transform: 'translateY(0)', whiteSpace: 'nowrap',
              padding: '4px 7px', borderRadius: 5,
              background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(255,255,255,0.7)',
              border: `1px solid ${THEME.line}`,
              textAlign: 'center', lineHeight: 1.3,
            }}>
              <div style={{ fontWeight: 700, color: THEME.text, fontSize: 9.5, letterSpacing: 0.3 }}>{e.date.split(',')[0].split(' ').slice(0,2).join(' ')}</div>
              <div style={{ fontSize: 9.5, color: THEME.textDim, marginTop: 1, maxWidth: 90, whiteSpace: 'normal' }}>{e.label}</div>
            </div>
            <div style={{
              position: 'absolute', top: 92, left: '50%', transform: 'translateX(-50%)',
              width: 16, height: 16, borderRadius: 8,
              background: e.kind === 'now' ? THEME.blue : e.tone + '60',
              border: `2px solid ${THEME.bg}`,
              boxShadow: e.kind === 'now' ? `0 0 0 4px ${THEME.blueSoft}` : 'none',
            }}/>
          </div>
        ))}
      </div>
    </div>
  </div>
);

const NarrativeTimeline = ({ events }) => (
  <div style={{ maxWidth: 680 }}>
    <div style={{
      padding: '20px 22px', borderRadius: 14, marginBottom: 18,
      background: `linear-gradient(135deg, ${THEME.blueSoft}, transparent)`,
      border: `1px solid ${THEME.blue}30`,
    }}>
      <div style={{ fontSize: 10.5, color: THEME.textMute, letterSpacing: 1.2, textTransform: 'uppercase', fontWeight: 700, marginBottom: 6 }}>The story you'll tell the judge</div>
      <div style={{ fontFamily: 'Fraunces', fontSize: 19, color: THEME.text, fontWeight: 500, lineHeight: 1.5, letterSpacing: -0.2 }}>
        On <strong>March 14, 2025</strong>, you signed a contract with Northbay Contracting and wired a $4,200 deposit. They demolished part of your kitchen, then disappeared. After repeated attempts to reach them, you hired Bayside Renovations, who completed the work for $11,840. You are seeking $8,420 in damages. Your deposit plus the cost differential.
      </div>
    </div>
    <SectionLabel>Key moments, in order</SectionLabel>
    <VerticalTimeline events={events.slice(0, -1)}/>
  </div>
);

/* ============================================================
   READINESS. A.8 readiness checklist (already exists)
   Variants: 'sectional' (existing) | 'kanban' | 'gauge'
   ============================================================ */

const ClientReadinessScreen = ({ jx, variant = 'sectional', predictiveOptIn, onTogglePredictive, onConsult }) => {
  const total = READINESS_BUCKETS.reduce((s, b) => s + b.items.length, 0);
  const done = READINESS_BUCKETS.reduce((s, b) => s + b.items.filter(i => i.complete).length, 0);
  const pct = Math.round((done / total) * 100);

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <JurisdictionRibbon jx={jx} onChange={() => {}}/>
      <PageHeader
        eyebrow={<>A.8 · Readiness check <JurisdictionPill jx={jx}/></>}
        title={`${pct}% ready · ${done} of ${total} items complete`}
        subtitle="Information-completeness only. Not a prediction of whether you will win."
        right={<Btn icon={Icons.download} kind="primary">Generate packet</Btn>}
      />
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 32px' }}>
        {variant === 'sectional' && (
          <div style={{ maxWidth: 820 }}>
            <ReadinessChecklist jx={jx} predictiveOptIn={predictiveOptIn} onTogglePredictive={onTogglePredictive} onConsult={onConsult}/>
          </div>
        )}
        {variant === 'kanban' && <ReadinessKanban pct={pct}/>}
        {variant === 'gauge' && <ReadinessGauge pct={pct} done={done} total={total} jx={jx} predictiveOptIn={predictiveOptIn} onTogglePredictive={onTogglePredictive}/>}
      </div>
    </div>
  );
};

const ReadinessKanban = ({ pct }) => {
  const cols = [
    { id: 'todo', label: 'To do', tone: THEME.warn, items: READINESS_BUCKETS.flatMap(b => b.items.filter(i => !i.complete && !i.soft).map(i => ({ ...i, bucket: b.label }))) },
    { id: 'soft', label: 'Soft prompts', tone: THEME.accent, items: READINESS_BUCKETS.flatMap(b => b.items.filter(i => i.soft).map(i => ({ ...i, bucket: b.label }))) },
    { id: 'done', label: 'Complete', tone: THEME.success, items: READINESS_BUCKETS.flatMap(b => b.items.filter(i => i.complete).map(i => ({ ...i, bucket: b.label }))) },
  ];
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12 }}>
      {cols.map(col => (
        <div key={col.id} style={{
          padding: 12, borderRadius: 12,
          background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.02)' : 'rgba(255,255,255,0.5)',
          border: `1px solid ${THEME.line}`, minHeight: 400,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12, padding: '0 4px' }}>
            <div style={{ width: 8, height: 8, borderRadius: 4, background: col.tone }}/>
            <div style={{ fontSize: 11, color: THEME.text, letterSpacing: 0.6, fontWeight: 700, textTransform: 'uppercase' }}>{col.label}</div>
            <span style={{ fontSize: 10, color: THEME.textMute, padding: '1px 7px', borderRadius: 8, background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.04)' }}>{col.items.length}</span>
          </div>
          {col.items.map((it, i) => (
            <div key={i} style={{
              padding: '10px 12px', marginBottom: 6, borderRadius: 9,
              background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.03)' : '#fff',
              border: `1px solid ${THEME.line}`, borderLeft: `2px solid ${col.tone}`,
            }}>
              <div style={{ fontSize: 9.5, color: THEME.textMute, letterSpacing: 0.7, textTransform: 'uppercase', fontWeight: 700, marginBottom: 4 }}>{it.bucket}</div>
              <div style={{ fontSize: 12, color: THEME.text, fontWeight: 500, lineHeight: 1.4, marginBottom: it.note ? 4 : 0 }}>{it.label}</div>
              {it.note && <div style={{ fontSize: 11, color: THEME.textDim, lineHeight: 1.4 }}>{it.note}</div>}
            </div>
          ))}
        </div>
      ))}
    </div>
  );
};

const ReadinessGauge = ({ pct, done, total, jx, predictiveOptIn, onTogglePredictive }) => {
  const r = 80, c = 2 * Math.PI * r;
  return (
    <div style={{ maxWidth: 720, display: 'flex', flexDirection: 'column', gap: 18 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 24, padding: '24px 26px', borderRadius: 16,
        background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.6)',
        border: `1px solid ${THEME.line}` }}>
        <svg width={200} height={200} viewBox="-100 -100 200 200">
          <circle r={r} fill="none" stroke={THEME.line} strokeWidth={12}/>
          <circle r={r} fill="none" stroke={THEME.success} strokeWidth={12} strokeLinecap="round"
            strokeDasharray={c} strokeDashoffset={c - (c * pct / 100)} transform="rotate(-90)"/>
          <text x={0} y={-2} textAnchor="middle" fontSize={36} fill={THEME.text} fontFamily="Fraunces" fontWeight={500}>{pct}%</text>
          <text x={0} y={22} textAnchor="middle" fontSize={11} fill={THEME.textMute}>{done}/{total} items</text>
        </svg>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: 'Fraunces', fontSize: 22, color: THEME.text, fontWeight: 500, lineHeight: 1.2, marginBottom: 8 }}>You're close.</div>
          <div style={{ fontSize: 13, color: THEME.textDim, lineHeight: 1.55, marginBottom: 14 }}>
            Two open items: damages receipts and service-of-process method. Both are quick. After that, generate the packet.
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <Btn icon={Icons.upload} kind="ghost">Add receipts</Btn>
            <Btn icon={Icons.send} kind="primary">Choose service</Btn>
          </div>
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10 }}>
        {READINESS_BUCKETS.map(b => {
          const cmp = b.items.filter(i => i.complete).length;
          return (
            <Card key={b.id} padding="14px 16px">
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                <div style={{ fontFamily: 'Fraunces', fontSize: 14, color: THEME.text, fontWeight: 600 }}>{b.label}</div>
                <span style={{ fontSize: 11, color: THEME.textMute }}>{cmp}/{b.items.length}</span>
              </div>
              <Progress pct={Math.round((cmp / b.items.length) * 100)}
                tone={cmp === b.items.length ? THEME.success : THEME.blue}/>
            </Card>
          );
        })}
      </div>
    </div>
  );
};

/* ============================================================
   COURT PREP. A.10 day-of-court coaching
   Variants: 'checklist' | 'simulation' | 'cards'
   ============================================================ */

const COURT_PREP_BUCKETS = [
  { label: 'Logistics', items: [
    { t: 'Court address: 141 Livingston St, Brooklyn, NY 11201', sub: 'Kings County Civil Court · Part 38 · Room 502', icon: Icons.flag, done: true },
    { t: 'Arrive at 9:00 AM (30 min before hearing)', sub: 'Security screening line averages 12-18 min in the morning.', icon: Icons.clock, done: true },
    { t: 'Bring photo ID + 3 copies of every exhibit', sub: 'One for you, one for the judge, one for opposing party.', icon: Icons.doc, done: false },
  ]},
  { label: 'What to expect', items: [
    { t: 'You\'ll be called by case name', sub: 'When you hear "Chen v. Northbay," walk to the table marked "Plaintiff." Stay standing until the judge tells you to sit.', icon: Icons.user, done: true },
    { t: 'You speak first. You\'re the plaintiff', sub: 'Brief opening: who you are, what they did, what you\'re asking for. 90 seconds max.', icon: Icons.send, done: true },
    { t: 'Judge will ask questions', sub: 'Common ones: "Did you have a written contract?" "When did you first attempt to contact them?" Answer directly. Don\'t volunteer.', icon: Icons.alert, done: true },
  ]},
  { label: 'Things you don\'t have to know', items: [
    { t: 'Legal terms ("hearsay," "objection")', sub: 'Small claims is informal. You won\'t need to make legal objections.', icon: Icons.shield, done: true, soft: true },
    { t: 'Whether to call witnesses', sub: 'You don\'t need any. Your exhibits speak for themselves.', icon: Icons.shield, done: true, soft: true },
    { t: 'How to dress', sub: 'Business casual. No t-shirts, no shorts. You\'ll be fine.', icon: Icons.shield, done: true, soft: true },
  ]},
];

const ClientCourtPrepScreen = ({ jx, variant = 'checklist' }) => {
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <JurisdictionRibbon jx={jx} onChange={() => {}}/>
      <PageHeader
        eyebrow={<>A.10 · Court prep <JurisdictionPill jx={jx}/></>}
        title="Hearing in 18 days · Wednesday, April 16 · 9:30 AM"
        subtitle="A walkthrough of what happens in a small claims hearing. Written by attorneys who've been there."
        right={<Btn icon={Icons.book} kind="primary">Run mock hearing</Btn>}
      />
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 32px' }}>
        {variant === 'checklist' && <CourtPrepChecklist/>}
        {variant === 'simulation' && <CourtPrepSimulation/>}
        {variant === 'cards' && <CourtPrepCards/>}
      </div>
    </div>
  );
};

const CourtPrepChecklist = () => (
  <div style={{ maxWidth: 760, display: 'flex', flexDirection: 'column', gap: 16 }}>
    {COURT_PREP_BUCKETS.map(b => (
      <div key={b.label}>
        <SectionLabel>{b.label}</SectionLabel>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {b.items.map((it, i) => (
            <div key={i} style={{
              padding: '12px 14px', borderRadius: 10,
              background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
              border: `1px solid ${THEME.line}`,
              display: 'flex', alignItems: 'flex-start', gap: 12,
            }}>
              <div style={{
                width: 28, height: 28, borderRadius: 14, flexShrink: 0,
                background: it.done ? 'rgba(91,167,115,0.18)' : THEME.mode === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {it.done ? <Icon d={Icons.check} size={13} stroke={THEME.success} sw={3}/> : <Icon d={it.icon} size={13} stroke={THEME.textMute}/>}
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13.5, color: THEME.text, fontWeight: 600, marginBottom: 3 }}>{it.t}</div>
                <div style={{ fontSize: 12, color: THEME.textDim, lineHeight: 1.5 }}>{it.sub}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    ))}
  </div>
);

const CourtPrepCards = () => (
  <div style={{ maxWidth: 920 }}>
    {COURT_PREP_BUCKETS.map(b => (
      <div key={b.label} style={{ marginBottom: 18 }}>
        <SectionLabel>{b.label}</SectionLabel>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
          {b.items.map((it, i) => (
            <div key={i} style={{
              padding: '14px 16px', borderRadius: 12,
              background: THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.55)',
              border: `1px solid ${THEME.line}`,
            }}>
              <div style={{
                width: 30, height: 30, borderRadius: 8, marginBottom: 10,
                background: it.soft ? 'rgba(217,144,54,0.16)' : THEME.blueSoft,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon d={it.icon} size={14} stroke={it.soft ? THEME.warn : THEME.blue}/>
              </div>
              <div style={{ fontSize: 13, color: THEME.text, fontWeight: 600, marginBottom: 4, lineHeight: 1.35 }}>{it.t}</div>
              <div style={{ fontSize: 11.5, color: THEME.textDim, lineHeight: 1.55 }}>{it.sub}</div>
            </div>
          ))}
        </div>
      </div>
    ))}
  </div>
);

const CourtPrepSimulation = () => {
  const [step, setStep] = React.useState(0);
  const exchanges = [
    { who: 'Court Officer', text: '"Chen v. Northbay Contracting." Plaintiff, please approach.', tip: 'Walk to the plaintiff\'s table. Stand. Wait for the judge.' },
    { who: 'Judge', text: '"Mr. Chen, you may begin."', tip: 'Open with a brief summary. 60-90 seconds. Who you are, what they did, what you want.' },
    { who: 'You', text: '"Your Honor, my name is Marcus Chen. On March 14, 2025, I hired Northbay Contracting to remodel my kitchen for $4,200 deposit. They demolished part of the kitchen, then stopped work entirely on March 21. I am asking for return of my deposit plus $4,220 in additional costs to complete the work. Total: $8,420."', tip: 'Stay factual. No "ripped me off" language. Judges respond to facts and dollars, not adjectives.' },
    { who: 'Judge', text: '"Did you have a written contract?"', tip: 'Yes. Reach for Exhibit A. Hand a copy to the court officer if asked.' },
    { who: 'You', text: '"Yes, Your Honor. The signed agreement is Exhibit A."', tip: 'Don\'t volunteer extra info. Wait for the next question.' },
  ];

  return (
    <div style={{ maxWidth: 720 }}>
      <div style={{ marginBottom: 18, padding: '14px 18px', borderRadius: 12,
        background: `linear-gradient(135deg, ${THEME.blueSoft}, transparent)`,
        border: `1px solid ${THEME.blue}30` }}>
        <div style={{ fontSize: 11, color: THEME.textMute, letterSpacing: 1.2, textTransform: 'uppercase', fontWeight: 700, marginBottom: 4 }}>Mock hearing · scripted exchange</div>
        <div style={{ fontSize: 13, color: THEME.text, lineHeight: 1.55 }}>
          Step through a typical small claims opening. The tip below each line is what to think about, not say.
        </div>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 14 }}>
        {exchanges.slice(0, step + 1).map((ex, i) => (
          <div key={i} style={{
            padding: '14px 16px', borderRadius: 11,
            background: ex.who === 'You' ? THEME.blueSoft :
              ex.who === 'Judge' ? THEME.mode === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(255,255,255,0.7)' :
              THEME.mode === 'dark' ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.5)',
            border: `1px solid ${ex.who === 'You' ? THEME.blue + '40' : THEME.line}`,
            borderLeft: `3px solid ${ex.who === 'You' ? THEME.blue : ex.who === 'Judge' ? THEME.accent : THEME.textMute}`,
          }}>
            <div style={{ fontSize: 10, color: THEME.textMute, letterSpacing: 1, textTransform: 'uppercase', fontWeight: 700, marginBottom: 4 }}>{ex.who}</div>
            <div style={{ fontSize: 14, color: THEME.text, lineHeight: 1.55, marginBottom: 8, fontFamily: 'Fraunces' }}>{ex.text}</div>
            <div style={{ fontSize: 11.5, color: THEME.textDim, lineHeight: 1.5, paddingTop: 8, borderTop: `1px dashed ${THEME.line}` }}>
              <span style={{ color: THEME.accent, fontWeight: 600 }}>Tip. </span>{ex.tip}
            </div>
          </div>
        ))}
      </div>

      <div style={{ display: 'flex', gap: 8 }}>
        {step < exchanges.length - 1 && (
          <Btn icon={Icons.arrowRight} kind="primary" onClick={() => setStep(s => s + 1)}>Next exchange</Btn>
        )}
        {step > 0 && <Btn kind="ghost" onClick={() => setStep(0)}>Restart</Btn>}
        <div style={{ flex: 1 }}/>
        <div style={{ fontSize: 11, color: THEME.textMute, alignSelf: 'center' }}>
          Step {step + 1} of {exchanges.length}
        </div>
      </div>
    </div>
  );
};

window.ClientLegalTheoryScreen = ClientLegalTheoryScreen;
window.ClientEvidenceScreen = ClientEvidenceScreen;
window.ClientTimelineScreen = ClientTimelineScreen;
window.ClientReadinessScreen = ClientReadinessScreen;
window.ClientCourtPrepScreen = ClientCourtPrepScreen;
