File size: 7,164 Bytes
4ae4ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""Render the live thought card as HTML."""

from __future__ import annotations

from card_engine import ActiveCard, CardState


def render_card(active: ActiveCard) -> str:
    """Render the thought card HTML based on current state."""
    if active.state == CardState.IDLE:
        return ""

    card = active.card
    sections = []

    # Situation + Thought (always visible once triggered)
    if active.state.value != "idle":
        thought_text = card.automatic_thought or "..."
        sections.append(f"""
        <div style="margin-bottom:12px;">
            <div style="font-size:0.7rem; font-weight:700; color:#5a6a7a; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">AUTOMATIC THOUGHT</div>
            <div style="font-size:0.9rem; color:#e8edf3; line-height:1.4;">"{thought_text}"</div>
        </div>
        """)

    # Distortion tags
    if card.distortions:
        tags = "".join(
            f'<span style="display:inline-block; background:rgba(139,92,246,0.2); border:1px solid rgba(139,92,246,0.4); border-radius:20px; padding:4px 12px; font-size:0.75rem; color:#a78bfa; font-weight:500; margin-right:6px; margin-bottom:4px;">{d}</span>'
            for d in card.distortions
        )
        sections.append(f"""
        <div style="margin-bottom:12px; display:flex; flex-wrap:wrap; gap:6px;">
            {tags}
        </div>
        """)

    # Evidence FOR
    if card.evidence_for:
        items = "".join(f'<li style="font-size:0.85rem; color:#e8edf3; padding:4px 0 4px 12px; border-left:2px solid rgba(255,255,255,0.08); margin-bottom:4px;">{e}</li>' for e in card.evidence_for)
        sections.append(f"""
        <div style="margin-bottom:12px;">
            <div style="font-size:0.7rem; font-weight:700; color:#5a6a7a; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">EVIDENCE FOR</div>
            <ul style="list-style:none; padding:0; margin:0;">{items}</ul>
        </div>
        """)

    # Evidence AGAINST
    if card.evidence_against:
        items = "".join(f'<li style="font-size:0.85rem; color:#e8edf3; padding:4px 0 4px 12px; border-left:2px solid rgba(255,255,255,0.08); margin-bottom:4px;">{e}</li>' for e in card.evidence_against)
        sections.append(f"""
        <div style="margin-bottom:12px;">
            <div style="font-size:0.7rem; font-weight:700; color:#5a6a7a; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">EVIDENCE AGAINST</div>
            <ul style="list-style:none; padding:0; margin:0;">{items}</ul>
        </div>
        """)

    # Balanced thought (reframe)
    if card.balanced_thought:
        sections.append(f"""
        <div style="margin-bottom:12px;">
            <div style="font-size:0.7rem; font-weight:700; color:#5a6a7a; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">πŸ”„ BALANCED THOUGHT</div>
            <div style="font-size:0.9rem; color:#22c55e; line-height:1.4; font-style:italic;">"{card.balanced_thought}"</div>
        </div>
        """)

    # Complete state
    border_style = "border-color:rgba(34,197,94,0.5); box-shadow:0 0 20px rgba(34,197,94,0.15);" if active.state == CardState.COMPLETE else ""

    return f"""
    <div style="background:#1e2a3a; border:1px solid rgba(255,255,255,0.08); border-radius:12px; padding:16px; {border_style}">
        <div style="font-size:0.85rem; color:#8899aa; margin-bottom:12px; font-weight:600; letter-spacing:0.5px;">πŸ“‹ Live Thought Card</div>
        {''.join(sections)}
    </div>
    """


def render_empty_card() -> str:
    """Render a minimal waiting state after user starts chatting."""
    return """
    <div style="display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:120px; text-align:center; padding:24px 16px;">
        <div style="font-size:0.82rem; color:#8899aa; line-height:1.5; max-width:260px;">
            Listening... a thought card will appear here once a thinking pattern is detected.
        </div>
    </div>
    """


def render_intro_card() -> str:
    """Render the benefit-focused 'how it helps you' explanation for the How it works tab."""
    return """
    <div style="padding:14px;">
        <div style="font-size:0.95rem; font-weight:700; color:#e8edf3; margin-bottom:10px;">A calmer way to untangle your thoughts</div>

        <div style="font-size:0.8rem; color:#8899aa; line-height:1.6; margin-bottom:14px;">
            When you're caught in a worry or a harsh thought, it's hard to see it clearly from the inside.
            REFRAME is a gentle, judgment-free space to talk it through β€” and watch an unhelpful thought
            become a fairer, kinder one.
        </div>

        <div style="font-size:0.75rem; color:#8899aa; line-height:1.5; margin-bottom:10px;">
            <strong style="color:#e8edf3;">How it helps you:</strong>
        </div>

        <div style="margin-bottom:8px; padding-left:8px; border-left:2px solid rgba(139,92,246,0.3);">
            <div style="font-size:0.73rem; color:#a78bfa; font-weight:600;">See the thinking trap</div>
            <div style="font-size:0.7rem; color:#8899aa;">It gently names patterns like catastrophizing or all-or-nothing thinking β€” the ones that are hard to spot in your own head.</div>
        </div>

        <div style="margin-bottom:8px; padding-left:8px; border-left:2px solid rgba(139,92,246,0.3);">
            <div style="font-size:0.73rem; color:#a78bfa; font-weight:600;">Questions, not lectures</div>
            <div style="font-size:0.7rem; color:#8899aa;">Rather than telling you what to think, it asks β€” what supports this thought, and what doesn't? You stay in control.</div>
        </div>

        <div style="margin-bottom:8px; padding-left:8px; border-left:2px solid rgba(139,92,246,0.3);">
            <div style="font-size:0.73rem; color:#a78bfa; font-weight:600;">Reframes you actually believe</div>
            <div style="font-size:0.7rem; color:#8899aa;">The balanced thought is yours, in your own words β€” which is exactly why it sticks with you.</div>
        </div>

        <div style="margin-bottom:8px; padding-left:8px; border-left:2px solid rgba(34,197,94,0.3);">
            <div style="font-size:0.73rem; color:#22c55e; font-weight:600;">See yourself grow</div>
            <div style="font-size:0.7rem; color:#8899aa;">Saved cards and your pattern tracker reveal what keeps coming up β€” and noticing is where change begins.</div>
        </div>

        <div style="margin-top:12px; padding:8px; background:rgba(139,92,246,0.05); border-radius:8px; font-size:0.7rem; color:#8899aa; line-height:1.5;">
            πŸ’¬ Just talk β€” by voice or text. No jargon, no pressure. It's grounded in
            <strong style="color:#a78bfa;">Cognitive Behavioral Therapy (CBT)</strong>, the most
            evidence-based approach for reshaping unhelpful thinking.
        </div>

        <div style="margin-top:10px; font-size:0.66rem; color:#5a6a7a; line-height:1.5;">
            A supportive companion β€” not a replacement for professional care. If you're ever in crisis,
            it will surface helplines right away.
        </div>
    </div>
    """