Skip to content

fix(landing,docs): comprehensive mobile responsive pass#41

Merged
johnnichev merged 1 commit intomainfrom
fix/mobile-responsive-pass
Apr 6, 2026
Merged

fix(landing,docs): comprehensive mobile responsive pass#41
johnnichev merged 1 commit intomainfrom
fix/mobile-responsive-pass

Conversation

@johnnichev
Copy link
Copy Markdown
Owner

Summary

Fixes the catastrophic mobile layout reported on Galaxy S23. The landing page was effectively unusable below ~1024px due to a combination of bugs that all surfaced together. Plus the docs site had a broken nav icon that triggered a half-rendered state when clicked.

Issues addressed (from the bug report):

# Issue Fix
1 Docs nav book icon breaks the page when clicked extra.homepage → QUICKSTART, removed broken mike provider
2 Builder iframe unusable on mobile Mobile fallback CTA card replaces iframe at <=768px
3 Footer too cluttered on mobile Stacks vertically, smaller text, more breathing room
4 pip-install button squeezed to "l sele" Hero buttons stack vertically at <=640px
5 Guardrails code block overflowing viewport width min-width: 0 on grid children + .code-frame
6 Eval/trace previews scrolling sideways Inner HTML responsive @media queries + .table-wrap
7 Comparison tables broken/cut off .cmp-scroll wrapper with edge-gradient mask + scroll hint
Whole page horizontal overflow html, body { overflow-x: hidden } (was body alone)
Header nav not collapsing Bumped breakpoint 900px → 1024px + hamburger menu

Root cause (the hidden gotcha)

The Galaxy S23 was almost certainly in Chrome's "Desktop Site" mode, which reports a viewport of ~980px — just over the existing 900px breakpoint. This defeated .hide-mobile and kept all layouts in their desktop forms but rendered on a phone screen, producing the squeezed/overflowing/cut-off symptoms.

The fix is structural, not just CSS patches:

  1. Bumped the narrow-mode breakpoint to 1024px to catch Desktop Site mode and any other phones reporting >900px
  2. Added a hamburger menu so the collapsed nav is still functional
  3. Fixed all the underlying overflow patterns that caused horizontal page scroll regardless of breakpoint

Detailed changes

landing/index.html (+395 / -16)

Page-level overflow fix

  • html, body { overflow-x: hidden; max-width: 100% } (previously only body)
  • Defensive max-width: 100% on img, video, iframe, table, pre

Hamburger menu

  • New .nav-burger button + .nav-drawer slide-down panel
  • aria-expanded / aria-hidden / aria-controls for accessibility
  • Click outside, Escape key, and resize-to-desktop all close the drawer
  • Body scroll lock while drawer is open
  • Animated burger → X transform on toggle

Hero buttons

  • .hero-actions { flex-direction: column } at <=640px
  • Override inline flex: 1 with !important so each button gets full width

Code blocks

  • .code-frame { min-width: 0; max-width: 100% }
  • .grid-2/3/4 > * { min-width: 0 } (the actual flex/grid sizing trap fix)
  • .code-body { -webkit-overflow-scrolling: touch } for iOS momentum
  • Smaller font/padding at <=640px

Comparison tables

  • New .cmp-scroll wrapper with mask-image edge gradient
  • .cmp-table { min-width: 640px } forces readable column widths
  • .cmp-hint ("scroll → for full comparison") shown at <=768px
  • Both comparison tables migrated to the new wrapper

Builder section

  • New .builder-mobile-fallback card with cyan CTA button
  • .builder-frame[data-builder-iframe] { display: none } at <=768px
  • Iframe replaced with: "The visual builder needs more room. Open it in a new tab to try it on a desktop."

Eval/trace iframes

  • Iframe height responsive: 380px → 320px at <=768px
  • (Inner HTML files updated separately — see below)

Footer

  • Stacks vertically at <=640px with centered alignment
  • New .footer-attribution wrapper with smaller .footer-meta text
  • Reduced font size and tighter gap on mobile

Touch-device hover guard (the touch-stickiness follow-up from earlier)

  • Single @media (hover: none) block at the bottom of the CSS
  • Resets transform and box-shadow side of hover (not color) on touch
  • Cleaner than wrapping 40+ individual hover rules

