Restyle the HUD as an observatory instrument

Replaces the generic rounded dark cards floating over the scene with a
single instrument language: hairline frames cut by accent corner ticks, a
viewport frame that reads the whole screen as one panel, and readouts whose
figures are what the eye lands on.

- styles.css: retune the tokens (deeper void/panel, brighter text/muted so
  every label clears 4.5:1 even over the brightest part of the skybox) and
  add two utilities — `hud-brackets` draws the four corner ticks from eight
  background gradients so no panel pays for them in DOM, `hud-acquire` wipes
  a panel down on mount as its one authored moment (reduced-motion aware).
- Drop Orbitron: every string in this UI is a measurement, an identifier, or
  a catalog label, so one readout face carries the hierarchy through weight,
  size, and tracking — and the HUD paints one font request sooner.
- Search: reticle mark instead of a magnifier, transparent field inside a
  framed shell, results as a dense two-column list with a match count, and
  the previously missing empty state.
- Info panel: return rail, name/class header, and a readout table with
  tabular figures and the unit tinted back off the number.
- Star labels: a hairline leader back to the star they name. The offset moved
  from `translate-*` to a margin because CSS2DRenderer overwrites the inline
  transform every frame, which silently beat the old classes.
- Both top-anchored overlays drop below the search field under `sm` so they
  no longer stack on top of it on a phone, and focus moved from a removed
  outline plus ring to real `focus-visible` outlines.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
2026-08-07 17:42:14 +02:00
co-authored by Claude Opus 5
parent d7e8ea1d4d
commit 836816ffbd
8 changed files with 161 additions and 55 deletions
@@ -75,9 +75,9 @@ const STAR_MARKER_RADIUS_AU = 0.2;
<button
type="button"
(click)="exitSystem()"
class="absolute top-4 left-4 flex items-center gap-1.5 rounded-md border border-border bg-panel/70 px-3 py-1.5 font-body text-xs tracking-wide text-muted uppercase backdrop-blur-md transition-colors hover:border-accent hover:text-accent focus:outline-none focus:ring-1 focus:ring-accent/50"
class="hud-brackets hud-acquire absolute top-20 left-4 flex items-center gap-2 border border-border/60 bg-panel/85 px-3 py-2 font-body text-[10px] tracking-[0.16em] text-muted uppercase backdrop-blur-md transition-colors hover:border-accent/70 hover:text-accent focus-visible:border-accent/70 focus-visible:text-accent focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-accent sm:top-4"
>
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 6l-6 6 6 6" />
</svg>
Galaxy
@@ -61,7 +61,13 @@ export class StarLabelOverlay {
const element = document.createElement('div');
// Tailwind utility classes assigned directly since this element lives outside Angular's
// view encapsulation (see the class comment above) rather than through a component template.
element.className = 'translate-x-1.5 -translate-y-1.5 whitespace-nowrap font-body text-[11px] text-accent [text-shadow:0_0_4px_rgba(0,0,0,0.9)]';
//
// The offset is a margin rather than a `translate-*` utility because `CSS2DRenderer` writes
// its own `transform` to the inline style every frame, which would win over any class. The
// `::before` hairline is the leader line back to the star the name belongs to — without it a
// margin-shifted label just floats near a point instead of pointing at it.
element.className =
"relative ml-3 whitespace-nowrap font-body text-[11px] tracking-[0.08em] text-accent uppercase [text-shadow:0_0_6px_var(--color-void),0_0_3px_var(--color-void)] before:absolute before:top-1/2 before:-left-3 before:h-px before:w-2.5 before:bg-accent/60 before:content-['']";
element.textContent = point.name;
const object = new CSS2DObject(element);