{# `data-base` is what makes a custom theme inherit: tokens.css matches `[data-base="shire"]` as well as `[data-theme="shire"]`, so a custom light theme gets the whole parchment palette underneath its own handful of colours. Without it, four light colours would sit on Moria's near-black surfaces. `data-themes` is the list of `id:base` pairs, which is what the browser needs in order to set both attributes when somebody switches -- one attribute to split rather than a JSON island to parse. #} {# `viewport-fit=cover` is what lets `env(safe-area-inset-*)` resolve to anything but zero, and without it the `black-translucent` status bar style below is a promise with nothing behind it: iOS puts the page under the clock and the notch and the tokens that would have paid for it stay at 0. No `maximum-scale` and no `user-scalable=no` -- pinch-zoom is somebody's accessibility setting, not a layout problem to be suppressed. #} {% block title %}{{ brand.name }}{% endblock %} {# 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. #} {# Two, scoped by preference, so the browser has an answer before any of our CSS or JavaScript has run. There used to be one and it was Moria's near-black, so every reader of the light theme got a dark browser chrome on every page load until `app.js` -- which is deferred -- corrected it. `applyTheme` still has the last word, and still reads the value from `--bg` rather than repeating a hex here; these two are only what is painted before it can. The values are read out of tokens.css at startup (`theme_colour` in web/templating.py), so the colour has one home. #} {% block head %}{% endblock %} {# The scripts' words. `js_strings()` is the part of the catalogue the files under static/js ask for with `t("…")`, in this reader's language, and empty in English -- a missing key is its own English, as on the server. `lembasT` is defined here, inline and not deferred, so it exists before any of the deferred scripts below runs, whichever order they load in. Same `%(name)s` fields as `t()`, so one catalogue entry serves both halves. `tojson` escapes `<`, `>` and `&`, so a translation cannot close the island. #} {# 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). #} {% include "partials/icons.html" %} {# The copy button every code block in a reply gets. A template rather than markup in the reply itself: model output goes through a sanitiser that does not allow