Emergency Hotline: Call 1-844-363-1423 (United We Dream Hotline)
ICE Encounter

Navigation Architecture at Scale

As page count eclipses 200, traditional hierarchical dropdown menus become a severe usability liability. They hide options until explicit hover actions, force reliance on short-term memory, and trigger cascading usability failures with imprecise cursor movements.


Mega-Menu Implementation

Mega-menus are imperative for a 223-page architecture. By exposing the full breadth of a macro-category simultaneously, users can visually compare all available choices without friction.

Desktop Mega-Menu Specifications

Feature Implementation
Two-Dimensional Layout Options grouped logically within large drop-down panel
Visual Anchors Subtle iconography for high-priority items
Featured Content Highlighted CTAs (e.g., "Know Your Rights" printable)
Whitespace Ample spacing to denote hierarchy vs. nested indentations
<nav class="mega-nav" aria-label="Main navigation">
  <ul class="mega-nav__list">
    <li class="mega-nav__item">
      <button class="mega-nav__trigger"
              aria-expanded="false"
              aria-controls="menu-emergency">
        Emergency Help
      </button>
      <div class="mega-nav__panel" id="menu-emergency" hidden>
        <div class="mega-nav__columns">
          <div class="mega-nav__column">
            <h3>Immediate Help</h3>
            <ul>
              <li><a href="/printables/red-card/">Red Card</a></li>
              <li><a href="/emergency/hotlines/">Crisis Hotlines</a></li>
            </ul>
          </div>
          <div class="mega-nav__column">
            <h3>Rapid Response</h3>
            <ul>
              <li><a href="/resources/legal-observer/">Legal Observer</a></li>
              <li><a href="/resources/coalition/">Find Local Network</a></li>
            </ul>
          </div>
          <div class="mega-nav__featured">
            <a href="/printables/" class="mega-nav__cta">
              Download All Printables →
            </a>
          </div>
        </div>
      </div>
    </li>
    <!-- Additional menu items -->
  </ul>
</nav>

Mega-Menu Accessibility (WCAG)

Requirement Implementation
Keyboard Navigation Tab and Enter support
ARIA Roles aria-expanded, aria-controls, aria-haspopup
Focus Trapping Focus remains within menu until dismissed
Escape Key Closes menu and returns focus to trigger
// Mega-menu keyboard handling
const megaNav = document.querySelector('.mega-nav');

megaNav.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') {
    closeAllPanels();
    document.activeElement.closest('.mega-nav__item')
      ?.querySelector('.mega-nav__trigger')?.focus();
  }
});

function closeAllPanels() {
  megaNav.querySelectorAll('.mega-nav__panel').forEach(panel => {
    panel.hidden = true;
    panel.previousElementSibling.setAttribute('aria-expanded', 'false');
  });
}

Mobile Navigation Patterns

Navigating 223 pages on a 375-pixel viewport requires strict spatial economy. The traditional hamburger menu is critically insufficient for deep hierarchies if implemented as a single, endlessly scrolling vertical list.

Accordion Progression

The mobile menu must utilize a nested accordion structure. Tapping a macro-category expands sub-sections inline, pushing other items down rather than forcing page loads.

<nav class="mobile-nav" aria-label="Mobile navigation">
  <div class="mobile-nav__accordion">
    <details class="mobile-nav__section">
      <summary class="mobile-nav__trigger">
        Emergency Help
        <span class="mobile-nav__count">12 resources</span>
      </summary>
      <ul class="mobile-nav__links">
        <li><a href="/printables/red-card/">Red Card</a></li>
        <li><a href="/emergency/hotlines/">Crisis Hotlines</a></li>
        <li><a href="/resources/legal-observer/">Legal Observer</a></li>
      </ul>
    </details>

    <details class="mobile-nav__section">
      <summary class="mobile-nav__trigger">
        Know Your Rights
        <span class="mobile-nav__count">22 guides</span>
      </summary>
      <!-- Nested subsections -->
    </details>
  </div>
</nav>
.mobile-nav__section {
  border-bottom: 1px solid var(--color-border);
}

.mobile-nav__trigger {
  display: flex;
  justify-content: space-between;
  padding: 1rem;
  font-weight: 600;
  cursor: pointer;
}

.mobile-nav__section[open] .mobile-nav__trigger {
  background: var(--color-highlight);
}

.mobile-nav__links {
  padding: 0 1rem 1rem;
}

.mobile-nav__links a {
  display: block;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border-light);
}

Sticky Bottom Navigation for Crisis

Emergency resources must bypass standard menu interaction entirely. A persistent sticky bottom bar ensures zero-click discovery during high-stress scenarios.

<nav class="crisis-bar" aria-label="Emergency actions">
  <a href="/emergency/" class="crisis-bar__item crisis-bar__item--emergency">
    <span class="crisis-bar__icon">🆘</span>
    <span class="crisis-bar__label">Emergency</span>
  </a>
  <a href="tel:+18001234567" class="crisis-bar__item">
    <span class="crisis-bar__icon">📞</span>
    <span class="crisis-bar__label">Hotline</span>
  </a>
  <a href="/printables/red-card/" class="crisis-bar__item">
    <span class="crisis-bar__icon">🔴</span>
    <span class="crisis-bar__label">Red Card</span>
  </a>
</nav>
.crisis-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  background: var(--color-surface);
  padding: 0.5rem 0 env(safe-area-inset-bottom);
  box-shadow: 0 -2px 10px rgba(0,0,0,0.15);
  z-index: 1000;
}

.crisis-bar__item--emergency {
  background: var(--color-error);
  color: white;
  border-radius: 8px;
  padding: 0.5rem 1rem;
}

Sectional Sidebars (In-Page Navigation)

For mid-level navigation within 7-12 page resource sections, a top-anchored "In This Section" dropdown replaces the desktop sidebar on mobile.

<nav class="section-nav" aria-label="Section navigation">
  <details class="section-nav__dropdown">
    <summary class="section-nav__trigger">
      In This Section: Facility Monitoring
      <span class="section-nav__chevron">▼</span>
    </summary>
    <ul class="section-nav__links">
      <li><a href="./overview/">Overview</a></li>
      <li><a href="./data-sources/" aria-current="page">Data Sources</a></li>
      <li><a href="./monitoring-tools/">Monitoring Tools</a></li>
    </ul>
  </details>
</nav>
.section-nav {
  position: sticky;
  top: 0;
  background: var(--color-surface);
  z-index: 100;
  border-bottom: 1px solid var(--color-border);
}

.section-nav__trigger {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 1rem;
  font-weight: 600;
}

.section-nav__dropdown[open] .section-nav__chevron {
  transform: rotate(180deg);
}

Mobile Usage in Immigrant Communities

Smartphone reliance within immigrant communities is exceptionally high. Research shows up to 98% of specific demographics utilize mobile devices for internet access, often as their sole digital conduit.

Smartphones have transitioned from auxiliary communication devices to the primary mechanism for navigating legal systems, submitting applications, and storing crucial documentation.


Design Constraints

Technical Realities

Constraint Impact
Prepaid data plans Limited monthly data allocation
Older Android devices Slower processors, less RAM
3G connectivity Rural border areas, detention peripheries
Intermittent connection Spotty coverage during travel

Design Implications

Mobile-first design must encompass:

  1. Strict data conservation
  2. Performance budgeting
  3. Offline resilience
  4. One-handed operation

Thumb-Zone Navigation

During an active encounter with law enforcement, users likely have only one hand free. Interface design must respect the "Thumb Zone."

Zone Mapping

Zone Location Content Type
Green (Easy) Lower center Primary actions, emergency buttons
Yellow (Stretch) Sides, upper center Secondary navigation
Red (Hard) Top corners Destructive actions, settings

Implementation

/* Position critical actions in thumb zone */
.emergency-actions {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 1rem;
  display: flex;
  gap: 1rem;
}

.action-button--primary {
  min-height: 56px; /* Larger than standard */
  min-width: 56px;
  padding: 1rem 1.5rem;
  font-size: 1.125rem;
}

Touch Target Sizes

Standard Minimum Size Advocacy Recommendation
Apple HIG 44px 56px for emergency actions
Google Material 48dp 56dp for crisis interfaces
WCAG 44×44px 56×56px under stress
/* Emergency button sizing */
.button--emergency {
  min-width: 56px;
  min-height: 56px;
  padding: 1rem;

  /* Prevent accidental double-tap */
  touch-action: manipulation;
}

/* Spacing to prevent mis-taps */
.button-group {
  gap: 12px; /* Minimum spacing between targets */
}

Progressive Web App (PWA)

Service Worker Strategy

Critical "Know Your Rights" materials must remain accessible during total connectivity loss.

// sw.js - Service Worker
const CACHE_NAME = 'advocacy-v1';
const CRITICAL_URLS = [
  '/',
  '/emergency/',
  '/know-your-rights/',
  '/printables/red-card/',
  '/css/main.css',
  '/js/app.js'
];

// Install: cache critical resources
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(CRITICAL_URLS))
  );
});

// Fetch: serve from cache, update in background
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        // Return cache, fetch update in background
        const fetchPromise = fetch(event.request)
          .then(networkResponse => {
            caches.open(CACHE_NAME)
              .then(cache => cache.put(event.request, networkResponse.clone()));
            return networkResponse;
          });

        return response || fetchPromise;
      })
  );
});

Caching Strategies by Content Type

Content Type Strategy Rationale
App Shell Cache-first Load instantly regardless of connection
KYR Text Stale-while-revalidate Immediate offline, silent updates
Form Submissions Background Sync Queue locally, transmit when online
Real-time Data Network-first Fresh data paramount, cache fallback

Manifest Configuration

{
  "name": "Immigration Rights Guide",
  "short_name": "Rights Guide",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#1a1a2e",
  "theme_color": "#4361ee",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

Offline Indicators

Clear offline indicators reassure users that cached content remains accurate:

<div class="offline-banner" role="alert" hidden>
  <span class="offline-icon" aria-hidden="true"></span>
  <p>You're offline. This page is saved and accurate.</p>
</div>
// Show/hide offline indicator
window.addEventListener('online', () => {
  document.querySelector('.offline-banner').hidden = true;
});

window.addEventListener('offline', () => {
  document.querySelector('.offline-banner').hidden = false;
});

Graceful Degradation

// Check connectivity before critical actions
async function submitReport(data) {
  if (!navigator.onLine) {
    // Queue for later
    await queueForSync(data);
    showNotification('Report saved. Will submit when online.');
    return;
  }

  // Normal submission
  await fetch('/api/report', {
    method: 'POST',
    body: JSON.stringify(data)
  });
}

Data Conservation

Image Optimization

<!-- Responsive images with modern formats -->
<picture>
  <source srcset="/images/hero.avif" type="image/avif">
  <source srcset="/images/hero.webp" type="image/webp">
  <img src="/images/hero.jpg"
       alt="Community support"
       loading="lazy"
       decoding="async"
       width="800"
       height="450">
</picture>

Lazy Loading Strategy

<!-- Critical images: eager load for LCP -->
<img src="/images/hero.webp" loading="eager">

<!-- Below fold: lazy load -->
<img src="/images/content.webp" loading="lazy">

Font Optimization

/* System font stack for zero font download */
.body-text {
  font-family: -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, Oxygen, Ubuntu,
               sans-serif;
}

/* Subset fonts for specific languages */
@font-face {
  font-family: 'Noto Sans';
  src: url('/fonts/noto-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF; /* Latin only */
  font-display: swap;
}

Core Web Vitals Targets

Performance Budgets

Metric Target Measurement
LCP < 2.5s 75th percentile mobile
FID/INP < 100ms Responsive to panic inputs
CLS < 0.1 No accidental mis-taps

JavaScript Budget

Resource Budget
Total JS < 100KB compressed
Critical JS < 20KB inline
Deferred JS Lazy load on interaction

CSS Budget

Resource Budget
Critical CSS < 14KB inline
Full CSS < 50KB
Above-fold Inline in <head>

3G Network Optimization

Preload Critical Resources

<head>
  <!-- Preload critical fonts -->
  <link rel="preload" href="/fonts/noto-latin.woff2"
        as="font" type="font/woff2" crossorigin>

  <!-- Preload critical CSS -->
  <link rel="preload" href="/css/critical.css" as="style">

  <!-- DNS prefetch for external resources -->
  <link rel="dns-prefetch" href="//tile.openstreetmap.org">
</head>

Connection-Aware Loading

// Adapt to connection quality
const connection = navigator.connection || {};
const effectiveType = connection.effectiveType || '4g';

if (effectiveType === '2g' || effectiveType === 'slow-2g') {
  // Disable non-critical images
  document.querySelectorAll('img[data-optional]')
    .forEach(img => img.remove());

  // Use text-only map alternative
  document.querySelector('.map-container').hidden = true;
  document.querySelector('.map-text-alternative').hidden = false;
}

Mobile Navigation Patterns

Bottom Navigation

<nav class="bottom-nav" aria-label="Main navigation">
  <a href="/emergency/" class="bottom-nav__item">
    <span class="bottom-nav__icon" aria-hidden="true"></span>
    <span class="bottom-nav__label">Emergency</span>
  </a>
  <a href="/know-your-rights/" class="bottom-nav__item">
    <span class="bottom-nav__icon" aria-hidden="true"></span>
    <span class="bottom-nav__label">Rights</span>
  </a>
  <a href="/find-help/" class="bottom-nav__item">
    <span class="bottom-nav__icon" aria-hidden="true"></span>
    <span class="bottom-nav__label">Find Help</span>
  </a>
</nav>
.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  background: var(--color-surface);
  padding: 0.5rem 0 env(safe-area-inset-bottom);
  box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
}

.bottom-nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.75rem;
  min-width: 64px;
  min-height: 56px;
}

Swipe Gesture Caution

Swipe gestures are learned behaviors that degrade under panic. Never require swiping for critical actions:

// Supplement swipe with visible buttons
carousel.addEventListener('swipe', handleSwipe);

// Always show navigation buttons
<button class="carousel-prev">Previous</button>
<button class="carousel-next">Next</button>

Testing Checklist

Device Testing

  • [ ] Tested on 3-year-old Android device
  • [ ] Tested on throttled 3G connection
  • [ ] Tested with airplane mode (offline)
  • [ ] Tested one-handed operation
  • [ ] Tested with large text accessibility setting

Performance Testing

  • [ ] Lighthouse mobile score > 90
  • [ ] LCP < 2.5s on 3G
  • [ ] Total page weight < 500KB
  • [ ] PWA installable
  • [ ] Offline mode functional

Related Resources