"""
Generator: Sector Rotation Dashboard — Concept Deck
Produces: concept-deck.pptx (10 slides)
Theme: Dark trading terminal / AR Controls brand direction
"""

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.util import Inches, Pt
import copy

# ── Colour palette ────────────────────────────────────────────────────────────
BG_DARK    = RGBColor(0x0E, 0x11, 0x17)   # #0E1117  slide background
SURFACE    = RGBColor(0x16, 0x1B, 0x22)   # #161B22  card / accent block
BORDER     = RGBColor(0x30, 0x36, 0x3D)   # #30363D
TEXT_PRI   = RGBColor(0xE6, 0xED, 0xF3)   # #E6EDF3  primary text
TEXT_SEC   = RGBColor(0x8B, 0x94, 0x9E)   # #8B949E  secondary text
GREEN      = RGBColor(0x3F, 0xB9, 0x50)   # #3FB950  positive / success
RED_ACC    = RGBColor(0xE6, 0x00, 0x00)   # #E60000  AR Controls red accent
AMBER      = RGBColor(0xD2, 0x99, 0x22)   # #D29922  alert / rotation
BLUE_ACC   = RGBColor(0x58, 0xA6, 0xFF)   # #58A6FF  accent blue

# ── Slide dimensions: widescreen 16:9 ────────────────────────────────────────
SLIDE_W = Inches(13.33)
SLIDE_H = Inches(7.5)

prs = Presentation()
prs.slide_width  = SLIDE_W
prs.slide_height = SLIDE_H

BLANK_LAYOUT = prs.slide_layouts[6]  # completely blank


def new_slide():
    slide = prs.slides.add_slide(BLANK_LAYOUT)
    # Dark background fill
    bg = slide.background
    fill = bg.fill
    fill.solid()
    fill.fore_color.rgb = BG_DARK
    return slide


def add_rect(slide, left, top, width, height, fill_rgb=None, line_rgb=None, line_pt=None):
    shape = slide.shapes.add_shape(
        1,  # MSO_SHAPE_TYPE.RECTANGLE
        Inches(left), Inches(top), Inches(width), Inches(height)
    )
    if fill_rgb:
        shape.fill.solid()
        shape.fill.fore_color.rgb = fill_rgb
    else:
        shape.fill.background()
    if line_rgb:
        shape.line.color.rgb = line_rgb
        shape.line.width = Pt(line_pt or 1)
    else:
        shape.line.fill.background()
    return shape


def add_text(slide, text, left, top, width, height,
             font_size=16, bold=False, color=None, align=PP_ALIGN.LEFT,
             italic=False, font_name="Calibri"):
    txbox = slide.shapes.add_textbox(
        Inches(left), Inches(top), Inches(width), Inches(height)
    )
    tf = txbox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.alignment = align
    run = p.add_run()
    run.text = text
    run.font.size = Pt(font_size)
    run.font.bold = bold
    run.font.italic = italic
    run.font.color.rgb = color or TEXT_PRI
    run.font.name = font_name
    return txbox


def add_text_multi(slide, lines, left, top, width, height,
                   font_size=14, color=None, bold=False, line_spacing=1.15):
    """Add multiple lines as separate paragraphs in one textbox."""
    txbox = slide.shapes.add_textbox(
        Inches(left), Inches(top), Inches(width), Inches(height)
    )
    tf = txbox.text_frame
    tf.word_wrap = True
    for i, (txt, opts) in enumerate(lines):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.alignment = opts.get("align", PP_ALIGN.LEFT)
        run = p.add_run()
        run.text = txt
        run.font.size = Pt(opts.get("size", font_size))
        run.font.bold = opts.get("bold", bold)
        run.font.color.rgb = opts.get("color", color or TEXT_PRI)
        run.font.name = opts.get("font", "Calibri")
    return txbox


