<!doctype html>
<html lang="en" data-theme="{{ theme }}"{% if layout %} style="{{ layout }}"{% endif %}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}LLeMbas{% endblock %}</title>
<meta name="description" content="LLeMbas - a web UI for your language models.">
<meta name="color-scheme" content="dark light">

<link rel="icon" href="{{ url_for('static', path='img/favicon.svg') }}" type="image/svg+xml">

{#
  Installing as an app. The manifest is a route, not a file, because it carries
  the instance name; the icons are PNG because a launcher will not take an SVG.
  theme-color is rewritten by app.js when the theme changes -- the value here is
  only what the browser paints with before the stylesheet has resolved.
#}
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#101317">
<link rel="apple-touch-icon" href="{{ url_for('static', path='img/apple-touch-icon-180.png') }}">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="LLeMbas">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

<link rel="stylesheet" href="{{ url_for('static', path='css/tokens.css') }}">
<link rel="stylesheet" href="{{ url_for('static', path='css/app.css') }}">
{% block head %}{% endblock %}

{#
  Applied before first paint so a reload never flashes the wrong theme. The
  server already rendered data-theme from the signed-in user's preference; this
  only corrects it for a visitor whose local choice differs (or who is signed
  out, where the server has nothing to go on).
#}
<script>
  (function () {
    try {
      var stored = localStorage.getItem("lembas-theme");
      if (stored && stored !== document.documentElement.dataset.theme) {
        document.documentElement.dataset.theme = stored;
      }
    } catch (e) { /* private mode: the server-rendered theme stands */ }

    /* Panel widths, for the same reason and in the same breath. app.js also
       applies these, but it is deferred -- so without this a panel dragged
       wider opens at its default and jumps once the script runs. */
    try {
      var widths = JSON.parse(localStorage.getItem("lembas-panel-widths") || "{}");
      Object.keys(widths).forEach(function (name) {
        if (name.indexOf("--") === 0) {
          document.documentElement.style.setProperty(name, widths[name] + "px");
        }
      });
    } catch (e) { /* the stylesheet's defaults stand */ }
  })();
</script>
</head>
<body{% block body_attrs %}{% endblock %}>
{% include "partials/icons.html" %}

{% block body %}{% endblock %}

<script src="{{ url_for('static', path='vendor/htmx.min.js') }}" defer></script>
<script src="{{ url_for('static', path='vendor/htmx-ext-sse.js') }}" defer></script>
<script src="{{ url_for('static', path='vendor/alpine.min.js') }}" defer></script>
<script src="{{ url_for('static', path='js/app.js') }}" defer></script>
<script src="{{ url_for('static', path='js/ui.js') }}" defer></script>
{# commands.js before composer.js: the second reads the first's table to draw
   the `/` menu, and both are deferred so the order here is the run order. #}
<script src="{{ url_for('static', path='js/commands.js') }}" defer></script>
<script src="{{ url_for('static', path='js/composer.js') }}" defer></script>
<script src="{{ url_for('static', path='js/audio.js') }}" defer></script>

{#
  The version in the query string is what versions the worker's cache, so a
  release invalidates it without anyone remembering to bump a constant.
  serviceWorker is absent over plain http, which is why a LAN install without
  TLS silently offers no install prompt -- that is the browser's rule, not ours.
#}
<script>
  if ("serviceWorker" in navigator) {
    window.addEventListener("load", function () {
      navigator.serviceWorker.register("/sw.js?v={{ version }}").catch(function () {
        /* An install failure must never break the page it was loaded from. */
      });
    });
  }
</script>
{% block scripts %}{% endblock %}
</body>
</html>
