commit fa7d49b44274582f2c1b34bd5d6b946d7e84d98f
parent 2d37174d152c6a15eedcb65fd9c971adda503857
Author: claude-cdn-bot <claude-bot@users.noreply.github.com>
Date: Wed, 14 Oct 2026 03:17:43 +0000
fix(ui): centre header icons and stop buttons looking stuck pressed on touch
- The menu (hamburger) and moon icons sat ~4px above the centre of their buttons: two of the four icon wrappers were
plain inline boxes resting on a text baseline while the others were flex boxes. All icon-button wrappers now
centre the same way, so nothing shifts when the menu or theme toggles (measured 0px off in light/dark, open/closed).
- :hover sticks after a tap on touch screens, leaving the menu button looking pressed. Hover highlights on buttons,
nav links and icon buttons now apply only under @media (hover: hover); icon buttons get a proper :active state.
- 7 new browser checks (96 total); repo tests and axe-core (0 violations) pass.
Diffstat:
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/app/static/app.css b/app/static/app.css
@@ -301,12 +301,12 @@ body.turbo-loading .page { opacity: 0.55; pointer-events: none; transition: opac
cursor: pointer;
transition: background 0.12s, color 0.12s;
}
-.nav-link:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
+@media (hover: hover) { .nav-link:hover { color: var(--text); background: var(--surface-2); text-decoration: none; } }
.nav-link.is-active { color: var(--accent); background: var(--accent-soft); }
.nav-link svg { flex: none; }
.nav-cta { margin-left: 0.4rem; background: var(--accent-solid); color: var(--accent-contrast); font-weight: 600; }
-.nav-cta:hover { background: var(--accent-hover); color: var(--accent-contrast); }
-:root[data-theme="dark"] .nav-cta:hover { background: #4a7ff0; }
+@media (hover: hover) { .nav-cta:hover { background: var(--accent-hover); color: var(--accent-contrast); } }
+@media (hover: hover) { :root[data-theme="dark"] .nav-cta:hover { background: #4a7ff0; } }
.nav-cta.is-active { background: var(--accent-solid); color: var(--accent-contrast); box-shadow: inset 0 0 0 2px color-mix(in srgb, #fff 35%, transparent); }
.more { position: relative; }
@@ -440,16 +440,16 @@ html[data-notice="off"] .site-notice { display: none; }
box-shadow: var(--shadow-sm);
transition: background 0.12s, border-color 0.12s, transform 0.08s, box-shadow 0.12s;
}
-.btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); text-decoration: none; }
+@media (hover: hover) { .btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); text-decoration: none; } }
.btn:active:not(:disabled) { transform: translateY(1px); box-shadow: none; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn svg { flex: none; }
.btn-sm { min-height: 2rem; padding: 0.3rem 0.7rem; font-size: var(--fs-sm); border-radius: var(--r-sm); }
.btn-primary { background: var(--accent-solid); border-color: var(--accent-solid); color: var(--accent-contrast); }
-.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-contrast); }
-:root[data-theme="dark"] .btn-primary:hover:not(:disabled) { background: #4a7ff0; border-color: #4a7ff0; }
+@media (hover: hover) { .btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-contrast); } }
+@media (hover: hover) { :root[data-theme="dark"] .btn-primary:hover:not(:disabled) { background: #4a7ff0; border-color: #4a7ff0; } }
.btn-ghost-danger { box-shadow: none; color: var(--muted); }
-.btn-ghost-danger:hover:not(:disabled) { color: var(--danger); border-color: var(--danger-border); background: var(--danger-soft); }
+@media (hover: hover) { .btn-ghost-danger:hover:not(:disabled) { color: var(--danger); border-color: var(--danger-border); background: var(--danger-soft); } }
.btn.is-done { color: var(--success); border-color: var(--success); }
.icon-btn {
@@ -466,7 +466,8 @@ html[data-notice="off"] .site-notice { display: none; }
cursor: pointer;
transition: background 0.12s, color 0.12s;
}
-.icon-btn:hover { background: var(--surface-2); color: var(--text); }
+@media (hover: hover) { .icon-btn:hover { background: var(--surface-2); color: var(--text); } }
+.icon-btn > span { display: inline-flex; align-items: center; justify-content: center; }
.site-header__tools .nav-toggle { display: none; }
.text-input, .select, .filter-input, .search-input, .url-input {
@@ -765,6 +766,8 @@ html[data-js] .file-view.is-pending .file-view__content { display: none; }
.file-skel__preview { display: grid; gap: 0.85rem; align-content: start; min-height: 16rem; padding: 1.1rem 1rem 1.3rem; }
.sk-previewbar { width: 100%; height: 2rem; border-radius: var(--r-sm); margin-bottom: 0.4rem; }
+.icon-btn:active { background: var(--surface-3); color: var(--text); }
+
/* ============================== 8. Upload ============================== */
.upload { max-width: 44rem; }
.dropzone {