def accent_bar(slide, left=0.3, top=1.0, width=0.04, height=5.5):
    """Thin vertical red accent bar on the left."""
    add_rect(slide, left, top, width, height, fill_rgb=RED_ACC)


def slide_tag(slide, text="SECTOR ROTATION DASHBOARD"):
    """Share-Tech-Mono style tag at top-left."""
    add_text(slide, text, 0.35, 0.18, 8, 0.3,
             font_size=8, color=RED_ACC, bold=False,
             font_name="Courier New")


def footer(slide, text="TradeDingo — Sector Intelligence | Andrew Ramsey | 2026"):
    add_text(slide, text, 0.35, 7.15, 12, 0.28,
             font_size=8, color=TEXT_SEC, align=PP_ALIGN.LEFT,
             font_name="Courier New")


def divider(slide, top=1.1):
    """Thin horizontal red divider line."""
    add_rect(slide, 0.35, top, 12.6, 0.03, fill_rgb=RED_ACC)


# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 1 — Title
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
# Left red accent bar
add_rect(s, 0.35, 0.5, 0.06, 6.5, fill_rgb=RED_ACC)

# Tag
add_text(s, "—— TRADEDINGO // SECTOR INTELLIGENCE", 0.55, 0.5, 10, 0.35,
         font_size=9, color=RED_ACC, font_name="Courier New")

# Main title
add_text(s, "SECTOR ROTATION", 0.55, 1.2, 12, 1.6,
         font_size=72, bold=True, color=TEXT_PRI, font_name="Calibri")
add_text(s, "DASHBOARD", 0.55, 2.6, 12, 1.3,
         font_size=72, bold=True, color=RED_ACC, font_name="Calibri")

# Subtitle
add_text(s, "Catch rotations early. Trade the leaders.\nA sector intelligence layer for TradeDingo.",
         0.55, 4.1, 9, 1.0,
         font_size=18, color=TEXT_SEC, font_name="Calibri")

# Stat box
add_rect(s, 0.55, 5.3, 4.0, 1.5, fill_rgb=SURFACE, line_rgb=RED_ACC, line_pt=1)
add_text(s, "$1,000,000+", 0.75, 5.4, 3.6, 0.7,
         font_size=36, bold=True, color=GREEN, font_name="Calibri")
add_text(s, "made in 2 months with sector rotation strategy", 0.75, 5.95, 3.6, 0.6,
         font_size=10, color=TEXT_SEC, font_name="Calibri")

footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 2 — Problem
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "THE PROBLEM", 0.55, 0.62, 10, 0.55,
         font_size=36, bold=True, color=TEXT_PRI, font_name="Calibri")

problems = [
    ("❌  Watching individual tickers misses the rotation signal",
     {"size": 16, "color": TEXT_PRI, "bold": True}),
    ("     By the time a single stock moves, the sector is already pricing it in.",
     {"size": 13, "color": TEXT_SEC}),
    ("",  {"size": 8, "color": TEXT_SEC}),
    ("❌  TradeDingo's pre-market briefing cron fires on zero tickers",
     {"size": 16, "color": TEXT_PRI, "bold": True}),
    ("     watchlist.md is empty — briefing never sends. Critical infrastructure blocked.",
     {"size": 13, "color": TEXT_SEC}),
    ("",  {"size": 8, "color": TEXT_SEC}),
    ("❌  No sector-level view anywhere in the stack",
     {"size": 16, "color": TEXT_PRI, "bold": True}),
    ("     60+ tickers across 16 sectors exist in Andrew's head, nowhere else.",
     {"size": 13, "color": TEXT_SEC}),
    ("",  {"size": 8, "color": TEXT_SEC}),
    ("❌  Rotation alerts don't exist",
     {"size": 16, "color": TEXT_PRI, "bold": True}),
    ("     No Telegram alert fires when a sector's relative strength rank suddenly improves.",
     {"size": 13, "color": TEXT_SEC}),
]
add_text_multi(s, problems, 0.55, 1.4, 12.3, 5.5, font_size=14)
footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 3 — Solution
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "THE SOLUTION", 0.55, 0.62, 10, 0.55,
         font_size=36, bold=True, color=TEXT_PRI, font_name="Calibri")

