Music — Classical / Orchestra Landing
An elegant landing page for the fictional Aurelian Symphony's 2026 concert season, built in ivory, deep navy, and gold with serif display headings. A refined hero sets a CSS concert-hall scene with a gilded dome, twinkling chandelier, and drifting motes, alongside a stately tagline and a subtle waveform sampler. Below it sit a filterable season calendar with expandable programme notes, a conductor spotlight, three subscription packages, a venue section, and a timeless footer.
MCP
Código
:root {
--bg: #0e1730;
--bg-2: #13203f;
--surface: #17274a;
--surface-2: #1d3057;
--text: #f4efe2;
--muted: #b9c0d4;
--line: rgba(244, 239, 226, 0.12);
--line-2: rgba(244, 239, 226, 0.22);
--accent: #c9a24b;
--accent-soft: rgba(201, 162, 75, 0.16);
--paper: #f4efe2;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--r-full: 999px;
--display: "Cormorant Garamond", Georgia, serif;
--body: "Inter", system-ui, -apple-system, sans-serif;
--shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.7);
--shadow-soft: 0 12px 40px -24px rgba(0, 0, 0, 0.6);
--maxw: 1160px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--body);
background: var(--bg);
color: var(--text);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
}
.wrap {
width: 100%;
max-width: var(--maxw);
margin: 0 auto;
padding: 0 clamp(20px, 5vw, 48px);
}
a { color: inherit; text-decoration: none; }
.skip-link {
position: absolute;
left: -999px;
top: 8px;
background: var(--accent);
color: #1a1407;
padding: 10px 16px;
border-radius: var(--r-sm);
z-index: 100;
font-weight: 600;
}
.skip-link:focus { left: 16px; }
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 3px;
border-radius: 4px;
}
/* ---------- Buttons ---------- */
.btn {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--body);
font-weight: 600;
font-size: 0.94rem;
letter-spacing: 0.01em;
padding: 13px 26px;
border-radius: var(--r-full);
border: 1px solid transparent;
cursor: pointer;
transition: transform 0.18s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
background: transparent;
color: var(--text);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn--gold {
background: linear-gradient(180deg, #e3bd6a, var(--accent));
color: #1a1407;
box-shadow: 0 14px 30px -16px rgba(201, 162, 75, 0.7);
}
.btn--gold:hover { box-shadow: 0 18px 38px -16px rgba(201, 162, 75, 0.85); }
.btn--outline {
border-color: var(--line-2);
color: var(--text);
}
.btn--outline:hover { border-color: var(--accent); color: var(--accent); }
.btn--ghost {
border-color: var(--line-2);
font-size: 0.85rem;
padding: 10px 18px;
}
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn--quiet { color: var(--muted); padding: 13px 18px; }
.btn--quiet:hover { color: var(--text); }
/* ---------- Topbar ---------- */
.topbar {
position: sticky;
top: 0;
z-index: 50;
background: rgba(14, 23, 48, 0.78);
backdrop-filter: blur(14px);
border-bottom: 1px solid var(--line);
}
.topbar__inner {
display: flex;
align-items: center;
justify-content: space-between;
height: 72px;
gap: 24px;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand__mark {
display: inline-flex;
align-items: flex-end;
gap: 3px;
height: 22px;
}
.brand__mark span {
width: 4px;
background: var(--accent);
border-radius: 2px;
}
.brand__mark span:nth-child(1) { height: 10px; }
.brand__mark span:nth-child(2) { height: 22px; }
.brand__mark span:nth-child(3) { height: 14px; }
.brand__name {
font-family: var(--display);
font-size: 1.4rem;
font-weight: 600;
letter-spacing: 0.02em;
}
.brand__name em { color: var(--accent); font-style: italic; }
.nav { display: flex; gap: 28px; }
.nav a {
color: var(--muted);
font-size: 0.92rem;
font-weight: 500;
position: relative;
transition: color 0.2s ease;
}
.nav a::after {
content: "";
position: absolute;
left: 0; bottom: -6px;
width: 0; height: 1px;
background: var(--accent);
transition: width 0.25s ease;
}
.nav a:hover { color: var(--text); }
.nav a:hover::after { width: 100%; }
/* ---------- Hero ---------- */
.hero {
position: relative;
overflow: hidden;
padding: clamp(72px, 12vw, 140px) 0 clamp(64px, 9vw, 110px);
background:
radial-gradient(120% 80% at 50% -10%, rgba(201, 162, 75, 0.14), transparent 60%),
linear-gradient(180deg, var(--bg-2), var(--bg) 75%);
}
.hero__inner { position: relative; z-index: 2; max-width: 760px; }
.hero__eyebrow {
font-size: 0.82rem;
letter-spacing: 0.32em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 18px;
font-weight: 600;
}
.hero__title {
font-family: var(--display);
font-weight: 600;
font-size: clamp(3rem, 9vw, 6.4rem);
line-height: 0.98;
margin: 0 0 26px;
letter-spacing: 0.01em;
}
.hero__title em { font-style: italic; color: var(--accent); }
.hero__lede {
font-size: clamp(1.04rem, 2.3vw, 1.28rem);
color: var(--muted);
max-width: 56ch;
margin: 0 0 34px;
}
.hero__actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 14px;
margin-bottom: 30px;
}
.listen { border: 1px solid var(--line-2); border-radius: var(--r-full); }
.listen.is-playing { border-color: var(--accent); color: var(--accent); }
.listen__icon {
width: 0; height: 0;
border-left: 10px solid currentColor;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
transition: all 0.2s ease;
}
.listen.is-playing .listen__icon {
border: none;
width: 10px; height: 11px;
border-left: 3px solid currentColor;
border-right: 3px solid currentColor;
}
.sampler {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 40px;
max-width: 460px;
}
.sampler__bars {
flex: 1;
display: flex;
align-items: center;
gap: 3px;
height: 40px;
}
.sampler__bars i {
flex: 1;
min-width: 2px;
background: var(--line-2);
border-radius: 2px;
height: 18%;
transform-origin: center;
transition: background 0.2s ease, height 0.12s ease;
}
.sampler__bars i.lit { background: var(--accent); }
.sampler.playing .sampler__bars i.active { background: linear-gradient(180deg, #e3bd6a, var(--accent)); }
.sampler__time {
font-size: 0.84rem;
color: var(--muted);
font-variant-numeric: tabular-nums;
min-width: 78px;
text-align: right;
}
.hero__stats {
display: flex;
gap: clamp(28px, 6vw, 56px);
margin: 0;
padding-top: 28px;
border-top: 1px solid var(--line);
}
.hero__stats dt {
font-size: 0.74rem;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 6px;
}
.hero__stats dd {
margin: 0;
font-family: var(--display);
font-size: 2.1rem;
font-weight: 600;
color: var(--text);
}
/* ---------- Hall scene ---------- */
.hall {
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
opacity: 0.9;
}
.hall__dome {
position: absolute;
top: -22%;
left: 50%;
transform: translateX(-50%);
width: 130%;
height: 70%;
border-radius: 0 0 50% 50% / 0 0 100% 100%;
background: radial-gradient(60% 80% at 50% 0%, rgba(201, 162, 75, 0.1), transparent 70%);
border-bottom: 1px solid var(--line);
}
.hall__arches {
position: absolute;
right: 0; top: 12%;
display: flex;
gap: 2.4vw;
opacity: 0.5;
}
.hall__arches span {
width: 4.2vw;
height: 32vh;
border-radius: 50% 50% 0 0 / 60% 60% 0 0;
border: 1px solid var(--line);
border-bottom: none;
background: linear-gradient(180deg, rgba(201, 162, 75, 0.05), transparent);
}
.hall__stage {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 22%;
background: linear-gradient(180deg, transparent, rgba(201, 162, 75, 0.07));
border-top: 1px solid var(--line);
}
.hall__chandelier {
position: absolute;
top: 6%;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
}
.hall__chandelier i {
width: 5px; height: 5px;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 14px 3px rgba(201, 162, 75, 0.55);
animation: twinkle 3.4s ease-in-out infinite;
}
.hall__chandelier i:nth-child(2n) { animation-delay: 0.6s; }
.hall__chandelier i:nth-child(3n) { animation-delay: 1.2s; }
@keyframes twinkle {
0%, 100% { opacity: 0.45; transform: scale(0.85); }
50% { opacity: 1; transform: scale(1.15); }
}
.hall__motes { position: absolute; inset: 0; }
.hall__motes i {
position: absolute;
width: 3px; height: 3px;
border-radius: 50%;
background: rgba(244, 239, 226, 0.5);
animation: drift 12s linear infinite;
}
.hall__motes i:nth-child(1) { left: 12%; top: 30%; animation-delay: 0s; }
.hall__motes i:nth-child(2) { left: 28%; top: 60%; animation-delay: 2s; }
.hall__motes i:nth-child(3) { left: 44%; top: 20%; animation-delay: 4s; }
.hall__motes i:nth-child(4) { left: 60%; top: 70%; animation-delay: 1s; }
.hall__motes i:nth-child(5) { left: 72%; top: 40%; animation-delay: 5s; }
.hall__motes i:nth-child(6) { left: 86%; top: 55%; animation-delay: 3s; }
.hall__motes i:nth-child(7) { left: 18%; top: 80%; animation-delay: 6s; }
.hall__motes i:nth-child(8) { left: 54%; top: 35%; animation-delay: 7s; }
.hall__motes i:nth-child(9) { left: 38%; top: 85%; animation-delay: 2.5s; }
.hall__motes i:nth-child(10) { left: 80%; top: 25%; animation-delay: 4.5s; }
@keyframes drift {
0% { transform: translateY(0) scale(0.6); opacity: 0; }
20% { opacity: 0.7; }
80% { opacity: 0.5; }
100% { transform: translateY(-60px) scale(1); opacity: 0; }
}
/* ---------- Section shells ---------- */
.section-head { max-width: 640px; margin: 0 0 44px; }
.kicker {
font-size: 0.78rem;
letter-spacing: 0.28em;
text-transform: uppercase;
color: var(--accent);
font-weight: 600;
margin: 0 0 14px;
}
.section-title {
font-family: var(--display);
font-weight: 600;
font-size: clamp(2.1rem, 5vw, 3.4rem);
line-height: 1.05;
margin: 0 0 14px;
}
.section-sub { color: var(--muted); font-size: 1.04rem; margin: 0; }
/* ---------- Season ---------- */
.season { padding: clamp(70px, 10vw, 120px) 0; }
.filters {
display: flex;
flex-direction: column;
gap: 14px;
margin-bottom: 38px;
}
.filters__set { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
font-family: var(--body);
font-size: 0.86rem;
font-weight: 500;
color: var(--muted);
background: var(--surface);
border: 1px solid var(--line);
padding: 9px 18px;
border-radius: var(--r-full);
cursor: pointer;
transition: all 0.18s ease;
}
.chip:hover { border-color: var(--line-2); color: var(--text); }
.chip.is-active {
background: var(--accent-soft);
border-color: var(--accent);
color: var(--accent);
}
.chip--series.is-active { background: var(--accent); color: #1a1407; border-color: var(--accent); }
.concerts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.concert {
border: 1px solid var(--line);
border-radius: var(--r-lg);
background: linear-gradient(180deg, var(--surface), var(--bg-2));
overflow: hidden;
transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.concert:hover {
border-color: var(--line-2);
box-shadow: var(--shadow-soft);
}
.concert.is-open { border-color: var(--accent); }
.concert__head {
display: grid;
grid-template-columns: 96px 1fr auto;
gap: clamp(16px, 3vw, 32px);
align-items: center;
width: 100%;
text-align: left;
background: none;
border: none;
color: inherit;
font-family: inherit;
cursor: pointer;
padding: clamp(18px, 3vw, 26px) clamp(20px, 4vw, 32px);
}
.concert__date {
text-align: center;
border-right: 1px solid var(--line);
padding-right: clamp(12px, 3vw, 24px);
}
.concert__day {
font-family: var(--display);
font-size: 2.4rem;
font-weight: 600;
line-height: 1;
color: var(--accent);
}
.concert__mon {
display: block;
font-size: 0.72rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
margin-top: 4px;
}
.concert__main { min-width: 0; }
.concert__series {
display: inline-block;
font-size: 0.7rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
border: 1px solid var(--line-2);
border-radius: var(--r-full);
padding: 3px 12px;
margin-bottom: 10px;
}
.concert__title {
font-family: var(--display);
font-size: clamp(1.3rem, 3vw, 1.7rem);
font-weight: 600;
margin: 0 0 6px;
}
.concert__people { color: var(--muted); font-size: 0.92rem; }
.concert__people b { color: var(--text); font-weight: 600; }
.concert__aside {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
}
.concert__time {
font-size: 0.84rem;
color: var(--muted);
font-variant-numeric: tabular-nums;
}
.concert__chev {
width: 26px; height: 26px;
display: grid;
place-items: center;
border-radius: 50%;
border: 1px solid var(--line-2);
color: var(--muted);
transition: transform 0.25s ease, color 0.2s ease, border-color 0.2s ease;
}
.concert.is-open .concert__chev { transform: rotate(180deg); color: var(--accent); border-color: var(--accent); }
.concert__chev svg { width: 12px; height: 12px; }
.concert__panel {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s ease;
}
.concert__panel-inner {
padding: 0 clamp(20px, 4vw, 32px) clamp(22px, 4vw, 30px);
display: grid;
grid-template-columns: 1fr auto;
gap: clamp(20px, 4vw, 40px);
border-top: 1px solid var(--line);
}
.programme { padding-top: 22px; }
.programme h4 {
font-size: 0.74rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 14px;
}
.programme ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.programme li {
display: flex;
justify-content: space-between;
gap: 18px;
padding-bottom: 12px;
border-bottom: 1px dashed var(--line);
}
.programme li:last-child { border-bottom: none; padding-bottom: 0; }
.programme .work { font-family: var(--display); font-size: 1.18rem; }
.programme .work small { display: block; font-family: var(--body); font-size: 0.82rem; color: var(--muted); margin-top: 2px; }
.programme .dur { color: var(--muted); font-size: 0.86rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.concert__buy {
padding-top: 22px;
display: flex;
flex-direction: column;
gap: 12px;
align-items: flex-start;
min-width: 180px;
border-left: 1px solid var(--line);
padding-left: clamp(20px, 4vw, 40px);
}
.concert__price { font-family: var(--display); font-size: 1.6rem; font-weight: 600; }
.concert__price small { font-family: var(--body); font-size: 0.78rem; color: var(--muted); }
.concert__seats { font-size: 0.82rem; color: var(--muted); }
.concert__seats.low { color: var(--accent); }
.concerts__empty {
text-align: center;
color: var(--muted);
padding: 48px 0;
font-family: var(--display);
font-size: 1.4rem;
}
/* ---------- Spotlight ---------- */
.spotlight {
padding: clamp(70px, 10vw, 120px) 0;
background: linear-gradient(180deg, var(--bg), var(--bg-2));
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.spotlight__grid {
display: grid;
grid-template-columns: 0.85fr 1.15fr;
gap: clamp(32px, 6vw, 72px);
align-items: center;
}
.spotlight__portrait { position: relative; }
.portrait {
position: relative;
aspect-ratio: 4 / 5;
border-radius: var(--r-lg);
background:
radial-gradient(80% 60% at 50% 18%, rgba(201, 162, 75, 0.22), transparent 60%),
linear-gradient(180deg, var(--surface-2), #0c1530);
border: 1px solid var(--line-2);
overflow: hidden;
box-shadow: var(--shadow);
}
.portrait__head {
position: absolute;
top: 22%; left: 50%;
transform: translateX(-50%);
width: 34%; aspect-ratio: 1;
border-radius: 50% 50% 48% 48%;
background: linear-gradient(160deg, #efe3c8, #cbb98c);
}
.portrait__shoulders {
position: absolute;
bottom: 0; left: 50%;
transform: translateX(-50%);
width: 78%; height: 44%;
border-radius: 50% 50% 0 0;
background: linear-gradient(180deg, #1f2c4f, #16223f);
border-top: 2px solid var(--accent);
}
.portrait__baton {
position: absolute;
top: 40%; right: 18%;
width: 28%; height: 3px;
background: var(--paper);
border-radius: 2px;
transform: rotate(-32deg);
box-shadow: 0 0 10px rgba(244, 239, 226, 0.5);
}
.portrait__plate {
position: absolute;
left: 16px; bottom: 16px;
background: rgba(14, 23, 48, 0.8);
backdrop-filter: blur(6px);
border: 1px solid var(--line-2);
border-radius: var(--r-full);
padding: 7px 16px;
font-size: 0.76rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent);
}
.spotlight__role { color: var(--accent); font-weight: 600; margin: 0 0 18px; }
.spotlight__text { color: var(--muted); font-size: 1.06rem; margin: 0 0 22px; max-width: 56ch; }
.spotlight__quote {
font-family: var(--display);
font-style: italic;
font-size: clamp(1.3rem, 3vw, 1.7rem);
line-height: 1.35;
margin: 0 0 24px;
padding-left: 22px;
border-left: 2px solid var(--accent);
color: var(--text);
}
.spotlight__meta { display: flex; flex-wrap: wrap; gap: 24px; }
.spotlight__meta span { font-size: 0.9rem; color: var(--muted); }
.spotlight__meta strong { display: block; color: var(--text); font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; margin-bottom: 3px; }
/* ---------- Packages ---------- */
.packages { padding: clamp(70px, 10vw, 120px) 0; }
.package-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 22px;
}
.pkg {
position: relative;
border: 1px solid var(--line);
border-radius: var(--r-lg);
background: linear-gradient(180deg, var(--surface), var(--bg-2));
padding: clamp(26px, 4vw, 38px);
display: flex;
flex-direction: column;
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.pkg:hover { transform: translateY(-4px); border-color: var(--line-2); box-shadow: var(--shadow-soft); }
.pkg--feature {
border-color: var(--accent);
background: linear-gradient(180deg, rgba(201, 162, 75, 0.12), var(--bg-2));
}
.pkg__ribbon {
position: absolute;
top: 18px; right: 18px;
background: var(--accent);
color: #1a1407;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 5px 12px;
border-radius: var(--r-full);
}
.pkg__name { font-family: var(--display); font-size: 1.9rem; font-weight: 600; margin: 0 0 8px; }
.pkg__price { margin: 0 0 22px; color: var(--muted); font-size: 0.92rem; }
.pkg__price span { font-family: var(--display); font-size: 2rem; color: var(--accent); font-weight: 600; }
.pkg__list { list-style: none; margin: 0 0 26px; padding: 0; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.pkg__list li { position: relative; padding-left: 26px; color: var(--muted); font-size: 0.94rem; }
.pkg__list li::before {
content: "";
position: absolute;
left: 0; top: 7px;
width: 12px; height: 7px;
border-left: 2px solid var(--accent);
border-bottom: 2px solid var(--accent);
transform: rotate(-45deg);
}
.pkg__cta { width: 100%; justify-content: center; }
/* ---------- Venue ---------- */
.venue {
padding: clamp(70px, 10vw, 120px) 0;
background: linear-gradient(180deg, var(--bg-2), var(--bg));
border-top: 1px solid var(--line);
}
.venue__grid {
display: grid;
grid-template-columns: 1.1fr 0.9fr;
gap: clamp(32px, 6vw, 72px);
align-items: center;
}
.venue-card {
position: relative;
aspect-ratio: 5 / 4;
border-radius: var(--r-lg);
background:
radial-gradient(100% 70% at 50% 0%, rgba(201, 162, 75, 0.16), transparent 60%),
linear-gradient(180deg, var(--surface), #0c1530);
border: 1px solid var(--line-2);
overflow: hidden;
box-shadow: var(--shadow);
}
.venue-card__dome {
position: absolute;
top: 14%; left: 50%;
transform: translateX(-50%);
width: 52%; aspect-ratio: 2 / 1;
border-radius: 100% 100% 0 0;
background: linear-gradient(180deg, rgba(201, 162, 75, 0.3), rgba(201, 162, 75, 0.05));
border: 1px solid var(--accent);
border-bottom: none;
}
.venue-card__cols {
position: absolute;
bottom: 24%; left: 50%;
transform: translateX(-50%);
display: flex;
gap: 8%;
width: 60%;
justify-content: center;
}
.venue-card__cols i {
width: 10px; height: 30vh;
max-height: 130px;
background: linear-gradient(180deg, var(--paper), #b9ab85);
border-radius: 2px 2px 0 0;
}
.venue-card__steps {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 22%;
background: repeating-linear-gradient(180deg, rgba(244, 239, 226, 0.14) 0 6px, transparent 6px 12px),
linear-gradient(180deg, #1a2647, #11203c);
border-top: 1px solid var(--accent);
}
.venue__text { color: var(--muted); font-size: 1.06rem; margin: 0 0 24px; max-width: 52ch; }
.venue__facts { list-style: none; margin: 0 0 30px; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; }
.venue__facts li { font-size: 0.94rem; color: var(--muted); }
.venue__facts strong { display: block; color: var(--text); font-size: 0.74rem; letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 4px; }
/* ---------- Footer ---------- */
.footer {
border-top: 1px solid var(--line);
padding: clamp(54px, 8vw, 84px) 0 32px;
background: var(--bg-2);
}
.footer__inner {
display: grid;
grid-template-columns: 1.3fr 2fr;
gap: clamp(32px, 6vw, 80px);
padding-bottom: 40px;
border-bottom: 1px solid var(--line);
}
.footer__brand .brand__name { font-size: 1.6rem; }
.footer__brand p { color: var(--muted); margin: 14px 0 0; font-size: 0.92rem; max-width: 38ch; }
.footer__cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.footer__cols h4 {
font-size: 0.74rem;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 16px;
}
.footer__cols a { display: block; color: var(--muted); font-size: 0.92rem; margin-bottom: 11px; transition: color 0.2s ease; }
.footer__cols a:hover { color: var(--text); }
.footer__base {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
padding-top: 26px;
color: var(--muted);
font-size: 0.84rem;
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 32px;
transform: translate(-50%, 24px);
background: var(--paper);
color: #1a1407;
padding: 14px 24px;
border-radius: var(--r-full);
font-weight: 600;
font-size: 0.92rem;
box-shadow: var(--shadow);
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease, transform 0.25s ease;
z-index: 80;
max-width: calc(100vw - 40px);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
/* ---------- Reveal ---------- */
.reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal.in { opacity: 1; transform: none; }
/* ---------- Responsive ---------- */
@media (max-width: 920px) {
.nav { display: none; }
.spotlight__grid,
.venue__grid { grid-template-columns: 1fr; }
.spotlight__portrait { max-width: 420px; }
.package-grid { grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; }
.footer__inner { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
.concert__panel-inner { grid-template-columns: 1fr; }
.concert__buy { border-left: none; border-top: 1px solid var(--line); padding-left: 0; padding-top: 18px; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; width: 100%; }
}
@media (max-width: 520px) {
.nav__cta { display: none; }
.topbar__inner { height: 64px; }
.hero { padding-top: 56px; }
.hero__stats { gap: 24px; flex-wrap: wrap; }
.hero__stats dd { font-size: 1.6rem; }
.sampler { flex-wrap: wrap; }
.concert__head { grid-template-columns: 64px 1fr; }
.concert__aside { grid-column: 1 / -1; flex-direction: row; justify-content: space-between; align-items: center; padding-top: 6px; }
.concert__day { font-size: 1.9rem; }
.footer__cols { grid-template-columns: 1fr 1fr; }
.footer__base { font-size: 0.78rem; }
.venue__facts { grid-template-columns: 1fr; }
.hall__arches { display: none; }
}(function () {
"use strict";
var prefersReduced = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
/* ---------------- Toast ---------------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2400);
}
/* ---------------- Concert data ---------------- */
var concerts = [
{
day: "11",
mon: "Oct",
month: "Oct",
series: "Masterworks",
title: "An Evening of Beethoven",
conductor: "Élise Maron",
soloist: "Anwar Beck, piano",
time: "Sat · 7:30pm",
price: 38,
seats: 220,
programme: [
{ work: "Coriolan Overture", sub: "Beethoven", dur: "8:00" },
{ work: "Piano Concerto No. 4", sub: "Beethoven · Anwar Beck", dur: "34:00" },
{ work: "Symphony No. 7", sub: "Beethoven", dur: "39:00" }
]
},
{
day: "25",
mon: "Oct",
month: "Oct",
series: "New Voices",
title: "Reservoir — A Premiere",
conductor: "Élise Maron",
soloist: "Composer in residence: Talia Wren",
time: "Sat · 7:30pm",
price: 32,
seats: 18,
programme: [
{ work: "Midnight Reservoir", sub: "Talia Wren · world premiere", dur: "22:00" },
{ work: "The Lark Ascending", sub: "Vaughan Williams", dur: "15:00" },
{ work: "Symphony No. 5", sub: "Sibelius", dur: "31:00" }
]
},
{
day: "09",
mon: "Nov",
month: "Nov",
series: "Recital",
title: "Cello by Candlelight",
conductor: "—",
soloist: "Mira Solveig, cello",
time: "Sun · 6:00pm",
price: 26,
seats: 64,
programme: [
{ work: "Cello Suite No. 1", sub: "J.S. Bach", dur: "18:00" },
{ work: "Sonata in G minor", sub: "Rachmaninoff", dur: "33:00" },
{ work: "Paper Lanterns", sub: "Talia Wren · encore", dur: "5:00" }
]
},
{
day: "22",
mon: "Nov",
month: "Nov",
series: "Masterworks",
title: "The Romantic Imagination",
conductor: "Henri Vael",
soloist: "Anwar Beck, piano",
time: "Sat · 7:30pm",
price: 42,
seats: 140,
programme: [
{ work: "Hebrides Overture", sub: "Mendelssohn", dur: "10:00" },
{ work: "Piano Concerto No. 2", sub: "Brahms · Anwar Beck", dur: "48:00" },
{ work: "Symphonic Dances", sub: "Rachmaninoff", dur: "35:00" }
]
},
{
day: "17",
mon: "Jan",
month: "Jan",
series: "Masterworks",
title: "New Year, New World",
conductor: "Élise Maron",
soloist: "Aurelian Chorus",
time: "Sat · 7:30pm",
price: 46,
seats: 9,
programme: [
{ work: "Symphony No. 9 ‘From the New World’", sub: "Dvořák", dur: "42:00" },
{ work: "Te Deum", sub: "Bruckner · with chorus", dur: "24:00" }
]
},
{
day: "31",
mon: "Jan",
month: "Jan",
series: "New Voices",
title: "Strings After Dark",
conductor: "Henri Vael",
soloist: "Quartet in residence",
time: "Sat · 9:00pm",
price: 24,
seats: 110,
programme: [
{ work: "Velvet Static", sub: "Talia Wren", dur: "16:00" },
{ work: "Metamorphosen", sub: "R. Strauss", dur: "26:00" },
{ work: "Adagio for Strings", sub: "Barber", dur: "9:00" }
]
},
{
day: "14",
mon: "Mar",
month: "Mar",
series: "Recital",
title: "A Soprano in Spring",
conductor: "—",
soloist: "Liora Fenn, soprano",
time: "Sat · 7:30pm",
price: 30,
seats: 70,
programme: [
{ work: "Four Last Songs", sub: "R. Strauss · Liora Fenn", dur: "22:00" },
{ work: "Knoxville: Summer of 1915", sub: "Barber", dur: "16:00" },
{ work: "Neon Tides", sub: "Talia Wren · song cycle", dur: "19:00" }
]
},
{
day: "28",
mon: "Mar",
month: "Mar",
series: "Masterworks",
title: "Mahler's Resurrection",
conductor: "Élise Maron",
soloist: "Aurelian Chorus & soloists",
time: "Sat · 7:00pm",
price: 52,
seats: 4,
programme: [
{ work: "Symphony No. 2 ‘Resurrection’", sub: "Mahler · with chorus", dur: "85:00" }
]
},
{
day: "16",
mon: "May",
month: "May",
series: "Masterworks",
title: "Season Finale: Firebird",
conductor: "Élise Maron",
soloist: "Mira Solveig, cello",
time: "Sat · 7:30pm",
price: 48,
seats: 32,
programme: [
{ work: "Cello Concerto", sub: "Elgar · Mira Solveig", dur: "30:00" },
{ work: "The Firebird Suite", sub: "Stravinsky", dur: "23:00" },
{ work: "Enigma Variations ‘Nimrod’", sub: "Elgar · finale", dur: "4:00" }
]
}
];
/* ---------------- Render concerts ---------------- */
var listEl = document.getElementById("concerts");
var emptyEl = document.getElementById("concertsEmpty");
var chevSvg =
'<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M2 4l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>';
function programmeRows(items) {
return items
.map(function (p) {
return (
'<li><span class="work">' +
p.work +
"<small>" +
p.sub +
"</small></span><span class=\"dur\">" +
p.dur +
"</span></li>"
);
})
.join("");
}
function buildConcert(c, i) {
var li = document.createElement("li");
li.className = "concert";
li.dataset.month = c.month;
li.dataset.series = c.series;
var low = c.seats <= 20;
var panelId = "panel-" + i;
var headId = "head-" + i;
li.innerHTML =
'<button class="concert__head" id="' +
headId +
'" type="button" aria-expanded="false" aria-controls="' +
panelId +
'">' +
'<span class="concert__date"><span class="concert__day">' +
c.day +
'</span><span class="concert__mon">' +
c.mon +
"</span></span>" +
'<span class="concert__main">' +
'<span class="concert__series">' +
c.series +
"</span>" +
'<span class="concert__title">' +
c.title +
"</span>" +
'<span class="concert__people">' +
(c.conductor !== "—" ? "Cond. <b>" + c.conductor + "</b> · " : "") +
c.soloist +
"</span>" +
"</span>" +
'<span class="concert__aside">' +
'<span class="concert__time">' +
c.time +
"</span>" +
'<span class="concert__chev">' +
chevSvg +
"</span>" +
"</span>" +
"</button>" +
'<div class="concert__panel" id="' +
panelId +
'" role="region" aria-labelledby="' +
headId +
'">' +
'<div class="concert__panel-inner">' +
'<div class="programme"><h4>Programme</h4><ul>' +
programmeRows(c.programme) +
"</ul></div>" +
'<div class="concert__buy">' +
'<span class="concert__price">£' +
c.price +
"<small> from</small></span>" +
'<span class="concert__seats' +
(low ? " low" : "") +
'">' +
(low ? "Only " + c.seats + " seats left" : c.seats + " seats available") +
"</span>" +
'<button class="btn btn--gold concert__ticket" type="button">Tickets</button>' +
"</div>" +
"</div>" +
"</div>";
return li;
}
if (listEl) {
concerts.forEach(function (c, i) {
listEl.appendChild(buildConcert(c, i));
});
}
/* ---------------- Expand / collapse ---------------- */
function closePanel(panel, head, concert) {
panel.style.maxHeight = "0px";
head.setAttribute("aria-expanded", "false");
concert.classList.remove("is-open");
}
function openPanel(panel, head, concert) {
panel.style.maxHeight = panel.scrollHeight + 40 + "px";
head.setAttribute("aria-expanded", "true");
concert.classList.add("is-open");
}
if (listEl) {
listEl.addEventListener("click", function (e) {
var ticket = e.target.closest(".concert__ticket");
if (ticket) {
var concertTitle = ticket
.closest(".concert")
.querySelector(".concert__title").textContent;
toast("Tickets reserved — " + concertTitle);
return;
}
var head = e.target.closest(".concert__head");
if (!head) return;
var concert = head.closest(".concert");
var panel = concert.querySelector(".concert__panel");
var isOpen = head.getAttribute("aria-expanded") === "true";
// close any other open ones for a tidy single-open feel
var others = listEl.querySelectorAll(".concert.is-open");
others.forEach(function (o) {
if (o !== concert) {
closePanel(
o.querySelector(".concert__panel"),
o.querySelector(".concert__head"),
o
);
}
});
if (isOpen) closePanel(panel, head, concert);
else openPanel(panel, head, concert);
});
}
/* ---------------- Filters ---------------- */
var activeMonth = "all";
var activeSeries = "all";
function applyFilters() {
if (!listEl) return;
var visible = 0;
listEl.querySelectorAll(".concert").forEach(function (c) {
var mOk = activeMonth === "all" || c.dataset.month === activeMonth;
var sOk = activeSeries === "all" || c.dataset.series === activeSeries;
var show = mOk && sOk;
c.style.display = show ? "" : "none";
if (show) visible++;
else {
// collapse hidden open panels
var head = c.querySelector(".concert__head");
if (head.getAttribute("aria-expanded") === "true") {
closePanel(c.querySelector(".concert__panel"), head, c);
}
}
});
if (emptyEl) emptyEl.hidden = visible !== 0;
}
function wireFilterSet(containerId, attr, setter) {
var container = document.getElementById(containerId);
if (!container) return;
container.addEventListener("click", function (e) {
var chip = e.target.closest(".chip");
if (!chip) return;
container.querySelectorAll(".chip").forEach(function (b) {
b.classList.remove("is-active");
b.setAttribute("aria-pressed", "false");
});
chip.classList.add("is-active");
chip.setAttribute("aria-pressed", "true");
setter(chip.dataset[attr]);
applyFilters();
});
}
wireFilterSet("monthFilters", "month", function (v) {
activeMonth = v;
});
wireFilterSet("seriesFilters", "series", function (v) {
activeSeries = v;
});
/* ---------------- Package CTAs ---------------- */
document.querySelectorAll(".pkg__cta").forEach(function (btn) {
btn.addEventListener("click", function () {
toast(btn.dataset.pkg + " subscription added — see you at the hall");
});
});
/* ---------------- Hero waveform sampler ---------------- */
var waveEl = document.getElementById("heroWave");
var samplerEl = waveEl ? waveEl.closest(".sampler") : null;
var listenBtn = document.getElementById("heroListen");
var timeEl = document.getElementById("heroTime");
var BAR_COUNT = 56;
var heights = [];
var bars = [];
var TOTAL = 134; // 2:14 in seconds
if (waveEl) {
for (var b = 0; b < BAR_COUNT; b++) {
var i = document.createElement("i");
// a smooth-ish pseudo waveform envelope
var env = Math.sin((b / BAR_COUNT) * Math.PI);
var h = 14 + env * 70 + (Math.sin(b * 1.7) + 1) * 12;
heights.push(Math.max(10, Math.min(100, h)));
i.style.height = heights[b] + "%";
waveEl.appendChild(i);
bars.push(i);
}
}
function fmt(s) {
var m = Math.floor(s / 60);
var r = Math.floor(s % 60);
return m + ":" + (r < 10 ? "0" : "") + r;
}
var playing = false;
var rafTimer = null;
var elapsed = 0;
var lastTick = 0;
function setProgressUI() {
var ratio = elapsed / TOTAL;
var litCount = Math.floor(ratio * BAR_COUNT);
for (var k = 0; k < BAR_COUNT; k++) {
bars[k].classList.toggle("lit", k < litCount);
bars[k].classList.toggle("active", k === litCount && playing);
}
if (timeEl) timeEl.textContent = fmt(elapsed) + " / 2:14";
}
function tick(now) {
if (!playing) return;
if (!lastTick) lastTick = now;
var dt = (now - lastTick) / 1000;
lastTick = now;
elapsed += dt;
// gently animate bar heights for a "living" waveform while playing
if (!prefersReduced) {
var idx = Math.floor((elapsed / TOTAL) * BAR_COUNT);
for (var k = Math.max(0, idx - 2); k <= Math.min(BAR_COUNT - 1, idx + 2); k++) {
var pulse = heights[k] + Math.sin(elapsed * 6 + k) * 10;
bars[k].style.height = Math.max(10, Math.min(100, pulse)) + "%";
}
}
if (elapsed >= TOTAL) {
stopPlayback(true);
return;
}
setProgressUI();
rafTimer = requestAnimationFrame(tick);
}
function startPlayback() {
playing = true;
lastTick = 0;
if (samplerEl) samplerEl.classList.add("playing");
if (listenBtn) {
listenBtn.classList.add("is-playing");
listenBtn.setAttribute("aria-pressed", "true");
listenBtn.querySelector(".listen__label").textContent = "Pause sample";
}
toast("Now sampling — Mahler, Symphony No. 2");
rafTimer = requestAnimationFrame(tick);
}
function stopPlayback(ended) {
playing = false;
cancelAnimationFrame(rafTimer);
if (samplerEl) samplerEl.classList.remove("playing");
if (listenBtn) {
listenBtn.classList.remove("is-playing");
listenBtn.setAttribute("aria-pressed", "false");
listenBtn.querySelector(".listen__label").textContent = "Listen to a sample";
}
if (ended) {
elapsed = 0;
// restore original heights
for (var k = 0; k < BAR_COUNT; k++) bars[k].style.height = heights[k] + "%";
setProgressUI();
}
}
if (listenBtn) {
listenBtn.addEventListener("click", function () {
if (playing) stopPlayback(false);
else startPlayback();
});
}
setProgressUI();
/* ---------------- Scroll reveal ---------------- */
var revealEls = document.querySelectorAll(".reveal");
if (prefersReduced || !("IntersectionObserver" in window)) {
revealEls.forEach(function (el) {
el.classList.add("in");
});
} else {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add("in");
io.unobserve(entry.target);
}
});
},
{ threshold: 0.12, rootMargin: "0px 0px -8% 0px" }
);
revealEls.forEach(function (el, idx) {
el.style.transitionDelay = Math.min(idx % 5, 4) * 60 + "ms";
io.observe(el);
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Aurelian Symphony — Season 2026</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,500&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#season">Skip to season</a>
<!-- ============ TOP BAR ============ -->
<header class="topbar" id="top">
<div class="wrap topbar__inner">
<a class="brand" href="#top" aria-label="Aurelian Symphony home">
<span class="brand__mark" aria-hidden="true">
<span></span><span></span><span></span>
</span>
<span class="brand__name">Aurelian <em>Symphony</em></span>
</a>
<nav class="nav" aria-label="Primary">
<a href="#season">Season</a>
<a href="#spotlight">Spotlight</a>
<a href="#packages">Subscribe</a>
<a href="#venue">Venue</a>
</nav>
<a class="btn btn--ghost nav__cta" href="#season">Browse the season</a>
</div>
</header>
<!-- ============ HERO ============ -->
<section class="hero" aria-labelledby="hero-title">
<div class="hall" aria-hidden="true">
<div class="hall__dome"></div>
<div class="hall__arches">
<span></span><span></span><span></span><span></span><span></span>
</div>
<div class="hall__stage"></div>
<div class="hall__chandelier">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>
<div class="hall__motes">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>
</div>
<div class="wrap hero__inner">
<p class="hero__eyebrow reveal">2026 — 2027 Concert Season</p>
<h1 class="hero__title reveal" id="hero-title">
Where silence<br />becomes <em>song</em>.
</h1>
<p class="hero__lede reveal">
Twelve evenings of orchestral splendour at the Aurelian Hall — from the thunder of
Beethoven to the shimmer of new commissions, led by conductors of rare conviction.
</p>
<div class="hero__actions reveal">
<a class="btn btn--gold" href="#season">Browse the season</a>
<button class="btn btn--quiet listen" id="heroListen" type="button" aria-pressed="false">
<span class="listen__icon" aria-hidden="true"></span>
<span class="listen__label">Listen to a sample</span>
</button>
</div>
<!-- refined waveform -->
<div class="sampler reveal" aria-hidden="true">
<div class="sampler__bars" id="heroWave"></div>
<span class="sampler__time" id="heroTime">0:00 / 2:14</span>
</div>
<dl class="hero__stats reveal">
<div><dt>Concerts</dt><dd>12</dd></div>
<div><dt>Musicians</dt><dd>84</dd></div>
<div><dt>Seasons</dt><dd>41st</dd></div>
</dl>
</div>
</section>
<!-- ============ SEASON ============ -->
<section class="season" id="season" aria-labelledby="season-title">
<div class="wrap">
<div class="section-head reveal">
<p class="kicker">The Programme</p>
<h2 class="section-title" id="season-title">A season in twelve movements</h2>
<p class="section-sub">
Filter the calendar by month or by series. Expand any evening to read the full programme.
</p>
</div>
<div class="filters reveal" role="group" aria-label="Filter concerts">
<div class="filters__set" id="monthFilters" aria-label="Filter by month">
<button class="chip is-active" type="button" data-month="all" aria-pressed="true">All months</button>
<button class="chip" type="button" data-month="Oct" aria-pressed="false">Oct</button>
<button class="chip" type="button" data-month="Nov" aria-pressed="false">Nov</button>
<button class="chip" type="button" data-month="Jan" aria-pressed="false">Jan</button>
<button class="chip" type="button" data-month="Mar" aria-pressed="false">Mar</button>
<button class="chip" type="button" data-month="May" aria-pressed="false">May</button>
</div>
<div class="filters__set" id="seriesFilters" aria-label="Filter by series">
<button class="chip chip--series is-active" type="button" data-series="all" aria-pressed="true">All series</button>
<button class="chip chip--series" type="button" data-series="Masterworks" aria-pressed="false">Masterworks</button>
<button class="chip chip--series" type="button" data-series="Recital" aria-pressed="false">Recital</button>
<button class="chip chip--series" type="button" data-series="New Voices" aria-pressed="false">New Voices</button>
</div>
</div>
<ul class="concerts" id="concerts" aria-label="Season concerts"></ul>
<p class="concerts__empty" id="concertsEmpty" hidden>No concerts match those filters.</p>
</div>
</section>
<!-- ============ SPOTLIGHT ============ -->
<section class="spotlight" id="spotlight" aria-labelledby="spotlight-title">
<div class="wrap spotlight__grid">
<div class="spotlight__portrait reveal" aria-hidden="true">
<div class="portrait">
<div class="portrait__head"></div>
<div class="portrait__shoulders"></div>
<div class="portrait__baton"></div>
</div>
<span class="portrait__plate">Principal Conductor</span>
</div>
<div class="spotlight__body reveal">
<p class="kicker">Artist Spotlight</p>
<h2 class="section-title" id="spotlight-title">Élise Maron</h2>
<p class="spotlight__role">Music Director & Conductor</p>
<p class="spotlight__text">
In her fourth season at the helm, Maron has reshaped the orchestra's voice — luminous,
unhurried, fearless in its quiet. Trained in Vienna and Lyon, she pairs the canon with
living composers, insisting that every programme hold a question as well as an answer.
</p>
<blockquote class="spotlight__quote">
“An orchestra is eighty-four people agreeing to listen harder than they speak.”
</blockquote>
<div class="spotlight__meta">
<span><strong>Debut</strong> Vienna, 2009</span>
<span><strong>Repertoire</strong> 200+ works</span>
<span><strong>Recordings</strong> 14</span>
</div>
</div>
</div>
</section>
<!-- ============ PACKAGES ============ -->
<section class="packages" id="packages" aria-labelledby="packages-title">
<div class="wrap">
<div class="section-head reveal">
<p class="kicker">Season Tickets</p>
<h2 class="section-title" id="packages-title">Subscribe to the season</h2>
<p class="section-sub">Reserve your seat for the year. Subscribers choose seats first and pay less per concert.</p>
</div>
<div class="package-grid">
<article class="pkg reveal">
<h3 class="pkg__name">Prelude</h3>
<p class="pkg__price"><span>£180</span> / 4 concerts</p>
<ul class="pkg__list">
<li>Choose any four evenings</li>
<li>Priority renewal</li>
<li>Digital programme notes</li>
</ul>
<button class="btn btn--outline pkg__cta" type="button" data-pkg="Prelude">Choose Prelude</button>
</article>
<article class="pkg pkg--feature reveal">
<span class="pkg__ribbon">Most chosen</span>
<h3 class="pkg__name">Resonance</h3>
<p class="pkg__price"><span>£420</span> / 8 concerts</p>
<ul class="pkg__list">
<li>Eight evenings, best seats</li>
<li>Invitation to open rehearsals</li>
<li>Interval reception included</li>
<li>10% on additional tickets</li>
</ul>
<button class="btn btn--gold pkg__cta" type="button" data-pkg="Resonance">Choose Resonance</button>
</article>
<article class="pkg reveal">
<h3 class="pkg__name">Maestro</h3>
<p class="pkg__price"><span>£640</span> / full season</p>
<ul class="pkg__list">
<li>All twelve concerts</li>
<li>Reserved parterre seating</li>
<li>Backstage salon evenings</li>
<li>Annual recording boxset</li>
</ul>
<button class="btn btn--outline pkg__cta" type="button" data-pkg="Maestro">Choose Maestro</button>
</article>
</div>
</div>
</section>
<!-- ============ VENUE / ABOUT ============ -->
<section class="venue" id="venue" aria-labelledby="venue-title">
<div class="wrap venue__grid">
<div class="venue__art reveal" aria-hidden="true">
<div class="venue-card">
<div class="venue-card__dome"></div>
<div class="venue-card__cols"><i></i><i></i><i></i><i></i><i></i></div>
<div class="venue-card__steps"></div>
</div>
</div>
<div class="venue__body reveal">
<p class="kicker">The Hall</p>
<h2 class="section-title" id="venue-title">Aurelian Hall</h2>
<p class="venue__text">
Opened in 1903 and acoustically restored in 2018, the Aurelian Hall seats 1,460 beneath a
gilded dome. Its shoebox geometry gives the strings a warmth that recording engineers
travel continents to capture.
</p>
<ul class="venue__facts">
<li><strong>Capacity</strong> 1,460 seats</li>
<li><strong>Address</strong> 14 Meridian Crescent</li>
<li><strong>Doors</strong> 45 minutes before curtain</li>
<li><strong>Access</strong> Step-free throughout</li>
</ul>
<a class="btn btn--outline" href="#season">Plan your evening</a>
</div>
</div>
</section>
<!-- ============ FOOTER ============ -->
<footer class="footer">
<div class="wrap footer__inner">
<div class="footer__brand">
<span class="brand__name">Aurelian <em>Symphony</em></span>
<p>Season 2026 — 2027. A fictional orchestra for illustration only.</p>
</div>
<nav class="footer__cols" aria-label="Footer">
<div>
<h4>Attend</h4>
<a href="#season">Concert calendar</a>
<a href="#packages">Season tickets</a>
<a href="#venue">Visit the hall</a>
</div>
<div>
<h4>Discover</h4>
<a href="#spotlight">Artists</a>
<a href="#season">Programme notes</a>
<a href="#top">Recordings</a>
</div>
<div>
<h4>Connect</h4>
<a href="#top">Newsletter</a>
<a href="#top">Patrons circle</a>
<a href="#top">Education</a>
</div>
</nav>
</div>
<div class="wrap footer__base">
<span>© 2026 Aurelian Symphony</span>
<span>Box office · +44 20 7946 0000</span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Classical / Orchestra Landing
A premium landing page for the fictional Aurelian Symphony and its 2026—2027 concert season, dressed in ivory, deep navy, and gold with elegant Cormorant Garamond display type over an Inter body. The hero pairs a serif headline with an atmospheric concert-hall scene drawn entirely in CSS — a gilded dome, a twinkling chandelier, receding arches, and slowly drifting dust motes — plus a season tagline, a “Browse the season” call to action, and a restrained waveform sampler.
The heart of the page is a season calendar of nine evenings, each with its date, series, conductor, and soloist. Filter chips narrow the list by month or by series, and any concert expands inline to reveal its full programme — works, composers, and durations — alongside pricing and a live “seats left” indicator that flags nearly sold-out nights. A conductor spotlight, three subscription packages (Prelude, Resonance, Maestro), an acoustically-restored venue section, and a stately footer round out the page.
All interactions are vanilla JS: the concert list and programmes render from data with
keyboard-usable, ARIA-wired accordions; the “listen to a sample” button drives a simulated
requestAnimationFrame playback that lights and animates the waveform with a running timestamp;
filters, package CTAs, and ticket buttons confirm through a small toast() helper; and sections
reveal on scroll via IntersectionObserver. Everything respects prefers-reduced-motion and
reflows cleanly down to ~360px.
Illustrative UI only — fictional artists, albums, tracks, and data. No real audio playback.