fix(ui): kiosk dropdown flash + never inherit the OS light theme

Outside-close listeners move from click to pointerdown: pointerdown
fires before the open-toggle re-render, so the kiosk's slow software
compositing can no longer detach the click target mid-flight and close
the menu the instant it opens. color-scheme:dark (CSS + meta) pins every
native control — select popups, scrollbars, pickers — dark regardless of
the user's OS theme; explicit select/option colors cover Firefox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago 2026-07-22 19:44:32 -04:00
parent 6a3b46b5a9
commit b193e64ffb
5 changed files with 26 additions and 8 deletions

View File

@ -14,6 +14,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content" />
<meta name="description" content="Archipelago - Your sovereign personal server" />
<meta name="theme-color" content="#000000" />
<!-- Dark-only app: pin native controls dark before CSS loads. -->
<meta name="color-scheme" content="dark" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

View File

@ -104,11 +104,11 @@ function handleClickOutside(e: MouseEvent) {
}
onMounted(() => {
document.addEventListener('click', handleClickOutside)
document.addEventListener('pointerdown', handleClickOutside)
})
onBeforeUnmount(() => {
document.removeEventListener('click', handleClickOutside)
document.removeEventListener('pointerdown', handleClickOutside)
})
</script>

View File

@ -131,10 +131,10 @@ async function loadIdentities() {
onMounted(() => {
loadIdentities()
document.addEventListener('click', onClickOutside)
document.addEventListener('pointerdown', onClickOutside)
})
onBeforeUnmount(() => {
document.removeEventListener('click', onClickOutside)
document.removeEventListener('pointerdown', onClickOutside)
})
</script>

View File

@ -2,6 +2,22 @@
@tailwind components;
@tailwind utilities;
/* The app is dark-only NEVER let the OS/browser theme leak into native
controls. Without this, select popups / scrollbars / date pickers follow
the user's OS setting (a light-mode ThinkPad rendered white dropdown
lists inside the dark UI, 2026-07-22). color-scheme pins Chromium's
native select popup dark; the explicit select/option rules cover
Firefox and the closed control itself. */
:root {
color-scheme: dark;
}
select,
select option,
select optgroup {
background-color: #16181d;
color: #fff;
}
/* Montserrat - header font (used in neode present) */
@font-face {
font-family: 'Montserrat';

View File

@ -350,7 +350,7 @@ function updateKeyboardInset() {
onMounted(async () => {
window.addEventListener('resize', handleResize)
document.addEventListener('click', handleDocClickForMenu)
document.addEventListener('pointerdown', handleDocClickForMenu)
window.addEventListener('archipelago:share-to-mesh', loadPendingFromSession)
if (window.visualViewport) {
window.visualViewport.addEventListener('resize', updateKeyboardInset)
@ -403,7 +403,7 @@ onMounted(async () => {
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
document.removeEventListener('click', handleDocClickForMenu)
document.removeEventListener('pointerdown', handleDocClickForMenu)
window.removeEventListener('archipelago:share-to-mesh', loadPendingFromSession)
if (window.visualViewport) {
window.visualViewport.removeEventListener('resize', updateKeyboardInset)
@ -1337,8 +1337,8 @@ function closeAttachMenuOnOutsideClick(ev: MouseEvent) {
const target = ev.target as HTMLElement
if (!target.closest('.mesh-attach-menu-anchor')) showAttachMenu.value = false
}
onMounted(() => document.addEventListener('click', closeAttachMenuOnOutsideClick))
onUnmounted(() => document.removeEventListener('click', closeAttachMenuOnOutsideClick))
onMounted(() => document.addEventListener('pointerdown', closeAttachMenuOnOutsideClick))
onUnmounted(() => document.removeEventListener('pointerdown', closeAttachMenuOnOutsideClick))
const attachError = ref<string | null>(null)
const fetchingCids = ref<Set<string>>(new Set())
const fetchedUrls = ref<Map<string, string>>(new Map())