add_text(s, "A Sector Rotation Dashboard inside TradeDingo that shows all 16 sector watchlists "
            "on one screen, ranks them by relative strength vs SPY, and fires an early-rotation "
            "alert when a sector's rank suddenly improves — so you're positioned before the crowd.",
         0.55, 1.3, 12.3, 1.1,
         font_size=14, color=TEXT_SEC, font_name="Calibri")

# Four solution pillars
pillars = [
    ("01", "PRE-SEEDED\nWATCHLISTS", "16 sectors, 60+ tickers loaded on day one. Zero manual entry."),
    ("02", "SECTOR\nHEAT MAP", "1D / 5D / 1M performance + RS rank vs SPY for every sector at a glance."),
    ("03", "ROTATION\nALERTS", "Telegram ping when any sector RS rank jumps 5+ positions. Catch it early."),
    ("04", "BRIEFING\nINTEGRATION", "Active tickers feed directly into the 08:30 BST pre-market cron. Fixes the empty-watchlist blocker."),
]

for i, (num, title, desc) in enumerate(pillars):
    left = 0.45 + i * 3.22
    add_rect(s, left, 2.7, 3.0, 4.2, fill_rgb=SURFACE, line_rgb=BORDER, line_pt=1)
    add_text(s, num, left + 0.2, 2.85, 1.0, 0.5,
             font_size=28, bold=True, color=RED_ACC, font_name="Calibri")
    add_text(s, title, left + 0.2, 3.35, 2.6, 0.9,
             font_size=14, bold=True, color=TEXT_PRI, font_name="Calibri")
    add_rect(s, left + 0.2, 4.25, 0.03, 1.5, fill_rgb=RED_ACC)
    add_text(s, desc, left + 0.35, 4.25, 2.45, 2.1,
             font_size=11, color=TEXT_SEC, font_name="Calibri")

footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 4 — The 16 Sectors
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "16 SECTOR WATCHLISTS — PRE-LOADED", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

sectors = [
    ("Memory",         "$MU  $SNDK  $WDC  $STX"),
    ("Semis",          "$NVDA  $AMD  $ARM  $INTC"),
    ("Networking",     "$AVGO  $MRVL  $CRDO"),
    ("Photonics",      "$AAOI  $LITE  $COHR  $NVTS  $GLW"),
    ("Infrastructure", "$DELL  $SMCI"),
    ("Data Centers",   "$IREN  $CIFR  $APLD  $NBIS"),
    ("Software",       "$MSFT  $NOW  $SNOW"),
    ("Defense",        "$PLTR  $KTOS  $AVAV"),
    ("Drones",         "$ONDS  $DPRO  $UMAC"),
    ("Robotics",       "$OUST  $SYM  $TSLA"),
    ("Space",          "$ASTS  $RKLB  $RDW  $LUNR"),
    ("Quantum",        "$IONQ  $QBTS  $RGTI"),
    ("Nuclear",        "$OKLO"),
    ("Fintech",        "$HOOD  $SOFI  $AFRM"),
    ("Copper",         "$FCX  $SCCO  $TECK"),
    ("Autonomous",     "$JOBY  $ACHR"),
]

# Render in 4 columns × 4 rows
col_w = 3.15
for i, (name, tickers) in enumerate(sectors):
    col = i % 4
    row = i // 4
    left = 0.45 + col * col_w
    top  = 1.45 + row * 1.45
    add_rect(s, left, top, 3.0, 1.3, fill_rgb=SURFACE, line_rgb=BORDER, line_pt=0.5)
    add_text(s, name.upper(), left + 0.15, top + 0.1, 2.7, 0.35,
             font_size=11, bold=True, color=TEXT_PRI, font_name="Calibri")
    add_text(s, tickers, left + 0.15, top + 0.45, 2.7, 0.7,
             font_size=9, color=GREEN, font_name="Courier New")

