{# Plan 49 — apply theme class BEFORE first paint to avoid a dark→light (or light→dark) flash. Reads `cmdop:theme` from localStorage; falls back to 'dark' (the design's native mode). #} {# Plan 48 — brand assets sourced from the marketing app (frontend/apps/web/public/static/logos/). Same icons across cmdop surfaces. #} {# Geist Sans + Geist Mono now self-hosted. @font-face lives in tailwind.input.css; the woff2 files are under /static/fonts. No external CDN dependency, no privacy leak, air-gap friendly. Preload the sans variant so it's ready by FCP. #} {# Plan 50 — Tailwind is built at image-build time into a static CSS bundle instead of fetching the ~100 KB CDN script at runtime. Config lives in tailwind.config.js, customisations in tailwind.input.css. For local dev: run `npm install && npm run build:css` once. #} {# Plan 50 — shared Alpine page helpers (toast / format / auto-refresh). Loaded before alpinejs so page components can mix it in via `Object.assign(pageHelper({...}), {...})` at the top of their factory. See static/admin/shared/page-helper.js. #} {# Plan 60 Phase 1.5 — paginationState() Alpine helper. Loaded eagerly so any page component (machines, fleets, schedules, …) can wire its listing endpoint through one fetch + state mixin instead of hand- rolling pagination. See static/admin/shared/pagination-state.js. #} {# Plan 61/2a — cmd-K quick-search palette. Loaded eagerly so the keyboard shortcut works on the first paint. See static/admin/shared/cmd-k.js. #} {# Plan 61/2b W3 — Jarvis slide-out dock + the deep-chat web component the chat pane mounts. Loaded globally so cmd+\ works on every page, and so machine_detail.html does not need its own deep-chat {% endif %} {% block head %}{% endblock %} {% if user %}
{% endif %} {# Plan 61/2a — flex column so the footer sticks to the bottom even on short pages. min-h-screen guarantees the column fills the viewport. #}
{% if user %}
{# cmd-K palette trigger — Vercel/Linear style "Search…" input-look with a ⌘K kbd hint on the right. Dispatches a `cmdk:open` window event that cmd-k.js listens for. Hidden on narrow screens — the keyboard shortcuts still work there. Docs link removed from the header — it now lives in the footer (`_footer.html`) only so we don't duplicate the affordance. #} {# Jarvis chat toggle — replaces the old FAB. Same dispatch the footer button + cmd+\\ shortcut use. Renders only when a Jarvis machine_id is resolved (Alpine.store('jarvisDock')). #} {# Plan 49 — theme toggle. Persists to localStorage key `cmdop:theme`. The inline script in reads this before first paint to avoid FOUC. #}
{% for f, role in fleets %} {{ f.name }} ({{ role }}) {% endfor %}
{% endif %}
{% block content %}{% endblock %}
{# Plan 61/2a — thin footer on every authenticated admin page. #} {% if user %} {% include 'admin/components/_footer.html' %} {% endif %}
{# Plan 61/2a — cmd-K palette. Lives outside the sidebar layout so it can teleport its modal to from anywhere. Auth gate matches the sidebar so the palette never appears on the login page. #} {% if user %} {% include 'admin/components/_cmd_k.html' %} {% endif %} {# Plan 61/2b W3 — Jarvis slide-out dock. Mounts only when there is an authenticated user + active fleet. The component resolves the fleet's `jarvis_id` once and hides itself if none exists. #} {% if user and fleet %} {% include 'admin/components/_jarvis_dock.html' %} {% endif %}
{% block scripts %}{% endblock %}