|
| 1 | +import { useMediaQuery, PHONE_QUERY } from './useMediaQuery.js'; |
| 2 | + |
1 | 3 | export type GridMode = 'living' | 'mood' | 'forge' | 'ecology' | 'divergence'; |
2 | 4 |
|
3 | 5 | /** Hints are scenario-templated. `{people}` = plural population noun, |
@@ -48,6 +50,49 @@ export function GridModePills({ |
48 | 50 | counts?: Partial<Record<GridMode, number>>; |
49 | 51 | labels: { person: string; people: string; Person: string; People: string }; |
50 | 52 | }) { |
| 53 | + const isPhone = useMediaQuery(PHONE_QUERY); |
| 54 | + |
| 55 | + // On phone viewports the 5-pill row was horizontally scrollable but |
| 56 | + // ate ~44px of vertical chrome + always required the user to swipe |
| 57 | + // sideways to see DIVERGENCE / ECOLOGY. Native <select> renders the |
| 58 | + // current mode + a tap target that opens the system picker — cleaner |
| 59 | + // and reclaims the row for actual viz content. |
| 60 | + if (isPhone) { |
| 61 | + return ( |
| 62 | + <select |
| 63 | + aria-label="Grid viz mode" |
| 64 | + value={mode} |
| 65 | + onChange={(e) => onChange(e.target.value as GridMode)} |
| 66 | + title={interpolate(MODES.find(m => m.key === mode)?.hint ?? '', labels)} |
| 67 | + style={{ |
| 68 | + width: '100%', |
| 69 | + padding: '8px 10px', |
| 70 | + fontSize: 16, // iOS Safari zoom-on-focus threshold |
| 71 | + fontFamily: 'var(--mono)', |
| 72 | + fontWeight: 800, |
| 73 | + letterSpacing: '0.08em', |
| 74 | + textTransform: 'uppercase', |
| 75 | + background: 'var(--bg-card)', |
| 76 | + color: 'var(--text-1)', |
| 77 | + border: '1px solid var(--border)', |
| 78 | + borderRadius: 6, |
| 79 | + cursor: 'pointer', |
| 80 | + minHeight: 44, // WCAG 2.5.5 target size |
| 81 | + }} |
| 82 | + > |
| 83 | + {MODES.map((m) => { |
| 84 | + const count = counts?.[m.key]; |
| 85 | + const countSuffix = typeof count === 'number' && count > 0 ? ` · ${count}` : ''; |
| 86 | + return ( |
| 87 | + <option key={m.key} value={m.key}> |
| 88 | + {m.label}{countSuffix} |
| 89 | + </option> |
| 90 | + ); |
| 91 | + })} |
| 92 | + </select> |
| 93 | + ); |
| 94 | + } |
| 95 | + |
51 | 96 | return ( |
52 | 97 | <div |
53 | 98 | role="tablist" |
|
0 commit comments