add_text(s, "16 sectors · 60 tickers · zero manual entry required",
         0.55, 7.15, 12, 0.3,
         font_size=9, color=TEXT_SEC, font_name="Courier New")

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 5 — Dashboard Screen Concept
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "DASHBOARD — SECTOR HEAT MAP VIEW", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

# Mock wireframe of the dashboard
add_rect(s, 0.55, 1.35, 12.3, 5.6, fill_rgb=SURFACE, line_rgb=BORDER, line_pt=1)

# Nav bar mockup
add_rect(s, 0.55, 1.35, 12.3, 0.4, fill_rgb=RGBColor(0x0A, 0x0D, 0x13))
add_text(s, "TradeDingo  |  Home   SECTORS ◆   Pre-Market   Alerts   Settings        Data: 08:47 BST",
         0.7, 1.38, 12.0, 0.33,
         font_size=9, color=TEXT_SEC, font_name="Courier New")

# Title row
add_text(s, "SECTOR ROTATION DASHBOARD", 0.7, 1.82, 7, 0.35,
         font_size=12, bold=True, color=TEXT_PRI, font_name="Calibri")
add_text(s, "[Sort: 1D ▼]  [Sort: 5D]  [Sort: RS Score]            [⟳ Refresh]",
         7.5, 1.82, 5.2, 0.35,
         font_size=9, color=BLUE_ACC, font_name="Courier New")

# Hot Rotation strip
add_rect(s, 0.6, 2.22, 12.2, 0.35, fill_rgb=RGBColor(0x21, 0x18, 0x06), line_rgb=AMBER, line_pt=0.5)
add_text(s, "★ TODAY'S FOCUS   🚀 Space  ·  🔬 Semis  ·  ⚡ Quantum                        [Clear]",
         0.75, 2.25, 12.0, 0.28,
         font_size=9, color=AMBER, font_name="Courier New")

# 4 sector cards
card_data = [
    ("🚀  SPACE", "#2  ↑ from #9", "+4.8%", GREEN, "HOT ROTATION"),
    ("🔬  SEMIS", "#3  ↑ from #7", "+3.9%", GREEN, "HOT ROTATION"),
    ("⚡  QUANTUM", "#5  ↑ from #12", "+6.1%", GREEN, "HOT ROTATION"),
    ("🛡  DEFENSE", "#8  → stable", "+0.9%", TEXT_SEC, ""),
]
card_w = 2.95
for i, (name, rank, perf, pcolor, badge) in enumerate(card_data):
    cl = 0.62 + i * card_w
    ct = 2.65
    add_rect(s, cl, ct, 2.8, 2.15,
             fill_rgb=RGBColor(0x10, 0x15, 0x1E),
             line_rgb=AMBER if badge else BORDER,
             line_pt=1.5 if badge else 0.5)
    add_text(s, name, cl + 0.1, ct + 0.08, 2.0, 0.35,
             font_size=11, bold=True, color=TEXT_PRI, font_name="Calibri")
    if badge:
        add_rect(s, cl + 1.8, ct + 0.08, 0.85, 0.28, fill_rgb=RGBColor(0x3D, 0x2A, 0x00))
        add_text(s, "🔥 HOT", cl + 1.82, ct + 0.1, 0.85, 0.25,
                 font_size=7, color=AMBER, font_name="Courier New")
    add_text(s, f"1D  {perf}", cl + 0.1, ct + 0.52, 1.2, 0.3,
             font_size=16, bold=True, color=pcolor, font_name="Calibri")
    add_text(s, rank, cl + 0.1, ct + 0.9, 2.5, 0.3,
             font_size=9, color=TEXT_SEC, font_name="Courier New")
    add_rect(s, cl + 0.1, ct + 1.3, 2.5, 0.08, fill_rgb=BORDER)
    fill_w = 2.0 if badge else 0.8
    add_rect(s, cl + 0.1, ct + 1.3, fill_w, 0.08, fill_rgb=pcolor)
    add_text(s, "[Expand ▼]  [★]", cl + 0.1, ct + 1.78, 2.5, 0.28,
             font_size=8, color=BLUE_ACC, font_name="Courier New")

