diff --git a/README.md b/README.md
index 88527db..b9eceeb 100644
--- a/README.md
+++ b/README.md
@@ -367,6 +367,8 @@ Then put it behind your existing reverse proxy like everything else
- [x] Library/artist grid tiles shrink fluidly on a narrow phone instead
of a fixed 160px floor collapsing to one column per row — see
docs/architecture.md
+- [x] Library page title now stays pinned alongside the search bar while
+ scrolling, instead of just the search bar — see docs/architecture.md
- [ ] Try a full party end-to-end with two real accounts (still the main gap)
- [ ] Try casting to a real Chromecast (only the SDK's own bootstrap is
confirmed here — no real device/session)
diff --git a/client/src/shell/Shell.css b/client/src/shell/Shell.css
index 09a2301..4e10556 100644
--- a/client/src/shell/Shell.css
+++ b/client/src/shell/Shell.css
@@ -79,7 +79,8 @@
position: sticky;
top: 0;
z-index: 3;
- padding: 14px 16px;
+ height: var(--mobile-topbar-h);
+ padding: 0 16px;
background: var(--bg-header);
}
diff --git a/client/src/styles/base.css b/client/src/styles/base.css
index 5748950..42506c1 100644
--- a/client/src/styles/base.css
+++ b/client/src/styles/base.css
@@ -14,6 +14,7 @@
--accent: #52b54b; /* Emby's theme-primary-color (hsl(116, 41.7%, 50.2%)) */
--accent-bright: #6ccf65; /* Emby's --theme-accent-text-color-darkbg */
--danger: #ff6b6b;
+ --mobile-topbar-h: 49px; /* shell/Shell.css's .mobileTopBar - a fixed height so any other sticky element (e.g. views/library's .libraryHeader) can stack directly below it instead of guessing its rendered height */
}
* { box-sizing: border-box; }
diff --git a/client/src/views/library/Library.css b/client/src/views/library/Library.css
new file mode 100644
index 0000000..71cc115
--- /dev/null
+++ b/client/src/views/library/Library.css
@@ -0,0 +1,24 @@
+/* ---- Library page header (title + search bar) - see Library.ts/html. ----
+ Wraps .pageHeader and tiles.css's .searchBar (already sticky on its own)
+ in one sticky block so the title stays put too, instead of scrolling
+ away while the search bar stays behind - reported directly. Needs its
+ own opaque background since .pageHeader's
has none - without it,
+ grid tiles scrolling underneath would show through the title text once
+ stuck. */
+.libraryHeader {
+ position: sticky;
+ top: 0;
+ z-index: 2;
+ background: var(--bg);
+ padding-top: 4px;
+}
+
+/* Below 720px, shell/Shell.css's own sticky .mobileTopBar already occupies
+ top:0 - stacking this header at top:0 too would have both fighting over
+ the same spot, with this one (later in paint order) covering the app's
+ brand bar. Stick it right below instead. */
+@media (max-width: 720px) {
+ .libraryHeader {
+ top: var(--mobile-topbar-h);
+ }
+}
diff --git a/client/src/views/library/Library.html b/client/src/views/library/Library.html
index 69365c4..e6d1fcd 100644
--- a/client/src/views/library/Library.html
+++ b/client/src/views/library/Library.html
@@ -1,4 +1,6 @@
-
-
+
+
+
+
Aucun résultat.
Chargement...
diff --git a/client/src/views/library/Library.ts b/client/src/views/library/Library.ts
index dcc0989..70a64d2 100644
--- a/client/src/views/library/Library.ts
+++ b/client/src/views/library/Library.ts
@@ -1,3 +1,4 @@
+import './Library.css';
import html from './Library.html';
import { getArtists, getLibraries, getLibraryItems } from '../../api/embyApi';
import { createParty } from '../../api/party';
diff --git a/docs/architecture.md b/docs/architecture.md
index e1c29b3..f7ef0ca 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -3911,6 +3911,58 @@ from 320 to 393px now gets 2 columns (previously 1), 430px gets 3, and
768/1200px match what the old fixed `160px` floor already gave -
confirmed empirically, not assumed from the formula alone.
+## The library header wasn't fully sticky: the title still scrolled away
+
+"A sticky search bar" (above) only ever made the `` itself
+sticky - asked for directly again, this time to also keep the page
+title (`.pageHeader`'s `
`) pinned alongside it on `views/library`,
+so both stay visible together while a long grid scrolls underneath
+instead of just the search box.
+
+New `.libraryHeader` wrapper (`views/library/Library.css` - the one
+view of this shape that had no dedicated stylesheet yet, everything
+borrowed from `tiles.css`/`base.css`) around the existing `.pageHeader`
++ `.searchBar` pair, `position: sticky; top: 0` on the wrapper itself
+with its own opaque `var(--bg)` background - the `
` has none of its
+own, so without this, tiles scrolling underneath would show through the
+title text once stuck. `.searchBar` keeps its own pre-existing
+`position: sticky; top: 0` from `tiles.css` unchanged (still needed as-is
+on `views/artist`/`views/album`, which don't get this wrapper); nested
+inside an already-stuck ancestor that isn't itself scrolling, it's
+inert rather than conflicting.
+
+Scoped to `views/library` only, not `tiles.css`'s shared `.pageHeader` -
+`views/home` uses that same class for a plain, non-sticky title, and
+`views/artist`/`views/album` have since moved to their own hero headers
+(see "Music UI rework" above), not `.pageHeader` at all.
+
+One real collision worth catching: below 720px, `shell/Shell.css`'s own
+`.mobileTopBar` is *also* `position: sticky; top: 0` (the app's brand
+bar, sitting above `.mainContent` as a sibling, not an ancestor) - the
+pre-existing sticky `.searchBar` already raced it for the same spot,
+just narrowly enough (one slim input) not to get reported. Stacking a
+whole title+search block at `top: 0` too would have properly covered
+it, later in paint order. `.mobileTopBar` got an explicit
+`height: var(--mobile-topbar-h)` (new `base.css` token, `49px` -
+replacing its previous padding-derived auto height with a fixed one
+anything else can reliably stack against), and `.libraryHeader` sticks
+to `top: var(--mobile-topbar-h)` instead of `0` under that same 720px
+breakpoint - directly below the brand bar instead of underneath it.
+
+Verified: full `typecheck`/`build` (client only). No Emby session is
+needed to see either state, so checked directly: real compiled
+`app.css` loaded (same-origin, from the running dev server) into two
+`