{# Vendor assets via asset() helper. Default mode = CDN (jsDelivr) with SRI; #}
{# when `ntasker assets fetch` ran and `assets_mode=local|auto`, they come from #}
{# the user-data dir under /static/vendor instead. SRI is emitted in both modes #}
{# (local mode: tamper detection). `crossorigin` is only required for CDN loading. #}
{% for tpl in plugin_slots['head'] %}{% include tpl %}{% endfor %}
{# Frontend i18n bridge: js_strings is built server-side per request. #}
{# Alpine magic property `$i18n('key')` is registered just below. #}
{# Sidebar section heading: a button that folds the section's body. #}
{# `key` is a name in settings.SIDEBAR_SECTIONS; the open state lives in #}
{# `sectionOpen` and is persisted to the `sidebar_sections` setting. #}
{% macro section_toggle(key, icon, label) %}
{% endmacro %}
{# One sidebar project row. `p` is the Alpine expression yielding the #}
{# project ({name, label, open_count}); the same markup serves flat rows, #}
{# family heads and indented children. `after_badge` is extra markup that #}
{# follows the open-count badge (the folded-family pill on head rows). #}
{% macro project_row(p, after_badge='') %}
{% endmacro %}
{# Action slots of a task row / board card -- the same three everywhere: the #}
{# agent button (resume when the task already has a session, else run), edit, #}
{# and a "..." menu with everything else. `compact` is the tighter board form. #}
{% macro task_actions(compact=false) %}
{% set b = 'btn btn-sm' ~ (' px-1 py-0' if compact else '') %}
{# Run -- only when the agent CLI + a PTY are available. The session #}
{# indicator (spinner / waiting) sits INSIDE the button, left of the #}
{# logo -- one pill; clicking a live one opens the session. #}
{# Agent CLI not installed: greyed-out logo in a non-clickable box, so #}
{# you still see which agent the task uses and the slot keeps its width. #}
{# Resume: reopen a finished task's stored session. #}
{% endmacro %}
{# Folded-family pill on a head row: how many children hide behind the #}
{# chevron; lit up when one of them is part of the active filter. #}
{# One row of the session pick-up dialog -- same markup for the running and the #}
{# finished list. `row` is the Alpine loop variable of the enclosing template. #}
{% macro session_pick_row() %}
{{ t('No tasks') }}