- Added 'navbarReady' event dispatch from navbar after rendering
- Language selector now waits for navbar container to exist
- Fixes race condition where language selector ran before navbar rendered
- Language toggle now functional on researcher, implementer, leader, about pages
- Create Economist SubmissionTracking package correctly:
* mainArticle = full blog post content
* coverLetter = 216-word SIR— letter
* Links to blog post via blogPostId
- Archive 'Letter to The Economist' from blog posts (it's the cover letter)
- Fix date display on article cards (use published_at)
- Target publication already displaying via blue badge
Database changes:
- Make blogPostId optional in SubmissionTracking model
- Economist package ID: 68fa85ae49d4900e7f2ecd83
- Le Monde package ID: 68fa2abd2e6acd5691932150
Next: Enhanced modal with tabs, validation, export
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
UX Simplification:
- Remove dropdown selector completely (was causing rendering conflicts)
- Use icon-only buttons on ALL devices (mobile and desktop)
- Show all 4 languages: 🇬🇧 English, 🇩🇪 Deutsch, 🇫🇷 Français, 🇳🇿 Te Reo Māori
- Māori button shows as disabled with "Planned" tooltip
Technical Changes:
- Eliminate all responsive breakpoint logic (md:hidden, md:block, md:flex)
- Single unified rendering path for all screen sizes
- Removed desktop dropdown and associated event handlers
- Simplified to one flex container with 4 icon buttons
- Active state management works across all buttons including disabled
Fixes:
- Resolves persistent issue where both dropdown and icons appeared on desktop
- Eliminates Tailwind responsive class conflicts
- Consistent UX across all devices
- Better touch targets (44x44px) on all platforms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Issue Confirmed by User:
- After F12 cache clear, initial load works
- BUT on desktop, both dropdown AND icons are rendering together
- Expected: Desktop shows ONLY dropdown, Mobile shows ONLY icons
Previous Attempt Failed:
- Desktop: `hidden md:flex md:relative`
- Mobile: `flex gap-1 md:hidden`
- Problem: `flex` as base class on mobile container created specificity conflict
- Both containers showed on desktop despite `md:hidden`
Root Cause:
- Mixing layout classes (flex) with visibility classes (hidden) on same element
- Tailwind applies base styles first, then responsive modifiers
- `flex` set display:flex, then `md:hidden` tried to override
- CSS specificity and cascade caused unpredictable behavior
Solution - Separate Display Control from Layout:
Desktop Container:
```html
<div class="hidden md:block"> <!-- Display control -->
<div class="relative"> <!-- Layout/positioning -->
<select>...</select>
</div>
</div>
```
Mobile Container:
```html
<div class="block md:hidden"> <!-- Display control -->
<div class="flex gap-1"> <!-- Layout -->
...buttons...
</div>
</div>
```
Why This Works:
1. Parent divs ONLY control visibility (hidden/block/md:hidden/md:block)
2. Child divs ONLY control layout (relative/flex/gap)
3. No conflicting display properties on same element
4. Clean separation of concerns
5. Predictable Tailwind cascade behavior
Behavior:
- Mobile (<768px):
- Desktop container: `hidden` (not visible) ✓
- Mobile container: `block` (visible) ✓
- Desktop (≥768px):
- Desktop container: `md:block` (visible) ✓
- Mobile container: `md:hidden` (not visible) ✓
Technical Notes:
- `hidden` = display: none !important (base)
- `md:block` = display: block at ≥768px
- `md:hidden` = display: none !important at ≥768px
- No flex/relative on visibility-controlling elements
- Nested structure ensures proper cascade
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Critical Issue:
- Desktop showed NOTHING on initial load after cache clear
- Then both dropdown AND icons appeared together
- Expected: Desktop = dropdown ONLY, Mobile = icons ONLY
Root Cause Analysis:
1. Wrapper div `language-selector` had no display control
2. Nested structure with `hidden md:block` on desktop container
3. Nested structure with `md:hidden` wrapping flex container on mobile
4. Tailwind `hidden` class uses `display: none !important`
5. Complex nesting caused CSS specificity and timing issues
6. Both containers fought for visibility control
Previous Structure (BROKEN):
```html
<div class="language-selector">
<!-- Desktop -->
<div class="hidden md:block md:relative">
<select>...</select>
</div>
<!-- Mobile -->
<div class="md:hidden">
<div class="flex gap-1">
...buttons...
</div>
</div>
</div>
```
New Structure (FIXED):
```html
<!-- Desktop - Direct sibling -->
<div class="hidden md:flex md:relative">
<select>...</select>
</div>
<!-- Mobile - Direct sibling -->
<div class="flex gap-1 md:hidden">
...buttons...
</div>
```
Key Improvements:
1. Removed wrapper div - eliminated ambiguity
2. Made both containers direct siblings in parent
3. Desktop: `hidden md:flex md:relative`
- hidden on mobile (display: none)
- flex on desktop (display: flex at md+)
- relative positioning only on desktop
4. Mobile: `flex gap-1 md:hidden`
- flex with gap on mobile (display: flex)
- hidden on desktop (display: none at md+)
5. Removed extra nested div wrappers
6. Each container explicitly controls own visibility AND layout
Technical Details:
- Tailwind mobile-first: base = mobile, md: = desktop (≥768px)
- `hidden` = display: none !important (all sizes)
- `md:flex` = display: flex at ≥768px
- `md:hidden` = display: none at ≥768px
- Using `flex` instead of `block` for better layout control
- Siblings don't interfere with each other's display logic
Result:
- Desktop (≥768px): Dropdown visible (flex), Icons hidden ✓
- Mobile (<768px): Icons visible (flex), Dropdown hidden ✓
- Clean, predictable behavior with no timing issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Issue:
- After cache clear, desktop was showing BOTH dropdown AND icon buttons
- Mobile was correctly showing only icon buttons
- Expected: Desktop = dropdown only, Mobile = icons only
Root Cause:
- Tailwind responsive classes were conflicting
- `flex md:hidden gap-1` applied flex at all times, then hid at md+
- `relative` was unconditionally applied to desktop dropdown container
- Separation of concerns was unclear between visibility and layout
Fix Applied:
1. Desktop dropdown container:
- Before: `class="hidden md:block relative"`
- After: `class="hidden md:block md:relative"`
- Now `relative` only applies at md+ breakpoint
2. Mobile icons container:
- Before: `class="flex md:hidden gap-1"` (single div)
- After: `class="md:hidden"` wrapping `class="flex gap-1"` (nested divs)
- Separated visibility control from layout control
- Parent div: controls visibility (hidden at md+)
- Child div: controls layout (flex with gap)
Technical Explanation:
- Tailwind mobile-first: Base styles apply to all, md: applies at ≥768px
- `hidden md:block` = hidden by default, block at md+
- `md:hidden` = visible by default, hidden at md+
- Nesting clarifies intent and prevents class conflicts
Result:
- Desktop (≥768px): Dropdown visible, icons hidden ✓
- Mobile (<768px): Icons visible, dropdown hidden ✓
Deployment:
- language-selector.js deployed to production
- Cache-busting version already in place (?v=0.1.0.1760643941)
- Users should see correct behavior after hard refresh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Mobile UX Improvements:
- Replace dropdown with icon-only buttons on mobile (<768px)
- Show flag icons (🇬🇧🇩🇪🇫🇷) with 44x44px touch targets
- Preserve dropdown with text on desktop (≥768px)
- Add visual feedback for active language selection
- Responsive design using Tailwind md: breakpoint
Pages Updated:
- Add i18n support to researcher.html
- Add i18n support to leader.html
- Add i18n support to implementer.html
- Add i18n support to about.html
- Add i18n support to faq.html
Technical Changes:
- Dual rendering: desktop dropdown + mobile icon buttons
- Event handlers for both desktop select and mobile buttons
- Active state management with visual indicators
- Accessibility: aria-labels and tooltips on icons
- Auto-refresh selector on language change
Mobile Optimization:
- Reduced navbar crowding on small screens
- Better touch targets (min 44x44px)
- Clear visual feedback for language selection
- No text truncation on mobile
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Mobile UX Improvements:
- Replace dropdown with icon-only flags on mobile (< 768px)
- Add 44x44px touch targets for better mobile interaction
- Add language selector to mobile menu drawer
- Desktop keeps full dropdown with language names (≥ 768px)
Language Selector Features:
- Mobile navbar: Icon-only buttons (🇬🇧🇩🇪🇫🇷)
- Desktop navbar: Dropdown with full text
- Mobile drawer: Full language list with checkmarks
- Active state: Blue ring around selected language
- Auto-close drawer after language selection
Accessibility:
- ARIA labels on all buttons
- aria-pressed state for current language
- Minimum 44x44px touch targets (WCAG AA)
- Keyboard navigation support maintained
- Screen reader support with role="group"
Technical Changes:
- language-selector.js: Rewritten with responsive versions
- navbar.js: Added mobile-menu-language-selector container
- i18n-simple.js: Added languageChanged event dispatch
UX Benefits:
- Space savings: ~87px saved in mobile navbar
- No crowding between language selector and hamburger menu
- Flag emojis are universally recognizable
- Touch-friendly buttons meet iOS/Android standards
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>