Viney Claude Sonnet 4.6 commited on
Commit
a3d2db9
Β·
1 Parent(s): c25cfbb

docs: implementation plan for AI interpretation visual differentiation

Browse files

6-task plan: theme tokens, ai_badge/interpretation_card helpers,
tension_card and quality_signal_chip updates, verdict.py and mda.py rendering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

docs/superpowers/plans/2026-05-07-interpretation-visual.md ADDED
@@ -0,0 +1,589 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Interpretation Visual Differentiation β€” Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Visually distinguish AI-interpreted fields from sourced facts across the Primer dashboard using a purple left-border + tinted background + "✦ AI" badge system.
6
+
7
+ **Architecture:** Pure frontend change. Add 4 color tokens to `theme.py`, add two HTML-helper functions to `components.py`, update the rendering of 2 fields in `verdict.py`, 1 field in `mda.py`, and modify 2 existing component functions (`tension_card`, `quality_signal_chip`). No schema or agent changes.
8
+
9
+ **Tech Stack:** Streamlit, Python f-strings for HTML, pytest for unit tests on string-returning helpers.
10
+
11
+ ---
12
+
13
+ ## File Map
14
+
15
+ | File | Change |
16
+ |------|--------|
17
+ | `dashboard/theme.py` | Add `AI_BG`, `AI_BORDER`, `AI_COLOR`, `AI_BADGE_BG` tokens |
18
+ | `dashboard/components.py` | Add `ai_badge()`, `interpretation_card()`; modify `tension_card()`, `quality_signal_chip()` |
19
+ | `dashboard/verdict.py` | Use `interpretation_card()` for `what_matters_most` and `non_obvious_takeaway` |
20
+ | `dashboard/mda.py` | Use `interpretation_card()` for `language_shift` |
21
+ | `tests/test_dashboard_components.py` | New file β€” unit tests for the new and modified helpers |
22
+
23
+ ---
24
+
25
+ ### Task 1: Add AI color tokens to `theme.py`
26
+
27
+ **Files:**
28
+ - Modify: `dashboard/theme.py`
29
+
30
+ - [ ] **Step 1: Add the 4 new tokens after the existing `PURPLE` line**
31
+
32
+ In `dashboard/theme.py`, find the line `PURPLE = "#8b5cf6"` (currently line 42) and add the four tokens immediately after it:
33
+
34
+ ```python
35
+ PURPLE = "#8b5cf6"
36
+ AI_BG = "#faf5ff"
37
+ AI_BORDER = "#ddd6fe"
38
+ AI_COLOR = "#7c3aed"
39
+ AI_BADGE_BG = "#ede9fe"
40
+ ```
41
+
42
+ - [ ] **Step 2: Verify the file is syntactically valid**
43
+
44
+ ```bash
45
+ python -c "from dashboard.theme import AI_BG, AI_BORDER, AI_COLOR, AI_BADGE_BG; print(AI_BG)"
46
+ ```
47
+
48
+ Expected output: `#faf5ff`
49
+
50
+ - [ ] **Step 3: Commit**
51
+
52
+ ```bash
53
+ git add dashboard/theme.py
54
+ git commit -m "feat: add AI interpretation color tokens to theme"
55
+ ```
56
+
57
+ ---
58
+
59
+ ### Task 2: Add `ai_badge()` and `interpretation_card()` helpers + write tests
60
+
61
+ **Files:**
62
+ - Modify: `dashboard/components.py`
63
+ - Create: `tests/test_dashboard_components.py`
64
+
65
+ - [ ] **Step 1: Write failing tests first**
66
+
67
+ Create `tests/test_dashboard_components.py`:
68
+
69
+ ```python
70
+ """Unit tests for dashboard/components.py HTML helpers."""
71
+ from __future__ import annotations
72
+ import pytest
73
+ from unittest.mock import patch, MagicMock
74
+
75
+
76
+ def test_ai_badge_default_label():
77
+ from dashboard.components import ai_badge
78
+ html = ai_badge()
79
+ assert "✦ AI Synthesis" in html
80
+ assert "#7c3aed" in html
81
+ assert "#ede9fe" in html
82
+
83
+
84
+ def test_ai_badge_custom_label():
85
+ from dashboard.components import ai_badge
86
+ html = ai_badge("AI")
87
+ assert "✦ AI" in html
88
+ assert "#7c3aed" in html
89
+
90
+
91
+ def test_interpretation_card_contains_badge_and_content():
92
+ from dashboard.components import interpretation_card
93
+ html = interpretation_card("What matters most", "<p>Some insight</p>")
94
+ assert "✦ AI Synthesis" in html
95
+ assert "#8b5cf6" in html # purple border
96
+ assert "#faf5ff" in html # purple tint background
97
+ assert "What matters most" in html
98
+ assert "<p>Some insight</p>" in html
99
+
100
+
101
+ def test_interpretation_card_custom_badge_label():
102
+ from dashboard.components import interpretation_card
103
+ html = interpretation_card("Language shift", "<p>tone changed</p>", badge_label="AI")
104
+ assert "✦ AI" in html
105
+ assert "Language shift" in html
106
+ ```
107
+
108
+ - [ ] **Step 2: Run tests to confirm they fail**
109
+
110
+ ```bash
111
+ python -m pytest tests/test_dashboard_components.py -v
112
+ ```
113
+
114
+ Expected: `ImportError` or `AttributeError` β€” `ai_badge` not yet defined.
115
+
116
+ - [ ] **Step 3: Add the imports and helpers to `dashboard/components.py`**
117
+
118
+ At the top of `dashboard/components.py`, extend the theme import to include the new tokens:
119
+
120
+ ```python
121
+ from dashboard.theme import (
122
+ GREEN, RED, AMBER, GRAY, BORDER, TEXT_FAINT,
123
+ BG, BG_MUTED, TEXT, TEXT_MUTED,
124
+ WARN_BG, WARN_BORDER,
125
+ BULL_BG, BULL_BORDER, BEAR_BG, BEAR_BORDER,
126
+ PURPLE, AI_BG, AI_BORDER, AI_COLOR, AI_BADGE_BG,
127
+ )
128
+ ```
129
+
130
+ Then add both helpers immediately after the existing `reliability_badge` function (after line 19):
131
+
132
+ ```python
133
+ # ── AI interpretation badge ───────────────────────────────────────────────────
134
+
135
+ def ai_badge(label: str = "AI Synthesis") -> str:
136
+ return (
137
+ f'<span style="background:{AI_BADGE_BG};color:{AI_COLOR};'
138
+ f'border:1px solid {AI_BORDER};border-radius:4px;'
139
+ f'padding:1px 7px;font-size:0.62rem;font-weight:600;">✦ {label}</span>'
140
+ )
141
+
142
+
143
+ # ── AI interpretation card wrapper ────────────────────────────────────────────
144
+
145
+ def interpretation_card(
146
+ header_label: str,
147
+ content_html: str,
148
+ badge_label: str = "AI Synthesis",
149
+ ) -> str:
150
+ return (
151
+ f'<div class="primer-card" style="background:{AI_BG};border:1px solid {BORDER};'
152
+ f'border-left:4px solid {PURPLE};border-radius:0 12px 12px 0;'
153
+ f'padding:20px 24px;margin-bottom:4px;">'
154
+ f'<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">'
155
+ f'<span style="font-size:0.62rem;font-weight:700;letter-spacing:0.1em;'
156
+ f'text-transform:uppercase;color:{TEXT_MUTED};">{header_label}</span>'
157
+ f'{ai_badge(badge_label)}'
158
+ f'</div>'
159
+ f'{content_html}'
160
+ f'</div>'
161
+ )
162
+ ```
163
+
164
+ - [ ] **Step 4: Run tests β€” expect pass**
165
+
166
+ ```bash
167
+ python -m pytest tests/test_dashboard_components.py::test_ai_badge_default_label tests/test_dashboard_components.py::test_ai_badge_custom_label tests/test_dashboard_components.py::test_interpretation_card_contains_badge_and_content tests/test_dashboard_components.py::test_interpretation_card_custom_badge_label -v
168
+ ```
169
+
170
+ Expected: 4 PASSED
171
+
172
+ - [ ] **Step 5: Commit**
173
+
174
+ ```bash
175
+ git add dashboard/components.py tests/test_dashboard_components.py
176
+ git commit -m "feat: add ai_badge and interpretation_card helpers"
177
+ ```
178
+
179
+ ---
180
+
181
+ ### Task 3: Update `tension_card()` β€” add AI badge to reading labels
182
+
183
+ **Files:**
184
+ - Modify: `dashboard/components.py` (the `tension_card` function, lines ~116–172)
185
+
186
+ The tension card panels keep their green/red backgrounds (they provide bull/bear orientation). We only add a micro "✦ AI" badge next to the "Surface reading" and "Deeper reading" labels.
187
+
188
+ - [ ] **Step 1: Write the failing test**
189
+
190
+ Add to `tests/test_dashboard_components.py`:
191
+
192
+ ```python
193
+ def test_tension_card_reading_panels_have_ai_badge():
194
+ """tension_card must add ✦ AI badge next to both reading labels."""
195
+ import streamlit as st
196
+ from unittest.mock import patch, call
197
+ from dashboard.components import tension_card
198
+
199
+ tension = {
200
+ "headline": "Revenue beat hides quality decline",
201
+ "weight": "material",
202
+ "bullish_reading": "Strong top-line momentum",
203
+ "bearish_reading": "One-time item inflated result",
204
+ "bullish_evidence": {"evidence_snippet": "q1", "reliability": "HIGH", "source": "10-Q"},
205
+ "bearish_evidence": {"evidence_snippet": "q2", "reliability": "HIGH", "source": "10-Q"},
206
+ }
207
+
208
+ with patch.object(st, "markdown") as mock_md:
209
+ tension_card(tension)
210
+ rendered = mock_md.call_args[0][0]
211
+
212
+ assert "✦ AI" in rendered
213
+ assert rendered.count("✦ AI") >= 2 # once per reading panel
214
+ ```
215
+
216
+ - [ ] **Step 2: Run test to confirm it fails**
217
+
218
+ ```bash
219
+ python -m pytest tests/test_dashboard_components.py::test_tension_card_reading_panels_have_ai_badge -v
220
+ ```
221
+
222
+ Expected: FAILED β€” "✦ AI" not in rendered HTML.
223
+
224
+ - [ ] **Step 3: Modify `tension_card()` in `dashboard/components.py`**
225
+
226
+ Find the `bull_side` variable inside `tension_card()`. Replace the single-div label line:
227
+
228
+ ```python
229
+ # BEFORE β€” find this inside tension_card():
230
+ f'<div style="font-size:0.58rem;font-weight:700;text-transform:uppercase;'
231
+ f'letter-spacing:0.09em;color:#059669;margin-bottom:6px;">Surface reading</div>'
232
+ ```
233
+
234
+ Replace with:
235
+
236
+ ```python
237
+ # AFTER
238
+ f'<div style="display:flex;align-items:center;gap:5px;margin-bottom:6px;">'
239
+ f'<span style="font-size:0.58rem;font-weight:700;text-transform:uppercase;'
240
+ f'letter-spacing:0.09em;color:#059669;">Surface reading</span>'
241
+ f'{ai_badge("AI")}'
242
+ f'</div>'
243
+ ```
244
+
245
+ Then find the `bear_side` label inside `tension_card()`. Replace:
246
+
247
+ ```python
248
+ # BEFORE β€” find this inside tension_card():
249
+ f'<div style="font-size:0.58rem;font-weight:700;text-transform:uppercase;'
250
+ f'letter-spacing:0.09em;color:#dc2626;margin-bottom:6px;">Deeper reading</div>'
251
+ ```
252
+
253
+ Replace with:
254
+
255
+ ```python
256
+ # AFTER
257
+ f'<div style="display:flex;align-items:center;gap:5px;margin-bottom:6px;">'
258
+ f'<span style="font-size:0.58rem;font-weight:700;text-transform:uppercase;'
259
+ f'letter-spacing:0.09em;color:#dc2626;">Deeper reading</span>'
260
+ f'{ai_badge("AI")}'
261
+ f'</div>'
262
+ ```
263
+
264
+ - [ ] **Step 4: Run test β€” expect pass**
265
+
266
+ ```bash
267
+ python -m pytest tests/test_dashboard_components.py::test_tension_card_reading_panels_have_ai_badge -v
268
+ ```
269
+
270
+ Expected: PASSED
271
+
272
+ - [ ] **Step 5: Commit**
273
+
274
+ ```bash
275
+ git add dashboard/components.py tests/test_dashboard_components.py
276
+ git commit -m "feat: mark tension card readings as AI interpretation"
277
+ ```
278
+
279
+ ---
280
+
281
+ ### Task 4: Update `quality_signal_chip()` β€” add AI label in expanded body
282
+
283
+ **Files:**
284
+ - Modify: `dashboard/components.py` (the `quality_signal_chip` function, lines ~191–234)
285
+
286
+ The chip keeps its existing assessment color (positive/neutral/concerning). We add a small "✦ AI assessment" label above the rationale text in the expanded body only.
287
+
288
+ - [ ] **Step 1: Write the failing test**
289
+
290
+ Add to `tests/test_dashboard_components.py`:
291
+
292
+ ```python
293
+ def test_quality_signal_chip_body_has_ai_label():
294
+ """quality_signal_chip must include an AI label before the rationale text in the body."""
295
+ from dashboard.components import quality_signal_chip
296
+
297
+ signal = {
298
+ "dimension": "guidance_dynamics",
299
+ "assessment": "positive",
300
+ "rationale": "Management raised full-year guidance for the third consecutive quarter.",
301
+ "evidence": {"evidence_snippet": "raised guidance", "source": "10-Q", "reliability": "HIGH"},
302
+ }
303
+
304
+ html = quality_signal_chip(signal)
305
+ assert "✦ AI" in html
306
+ assert "Management raised full-year guidance" in html
307
+ # AI label must appear before the rationale text
308
+ assert html.index("✦ AI") < html.index("Management raised full-year guidance")
309
+ ```
310
+
311
+ - [ ] **Step 2: Run test to confirm it fails**
312
+
313
+ ```bash
314
+ python -m pytest tests/test_dashboard_components.py::test_quality_signal_chip_body_has_ai_label -v
315
+ ```
316
+
317
+ Expected: FAILED
318
+
319
+ - [ ] **Step 3: Modify `quality_signal_chip()` in `dashboard/components.py`**
320
+
321
+ Inside `quality_signal_chip()`, find the body div that contains the rationale:
322
+
323
+ ```python
324
+ # BEFORE β€” find this in quality_signal_chip():
325
+ f'<div style="font-size:0.78rem;color:{TEXT};line-height:1.5;">{rationale}</div>'
326
+ ```
327
+
328
+ Replace with:
329
+
330
+ ```python
331
+ # AFTER
332
+ f'<div style="font-size:0.55rem;font-weight:600;text-transform:uppercase;'
333
+ f'letter-spacing:0.07em;color:{AI_COLOR};margin-bottom:3px;">✦ AI assessment</div>'
334
+ f'<div style="font-size:0.78rem;color:{TEXT};line-height:1.5;">{rationale}</div>'
335
+ ```
336
+
337
+ - [ ] **Step 4: Run test β€” expect pass**
338
+
339
+ ```bash
340
+ python -m pytest tests/test_dashboard_components.py::test_quality_signal_chip_body_has_ai_label -v
341
+ ```
342
+
343
+ Expected: PASSED
344
+
345
+ - [ ] **Step 5: Run the full test suite**
346
+
347
+ ```bash
348
+ python -m pytest tests/test_dashboard_components.py -v
349
+ ```
350
+
351
+ Expected: All 6 tests PASSED
352
+
353
+ - [ ] **Step 6: Commit**
354
+
355
+ ```bash
356
+ git add dashboard/components.py tests/test_dashboard_components.py
357
+ git commit -m "feat: mark earnings quality signal rationale as AI interpretation"
358
+ ```
359
+
360
+ ---
361
+
362
+ ### Task 5: Update `verdict.py` β€” `what_matters_most` and `non_obvious_takeaway`
363
+
364
+ **Files:**
365
+ - Modify: `dashboard/verdict.py`
366
+
367
+ - [ ] **Step 1: Add `interpretation_card` to the import from `dashboard.components`**
368
+
369
+ Find this line near the top of `dashboard/verdict.py`:
370
+
371
+ ```python
372
+ from dashboard.components import reliability_badge, source_badge, section_header, evidence_quote, fact_card, tension_card, quality_signal_chip
373
+ ```
374
+
375
+ Replace with:
376
+
377
+ ```python
378
+ from dashboard.components import reliability_badge, source_badge, section_header, evidence_quote, fact_card, tension_card, quality_signal_chip, interpretation_card
379
+ ```
380
+
381
+ - [ ] **Step 2: Replace the `what_matters_most` rendering block**
382
+
383
+ Find and replace this block (around line 333):
384
+
385
+ ```python
386
+ # BEFORE
387
+ wmm = brief.get("what_matters_most", "")
388
+ if wmm:
389
+ with st.expander("πŸ’‘ What matters most", expanded=True):
390
+ st.markdown(
391
+ f"""
392
+ <div class="primer-card" style="background:{BG_MUTED};border:1px solid {BORDER};
393
+ border-radius:12px;padding:20px 24px;margin-bottom:4px;">
394
+ <div style="font-size:0.62rem;font-weight:700;letter-spacing:0.1em;
395
+ text-transform:uppercase;color:{TEXT_MUTED};margin-bottom:8px;">
396
+ AI synthesis Β· the only interpretive field
397
+ </div>
398
+ <div style="font-size:1rem;line-height:1.7;color:{TEXT};">{wmm}</div>
399
+ </div>
400
+ """,
401
+ unsafe_allow_html=True,
402
+ )
403
+ ```
404
+
405
+ Replace with:
406
+
407
+ ```python
408
+ # AFTER
409
+ wmm = brief.get("what_matters_most", "")
410
+ if wmm:
411
+ with st.expander("πŸ’‘ What matters most", expanded=True):
412
+ st.markdown(
413
+ interpretation_card(
414
+ "What matters most",
415
+ f'<div style="font-size:1rem;line-height:1.7;color:{TEXT};">{wmm}</div>',
416
+ ),
417
+ unsafe_allow_html=True,
418
+ )
419
+ ```
420
+
421
+ - [ ] **Step 3: Replace the `non_obvious_takeaway` rendering block**
422
+
423
+ Inside `_render_analytical_edge()`, find and replace (around line 246):
424
+
425
+ ```python
426
+ # BEFORE
427
+ if takeaway:
428
+ st.markdown(
429
+ f'<div class="primer-card" style="background:{BG_MUTED};border:1px solid {BORDER};'
430
+ f'border-left:4px solid {GREEN};border-radius:0 10px 10px 0;'
431
+ f'padding:16px 20px;margin-bottom:16px;">'
432
+ f'<div style="font-size:0.58rem;font-weight:700;text-transform:uppercase;'
433
+ f'letter-spacing:0.1em;color:{TEXT_MUTED};margin-bottom:6px;">Non-obvious takeaway</div>'
434
+ f'<div style="font-size:0.95rem;font-style:italic;line-height:1.65;color:{TEXT};">'
435
+ f'{takeaway}'
436
+ f'</div>'
437
+ f'</div>',
438
+ unsafe_allow_html=True,
439
+ )
440
+ ```
441
+
442
+ Replace with:
443
+
444
+ ```python
445
+ # AFTER
446
+ if takeaway:
447
+ st.markdown(
448
+ interpretation_card(
449
+ "Non-obvious takeaway",
450
+ f'<div style="font-size:0.95rem;font-style:italic;line-height:1.65;color:{TEXT};">'
451
+ f'{takeaway}</div>',
452
+ ),
453
+ unsafe_allow_html=True,
454
+ )
455
+ ```
456
+
457
+ - [ ] **Step 4: Verify no Python errors**
458
+
459
+ ```bash
460
+ python -c "import dashboard.verdict"
461
+ ```
462
+
463
+ Expected: no output (clean import).
464
+
465
+ - [ ] **Step 5: Commit**
466
+
467
+ ```bash
468
+ git add dashboard/verdict.py
469
+ git commit -m "feat: apply AI interpretation styling to what_matters_most and non_obvious_takeaway"
470
+ ```
471
+
472
+ ---
473
+
474
+ ### Task 6: Update `mda.py` β€” `language_shift`
475
+
476
+ **Files:**
477
+ - Modify: `dashboard/mda.py`
478
+
479
+ - [ ] **Step 1: Add `interpretation_card` to the import in `mda.py`**
480
+
481
+ Find this line near the top of `dashboard/mda.py`:
482
+
483
+ ```python
484
+ from dashboard.components import reliability_badge, source_badge, section_header, evidence_quote, fact_card
485
+ ```
486
+
487
+ Replace with:
488
+
489
+ ```python
490
+ from dashboard.components import reliability_badge, source_badge, section_header, evidence_quote, fact_card, interpretation_card
491
+ ```
492
+
493
+ - [ ] **Step 2: Remove `INFO`, `INFO_BG`, `INFO_BORDER` from the theme import if unused elsewhere**
494
+
495
+ Check the theme import at the top of `dashboard/mda.py`:
496
+
497
+ ```python
498
+ from dashboard.theme import (
499
+ GREEN, AMBER, RED,
500
+ BG, BG_MUTED, BORDER, TEXT, TEXT_MUTED, TEXT_FAINT,
501
+ INFO, INFO_BG, INFO_BORDER,
502
+ )
503
+ ```
504
+
505
+ After updating `language_shift`, `INFO_BG` and `INFO_BORDER` will no longer be used in this file. Remove them:
506
+
507
+ ```python
508
+ from dashboard.theme import (
509
+ GREEN, AMBER, RED,
510
+ BG, BG_MUTED, BORDER, TEXT, TEXT_MUTED, TEXT_FAINT,
511
+ )
512
+ ```
513
+
514
+ (The `INFO` token is also unused β€” remove it too.)
515
+
516
+ - [ ] **Step 3: Replace the `language_shift` rendering block**
517
+
518
+ Find and replace (around line 52):
519
+
520
+ ```python
521
+ # BEFORE
522
+ if lang:
523
+ with st.expander("πŸ”€ Language Shift vs Prior Periods", expanded=True):
524
+ st.markdown(
525
+ f"""
526
+ <div class="primer-card" style="background:{INFO_BG};border:1px solid {INFO_BORDER};
527
+ border-radius:10px;padding:16px 18px;margin-bottom:16px;">
528
+ <div style="font-size:0.9rem;line-height:1.6;color:{TEXT};">{lang}</div>
529
+ </div>
530
+ """,
531
+ unsafe_allow_html=True,
532
+ )
533
+ ```
534
+
535
+ Replace with:
536
+
537
+ ```python
538
+ # AFTER
539
+ if lang:
540
+ with st.expander("πŸ”€ Language Shift vs Prior Periods", expanded=True):
541
+ st.markdown(
542
+ interpretation_card(
543
+ "Language shift",
544
+ f'<div style="font-size:0.9rem;line-height:1.6;color:{TEXT};">{lang}</div>',
545
+ ),
546
+ unsafe_allow_html=True,
547
+ )
548
+ ```
549
+
550
+ - [ ] **Step 4: Verify no Python errors**
551
+
552
+ ```bash
553
+ python -c "import dashboard.mda"
554
+ ```
555
+
556
+ Expected: no output (clean import).
557
+
558
+ - [ ] **Step 5: Run the full test suite**
559
+
560
+ ```bash
561
+ python -m pytest tests/ -v --tb=short
562
+ ```
563
+
564
+ Expected: all tests pass (no regressions).
565
+
566
+ - [ ] **Step 6: Commit**
567
+
568
+ ```bash
569
+ git add dashboard/mda.py
570
+ git commit -m "feat: apply AI interpretation styling to language_shift in MD&A"
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Post-Implementation Check
576
+
577
+ After all 6 tasks are committed, do a visual check by running the app:
578
+
579
+ ```bash
580
+ streamlit run app.py
581
+ ```
582
+
583
+ Generate a brief for any ticker in your test data and verify:
584
+ 1. `what_matters_most` β€” purple left border + "✦ AI Synthesis" badge, not the old gray card
585
+ 2. `non_obvious_takeaway` (Analytical Edge section) β€” same purple treatment, no green border
586
+ 3. Tension cards β€” green/red backgrounds preserved, "✦ AI" badge appears next to both "Surface reading" and "Deeper reading" labels
587
+ 4. Earnings quality chips (expanded) β€” "✦ AI assessment" label appears above the rationale text
588
+ 5. MD&A Language Shift β€” purple treatment instead of blue
589
+ 6. All SourcedFact cards (what_changed, bull_points, bear_points) β€” unchanged