v3: search engine, responsive header with compact user menu

This commit is contained in:
khannurien
2026-03-29 11:56:31 +00:00
parent f0f6472db6
commit cbb3505139
31 changed files with 1206 additions and 178 deletions

View File

@@ -1573,10 +1573,10 @@ body.has-player .fab-new {
transform: translateY(-1px);
}
@media (min-width: 740px) {
@media (min-width: 860px) {
.app-header--has-center {
display: grid;
grid-template-columns: 1fr auto 1fr;
grid-template-columns: auto 1fr auto;
}
}
@@ -1593,14 +1593,38 @@ body.has-player .fab-new {
display: none;
align-items: center;
justify-content: center;
min-width: 0;
overflow: hidden;
container-type: inline-size;
}
@media (min-width: 740px) {
@media (min-width: 860px) {
.app-header-center {
display: flex;
}
}
/* When the search bar is expanded, immediately clear the rest of the center —
the expanded input needs the full column width */
.app-header-center:has(.search-bar--expanded) .index-presence,
.app-header-center:has(.search-bar--expanded) .feed-sort {
display: none;
}
/* As the center column shrinks (viewport narrow, search collapsed),
shed content in order: presence first, then tabs (still in .index-below-header) */
@container (max-width: 460px) {
.index-presence {
display: none;
}
}
@container (max-width: 280px) {
.feed-sort {
display: none;
}
}
.header-center-slot {
display: flex;
align-items: center;
@@ -1617,7 +1641,33 @@ body.has-player .fab-new {
justify-content: flex-end;
gap: 0.6rem;
margin-left: auto;
flex-wrap: wrap;
flex-shrink: 0;
flex-wrap: nowrap;
}
/* Text links — visible only at wide viewports */
.nav-links {
display: none;
align-items: center;
gap: 0.6rem;
}
@media (min-width: 1150px) {
.nav-links {
display: flex;
}
}
/* Avatar menu — visible only below the text-links breakpoint */
.nav-compact {
display: flex;
align-items: center;
}
@media (min-width: 1150px) {
.nav-compact {
display: none;
}
}
.app-header-user {
@@ -1637,6 +1687,57 @@ body.has-player .fab-new {
background: var(--color-header-user-bg-hover);
}
/* ── User menu (compact nav) ── */
.user-menu {
position: relative;
}
.user-menu-trigger {
display: flex;
align-items: center;
background: transparent;
border: none;
border-radius: 8px;
padding: 0.25rem;
cursor: pointer;
transition: background 0.15s;
}
.user-menu-trigger:hover {
background: var(--color-header-user-bg-hover);
}
.user-menu-dropdown {
position: absolute;
top: calc(100% + 0.4rem);
right: 0;
min-width: 150px;
background: var(--color-surface);
border: 2px solid var(--color-border-subtle);
border-radius: 10px;
padding: 0.35rem;
display: flex;
flex-direction: column;
gap: 0.15rem;
z-index: 100;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
.user-menu-item {
display: block;
padding: 0.45rem 0.75rem;
border-radius: 7px;
text-decoration: none;
color: var(--color-text);
font-size: 0.9rem;
font-weight: 600;
transition: background 0.12s;
}
.user-menu-item:hover {
background: var(--color-header-user-bg-hover);
}
/* ── Auth card ── */
.auth-card {
width: 100%;
@@ -1780,6 +1881,7 @@ body.has-player .fab-new {
display: inline-flex;
align-items: center;
justify-content: center;
white-space: nowrap;
cursor: pointer;
border-radius: 8px;
font-family: inherit;
@@ -1866,7 +1968,7 @@ body.has-player .fab-new {
gap: 0;
}
@media (min-width: 740px) {
@media (min-width: 860px) {
.index-page .dump-feed {
margin-top: 1rem;
}
@@ -1913,7 +2015,7 @@ body.has-player .fab-new {
padding: 0.6rem 1.25rem 0;
}
@media (min-width: 740px) {
@media (min-width: 860px) {
.index-below-header {
display: none;
}
@@ -3597,3 +3699,144 @@ body.has-player .fab-new {
z-index: 9999;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
/* ── Search bar (in header center slot) ── */
.search-bar {
display: flex;
align-items: center;
gap: 0.4rem;
width: 100%;
max-width: 380px;
}
.search-bar--collapsible {
width: auto;
max-width: none;
}
.search-bar--collapsible.search-bar--expanded {
width: 100%;
max-width: 320px;
}
.search-bar-input {
flex: 1;
padding: 0.3rem 0.7rem;
border-radius: 8px;
border: 2px solid var(--color-border-subtle);
background: var(--color-bg);
color: var(--color-text);
font-size: 0.875rem;
font-family: inherit;
outline: none;
transition: max-width 0.25s ease, opacity 0.2s ease, padding 0.25s ease,
border-width 0.25s ease, border-color 0.15s;
min-width: 0;
}
/* Collapsed state: hide the input while keeping it in the DOM */
.search-bar--collapsible .search-bar-input {
max-width: 0;
opacity: 0;
padding-left: 0;
padding-right: 0;
border-width: 0;
pointer-events: none;
}
/* Expanded state: animate it open */
.search-bar--collapsible.search-bar--expanded .search-bar-input {
max-width: 280px;
opacity: 1;
padding-left: 0.7rem;
padding-right: 0.7rem;
border-width: 2px;
pointer-events: auto;
}
.search-bar-input:focus {
border-color: var(--color-accent);
}
.search-bar-btn {
padding: 0.3rem 0.55rem;
background: transparent;
border: 2px solid var(--color-border-subtle);
border-radius: 8px;
cursor: pointer;
font-size: 0.875rem;
flex-shrink: 0;
transition: border-color 0.15s;
}
.search-bar-btn:hover {
border-color: var(--color-accent);
}
/* ── Search page ── */
.search-page {
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 3rem;
}
.search-tabs {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 1rem 1.25rem 0;
width: 100%;
max-width: 860px;
box-sizing: border-box;
}
.search-page-empty {
padding: 3rem 1.25rem;
color: var(--color-text-secondary);
text-align: center;
font-size: 0.95rem;
}
/* ── User results ── */
.user-results {
list-style: none;
margin: 0;
padding: 0.75rem 1.25rem 0;
display: flex;
flex-direction: column;
gap: 0.5rem;
max-width: 860px;
width: 100%;
box-sizing: border-box;
}
.user-result-item {
display: flex;
flex-direction: column;
gap: 0.2rem;
padding: 0.75rem 1rem;
background: var(--color-surface);
border-radius: 10px;
border: 2px solid var(--color-border-subtle);
text-decoration: none;
color: var(--color-text);
transition: border-color 0.15s;
}
.user-result-item:hover {
border-color: var(--color-accent);
}
.user-result-name {
font-weight: 600;
font-size: 0.95rem;
}
.user-result-description {
font-size: 0.85rem;
color: var(--color-text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}