add_text(s, "Responsive grid — 4 cols desktop, 2 cols tablet, 1 col mobile. Cards sort by active criterion.",
         0.55, 6.85, 12.3, 0.3,
         font_size=9, color=TEXT_SEC, font_name="Calibri", align=PP_ALIGN.CENTER)
footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 6 — Expanded Ticker View
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "DRILL-DOWN — TICKER INTELLIGENCE", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

# Expanded card wireframe
add_rect(s, 0.55, 1.38, 12.3, 5.55, fill_rgb=SURFACE, line_rgb=AMBER, line_pt=1.5)

# Card header
add_text(s, "🚀  SPACE                                                     🔥 HOT ROTATION",
         0.75, 1.5, 12.0, 0.4,
         font_size=13, bold=True, color=TEXT_PRI, font_name="Calibri")
add_text(s, "1D  +4.8%     5D  +11.2%     1M  +22.4%     RS Rank: #2 ↑ from #9 yesterday",
         0.75, 1.9, 12.0, 0.33,
         font_size=10, color=TEXT_SEC, font_name="Courier New")

add_rect(s, 0.55, 2.27, 12.3, 0.03, fill_rgb=BORDER)

# Table header
header_cols = [("TICKER", 0.75), ("LAST", 2.15), ("1D%", 3.3), ("PM GAP%", 4.45),
               ("RVOL", 5.8), ("GAP TYPE", 7.05), ("ACTIVE", 11.4)]
for label, lft in header_cols:
    add_text(s, label, lft, 2.35, 1.5, 0.32,
             font_size=9, bold=True, color=TEXT_SEC, font_name="Courier New")

add_rect(s, 0.55, 2.7, 12.3, 0.03, fill_rgb=BORDER)

# Ticker rows
ticker_rows = [
    ("ASTS",  "$27.40", "+5.2%",  "+5.2%",  "3.4×",  "Gap-and-Go ↑",    True,  GREEN),
    ("RKLB",  "$18.90", "+3.1%",  "+2.9%",  "1.8×",  "Opening Drive",    True,  GREEN),
    ("RDW",   "$7.25",  "+4.4%",  "+4.1%",  "2.1×",  "Gap-and-Go ↑",    True,  GREEN),
    ("LUNR",  "$6.88",  "+2.2%",  "+1.9%",  "1.2×",  "Moderate Gap",     True,  TEXT_SEC),
]
row_cols = [0.75, 2.15, 3.3, 4.45, 5.8, 7.05, 11.4]
for ri, (tk, last, d1, pm, rvol, gap_type, active, pcolor) in enumerate(ticker_rows):
    rt = 2.8 + ri * 0.72
    bg_c = RGBColor(0x10, 0x15, 0x1E) if ri % 2 == 0 else SURFACE
    add_rect(s, 0.55, rt, 12.3, 0.7, fill_rgb=bg_c)
    add_text(s, tk,       row_cols[0], rt + 0.18, 1.3, 0.35, font_size=11, bold=True, color=BLUE_ACC, font_name="Courier New")
    add_text(s, last,     row_cols[1], rt + 0.18, 1.1, 0.35, font_size=10, color=TEXT_PRI, font_name="Courier New")
    add_text(s, d1,       row_cols[2], rt + 0.18, 1.0, 0.35, font_size=10, bold=True, color=pcolor, font_name="Courier New")
    add_text(s, pm,       row_cols[3], rt + 0.18, 1.2, 0.35, font_size=10, color=pcolor, font_name="Courier New")
    rvol_color = AMBER if float(rvol[:-1]) >= 2.0 else GREEN if float(rvol[:-1]) >= 1.5 else TEXT_SEC
    add_text(s, rvol,     row_cols[4], rt + 0.18, 1.0, 0.35, font_size=10, color=rvol_color, font_name="Courier New")
    gap_c = GREEN if "Go ↑" in gap_type or "Drive" in gap_type else TEXT_SEC
    add_text(s, gap_type, row_cols[5], rt + 0.18, 3.8, 0.35, font_size=9, color=gap_c, font_name="Courier New")
    pill_c = BLUE_ACC if active else TEXT_SEC
    pill_t = "● ON" if active else "○ OFF"
    add_text(s, pill_t,   row_cols[6], rt + 0.18, 1.0, 0.35, font_size=9, bold=True, color=pill_c, font_name="Courier New")