landing/eval-report-preview.html (+22 / -1)

  • html, body { overflow-x: hidden; max-width: 100% }
  • New @media (max-width: 560px) block: smaller padding, simplified 2-col stat grid, smaller table padding
  • .table-wrap with horizontal scroll inside the iframe
  • All scrolling happens inside the iframe instead of forcing the parent page wider

landing/trace-preview.html (+15 / -1)

  • Same html, body { overflow-x: hidden } fix
  • New .table-wrap with min-width: 380px table inside
  • @media (max-width: 560px) block: smaller padding, font, table padding
  • Stats inline → block on mobile

mkdocs.yml (+5 / -2)

  • Removed extra.version.provider: mike — was fetching versions.json (which doesn't exist), causing 404s and breaking the docs nav state
  • Added extra.homepage: https://selectools.dev/QUICKSTART/ — the actual root cause of the broken docs nav icon. Clicking the logo navigated to /, which is the landing page (overwritten by the deploy workflow). Material's instant-navigation could not render the landing page HTML inside the docs shell, causing the half-rendered broken state. Now the icon goes to QUICKSTART, which is a real Material docs page.

docs/index.md (+99 / -3)

  • Replaced the JS-redirect hack (window.location.replace("QUICKSTART/")) with a proper Material grid-cards welcome page
  • Two <div class="grid cards"> sections: "Get started in 5 minutes" (4 cards) and "Explore the modules" (6 cards)
  • Visual builder CTA with md-button styling
  • The redirect approach broke under navigation.instant. The welcome page is what local mkdocs serve shows now. Production still overwrites it with the landing page, but the extra.homepage config above ensures that's never reached from the docs nav.

Local-only follow-ups (in .private/, gitignored, not in this PR)

Done as part of the same work session but not committed because .private/ is gitignored:

  • 44 URL replacements across 14 launch/blog files in .private/ — same johnnichev.github.io/selectoolsselectools.dev sweep we did for public files in PR feat: animation/delight pass + selectools.dev custom domain #40, now extended to launch posts and blog drafts
  • .private/launch-prep/gsc-migration-checklist.md — new file with the full Google Search Console migration playbook (add new property, TXT verification, sitemap submission, change-of-address wizard, monitoring schedule, what NOT to do)

Test plan

Pre-merge — verify the build is clean (already done locally):

  • mkdocs build produces 0 errors / 0 warnings
  • HTML structural balance checked (style/script/nav/table/footer all balanced)
  • JS syntax validated with node --check (passes)
  • Both preview HTML files structural balance checked
  • All 14 pre-commit hooks pass

Post-merge — verify on production at https://selectools.dev

Required device combos:

  • Galaxy S23, Chrome, normal mobile mode
  • Galaxy S23, Chrome, "Desktop Site" mode ← this was the hidden gotcha
  • iPhone, Safari, mobile mode (test the iOS-specific fixes)
  • Desktop, Chrome (regression check)

For each combo, walk through:

  • Hamburger button visible (or hidden on desktop)
  • Hamburger opens/closes the drawer
  • Pressing Esc inside the drawer closes it
  • Tapping any drawer link navigates and closes the drawer
  • No horizontal page scroll on any section
  • Hero buttons are full-width and tappable (pip-install no longer squeezed)
  • Stats count-up still fires when scrolled into view
  • Code blocks scroll inside their own boxes (not the page)
  • Comparison tables show edge-gradient hint on the right side
  • Comparison tables scroll horizontally inside their wrappers
  • "scroll → for full comparison" hint appears on mobile
  • Builder section shows the "Open builder →" CTA card (not the desktop iframe) at narrow widths
  • Eval/trace previews fit within their iframes without forcing the page wider
  • Footer stacks vertically with centered alignment and breathing room
  • Tap states don't "stick" (touch hover guard working)

For the docs site:

  • Visit https://selectools.dev/QUICKSTART/
  • Click the "Selectools" book icon at the top of the docs nav
  • Verify it goes to the QUICKSTART page (not a broken state)
  • No 404s for versions.json in DevTools Network tab

What's NOT in this PR

  • Visual redesign / restructuring of the landing page (this is a layout fix, not a redesign)
  • Touching the simulation player, hero flow SVG, or existing animations (intentionally untouched)
  • Replacing the eval/trace iframes with native HTML (would be a larger refactor — the responsive @media queries on the inner files achieve the same UX with less risk)
  • Server-side redirects from / to /QUICKSTART/ for docs (would require an Actions workflow change; the extra.homepage config solves the same problem more cleanly)

If anything still looks off after merge, the easiest fix-loop is to add to this same branch and re-merge — I can iterate quickly on any specific symptoms you find.

Fixes the catastrophic mobile layout issues reported on Galaxy S23. The
landing page was effectively unusable below ~1024px due to a combination
of bugs that all surfaced together: nav not collapsing, hero buttons
squeezed, code blocks forcing horizontal page overflow, comparison tables
spilling off the right edge, builder iframe rendering at desktop width,
eval/trace preview iframes scrolling sideways, and footer cluttered. Plus
the docs site had a broken nav icon that triggered a half-rendered state.

Root causes addressed:

1. **html, body { overflow-x: hidden }** instead of body alone — iOS
   Safari and some Android browsers ignore the rule unless both have it.
   Plus defensive `max-width: 100%` on img/video/iframe/table/pre.

2. **Hamburger menu** — bumped collapse breakpoint from 900px to 1024px
   so Chrome's "Desktop Site" mode (~980px viewport) also collapses.
   Replaced inline nav-links with a slide-down drawer triggered by an
   accessible hamburger button (aria-expanded, Esc to close, focus return,
   resize listener that auto-closes when going back to desktop).

3. **Hero buttons stack vertically** at <=640px. Previous flex:1 layout
   crushed the pip-install button to "l sele" because three CTAs couldn't
   share 360px. New layout: full-width buttons stacked vertically.

4. **Code blocks** — added `min-width: 0` to .code-frame and to all
   grid-2/3/4 children. The classic flex/grid sizing trap: default
   min-width: auto resolves to max-content, so long code lines forced
   parents wider than the viewport. Setting min-width: 0 lets containers
   shrink and the inner overflow-x: auto handles scrolling within the
   code box. Smaller font/padding at <=640px.

5. **Comparison tables** — wrapped in .cmp-scroll containers with
   overflow-x: auto + edge-gradient mask images so users can see there's
   more content. min-width: 640px on the table forces readable column
   widths. Added "scroll → for full comparison" hint at <=768px.

6. **Builder iframe** — desktop-only widget. Added .builder-mobile-fallback
   card that replaces the iframe at <=768px with a "The visual builder
   needs more room. Open in new tab →" CTA. Uses data-builder-iframe
   attribute selector to hide the iframe specifically.

7. **Eval/trace preview iframes** — made the inner HTML files responsive
   with @media (max-width: 560px): reduced padding, simplified grids
   (3-col → 2-col), wrapped tables in .table-wrap with their own
   horizontal scroll. Iframe height drops from 380px to 320px on mobile.

8. **Footer** — stacks vertically at <=640px with centered alignment,
   smaller meta text, more breathing room.

9. **Touch-device hover guard** — single @media (hover: none) override
   block at the bottom of the CSS that resets only transform/box-shadow
   side of hover (not color) on touch devices. Eliminates "sticky hover"
   after tap. Cleaner than wrapping 40+ individual hover rules.

Docs fixes:

10. **Removed `extra.version.provider: mike`** from mkdocs.yml — this
    was fetching versions.json (which doesn't exist), causing 404s and
    breaking the docs nav state.

11. **Added `extra.homepage`** pointing to QUICKSTART. The actual root
    cause of the broken docs nav icon: clicking it navigated to / which
    is the landing page (overwritten by the workflow), and Material's
    instant-navigation could not render the landing page HTML inside the
    docs shell. Now the icon goes to a real Material docs page.

12. **Replaced `docs/index.md`** JS-redirect hack with a proper Material
    grid-cards welcome page. The redirect approach broke under
    navigation.instant. The welcome page is what local `mkdocs serve`
    shows now (production still overwrites it with the landing page).

Test plan after merge:
  - Open https://selectools.dev on Galaxy S23 in normal Chrome mode
  - Open in Chrome "Desktop Site" mode (this was the hidden gotcha)
  - Verify hamburger menu opens/closes, Esc dismisses, anchor links work
  - Verify all hero buttons are full-width and tappable
  - Verify pip-install button is no longer squeezed
  - Verify no horizontal page scroll on any section
  - Verify code blocks scroll inside their own boxes, not the page
  - Verify comparison tables scroll horizontally with edge gradient hint
  - Verify builder section shows the "open in new tab" CTA, not iframe
  - Verify eval/trace previews fit within iframe without page overflow
  - Verify footer stacks cleanly
  - Verify docs site logo click goes to QUICKSTART, not broken state

NOT in this commit (gitignored):
  - .private/ URL sweep (44 replacements across 14 launch/blog files)
  - .private/launch-prep/gsc-migration-checklist.md (new)
@johnnichev johnnichev merged commit d2b5352 into main Apr 6, 2026
9 checks passed
johnnichev added a commit that referenced this pull request Apr 6, 2026
Addresses the 10 issues from Galaxy S23 testing after PR #41.

Critical: header still showed full nav on mobile because Chrome's "Desktop
Site" mode reports a viewport of ~1280px (not ~980px as initially assumed),
which exceeded the 1024px breakpoint added in PR #41. The fix is to detect
touch input via `@media (pointer: coarse)`, which the Desktop Site toggle
cannot override. This is the only reliable signal for "this is a touch
device, no matter what the viewport pretends to be."

Issues fixed:

1. **Header nav still showing on mobile** — Added @media (pointer: coarse)
   block that forces hamburger + drawer regardless of reported viewport.
   Also removes nav-hide-on-scroll on touch (issue #10): the auto-hide
   stays as a desktop progressive enhancement only.

2. **Hero pill grid felt templated** — Replaced 8 generic pills with a
   cleaner "Works with · OpenAI Anthropic Gemini Ollama" provider strip.
   Each provider gets a small cyan dot prefix. Removed the redundant
   feature pills (Multi-Agent Graphs, 50 Evaluators, etc.) since they
   already appear in the dedicated features section below.

3. **Supervisor agent chips broke into 3+1 layout** — Switched .sim-agents
   to a 2-column CSS grid with `:last-child:nth-child(odd)` selector that
   spans the orphaned last item across both columns. Handles 2/3/4 agent
   counts gracefully.

4. **"What is Selectools?" copy too dense** — Restructured into 3 short
   paragraphs with a visually distinct middle line listing capabilities
   separated by middle-dots. Removed the redundant "Unlike LangChain..."
   framing (the comparison tables already make this case). Closing
   paragraph keeps the brand voice.

5. **Code block scroll indicator** — Added a right-edge gradient mask to
   .code-body matching the comparison table pattern. Signals "more content
   this way" for horizontally-scrollable code. Mask drops on hover/focus
   so users see the full content when engaging. Also reduced code font
   slightly on mobile (12px → 11.5px) for better fit.

6. **Feature cards too tall on mobile** — Compact card layout under
   @media (max-width: 768px), (pointer: coarse): 28px → 20px padding,
   40 → 32px icon, 32 → 14px grid gap. Cards now feel like a tight
   group instead of 1/3-screen blocks with awkward gaps.

7. **"Live · no server required" chip orphaned** — Moved inline with the
   "Visual Agent Builder" section label so it reads as a header annotation
   rather than a floating chip between the description and the card.

8. **Comparison table cells wrapping to 3 lines** — Bumped .cmp-table
   min-width from 640px to 800px so each column has ~115px (enough for
   "macOS desktop app" and "No (desktop only)" to fit on 1-2 lines).
   Added `white-space: nowrap` to .yes/.no/.mid verdict cells so 2-3 char
   answers never wrap awkwardly.

9. **No gap before first builder card in "Three paths"** — Added explicit
   margin-bottom: 64px on the section description and padding-top: 8px
   on the cards container.

10. **Header should always be visible** — Removed the hide-on-scroll-down
    behavior on touch devices (kept on desktop where it's a thoughtful
    progressive enhancement). On mobile the nav now stays fixed at the
    top throughout scrolling, which doubles as a wayfinding aid.

Approach informed by /adapt and /clarify skill guidelines. The
@media (pointer: coarse) pattern is the key insight from /adapt:
viewport-based responsive design is fundamentally fragile because users
can override it (Desktop Site mode, Reader Mode, browser zoom). Touch
input is a hardware property that cannot be spoofed.
johnnichev added a commit that referenced this pull request Apr 6, 2026
#42)

Addresses the 10 issues from Galaxy S23 testing after PR #41.

Critical: header still showed full nav on mobile because Chrome's "Desktop
Site" mode reports a viewport of ~1280px (not ~980px as initially assumed),
which exceeded the 1024px breakpoint added in PR #41. The fix is to detect
touch input via `@media (pointer: coarse)`, which the Desktop Site toggle
cannot override. This is the only reliable signal for "this is a touch
device, no matter what the viewport pretends to be."

Issues fixed:

1. **Header nav still showing on mobile** — Added @media (pointer: coarse)
   block that forces hamburger + drawer regardless of reported viewport.
   Also removes nav-hide-on-scroll on touch (issue #10): the auto-hide
   stays as a desktop progressive enhancement only.

2. **Hero pill grid felt templated** — Replaced 8 generic pills with a
   cleaner "Works with · OpenAI Anthropic Gemini Ollama" provider strip.
   Each provider gets a small cyan dot prefix. Removed the redundant
   feature pills (Multi-Agent Graphs, 50 Evaluators, etc.) since they
   already appear in the dedicated features section below.

3. **Supervisor agent chips broke into 3+1 layout** — Switched .sim-agents
   to a 2-column CSS grid with `:last-child:nth-child(odd)` selector that
   spans the orphaned last item across both columns. Handles 2/3/4 agent
   counts gracefully.

4. **"What is Selectools?" copy too dense** — Restructured into 3 short
   paragraphs with a visually distinct middle line listing capabilities
   separated by middle-dots. Removed the redundant "Unlike LangChain..."
   framing (the comparison tables already make this case). Closing
   paragraph keeps the brand voice.

5. **Code block scroll indicator** — Added a right-edge gradient mask to
   .code-body matching the comparison table pattern. Signals "more content
   this way" for horizontally-scrollable code. Mask drops on hover/focus
   so users see the full content when engaging. Also reduced code font
   slightly on mobile (12px → 11.5px) for better fit.

6. **Feature cards too tall on mobile** — Compact card layout under
   @media (max-width: 768px), (pointer: coarse): 28px → 20px padding,
   40 → 32px icon, 32 → 14px grid gap. Cards now feel like a tight
   group instead of 1/3-screen blocks with awkward gaps.

7. **"Live · no server required" chip orphaned** — Moved inline with the
   "Visual Agent Builder" section label so it reads as a header annotation
   rather than a floating chip between the description and the card.

8. **Comparison table cells wrapping to 3 lines** — Bumped .cmp-table
   min-width from 640px to 800px so each column has ~115px (enough for
   "macOS desktop app" and "No (desktop only)" to fit on 1-2 lines).
   Added `white-space: nowrap` to .yes/.no/.mid verdict cells so 2-3 char
   answers never wrap awkwardly.

9. **No gap before first builder card in "Three paths"** — Added explicit
   margin-bottom: 64px on the section description and padding-top: 8px
   on the cards container.

10. **Header should always be visible** — Removed the hide-on-scroll-down
    behavior on touch devices (kept on desktop where it's a thoughtful
    progressive enhancement). On mobile the nav now stays fixed at the
    top throughout scrolling, which doubles as a wayfinding aid.

Approach informed by /adapt and /clarify skill guidelines. The
@media (pointer: coarse) pattern is the key insight from /adapt:
viewport-based responsive design is fundamentally fragile because users
can override it (Desktop Site mode, Reader Mode, browser zoom). Touch
input is a hardware property that cannot be spoofed.
@johnnichev johnnichev deleted the fix/mobile-responsive-pass branch April 8, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant