Files
musicmouse/web/src/components/AppHeader.tsx
Martin Bauer 0f08e1d16c Web frontend: touch layout for phones
Phones got the kiosk's keyboard-first layout squeezed down: shelves cut off
by the tab rail and a header taking a fifth of the screen. They now get
their own layout, chosen by a media query (narrow, or short landscape on a
touch screen); tablets and desktop are unchanged.

- Pick a group (Musik/Hörbücher/Podcasts), then a category, then scroll
  through a grid of smaller albums.
- A floating glass dock: mini player, Musik/Zimmer tabs (no typing tab - a
  phone has no keyboard for it) and a search button that turns into a real
  search field, raised above the on-screen keyboard.
- Album sheet and room page get compact phone variants.

Browse state stays in the shared UiState, so resizing or rotating keeps
your place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:33:26 +02:00

49 lines
1.2 KiB
TypeScript

import type { ReactNode } from "react";
interface Props {
title?: string;
mascot?: string;
/** Shown next to the title when the mouse is reachable but the firmware is not. */
status?: ReactNode;
/** The phone size: a smaller mascot and title. */
compact?: boolean;
}
export function AppHeader({
title = "Musik Delfin",
mascot = "/dolphin-mascot.png",
status,
compact = false,
}: Props) {
const mascotSize = compact ? 44 : 64;
return (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
gap: compact ? 10 : 16,
// The status bar is translucent in standalone mode, so make room for it.
padding: compact
? "calc(12px + env(safe-area-inset-top)) 16px 4px"
: "calc(18px + env(safe-area-inset-top)) 32px 6px",
flex: "none",
position: "relative",
}}
>
<img src={mascot} alt="" style={{ width: mascotSize, height: mascotSize, objectFit: "contain" }} />
<div
style={{
fontSize: compact ? 28 : 34,
fontWeight: 900,
color: "var(--paper)",
textShadow: "0 3px 14px oklch(15% 0.05 210 / .5)",
}}
>
{title}
</div>
{status}
</div>
);
}