{# `lang` is what tells a screen reader which voice to read the page in, and what a browser offers to translate from. It was absent entirely, so assistive technology fell back to the OS language and read a German UI in an English voice. The request locale, not the user's stored preference: they agree for a signed-in user, and for the login page the request locale is the only one there is. Underscores become hyphens because BCP 47 writes en-PI where Symfony writes en_PI, and an invalid tag is ignored the same as a missing one. #} rather than threaded through each controller as a Stimulus value because it is wanted in three unrelated places already (the send-later menu, the snooze menu, and anything that formats a time next) and none of them share a template. Same argument as ClockGlobal being a Twig global rather than a controller variable. Read through `prefersHour12()` in assets/clock_format.js. #} data-clock-hour12="{{ clock.is12Hour ? 'true' : 'false' }}" style="{{ appearance_vars() }}">
{# Without this the browser assumes a ~980px desktop canvas and scales the whole app down. `viewport-fit=cover` lets the gradient run under the notch; the safe-area padding in app.css keeps content clear of it. Zoom is NOT pinned. `maximum-scale=1, user-scalable=no` used to be here to make the app feel installed rather than page-like; it also took away pinch-zoom, which WCAG 1.4.4 requires and which is the only way some people read anything at all. The reason it was added — iOS zooming when a small form control takes focus — is already handled by the 16px form-control rule in app.css, which is what actually prevents that; iOS ignores user-scalable anyway, so this only ever disabled zoom on Android where nothing was wrong. `interactive-widget=resizes-content`: the default (resizes-visual) shrinks only the visual viewport for the keyboard and leaves the layout viewport — where fixed elements live — at full height, so the page behind the fullscreen compose window stayed pannable and showed through below it. Resizing the content instead means fixed elements end above the keyboard and there is nothing to pan. WHICH BROWSERS HONOUR IT HAS MOVED, and nothing here assumes an answer any more. This used to say "iOS ignores this keyword" and treated the compose controller's visualViewport tracking as the fallback for that. Safari has since shipped support, and a window sized to the visual viewport on a browser that HAS resized the layout viewport comes out shorter than the page behind it — which is a strip of mail list under the composer, in a screenshot from an iPhone none of us owns. So the controller no longer asks which platform it is on: it fills the layout viewport, whatever that currently is, and pads its own foot by however much of itself is covered. Both readings of this keyword are correct under that rule, which is why the rule names neither. See compose_controller#_trackViewport. #}