Skip to content

ADR-036 — ?-chip cross-screen pattern: click navigates, hover tooltip on desktop

Status · Accepted Date · 2026-05-07 Closes · RFC-011 (with ADR-034, ADR-035) TA anchor · §components / primary-route-pages Related · PRD-008, ADR-018 (mobile-first), ADR-024 (deep-link URLs)

Context

PRD-008 promises a ? chip next to every technical label in the Orrery HUD that names a concept covered in /science. The chips appear on /plan (porkchop axes), /fly (HUD rows), /missions FLIGHT tab (C3, V∞, TLI, TMI, TCM, OI, total ∆v), /explore planet panels (Keplerian element rows), /earth (orbit-altitude regimes), /moon and /mars (trajectory-type narrative). ~30 attachment points total.

RFC-011 OQ-3 asked how the ? chip behaves: click only, click + hover tooltip, or click into a popover modal.

Decision

Behaviour (RFC OQ-3 — Option B)

The ? chip:

  • Renders as a 14×14 px circle with a question-mark glyph. Min hit area 24×24 px (smaller than ADR-018's 44 px primary touch baseline because chips sit inline next to HUD labels and would crowd out content otherwise).
  • On hover (desktop only): shows the section's intro_sentence (≤ 80 chars) as a title attribute / native browser tooltip. No custom popover JS, no portal, no positioning math.
  • On click / tap (both desktop and mobile): navigates to /science/[tab]/[section]. Full SvelteKit page navigation; the user lands on the static-prerendered section page.
  • No popover modal: rejected per RFC-011 OQ-3 Option C. A modal on mobile click is exactly the context-loss anti-pattern PRD-008 wants to avoid.

Component (src/lib/components/ScienceChip.svelte)

Single reusable component with props { tab: string, section: string, hoverTitle?: string }:

svelte
<a
  href={`${base}/science/${tab}/${section}`}
  class="science-chip"
  title={hoverTitle ?? ''}
  aria-label={`Learn about ${section}`}
>?</a>

CSS: 14 px circle, white-50 fill, white-90 question mark, 1 px border, 24 px hit area via padding. Hover/focus states bump to teal (#4ecdc4). Matches the mission LEARN tab link aesthetic.

Typography + placement contract

The chip lives inline with its label, not on a separate line. Examples:

html
<dt>C3 <ScienceChip tab="propulsion" section="c3" /></dt>
<span class="hud-key">∆V HELIO <ScienceChip tab="propulsion" section="dv" /></span>

Keeps the label as a single visual unit; the chip reads as "tap for definition" punctuation.

Internationalisation

The hoverTitle prop comes from the section's intro_sentence (already localised per ADR-017). No additional i18n keys required for the chip itself; the chip's aria-label uses the section ID directly.

For surfaces where the label is not yet i18n'd (e.g. /earth LEO/MEO/GEO/HEO regime labels, /moon and /mars mission_type strings), Phase 2 work adds the i18n keys as a prerequisite — chip placement waits on label internationalisation.

Consequences

Positive: Zero new component infrastructure beyond ScienceChip.svelte. Hover tooltip is free (native title). Mobile UX preserves single-flow — no modal context-loss. Deep-linkable URLs (/science/[tab]/[section]) match the rest of the app's URL contract per ADR-024. Reuses the existing LEARN-tab link aesthetic, no new design tokens.

Negative: Native title tooltips are minimally styled and time out on long hovers — not a polished tooltip experience on desktop, but the click-navigate is the primary interaction so the tooltip is a desktop convenience, not a contract. ~30 attachment points across 7 routes is meaningful integration scope (Phase 2).

Implementation notes

  • Component: src/lib/components/ScienceChip.svelte.
  • Phase 1 (this ADR's scope): the chip component + the "see in app" inverse chip on the /science side (SeeInAppChip.svelte linking back to existing routes).
  • Phase 2 (separate batch): wire ~30 chip placements across /plan, /fly, /missions, /explore, /earth, /moon, /mars. Tracked under issue #39 Phase D.
  • Section ID stability: the chip's tab + section props rely on the URL contract from PRD-008 §scope. Section IDs are an enum in science-section.schema.json; renaming a section is a breaking change and requires migrating chip placements in lockstep.

Orrery — architecture documentation · MIT · No tracking