# Action row
add_text(s, "[+ Add Ticker]          [📊 History]          [Collapse ▲]",
         7.5, 6.75, 5.2, 0.3,
         font_size=9, color=BLUE_ACC, font_name="Courier New")
footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 7 — User Flow
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "MORNING WORKFLOW — 5 MINUTES", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

steps = [
    ("08:30 BST", "Open TradeDingo Sector Dashboard",
     "Dashboard auto-fetches overnight data for all 16 sectors"),
    ("08:32",     "Scan hot sectors",
     "Cards sorted by 1D RS. Hot Rotation badges on Space, Semis, Quantum"),
    ("08:34",     "Expand top sector → Space",
     "Ticker table shows ASTS +5.2% gap, RVOL 3.4× → Gap-and-Go candidate auto-classified"),
    ("08:36",     "Star sectors for focus",
     "Space + Semis starred → pinned to Today's Focus strip"),
    ("08:38",     "Check Telegram",
     "08:30 BST pre-market briefing already fired — covers all 60 active tickers, S/R levels, RVOL"),
    ("09:30",     "US market opens",
     "Dashboard continues updating every 30 min. Rotation Alert fires via Telegram if rank shifts"),
]

for i, (time_s, title, desc) in enumerate(steps):
    t = 1.45 + i * 0.88
    # Step number circle
    add_rect(s, 0.55, t, 0.5, 0.5, fill_rgb=RED_ACC)
    add_text(s, str(i + 1), 0.55, t + 0.08, 0.5, 0.35,
             font_size=14, bold=True, color=TEXT_PRI, align=PP_ALIGN.CENTER, font_name="Calibri")
    # Time
    add_text(s, time_s, 1.15, t + 0.07, 1.2, 0.35,
             font_size=9, color=AMBER, font_name="Courier New")
    # Title
    add_text(s, title, 2.45, t, 5.0, 0.35,
             font_size=12, bold=True, color=TEXT_PRI, font_name="Calibri")
    # Desc
    add_text(s, desc, 2.45, t + 0.38, 10.3, 0.38,
             font_size=10, color=TEXT_SEC, font_name="Calibri")
    # Connector line (not on last)
    if i < len(steps) - 1:
        add_rect(s, 0.77, t + 0.5, 0.06, 0.37, fill_rgb=BORDER)

footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 8 — Technical Approach
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "TECHNICAL APPROACH", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

# Left column — stack
add_rect(s, 0.55, 1.35, 5.8, 5.6, fill_rgb=SURFACE, line_rgb=BORDER, line_pt=0.5)
add_text(s, "EXISTING STACK (unchanged)", 0.75, 1.48, 5.4, 0.35,
         font_size=10, bold=True, color=TEXT_SEC, font_name="Courier New")
