fix: unclip search-suggest dropdown — nebula clip moved to dedicated .band-bg layer; suggest above sticky header

This commit is contained in:
ctao
2026-07-24 23:44:54 +02:00
parent 3b736af25e
commit 2de0cf148e
9 changed files with 24 additions and 8 deletions
+5 -2
View File
@@ -66,8 +66,11 @@ ctao.org animates nebula videos under Galaxy vignettes; our translation:
1. **Band nebula** — one `--nebula` stack (Cherenkov .38 / Azure .33 / 1. **Band nebula** — one `--nebula` stack (Cherenkov .38 / Azure .33 /
Indigo .80 radial fields) used by hero + auth bands, static and animated Indigo .80 radial fields) used by hero + auth bands, static and animated
alike; the animated variant is an oversized pseudo-layer drifting via alike; the animated variant is an oversized `.band-bg::before` layer
`transform` only, 22s alternate. Clearly visible glow, never neon. drifting via `transform` only, 22s alternate. Clearly visible glow, never
neon. `.band-bg` (first child of every band) owns the `overflow: hidden`
clip — NEVER put overflow on the band itself: it would clip overlays like
the search-suggest dropdown.
2. **Whole-page ambient** — `.has-ambient::before`: fixed brand-hue wash 2. **Whole-page ambient** — `.has-ambient::before`: fixed brand-hue wash
(Cherenkov .16 / Azure .12 / Indigo .10 — visible pastel fields, white (Cherenkov .16 / Azure .12 / Indigo .10 — visible pastel fields, white
cards pop against them) drifting on a 60s alternate cycle. Opt-in per page cards pop against them) drifting on a 60s alternate cycle. Opt-in per page
+1
View File
@@ -20,6 +20,7 @@ const tickets = [
--- ---
<Base title="CTAO Science Portal — Dashboard" description="User dashboard (mock)"> <Base title="CTAO Science Portal — Dashboard" description="User dashboard (mock)">
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">User area</div> <div class="eyebrow">User area</div>
<h1>Dashboard</h1> <h1>Dashboard</h1>
+1
View File
@@ -19,6 +19,7 @@ const services = [
--- ---
<Base title="CTAO Science Portal" description="News, observation proposals, data and user services of the Cherenkov Telescope Array Observatory" ambient> <Base title="CTAO Science Portal" description="News, observation proposals, data and user services of the Cherenkov Telescope Array Observatory" ambient>
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">Cherenkov Telescope Array Observatory</div> <div class="eyebrow">Cherenkov Telescope Array Observatory</div>
<h1>CTAO Science Portal</h1> <h1>CTAO Science Portal</h1>
+1
View File
@@ -3,6 +3,7 @@ import Base from '../layouts/Base.astro';
--- ---
<Base title="CTAO Science Portal — Sign in" description="Sign in via CTAO AAI (mock)"> <Base title="CTAO Science Portal — Sign in" description="Sign in via CTAO AAI (mock)">
<section class="auth-band"> <section class="auth-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="auth-card"> <div class="auth-card">
<img class="auth-logo" src="/brand/CTAO_Logo_positive.svg" alt="CTAO" /> <img class="auth-logo" src="/brand/CTAO_Logo_positive.svg" alt="CTAO" />
<span class="badge-mock">Mock — AAI integration pending</span> <span class="badge-mock">Mock — AAI integration pending</span>
+1
View File
@@ -10,6 +10,7 @@ const iso = (d) => d.toISOString().slice(0, 10);
--- ---
<Base title="CTAO Science Portal — News" description="News and announcements of the CTAO"> <Base title="CTAO Science Portal — News" description="News and announcements of the CTAO">
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">Cherenkov Telescope Array Observatory</div> <div class="eyebrow">Cherenkov Telescope Array Observatory</div>
<h1>News &amp; Announcements</h1> <h1>News &amp; Announcements</h1>
+1
View File
@@ -3,6 +3,7 @@ import Base from '../layouts/Base.astro';
--- ---
<Base title="CTAO Science Portal — Proposals" description="Observation proposal submission (mock)"> <Base title="CTAO Science Portal — Proposals" description="Observation proposal submission (mock)">
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">Proposal Submission</div> <div class="eyebrow">Proposal Submission</div>
<h1>Observation proposals</h1> <h1>Observation proposals</h1>
+1
View File
@@ -3,6 +3,7 @@ import Base from '../layouts/Base.astro';
--- ---
<Base title="CTAO Science Portal — Search" description="Search CTAO news and announcements"> <Base title="CTAO Science Portal — Search" description="Search CTAO news and announcements">
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">Science Portal</div> <div class="eyebrow">Science Portal</div>
<h1>Search</h1> <h1>Search</h1>
+1
View File
@@ -10,6 +10,7 @@ const channels = [
--- ---
<Base title="CTAO Science Portal — Support" description="User support: help desk, FAQ, forum, mailing lists (mock)"> <Base title="CTAO Science Portal — Support" description="User support: help desk, FAQ, forum, mailing lists (mock)">
<section class="hero-band"> <section class="hero-band">
<div class="band-bg" aria-hidden="true"></div>
<div class="container hero"> <div class="container hero">
<div class="eyebrow">User services</div> <div class="eyebrow">User services</div>
<h1>User Support</h1> <h1>User Support</h1>
+12 -6
View File
@@ -202,8 +202,11 @@ img { max-width: 100%; height: auto; display: block; }
pseudo-layer (see the motion block at the end of this file). */ pseudo-layer (see the motion block at the end of this file). */
.hero-band { .hero-band {
background: var(--nebula), var(--galaxy); background: var(--nebula), var(--galaxy);
color: #fff; padding: var(--space-band) 0; position: relative; overflow: hidden; color: #fff; padding: var(--space-band) 0; position: relative;
/* NO overflow:hidden here — it would clip the search-suggest dropdown.
The animated nebula is clipped by its own .band-bg frame instead. */
} }
.band-bg { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.hero { position: relative; } /* content above the animated nebula layer */ .hero { position: relative; } /* content above the animated nebula layer */
.hero h1 { font-size: clamp(2rem, 6vw, 3.6rem); margin: 0 0 10px; line-height: 1.12; font-weight: 700; } .hero h1 { font-size: clamp(2rem, 6vw, 3.6rem); margin: 0 0 10px; line-height: 1.12; font-weight: 700; }
.hero p { color: var(--cherenkov); font-size: 1.08rem; max-width: 62ch; margin: 0; } /* subtitle per BRAND D.3.4 */ .hero p { color: var(--cherenkov); font-size: 1.08rem; max-width: 62ch; margin: 0; } /* subtitle per BRAND D.3.4 */
@@ -224,10 +227,12 @@ img { max-width: 100%; height: auto; display: block; }
.hero-search input:focus, .search-form input:focus { border-color: var(--azure); } .hero-search input:focus, .search-form input:focus { border-color: var(--azure); }
/* Live suggestions under the hero search — plain links, Tab-accessible */ /* Live suggestions under the hero search — plain links, Tab-accessible */
.suggest { .suggest {
position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 5; position: absolute; top: calc(100% + 8px); left: 0; right: 0;
list-style: none; margin: 0; padding: 6px; text-align: left; z-index: 11; /* above the sticky header (10) — never slides under it on scroll */
list-style: none; margin: 0; padding: 8px; text-align: left;
background: #fff; border: 1px solid var(--border); border-radius: var(--radius); background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
box-shadow: var(--shadow-lifted); box-shadow: var(--shadow-lifted);
max-height: min(60vh, 480px); overflow: auto; /* long lists scroll on mobile */
} }
.suggest:empty { display: none; } .suggest:empty { display: none; }
.suggest li { display: flex; align-items: center; gap: var(--space-s); padding: 0 12px; border-radius: calc(var(--radius) - 8px); } .suggest li { display: flex; align-items: center; gap: var(--space-s); padding: 0 12px; border-radius: calc(var(--radius) - 8px); }
@@ -440,7 +445,7 @@ img { max-width: 100%; height: auto; display: block; }
/* Auth (login mock) — nebula backdrop + floating card, modern auth pattern */ /* Auth (login mock) — nebula backdrop + floating card, modern auth pattern */
.auth-band { .auth-band {
min-height: calc(100dvh - 64px); position: relative; overflow: hidden; min-height: calc(100dvh - 64px); position: relative;
display: grid; place-items: center; padding: var(--space-band) var(--gutter); display: grid; place-items: center; padding: var(--space-band) var(--gutter);
background: var(--nebula), var(--galaxy); background: var(--nebula), var(--galaxy);
} }
@@ -490,9 +495,10 @@ img { max-width: 100%; height: auto; display: block; }
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
@view-transition { navigation: auto; } @view-transition { navigation: auto; }
html { scroll-behavior: smooth; } html { scroll-behavior: smooth; }
/* Bands hand their glow to a slowly roaming pseudo-layer (same --nebula stack) */ /* Bands hand their glow to a slowly roaming layer inside the .band-bg clip
frame (same --nebula stack) — the band itself never clips its overlays */
.hero-band, .auth-band { background: var(--galaxy); } .hero-band, .auth-band { background: var(--galaxy); }
.hero-band::before, .auth-band::before { .band-bg::before {
content: ""; position: absolute; inset: -45% -30%; content: ""; position: absolute; inset: -45% -30%;
background: var(--nebula); background: var(--nebula);
animation: nebula 22s ease-in-out infinite alternate; animation: nebula 22s ease-in-out infinite alternate;