From b8f9f6d5373bd82acc2c872e8ebde81113a6c33d Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sun, 13 Sep 2026 00:16:42 +0200 Subject: [PATCH] Give the tab rail its own glass bar and reserve space for it The three tab buttons now share one frosted glass pill instead of each floating separately, and BrowseView/RoomView reserve TAB_RAIL_CLEARANCE of right-side padding so a full-width row or grid never renders under it - verified against the real library, where dense rows (e.g. Conni's 82 audiobooks) previously butted right up against the rail. Also gitignore the real (non-.example) tippen-curriculum.yml and tippen-progress.json, matching config.yml's own privacy treatment, since the curriculum now contains real reward paths into a personal library. Co-Authored-By: Claude Sonnet 5 --- python-backend/.gitignore | 2 ++ web/src/components/BrowseView.tsx | 9 +++++++-- web/src/components/RoomView.tsx | 8 ++++++-- web/src/components/TabRail.tsx | 28 +++++++++++++++++++--------- web/src/lib/theme.ts | 6 ++++++ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/python-backend/.gitignore b/python-backend/.gitignore index b60d1fc..258c6ae 100644 --- a/python-backend/.gitignore +++ b/python-backend/.gitignore @@ -1,2 +1,4 @@ config.yml +tippen-curriculum.yml +tippen-progress.json /.musicmouse-cache diff --git a/web/src/components/BrowseView.tsx b/web/src/components/BrowseView.tsx index 65fe7d6..3dfacf3 100644 --- a/web/src/components/BrowseView.tsx +++ b/web/src/components/BrowseView.tsx @@ -30,6 +30,7 @@ import { rowTint, SHOW_ROW_ICONS, SHOW_ROW_TITLES, + TAB_RAIL_CLEARANCE, } from "../lib/theme"; import { Cover } from "./Cover"; @@ -142,7 +143,9 @@ export function BrowseView({
{shelves.map(({ group: shelfGroup, categories: shelfCategories }, index) => (
{songs.length > 0 && (
diff --git a/web/src/components/RoomView.tsx b/web/src/components/RoomView.tsx index 4edabee..1ffb265 100644 --- a/web/src/components/RoomView.tsx +++ b/web/src/components/RoomView.tsx @@ -7,7 +7,7 @@ import { useState } from "react"; import type { HaConfig } from "../api/types"; import { useHomeAssistant } from "../hooks/useHomeAssistant"; -import { SHOW_DECORATIVE_ANIMATIONS } from "../lib/theme"; +import { SHOW_DECORATIVE_ANIMATIONS, TAB_RAIL_CLEARANCE } from "../lib/theme"; import { AppHeader } from "./AppHeader"; import { Bubbles } from "./Bubbles"; import { LightCard } from "./LightCard"; @@ -40,7 +40,11 @@ export function RoomView({ config }: { config: HaConfig }) { }} > -
+
{config.scenes.length > 0 && ( {pages.map((candidate) => { @@ -47,13 +59,11 @@ export function TabRail({ page, onSelect, showRoom }: Props) { justifyContent: "center", border: "none", borderRadius: 999, - background: active ? "var(--accent)" : "oklch(97% 0.01 210 / .95)", - boxShadow: "0 6px 18px oklch(15% 0.05 210 / .4)", + background: active ? "var(--accent)" : "transparent", fontSize: 20, fontWeight: 900, - color: active ? "#fff" : "var(--ink)", cursor: "pointer", - transition: "background 0.15s ease, color 0.15s ease", + transition: "background 0.15s ease", }} > {PAGE_ICON[candidate]} diff --git a/web/src/lib/theme.ts b/web/src/lib/theme.ts index 242ed58..cdbd099 100644 --- a/web/src/lib/theme.ts +++ b/web/src/lib/theme.ts @@ -75,6 +75,12 @@ export const GROUP_LABEL: Record = { podcasts: "Podcasts", }; +/** How much horizontal space the tab rail's own glass bar claims on the right edge + * (its `right` inset plus its rendered width) - scrollable content reserves this much + * padding on that side so a full row/grid never renders underneath it. Keep in sync + * with the geometry in `TabRail.tsx`. */ +export const TAB_RAIL_CLEARANCE = 88; + /** Icon/label for the vertical tab rail - one entry per `UiState["page"]`. The * smarthome tab only renders when Home Assistant is configured (see `App.tsx`); the * other two always show. */