responsive-fix
Fix responsive/mobile layout issues (320px → desktop) in the MyJKKN app with CSS-only changes — horizontal overflow, clipped/overlapping elements, floating-button (FAB) collisions, unreadable text, an
SKILL.md.claude/skills/responsive-fix/SKILL.md
GitHubResponsive Fix — MyJKKN
Fix mobile/responsive layout bugs in this Next.js 15 + Tailwind CSS project with surgical, CSS-only changes. This skill exists because responsive fixes here have strict scope rules: the app is a shared production project, and the user allows ONLY visual/layout corrections — nothing else may change.
Invocation contract (read first)
This skill runs ONLY when the user explicitly invoked it. If you loaded this skill without the user naming it (e.g. they merely said "the page looks broken on mobile"), stop and handle the request normally without these instructions.
The user typically provides: a page path (e.g. /dashboard), a screenshot,
and/or a description like "320px la adi vangudhu" (broken at 320px). If no page
or component is named, ask which page to fix before touching anything.
Hard constraints (non-negotiable)
- CSS/className changes only. Never modify texts, labels, workflows, business logic, data fetching, handlers, imports of behavior, or other modules' code. If a real fix seems to require a logic change, STOP and ask.
- Only the named target. Fix only the page/component the user pointed at. If the root cause lives in a shared component (Navbar, BottomNav, a FAB), that's allowed — but explicitly tell the user it is shared and affects all pages, before or immediately with the fix.
- Root cause + math first. Before editing, state the cause with numbers (e.g. "6 items × min-w-[56px] = 336px > 320px viewport → last item clips"). Never apply a fix you can't explain arithmetically.
- Minimal diff. Prefer editing existing className strings over adding wrappers, new components, or new CSS files.
Definition of "responsive" (acceptance criteria)
A screen passes when ALL of these hold from 320px up to desktop:
- No horizontal scroll on the document at any width.
- No overlapping or cut-off content — including fixed/floating elements.
- Nothing overflows its own section/box — texts and buttons must stay
inside their containing card/section/container at every width (320px up).
No label, button, or child element may spill past its parent's border. Cure
per element: buttons in a row →
flex-wrap(or stackflex-colthensm:flex-row); long text →min-w-0+truncate/break-words; the button that must not shrink →shrink-0; genuinely wide content (tables, tab strips) → wrap the container inoverflow-x-autoso the box scrolls, not the page. - Readable text — nothing below ~10px; long text truncates with ellipsis
(
truncate+min-w-0) instead of clipping or forcing overflow. - Touch-friendly targets — interactive elements keep ≥ ~44px effective tap
area on touch layouts (Tailwind
h-11/w-11≈ 44px).
Test mentally (or in browser when available) at: 320, 375, 640 (sm), 768 (md), 1024 (lg), desktop.
Diagnostic playbook
Work through these known failure classes — they cover nearly every mobile bug seen in this codebase:
1. Horizontal overflow (page scrolls sideways)
Find the widest row of fixed-width items. Common causes and cures:
- Flex row where items can't shrink → add
min-w-0to the shrinkable item (usually the title/text) andshrink-0to icons/buttons that must not squish; give texttruncate. - Fixed min-widths that don't fit:
N items × min-w > 320→ make the min-width responsive (min-w-0 sm:min-w-[56px]). - Fixed pixel widths (
w-[400px]) →w-full max-w-[400px]. - Wide tables/charts → wrap in
overflow-x-auto(the container scrolls, the page does not).
2. Fixed/floating element collisions (FABs, banners, bottom nav)
- Position floating elements with CSS breakpoints, never user-agent
sniffing. A
isMobileDevice()check and alg:hiddennav WILL disagree (DevTools emulation, tablets) and cause overlap. Match the exact breakpoint of the element being avoided: nav islg:hidden→ FAB usesbottom-[Xrem] lg:bottom-4. - To align a FAB with others, compute centers:
center = bottom + height/2, then solve for the newbottom. State the math. - Keep each element's existing z-index hierarchy; don't invent new z values.
3. Header/toolbar rows too wide
Pattern proven in components/Navbar/Navbar.tsx: left cluster gets
min-w-0 flex-1 + title truncate; right cluster gets shrink-0; gaps and
paddings shrink at base and restore at sm: (space-x-1 sm:space-x-2,
px-3 on compact buttons).
4. Grids/cards breaking at small widths
Mobile-first stacking: grid-cols-1 sm:grid-cols-2 lg:grid-cols-4. Never let
a card enforce a min-width larger than ~288px (320 − page padding).
Workflow
- Identify — restate the reported issue; open the named page/component.
- Locate root cause — grep/read for the offending classes; verify with the arithmetic from the playbook above.
- Fix minimally — CSS/className only, mobile-first (
basestyles for 320px, thensm: md: lg:restore larger-screen appearance so desktop is pixel-identical to before). - Self-check — recompute widths at 320px; confirm desktop classes
(
sm:/lg:values) reproduce the pre-fix layout exactly. - Hand back — list changed files with line references, the cause, the math, and ask the user to re-test; fix further only what they report.
Verification math examples
- Bottom nav: 6 ×
min-w-[56px]= 336 > 320 → clip. Fixmin-w-0 sm:min-w-[56px]→ 6 × ~53px = 318 ≤ 320. ✓ - FAB alignment: red center 136+24=160, yellow center 80+24=104 → pair center
132 → green (44px tall) bottom = 132−22 = 110px =
bottom-[6.875rem]. ✓ - Header: fixed items 40+85+160+margins ≈ 410 > 320 → title must be the
flexible item (
min-w-0 flex-1+truncate). ✓