From 54207fc9ea14cee46cae554212ccc3d4c0ef263e Mon Sep 17 00:00:00 2001 From: Brandon Honeycutt <697896+brandonhon@users.noreply.github.com> Date: Fri, 5 Jun 2026 11:37:55 -0500 Subject: [PATCH 1/2] fix(web): mobile search results panel overflowing off-screen The desktop offset (left: rail-w + 16) and fixed 420px width pushed the search-results dropdown off the right edge on phones. Pin it full-width under the search bar (8px side margins) under .topbar.mobile. --- web/src/components/TopBar.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/components/TopBar.svelte b/web/src/components/TopBar.svelte index 7bd8ff6..b932850 100644 --- a/web/src/components/TopBar.svelte +++ b/web/src/components/TopBar.svelte @@ -544,4 +544,12 @@ line-height: 1.4; } .search-results a:hover { background: var(--line-soft); } + /* Mobile: the desktop offset (left: rail-w + 16) + fixed 420px width push + the panel off the right edge of a phone. Pin it under the full-width + search bar with small side margins instead. */ + .topbar.mobile .search-results { + left: 8px; + right: 8px; + width: auto; + } From eb288eb3b7d542edb8104cfa54a948541021e278 Mon Sep 17 00:00:00 2001 From: Brandon Honeycutt <697896+brandonhon@users.noreply.github.com> Date: Fri, 5 Jun 2026 10:48:20 -0500 Subject: [PATCH 2/2] =?UTF-8?q?feat(web):=20mobile=20settings=20=E2=80=94?= =?UTF-8?q?=20grouped=20inset-list=20redesign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile-only redesign of the settings drill-down: per-section icon chips + iOS-style grouped inset cards in the list view, and full-width actions in the detail view. Desktop is unchanged — the icon spans are display:none outside .modal.mobile, and all new styling is scoped to .modal.mobile. --- web/src/components/Settings.svelte | 107 +++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 28 deletions(-) diff --git a/web/src/components/Settings.svelte b/web/src/components/Settings.svelte index c47a1b8..efb033c 100644 --- a/web/src/components/Settings.svelte +++ b/web/src/components/Settings.svelte @@ -67,6 +67,29 @@ } function mobileBackToList() { sectionPicked = false; } + // Per-section glyphs shown only in the mobile settings list (the .nav-ic + // span is display:none on desktop, so the desktop rail stays text-only). + const NAV_ICONS: Record = { + profile: ``, + passkeys: ``, + notifications: ``, + inbox: ``, + preferences: ``, + filters: ``, + digest: ``, + stats: ``, + mobile: ``, + import: ``, + starter: ``, + llm: ``, + branding: ``, + database: ``, + session: ``, + email: ``, + users: ``, + about: ``, + }; + // --- Import & Data section ------------------------------------------- let importTab = $state<"live" | "file">("live"); let ttUrl = $state(""); @@ -936,36 +959,36 @@ @@ -1999,6 +2022,9 @@ flex: 1; background: linear-gradient(90deg, var(--line), transparent); } + /* Per-row glyphs are mobile-only; hidden on desktop so the rail stays a + clean text list (shown again under .modal.mobile below). */ + .nav-ic { display: none; } .nav button { background: transparent; border: 0; @@ -2050,29 +2076,54 @@ .modal.mobile .layout { grid-template-columns: 1fr; } .modal.mobile .layout[data-view="list"] .content, .modal.mobile .layout[data-view="detail"] .nav { display: none; } + /* Mobile list view = grouped inset cards (label on paper, rounded card of + rows with icon chips + chevron). iOS-grouped feel in ember's palette. */ .modal.mobile .layout[data-view="list"] .nav { border-right: 0; - padding: 8px 8px 24px; - background: var(--card); + padding: 10px 16px 28px; + background: var(--paper); + gap: 0; + } + .modal.mobile .nav-group { margin: 0 0 22px; gap: 0; } + .modal.mobile .nav-label { color: var(--ink-faint); padding: 0 8px 8px; } + .modal.mobile .nav-label::after { display: none; } + .modal.mobile .nav-ic { + display: grid; + place-items: center; + flex: none; + width: 30px; + height: 30px; + border-radius: 9px; + background: var(--ember-wash); + color: var(--ember); } + .modal.mobile .nav-ic :global(svg) { width: 17px; height: 17px; } + .modal.mobile .nav-ic-admin { background: rgba(176, 125, 26, 0.16); color: var(--gold); } .modal.mobile .nav button { - padding: 14px 16px; + display: flex; + align-items: center; + gap: 13px; + padding: 12px 36px 12px 14px; font-size: 15px; - border-radius: 10px; - /* Subtle chevron at the right edge so the affordance reads as "tap to - open a sub-screen", matching the iOS-style drill-down. */ + border-radius: 0; + background-color: var(--card); + border-left: 1px solid var(--line); + border-right: 1px solid var(--line); + /* Chevron affordance: "tap to open a sub-screen" (iOS-style drill-down). */ background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: right 14px center; background-size: 14px 14px; - padding-right: 36px; - } - .modal.mobile .nav button.active { - /* On mobile, "active" only matters momentarily before the detail view - slides in — keep it subtle so it doesn't read as a permanent state. */ - background-color: var(--ember-wash); } + .modal.mobile .nav button + button { border-top: 1px solid var(--line-soft); } + .modal.mobile .nav button:first-of-type { border-top: 1px solid var(--line); border-radius: 16px 16px 0 0; } + .modal.mobile .nav button:last-of-type { border-bottom: 1px solid var(--line); border-radius: 0 0 16px 16px; } + .modal.mobile .nav button:active { background-color: var(--paper-2); } + .modal.mobile .nav button.active { background-color: var(--ember-wash); } .modal.mobile .content { padding: 18px 16px 48px; } + /* Detail view: stack actions as full-width tap targets. */ + .modal.mobile .actions { flex-direction: column; align-items: stretch; } + .modal.mobile .actions button { width: 100%; padding: 13px; font-size: 15px; } /* Form scaffolding — collapse two-column grids and side-by-side rows so fields stop overflowing the screen on a phone. */