Skip to content
Signal

Platforms

HIG rules and audit

The HIG rules Signal follows, and every surface audited against them.

Rules

HIG as of 1 Oct 2026. The date in brackets is each page's latest change-log entry.

TopicHIG rulev3 value
Tap targets [Jun 2025]44 × 44 pt default, 28 × 28 pt minimum44 × 44 minimum on every control
Dynamic Type [Dec 2025]Body 17 pt default, 11 pt minimum. Custom fonts support Dynamic Type and Bold Text. Icons scale with text. Large Title 34, Title 3 20, Body 17, Footnote 13, Caption 2 11.Display 32 / Title 20 / Body 16 / Sub 13 / Cap 11, each relativeTo:
Liquid Glass [Sep 2025]Glass is for controls and navigation, not the content layer. Use it sparingly on custom controls.Opaque surfaces
Sheets [Mar 2026]Medium detent on iPhone. A resizable sheet has a grabber, and the grabber works with VoiceOver. Nonmodal is allowed.No native stop sheet. The Map panel and the pushed stop detail share one FloatingPanel: 132 / 50% / top + 4, with an adjustable grabber
Tab bars [Jun 2026]Navigation only. Visible except under a modal. Floats on Liquid Glass. Search tab at the trailing end.Native TabView: Home, Map, Search
Toolbars [Dec 2025]Back and Close in the bar. Symbols preferred. Group items.Settings toolbar item
Search [Jun 2026]Standard search tab: a landing page with the field at the top, keyboard on tapSearch-role tab, unfocused on entry
Alerts [Feb 2024]Don't use an alert merely to provide informationSystem alert for service alerts
Maps [Dec 2024]System map controls. Custom controls need contrast.System .mapControls
Widgets [Dec 2025]16 pt margin. Accented, clear and vibrant modes. Interaction through buttons and toggles only.Widgets + Live Activities
Live Activities [Dec 2025]14 pt Lock Screen margin. Essential actions only. StandBy at 2×.Approved v3 Live Activity spec
iPhone Duo [Sep 2026]Build to resize. Bars move to the side. Respect reserved regions. Don't override the default bar placement.Readiness checklist
Accessibility [Jun 2025]Contrast in both appearances. Not colour alone. Reduce Motion. Every control labelled.AA contrast, status as a word

Surfaces against the HIG

chitransit-app main 82560e7 (#97 map perf, #98 tabs + Map panel); stop detail, Map panel content and grabber rows at 3a3db9c (#102). Paths are relative to chitransit-app/. Rationale: docs/specs/ios-design.md.

CompliantDeviationGapn/a
SurfaceHIG rulev3 specApp todayStatusGap
Tab barNavigation only, Liquid Glass, search tab trailingTabView: Home, Map, SearchTab API on iOS 18+ (views/MainView.swift:128-142), .tabItem fallback (:144-158)Compliant—
Tab bar visibilityVisible except under a modal—Visible on every tab, including the stop detail pushed from Home or Search (views/StopView.swift:38-121)CompliantG5 (resolved)
Search tabStandard search tabSearch-role tab, unfocused.searchable(.navigationBarDrawer(.always)) (views/GlobalSearchView.swift:221-226)Compliant—
Map controlsSystem controlsSystem .mapControlsLocation, pitch, compass and scale (views/MapView.swift:705-710). The custom overlay is DEBUG-only.Compliant—
Map panel anchorsMedium detent for progressive disclosureLow 180 (Nearby 120) · half 50% · full top + 4FloatingPanel 3.2.4: .tip 180 absolute (120 on Nearby), .half 0.50 fractional, .full top + 4, all in .safeArea; Search is full only (views/Sheet/SheetPanels.swift:19-44). Removal is disabled (:585).Compliant—
Map panel grabberThe grabber works with VoiceOverGrabber 40 × 5A 44 pt adjustable element over the grabber: Panel position, Collapsed / Half / Expanded, Expand and Collapse actions, Escape collapses one anchor (views/MapPanelView.swift:222-264)CompliantG2 (resolved)
Map panel motionRespect Reduce MotionMotion off under Reduce MotionOne shared sheet spring (0.42 s, bounce 0.15) for drags, detent moves and the station slide; under Reduce Motion it becomes 0.17 s critically damped, or a 0.17 s fade for the station slide (utils/DesignTokens.swift, views/Sheet/SheetPanels.swift).CompliantG10 (resolved)
Map panel surfaceGlass for controls only. Don't hide system glass.Paper, 28 pt radius, sheet shadowPaper, radius 28 with continuous corners, shadow 0 −10 30 at 16% (views/MapView.swift:348-363)DeviationG9 (decided)
Map panel content—Nearby, or the selected station with an X. Peek: summary. Half: direction and its static arrivals. Full: everything (#68).Three presentations: peek summary, half arrivals, full details (views/StopView.swift:242-258, 409-455, 495). Only full expands timelines.CompliantG11 (resolved)
Map avoids the panelUse safe areas—.safeAreaPadding(.bottom, panelCoveredHeight), driven by the panel state (views/MapView.swift:504, 605-612)CompliantG3 on Duo
Stop detail (Home / Search)Push in the tab’s stack; tab bar stays visiblePushed page: a map under the shared panel, above the visible tab barPushed StopItemView: a map under the shared FloatingPanel layout and grabber, not removable, opens at half; the tab bar stays visible. Only the 44 pt grabber drags the surface, so the body scrolls and pulls to refresh (views/StopView.swift:22-35, 85-121)CompliantG5 (resolved)
Station header44 pt targets, Dynamic TypeDisplay title, 44 pt close and actionsCustom SheetHeaderButton X, 44 × 44, labelled “Close stop detail” (views/StopView.swift:524-541)Compliant—
Toolbar itemsBack and Close semantic. Icon and title on each item.—Settings .topBarTrailing Label. Custom Back .topBarLeading (views/StopView.swift:77). Done is text-only (views/HomeView.swift:265-275).GapG6
Cards and rows44 pt targetsPadding 14, radius 12, rows at least 64Matches. Edit / Done uses .padding(.vertical, -12) (views/FavoritesView.swift:212).CompliantG16
Live tracking feedbackCommunicate in contextBanner removed (#67)Inline Home sections, no banner (views/FavoritesView.swift:245-285)Compliant—
Type scaleBody 17, minimum 11, Bold TextBody 16, Display 32Figtree relativeTo:. No legibilityWeight handling.DeviationG14
Icon scalingIcons scale with text—Fixed 27 / 22 / 18 / 17 pt (views/StopView.swift:484, 532; views/Lists/ListComponents.swift:63, 222)GapG13
Sub-11 pt text11 pt minimumNo text in train circles7–8 pt line codes (views/FavoritesView.swift:527; ChiTransitWidget/FavoriteStopWidget.swift:408; ChiTransitWidget/ChiTransitWidgetLiveActivity.swift:248)GapG12
Service alertsNo informational alertsSystem alert (approved).alert (views/StopView.swift:315-319)DeviationG15
WidgetsRendering modes, buttonsAll families, refreshSmall, medium, inline and rectangular. No Button(intent:), no widgetAccentable.GapG17
Live ActivitiesTimely updatesPush updates (server shipped, CTA-65)pushType: nil (service/LiveActivityService.swift:477-480)GapG18
AccessibilityLabels, Reduce Motion, colour not aloneStatus as a word, AAPins are labelled buttons with the selected trait (views/MapView.swift:686). Controls are labelled.CompliantG10