{# Reusable cockpit presentation macros. The Overview is the TEMPLATE for a consistency pass across the
   cockpit (Paper / Replay / Backtest roll to these next), so the headline card, the provisional-Sharpe
   span, and the compact track row all live here. Pure presentation — no data is computed in templates. #}

{# ---- provisional_num: a number that DIMS + marks itself when its window is still pre-gate -------------
   Keep short-window forward stats visible ("fun to watch") but visibly NOT authoritative. `warming=True`
   renders muted with a "· pre-gate" marker; once the window clears it renders bright/normal. `cls` is the
   bright (cleared) sign-class (e.g. "pos"/"neg"); pre-gate always overrides to muted. #}
{% macro provisional_num(text, warming, cls="") %}
  {%- if warming -%}
    <span class="muted" title="forward window &lt; gate min-days — statistically provisional">{{ text }} <span class="tag">· pre-gate</span></span>
  {%- else -%}
    <span class="{{ cls }}">{{ text }}</span>
  {%- endif -%}
{% endmacro %}

{# ---- headline_card: the fund headline — the CONNECTED backfill record + a small live-readiness chip ---
   `h` is the backfill view: final_equity, total_return_pct, sharpe, max_dd_pct, since (year), title, and
   `gate` {days, min_days, status} for the secondary chip. `curve` is the pre-rendered multi-year SVG. #}
{% macro headline_card(h, curve) %}
<div class="section">
  <h2>Fund status <span class="muted" style="font-size:13px">— {{ h.title }}</span></h2>
  {% if h.has_record %}
  <div class="headline">
    <div class="headline-line">
      <span class="hl-equity">${{ h.final_equity|money }}</span>
      <span class="{{ 'pos' if h.total_return_pct >= 0 else 'neg' }}">{{ '%+.0f'|format(h.total_return_pct) }}%</span>
      <span class="muted">·</span>
      <span>Sharpe {{ '%.2f'|format(h.sharpe) }}</span>
      <span class="muted">·</span>
      <span class="neg">maxDD {{ '%.0f'|format(h.max_dd_pct) }}%</span>
      <span class="muted">· since {{ h.since }}</span>
      <span class="chip" title="live forward readiness — the gate reports, it never acts">live: gate {{ h.gate.days }}/{{ h.gate.min_days }} · <span class="badge {{ h.gate.status }}">{{ h.gate.status }}</span></span>
    </div>
    {% if curve %}<div class="headline-curve">{{ curve|safe }}</div>{% endif %}
  </div>
  {% else %}
  <p class="muted">no backfilled record yet · live: gate {{ h.gate.days }}/{{ h.gate.min_days }} · <span class="badge {{ h.gate.status }}">{{ h.gate.status }}</span></p>
  {% endif %}
</div>
{% endmacro %}

{# ---- exec_badge: the PAPER/LIVE execution-mode badge driven by the registry `execution` field. On every
   track so the operating console is unmissably consistent (all "paper" today; "live" flips green). #}
{% macro exec_badge(execution) %}<span class="badge-exec {{ execution }}" title="execution mode (registry)">{{ execution|upper }}</span>{% endmacro %}

{# ---- plan_pill: THE shared "does the real book track the plan" signal (D2.2/2.3, exec_reconcile.exec_vs_sim).
   `recon` is a ReconResult; renders nothing when `recon.has_exec` is False (no real exec data to compare
   yet — the holdings section still shows "no trades recorded yet" elsewhere). Amber when behind plan, green
   when ahead — plain words only, never "vs sim"/"divergence"/bps. #}
{% macro plan_pill(recon) %}{% if recon and recon.has_exec %}<span class="b {{ 'funded' if recon.divergence >= 0 else 'decaying' }} small"><span class="dot"></span>{{ '%.1f'|format((recon.divergence|abs) * 100) }}% {{ 'ahead of plan' if recon.divergence >= 0 else 'behind plan' }}</span>{% endif %}{% endmacro %}

{# ---- rollup_plan_pill: the SAME "behind/ahead of plan" pill as `plan_pill`, but for an account-wide
   `IbkrAccountRollup` (D4, Task 5's consolidated /paper card) rather than a single strategy's `ReconResult`
   — `rollup.agg_divergence` (mean of the executing rows' own divergence) instead of `recon.divergence`.
   Renders nothing when no strategy is executing yet (`n_executing == 0`). #}
{% macro rollup_plan_pill(rollup) %}{% if rollup and rollup.n_executing > 0 %}<span class="b {{ 'funded' if rollup.agg_divergence >= 0 else 'decaying' }} small"><span class="dot"></span>{{ '%.1f'|format((rollup.agg_divergence|abs) * 100) }}% {{ 'ahead of plan' if rollup.agg_divergence >= 0 else 'behind plan' }}</span>{% endif %}{% endmacro %}

{# ---- health_badge: the LOUD runtime-health axis (SEPARATE from the gate). A track that is STALE / NO_REF /
   BROKEN shows a red badge — visually impossible to confuse with a healthy WAIT — so a stale recompute
   (a strategy silently rotting for weeks) surfaces on day 1. HEALTHY renders nothing. #}
{% macro health_badge(f) %}{% if f.health and f.health != 'HEALTHY' %}<span class="badge-health {{ f.health }}" style="background:#c0392b;color:#fff;font-size:9px;font-weight:600;border-radius:3px;padding:1px 5px;margin-left:4px;letter-spacing:.03em" title="{{ f.health_reason }}">{% if f.health == 'STALE' %}STALE {{ f.health_stale_days }}d{% elif f.health == 'NO_REF' %}NO REF{% else %}{{ f.health }}{% endif %}</span>{% endif %}{% endmacro %}

{# ---- track_row: one compact edge row. `record` is the meaningful number (backfill/backtest ref, else
   "—"); the forward column shows the gate days/min · STATUS plus the dimmed provisional forward Sharpe.
   Carries the PAPER/LIVE badge (registry `execution`) beside the name. #}
{% macro track_row(f, spark) %}
<tr>
  <td data-label="edge"><a href="/strategy/{{ f.strategy_id }}">{{ f.display_name }}</a>
    {{ exec_badge(f.execution) }}{{ health_badge(f) }}
    {% if f.status %}<span class="badge WAIT" style="font-size:10px" title="{{ f.note }}">{{ f.status }}</span>{% endif %}</td>
  <td data-label="record">
    {%- if f.bt_status -%}
      Sh {{ '%.2f'|format(f.bt_sharpe) if f.bt_sharpe is not none else '—' }} <span class="muted">/ {{ '%+.0f'|format(f.bt_cagr*100) if f.bt_cagr is not none else '—' }}%</span>
    {%- else -%}
      <span class="muted">—</span>
    {%- endif -%}
  </td>
  <td data-label="forward">
    <span class="muted">{{ f.days }}/{{ f.gate_min_days }} · <span class="badge {{ f.gate_status }}">{{ f.gate_status }}</span></span>
    {{ provisional_num('Sh %.2f'|format(f.sharpe), f.warming, 'pos' if f.sharpe >= 0 else 'neg') }}
  </td>
  <td data-label="nav">{{ spark(f.strategy_id)|safe }}</td>
</tr>
{% endmacro %}

{# ---- deploy_constituent_row: one constituent edge of a DEPLOY book — its standalone (vol-targeted) venue
   metric. `e` = {strategy_id, display_name, linkable, sleeve, sharpe, ann_return_pct, max_dd_pct}. `linkable`
   signals whether `strategy_id` is a real STRATEGY_REGISTRY entry with a working /strategy page — a sleeve
   with no standalone registry entry (e.g. crypto_tstrend) renders as plain text, never a dead link. Always
   PAPER. #}
{% macro deploy_constituent_row(e) %}
<tr>
  <td data-label="edge">{% if e.linkable %}<a href="/strategy/{{ e.strategy_id }}">{{ e.display_name }}</a>{% else %}{{ e.display_name }}{% endif %} {{ exec_badge('paper') }}</td>
  <td data-label="metric">Sh {{ '%.2f'|format(e.sharpe) }} <span class="muted">/ {{ '%+.0f'|format(e.ann_return_pct) }}%</span></td>
  <td data-label="maxDD" class="neg">{{ '%.0f'|format(e.max_dd_pct) }}%</td>
</tr>
{% endmacro %}

{# ---- research_section: the dimmed, registry-driven RESEARCH block ("not the fund") — every research-tier
   tracker grouped by venue, each PAPER/LIVE-badged via track_row. REUSABLE so the same deploy/research
   structure can roll to the Paper page next. `groups` = [(venue, [FleetRow, ...]), ...]. #}
{% macro research_section(groups, spark) %}
<div class="section research">
  {# It's literally "not the fund" — collapsed by default so the main fund overview isn't a long wall;
     the summary is styled to match the section <h2> skin (font-size/border-bottom). #}
  <details>
    <summary style="font-size:15px; font-weight:600; cursor:pointer; padding-bottom:6px; border-bottom:1px solid #21262d; margin-bottom:12px">Research <span class="muted" style="font-size:13px; font-weight:400">— not the fund (experimental edges)</span></summary>
    <div class="table-wrap"><table class="fleet" id="research-fleet" hx-get="/" hx-trigger="every 60s" hx-select="#research-fleet" hx-swap="outerHTML">
      <thead><tr><th>edge</th><th>record</th><th>forward</th><th>nav</th></tr></thead>
      <tbody>
      {% for venue, rows in groups %}
        <tr class="subhead"><td colspan="4" class="muted">{{ venue }}</td></tr>
        {% for f in rows %}{{ track_row(f, spark) }}{% endfor %}
      {% endfor %}
      </tbody>
    </table></div>
    <p class="muted" style="font-size:12px"
       title="Phase-1 paper-forward readiness — reports only, never acts; short windows are noisy.">
      dimmed = pre-gate, statistically provisional</p>
  </details>
</div>
{% endmacro %}