stack_items = [
    ("Flask + Python",    "Backend framework"),
    ("SQLite / SQLAlchemy", "Database (add 3 new tables)"),
    ("Jinja2 templates",  "HTML rendering"),
    ("Chart.js",          "RS rank history charts"),
    ("Telegram Bot API",  "Rotation alerts (already wired)"),
    ("Polygon.io",        "Market data — provider TBC"),
]
for i, (tech, desc) in enumerate(stack_items):
    st = 1.95 + i * 0.72
    add_rect(s, 0.65, st, 5.5, 0.6, fill_rgb=BG_DARK, line_rgb=BORDER, line_pt=0.5)
    add_text(s, tech, 0.85, st + 0.07, 2.5, 0.3, font_size=11, bold=True, color=BLUE_ACC, font_name="Calibri")
    add_text(s, desc, 0.85, st + 0.33, 5.0, 0.25, font_size=9, color=TEXT_SEC, font_name="Calibri")

# Right column — new components
add_rect(s, 6.75, 1.35, 6.1, 5.6, fill_rgb=SURFACE, line_rgb=BORDER, line_pt=0.5)
add_text(s, "NEW COMPONENTS", 6.95, 1.48, 5.7, 0.35,
         font_size=10, bold=True, color=RED_ACC, font_name="Courier New")
new_items = [
    ("Sector + SectorTicker models", "SQLAlchemy — 3 new tables, seeded on first run"),
    ("Rotation Score algorithm",     "avg(ticker_1D) - SPY_1D → RS rank per session"),
    ("sector_data.py service",       "Polygon batch fetch + rank calculation + alert trigger"),
    ("/sectors blueprint",           "5 new Flask routes (dashboard, API, history)"),
    ("sectors.html + JS",            "Expand/collapse cards, live sort, add-ticker modal"),
    ("Seed script",                  "Pre-loads all 16 sectors + 60 tickers on first deploy"),
    ("Briefing engine patch",        "1-line change: read tickers from DB not YAML"),
]
for i, (comp, desc) in enumerate(new_items):
    st = 1.95 + i * 0.68
    add_rect(s, 6.85, st, 5.8, 0.6, fill_rgb=BG_DARK, line_rgb=BORDER, line_pt=0.5)
    add_text(s, comp, 7.0, st + 0.07, 5.3, 0.3, font_size=10, bold=True, color=TEXT_PRI, font_name="Calibri")
    add_text(s, desc, 7.0, st + 0.33, 5.5, 0.25, font_size=9, color=TEXT_SEC, font_name="Calibri")

footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 9 — Success Metrics
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "SUCCESS CRITERIA", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

criteria = [
    ("✓",  "16 sectors + 60 tickers render on day one with zero manual entry"),
    ("✓",  "Each sector shows 1D, 5D, 1M aggregate + RS rank vs SPY — colour coded"),
    ("✓",  "Hot Rotation badge fires when RS rank improves ≥5 positions in one session"),
    ("✓",  "Expanded ticker table shows: price, 1D%, premarket gap, RVOL, gap classification"),
    ("✓",  "Active/inactive ticker toggle persists to DB immediately — no save button needed"),
    ("✓",  "Pre-market briefing cron sources tickers from the dashboard DB — empty YAML fixed"),
    ("✓",  "Rotation alert delivers to Telegram within 2 minutes of trigger condition being met"),
    ("✓",  "30-day RS rank history chart renders per sector on demand"),
    ("✓",  "Dashboard loads within 3 seconds — acceptable for Flask + SQLite stack"),
    ("✓",  "Mobile layout readable on phone — sector cards stack, no horizontal scroll required"),
    ("✓",  "Zero auto-trade execution at any point — read-only intelligence dashboard"),
]
for i, (check, text) in enumerate(criteria):
    t = 1.38 + i * 0.53
    add_rect(s, 0.55, t, 0.4, 0.4, fill_rgb=RGBColor(0x0D, 0x2A, 0x12), line_rgb=GREEN, line_pt=1)
    add_text(s, check, 0.55, t + 0.05, 0.4, 0.32,
             font_size=12, bold=True, color=GREEN, align=PP_ALIGN.CENTER, font_name="Calibri")
    add_text(s, text, 1.1, t + 0.07, 12.0, 0.32,
             font_size=11, color=TEXT_PRI, font_name="Calibri")

footer(s)

# ══════════════════════════════════════════════════════════════════════════════
# SLIDE 10 — Open Questions + Next Steps
# ══════════════════════════════════════════════════════════════════════════════
s = new_slide()
accent_bar(s)
slide_tag(s)
divider(s, top=0.55)

add_text(s, "OPEN QUESTIONS + NEXT STEPS", 0.55, 0.62, 12, 0.55,
         font_size=32, bold=True, color=TEXT_PRI, font_name="Calibri")

# Left — open questions
add_rect(s, 0.55, 1.35, 6.2, 5.6, fill_rgb=SURFACE, line_rgb=AMBER, line_pt=1)
add_text(s, "⚠  QUESTIONS FOR ANDREW", 0.75, 1.48, 5.7, 0.35,
         font_size=10, bold=True, color=AMBER, font_name="Courier New")
questions = [
    "Data provider? Polygon Starter $29/mo vs Alpaca vs Yahoo Finance",
    "Intraday refresh: every 5 / 15 / 30 min?",
    "Rotation alert threshold: rank +5 positions / top-5 entry / RS >1% vs SPY?",
    "Mobile use? (affects design priority)",
    "History depth: 30 days or 90 days?",
    "Can Andrew add new sectors from UI, or is the list locked at 16?",
    "Benchmark: SPY only, or also QQQ?",
    "watchlist.md: deprecate fully or keep as DB export?",
]
for i, q in enumerate(questions):
    qt = 1.95 + i * 0.6
    add_text(s, f"Q{i+1}  {q}", 0.75, qt, 5.9, 0.52,
             font_size=10, color=TEXT_PRI, font_name="Calibri")

# Right — next steps
add_rect(s, 7.15, 1.35, 6.0, 5.6, fill_rgb=SURFACE, line_rgb=GREEN, line_pt=1)
add_text(s, "→  NEXT STEPS (in order)", 7.35, 1.48, 5.6, 0.35,
         font_size=10, bold=True, color=GREEN, font_name="Courier New")
next_steps = [
    ("1", "Andrew answers 8 open questions above"),
    ("2", "Confirm Polygon.io plan (critical path — blocks data layer)"),
    ("3", "Create DB migrations + seed script (Sector, SectorTicker, SectorSnapshot)"),
    ("4", "Build /sectors Flask blueprint + Jinja template"),
    ("5", "Implement rotation score algorithm + RS rank calculation"),
    ("6", "Wire Telegram rotation alert (reuse existing bot infra)"),
    ("7", "Patch pre-market briefing to read from DB"),
    ("8", "QA: morning dry-run, confirm all 60 tickers appear in briefing"),
    ("9", "Ship — no deploy blocker once data provider confirmed"),
]
for i, (num, step) in enumerate(next_steps):
    st = 1.95 + i * 0.54
    add_rect(s, 7.25, st, 0.38, 0.38, fill_rgb=RED_ACC)
    add_text(s, num, 7.25, st + 0.05, 0.38, 0.28,
             font_size=11, bold=True, color=TEXT_PRI, align=PP_ALIGN.CENTER, font_name="Calibri")
    add_text(s, step, 7.75, st + 0.07, 5.2, 0.32,
             font_size=10, color=TEXT_PRI, font_name="Calibri")

footer(s)

# ── Save ──────────────────────────────────────────────────────────────────────
out_path = "/tmp/orch-enhance/9953073e/concept-deck.pptx"
prs.save(out_path)
print(f"Saved: {out_path}")
