News — Glossy Lifestyle Magazine Landing
An airy, premium landing page for Maison, a fictional glossy lifestyle magazine. A high-contrast Playfair Display masthead sits above a fashion-editorial hero with a coverline and large cover image, a refined featured-stories switcher, a four-up story grid with a drop cap and a dark pull quote, a This Issue contents strip, a contributors row, and a black subscribe block with plan selection. Vanilla JS powers a tabbed story switcher, gentle scroll parallax, and a validated subscribe form.
MCP
Code
:root {
/* Glossy lifestyle palette — white + black + hot magenta */
--paper: #ffffff;
--paper-2: #faf9f8;
--paper-3: #f3f1ef;
--ink: #0c0b0a;
--ink-2: #1d1b19;
--ink-3: #45413c;
--muted: #8c867d;
--accent: #e6007e; /* hot magenta */
--accent-d: #b80064;
--accent-50: #fde4f2;
--rule: rgba(12, 11, 10, 0.14);
--rule-2: rgba(12, 11, 10, 0.28);
--rule-hair: rgba(12, 11, 10, 0.08);
--r-sm: 4px;
--r-md: 8px;
--r-lg: 12px;
--shadow-soft: 0 18px 48px -28px rgba(12, 11, 10, 0.45);
--display: "Playfair Display", "Times New Roman", Georgia, serif;
--ui: "Inter", system-ui, -apple-system, sans-serif;
--maxw: 1240px;
--gutter: clamp(20px, 5vw, 64px);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--ui);
font-size: 17px;
line-height: 1.5;
color: var(--ink);
background: var(--paper);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--accent); color: #fff; }
.skip-link {
position: absolute;
left: -999px;
top: 0;
background: var(--ink);
color: #fff;
padding: 10px 16px;
z-index: 100;
border-radius: 0 0 var(--r-md) 0;
}
.skip-link:focus { left: 0; }
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 3px;
}
/* ---------- kickers / labels ---------- */
.kicker {
font-family: var(--ui);
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted);
margin: 0 0 0.9rem;
}
.kicker-accent { color: var(--accent); }
/* ---------- buttons ---------- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5em;
font-family: var(--ui);
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
text-decoration: none;
padding: 0.95em 1.6em;
border-radius: var(--r-sm);
border: 1px solid var(--ink);
cursor: pointer;
transition: transform 0.18s ease, background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.btn-solid { background: var(--ink); color: #fff; }
.btn-solid:hover { background: var(--accent); border-color: var(--accent); transform: translateY(-2px); }
.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost:hover { background: var(--ink); color: #fff; transform: translateY(-2px); }
.btn-block { width: 100%; }
/* ---------- masthead ---------- */
.masthead {
position: sticky;
top: 0;
z-index: 60;
background: rgba(255, 255, 255, 0.92);
backdrop-filter: saturate(1.1) blur(10px);
border-bottom: 1px solid var(--rule);
}
.masthead-inner {
max-width: var(--maxw);
margin: 0 auto;
padding: 0 var(--gutter);
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 1rem;
min-height: 76px;
}
.masthead-meta {
font-size: 0.68rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
.logo { text-decoration: none; text-align: center; }
.logo-word {
font-family: var(--display);
font-weight: 800;
font-size: clamp(1.5rem, 4vw, 2.1rem);
letter-spacing: 0.32em;
text-indent: 0.32em;
color: var(--ink);
}
.masthead-right { display: flex; justify-content: flex-end; }
.nav {
display: flex;
align-items: center;
gap: 1.6rem;
font-size: 0.78rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.nav a { text-decoration: none; color: var(--ink-2); transition: color 0.2s ease; }
.nav a:hover { color: var(--accent); }
.nav-cta {
border: 1px solid var(--ink);
padding: 0.5em 1em;
border-radius: var(--r-sm);
}
.nav-cta:hover { background: var(--accent); border-color: var(--accent); color: #fff !important; }
.nav-toggle {
display: none;
position: absolute;
right: var(--gutter);
top: 22px;
width: 34px;
height: 30px;
background: none;
border: 0;
cursor: pointer;
padding: 6px 4px;
}
.nav-toggle span {
display: block;
height: 2px;
background: var(--ink);
margin: 5px 0;
transition: transform 0.25s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.mobile-nav {
display: none;
flex-direction: column;
padding: 0.5rem var(--gutter) 1.2rem;
border-top: 1px solid var(--rule-hair);
}
.mobile-nav a {
padding: 0.85rem 0;
text-decoration: none;
font-size: 0.82rem;
letter-spacing: 0.1em;
text-transform: uppercase;
border-bottom: 1px solid var(--rule-hair);
color: var(--ink-2);
}
.mobile-nav.is-open { display: flex; }
/* ---------- shared section frame ---------- */
.hero, .features, .issue-strip, .contributors, .subscribe {
max-width: var(--maxw);
margin: 0 auto;
padding: clamp(48px, 7vw, 96px) var(--gutter);
}
.section-head { margin-bottom: clamp(28px, 4vw, 48px); }
.section-head--center { text-align: center; }
.section-title {
font-family: var(--display);
font-weight: 700;
font-size: clamp(2rem, 5vw, 3.2rem);
line-height: 1.04;
letter-spacing: -0.01em;
margin: 0;
}
.section-sub {
margin: 0.7rem 0 0;
color: var(--ink-3);
font-size: 1.02rem;
}
/* ---------- simulated photography ---------- */
.cover-image {
position: relative;
width: 100%;
height: 100%;
border-radius: var(--r-sm);
overflow: hidden;
background-color: var(--paper-3);
}
.cover-image::after {
content: "";
position: absolute;
inset: 0;
background-image:
radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.35), transparent 60%),
linear-gradient(180deg, rgba(12, 11, 10, 0) 55%, rgba(12, 11, 10, 0.22) 100%);
mix-blend-mode: multiply;
pointer-events: none;
}
.cover-hero {
background-image:
radial-gradient(80% 60% at 70% 18%, #ffd6ea 0%, rgba(255, 214, 234, 0) 55%),
radial-gradient(70% 80% at 30% 80%, #ff9ecb 0%, rgba(255, 158, 203, 0) 60%),
linear-gradient(150deg, #ffe0ef 0%, #f6a8cf 38%, #e6007e 78%, #8a0a4c 100%);
}
.cover-1 {
background-image:
radial-gradient(60% 60% at 30% 25%, #fff6ec 0%, rgba(255,246,236,0) 60%),
linear-gradient(160deg, #f7ead8 0%, #e7cba6 45%, #c79e74 100%);
}
.cover-2 {
background-image:
radial-gradient(70% 50% at 70% 80%, #ffe3a3 0%, rgba(255,227,163,0) 55%),
linear-gradient(150deg, #28432b 0%, #3f6b3e 45%, #87a85a 100%);
}
.cover-3 {
background-image:
radial-gradient(60% 60% at 30% 20%, #fff4d9 0%, rgba(255,244,217,0) 55%),
linear-gradient(160deg, #bfe3ec 0%, #6aa8c2 40%, #2c5d77 100%);
}
.cover-4 {
background-image:
radial-gradient(60% 60% at 40% 30%, #fff 0%, rgba(255,255,255,0) 55%),
linear-gradient(150deg, #ffe5f1 0%, #f4afd0 50%, #d3699f 100%);
}
.cover-5 {
background-image:
radial-gradient(60% 60% at 35% 25%, #fff5e8 0%, rgba(255,245,232,0) 55%),
linear-gradient(160deg, #f0d9b8 0%, #cf9e6a 50%, #8c5a2e 100%);
}
.cover-6 {
background-image:
radial-gradient(60% 60% at 65% 25%, #fff7d6 0%, rgba(255,247,214,0) 55%),
linear-gradient(150deg, #ffe9c2 0%, #f4b96a 45%, #e6007e 110%);
}
figcaption {
margin-top: 0.7rem;
font-size: 0.78rem;
color: var(--muted);
letter-spacing: 0.01em;
}
figcaption em { color: var(--ink-3); font-style: italic; }
/* ---------- HERO ---------- */
.hero { padding-top: clamp(56px, 7vw, 96px); }
.hero-grid {
display: grid;
grid-template-columns: 1fr 1.05fr;
gap: clamp(32px, 5vw, 72px);
align-items: start;
}
.hero-coverline {
font-family: var(--display);
font-weight: 800;
font-size: clamp(2.8rem, 8vw, 5.6rem);
line-height: 0.98;
letter-spacing: -0.02em;
margin: 0 0 1.3rem;
}
.hero-coverline em { font-style: italic; color: var(--accent); font-weight: 600; }
.hero-dek {
max-width: 38ch;
color: var(--ink-3);
font-size: 1.08rem;
margin: 0 0 1.8rem;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-bottom: 2.4rem; }
.hero-coverlines {
list-style: none;
margin: 0;
padding: 1.4rem 0 0;
border-top: 1px solid var(--rule);
display: grid;
gap: 0.9rem;
}
.hero-coverlines li {
font-size: 0.96rem;
color: var(--ink-2);
display: flex;
gap: 0.8rem;
align-items: baseline;
padding-bottom: 0.9rem;
border-bottom: 1px solid var(--rule-hair);
}
.hero-coverlines li:last-child { border-bottom: 0; padding-bottom: 0; }
.cl-tag {
flex: 0 0 auto;
font-size: 0.66rem;
font-weight: 600;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--accent);
min-width: 4.5em;
}
.hero-figure { margin: 0; }
.hero-figure .cover-image {
aspect-ratio: 4 / 5;
max-height: clamp(360px, 42vw, 520px);
box-shadow: var(--shadow-soft);
}
/* ---------- FEATURES ---------- */
.feature-stage {
display: grid;
gap: 0;
}
.feature-tabs {
display: flex;
border-top: 1px solid var(--rule-2);
border-bottom: 1px solid var(--rule);
margin-bottom: clamp(28px, 4vw, 48px);
}
.feature-tab {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.35rem;
background: none;
border: 0;
border-right: 1px solid var(--rule-hair);
padding: 1.1rem 1.2rem 1.2rem;
text-align: left;
cursor: pointer;
color: var(--ink-3);
transition: color 0.2s ease, background 0.2s ease;
position: relative;
}
.feature-tab:last-child { border-right: 0; }
.feature-tab .tab-no {
font-family: var(--display);
font-size: 0.95rem;
font-style: italic;
color: var(--muted);
}
.feature-tab .tab-label {
font-family: var(--display);
font-weight: 600;
font-size: clamp(1rem, 2.2vw, 1.3rem);
line-height: 1.1;
color: var(--ink-2);
transition: color 0.2s ease;
}
.feature-tab::after {
content: "";
position: absolute;
left: 0; right: 0; bottom: -1px;
height: 2px;
background: var(--accent);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
.feature-tab:hover .tab-label { color: var(--accent); }
.feature-tab.is-active .tab-label { color: var(--ink); }
.feature-tab.is-active .tab-no { color: var(--accent); }
.feature-tab.is-active::after { transform: scaleX(1); }
.feature-panel {
display: grid;
grid-template-columns: 1.15fr 1fr;
gap: clamp(28px, 4vw, 56px);
align-items: center;
animation: fade-up 0.5s ease both;
}
.feature-panel[hidden] { display: none; }
@keyframes fade-up {
from { opacity: 0; transform: translateY(14px); }
to { opacity: 1; transform: translateY(0); }
}
.feature-figure { margin: 0; }
.feature-figure .cover-image { aspect-ratio: 5 / 4; }
.feature-headline {
font-family: var(--display);
font-weight: 700;
font-size: clamp(1.8rem, 4vw, 2.8rem);
line-height: 1.05;
letter-spacing: -0.01em;
margin: 0 0 0.7rem;
}
.feature-byline {
font-size: 0.85rem;
color: var(--muted);
letter-spacing: 0.02em;
margin: 0 0 1.2rem;
}
.feature-byline a { color: var(--ink-2); text-decoration: none; border-bottom: 1px solid var(--accent); }
.feature-byline a:hover { color: var(--accent); }
.feature-lede {
font-size: 1.08rem;
color: var(--ink-3);
margin: 0 0 1.4rem;
max-width: 46ch;
}
.read-more {
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
text-decoration: none;
color: var(--accent);
display: inline-flex;
gap: 0.5em;
align-items: center;
}
.read-more span { transition: transform 0.2s ease; }
.read-more:hover span { transform: translateX(4px); }
/* ---------- story grid ---------- */
.story-grid {
margin-top: clamp(48px, 6vw, 80px);
padding-top: clamp(36px, 4vw, 56px);
border-top: 1px solid var(--rule-2);
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: clamp(24px, 3vw, 40px);
}
.story-card { display: flex; flex-direction: column; }
.story-card--lede { grid-column: span 2; grid-row: span 1; }
.story-figure { margin: 0 0 1.1rem; }
.story-figure .cover-image { aspect-ratio: 4 / 3; }
.story-card--lede .story-figure .cover-image { aspect-ratio: 16 / 10; }
.story-headline {
font-family: var(--display);
font-weight: 700;
font-size: clamp(1.15rem, 2.4vw, 1.5rem);
line-height: 1.12;
letter-spacing: -0.005em;
margin: 0 0 0.6rem;
}
.story-card--lede .story-headline { font-size: clamp(1.5rem, 3vw, 2rem); }
.story-lede {
font-size: 1rem;
color: var(--ink-3);
text-align: justify;
hyphens: auto;
margin: 0 0 1rem;
}
.dropcap {
float: left;
font-family: var(--display);
font-weight: 700;
font-size: 3.4em;
line-height: 0.72;
padding: 0.06em 0.1em 0 0;
color: var(--accent);
}
.story-byline {
margin-top: auto;
font-size: 0.78rem;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--muted);
}
.story-byline a { color: var(--ink-2); text-decoration: none; }
.story-byline a:hover { color: var(--accent); }
.story-card--quote {
grid-column: span 2;
background: var(--ink);
color: #fff;
border-radius: var(--r-md);
padding: clamp(28px, 4vw, 48px);
display: flex;
align-items: center;
}
.pull-quote { margin: 0; }
.pull-quote p {
font-family: var(--display);
font-style: italic;
font-weight: 500;
font-size: clamp(1.4rem, 3vw, 2.1rem);
line-height: 1.2;
margin: 0 0 1.2rem;
}
.pull-quote cite {
font-style: normal;
font-size: 0.78rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent);
}
/* ---------- issue strip ---------- */
.issue-strip {
background: var(--paper-2);
max-width: none;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
}
.issue-head { max-width: var(--maxw); margin: 0 auto clamp(24px, 3vw, 40px); }
.issue-list {
max-width: var(--maxw);
margin: 0 auto;
list-style: none;
padding: 0;
border-top: 1px solid var(--rule-2);
}
.issue-list li {
display: grid;
grid-template-columns: 5rem 1fr auto;
gap: 1.2rem;
align-items: baseline;
padding: 1.05rem 0;
border-bottom: 1px solid var(--rule-hair);
transition: padding-left 0.2s ease, color 0.2s ease;
}
.issue-list li:hover { padding-left: 0.6rem; }
.issue-no {
font-family: var(--display);
font-style: italic;
color: var(--accent);
font-size: 1rem;
}
.issue-item {
font-size: clamp(1.05rem, 2.2vw, 1.35rem);
font-family: var(--display);
font-weight: 500;
color: var(--ink);
}
.issue-cat {
font-size: 0.68rem;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
/* ---------- contributors ---------- */
.contrib-row {
list-style: none;
margin: 0;
padding: 0;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: clamp(24px, 3vw, 44px);
}
.contrib { text-align: center; }
.contrib-portrait {
width: 100%;
aspect-ratio: 1 / 1;
border-radius: 999px;
margin: 0 auto 1.1rem;
max-width: 200px;
position: relative;
overflow: hidden;
}
.contrib-portrait::after {
content: "";
position: absolute; inset: 0;
background: radial-gradient(70% 60% at 50% 30%, rgba(255,255,255,0.4), transparent 60%);
mix-blend-mode: screen;
}
.portrait-a { background-image: linear-gradient(150deg, #ffd6ea 0%, #e6007e 100%); }
.portrait-b { background-image: linear-gradient(150deg, #d9eef5 0%, #2c5d77 100%); }
.portrait-c { background-image: linear-gradient(150deg, #e7f0d4 0%, #5e7d3a 100%); }
.portrait-d { background-image: linear-gradient(150deg, #f4e2c9 0%, #b07636 100%); }
.contrib-name {
font-family: var(--display);
font-weight: 700;
font-size: 1.25rem;
margin: 0 0 0.2rem;
}
.contrib-role {
font-size: 0.7rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 0.8rem;
}
.contrib-bio { font-size: 0.92rem; color: var(--ink-3); margin: 0; }
/* ---------- subscribe ---------- */
.subscribe-card {
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: clamp(32px, 5vw, 72px);
align-items: center;
background: var(--ink);
color: #fff;
border-radius: var(--r-lg);
padding: clamp(36px, 5vw, 72px);
box-shadow: var(--shadow-soft);
}
.subscribe-card .kicker-accent { color: var(--accent); }
.subscribe-title {
font-family: var(--display);
font-weight: 700;
font-size: clamp(2rem, 4.5vw, 3.2rem);
line-height: 1.04;
margin: 0 0 1rem;
}
.subscribe-dek { color: rgba(255,255,255,0.78); margin: 0 0 1.6rem; max-width: 40ch; }
.subscribe-perks {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 0.7rem;
}
.subscribe-perks li {
position: relative;
padding-left: 1.6rem;
font-size: 0.96rem;
color: rgba(255,255,255,0.86);
}
.subscribe-perks li::before {
content: "";
position: absolute;
left: 0; top: 0.55em;
width: 8px; height: 8px;
background: var(--accent);
border-radius: 999px;
}
.subscribe-form {
background: var(--paper);
color: var(--ink);
border-radius: var(--r-md);
padding: clamp(24px, 3vw, 36px);
display: grid;
gap: 1.1rem;
}
.field { display: grid; gap: 0.5rem; }
.field-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-3);
}
.subscribe-form input[type="email"] {
font: inherit;
padding: 0.9em 1em;
border: 1px solid var(--rule-2);
border-radius: var(--r-sm);
background: var(--paper-2);
color: var(--ink);
}
.subscribe-form input[type="email"]:focus-visible {
border-color: var(--accent);
outline: none;
box-shadow: 0 0 0 3px var(--accent-50);
}
.plan-group { border: 0; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.plan-group legend { padding: 0; margin-bottom: 0.5rem; }
.plan {
display: block;
border: 1px solid var(--rule);
border-radius: var(--r-sm);
padding: 0.85em 1em;
cursor: pointer;
transition: border-color 0.2s ease, background 0.2s ease;
}
.plan input { position: absolute; opacity: 0; pointer-events: none; }
.plan-body { display: flex; justify-content: space-between; align-items: baseline; }
.plan-name { font-weight: 600; }
.plan-price { font-family: var(--display); font-weight: 700; font-size: 1.3rem; }
.plan-price small { font-size: 0.6em; font-weight: 500; color: var(--muted); }
.plan:has(input:checked) { border-color: var(--accent); background: var(--accent-50); }
.plan:has(input:checked) .plan-price { color: var(--accent-d); }
.subscribe-fine { font-size: 0.78rem; color: var(--muted); text-align: center; margin: 0; }
/* ---------- footer ---------- */
.footer {
border-top: 1px solid var(--rule);
padding: clamp(40px, 5vw, 64px) var(--gutter);
text-align: center;
}
.footer-inner { max-width: var(--maxw); margin: 0 auto; }
.footer-logo {
font-family: var(--display);
font-weight: 800;
letter-spacing: 0.3em;
text-indent: 0.3em;
font-size: 1.4rem;
}
.footer-tag { color: var(--ink-3); margin: 0.6rem 0 1.4rem; }
.footer-nav {
display: flex;
justify-content: center;
gap: 1.4rem;
flex-wrap: wrap;
font-size: 0.76rem;
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 1.4rem;
}
.footer-nav a { text-decoration: none; color: var(--ink-2); }
.footer-nav a:hover { color: var(--accent); }
.footer-fine { font-size: 0.78rem; color: var(--muted); margin: 0; }
/* ---------- toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 140%);
background: var(--ink);
color: #fff;
padding: 0.9em 1.4em;
border-radius: var(--r-sm);
font-size: 0.9rem;
letter-spacing: 0.02em;
box-shadow: var(--shadow-soft);
z-index: 80;
opacity: 0;
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease;
max-width: calc(100vw - 40px);
text-align: center;
}
.toast.is-visible { transform: translate(-50%, 0); opacity: 1; }
.toast::before { content: "✦ "; color: var(--accent); }
/* ---------- responsive ---------- */
@media (max-width: 980px) {
.story-grid { grid-template-columns: repeat(2, 1fr); }
.story-card--lede, .story-card--quote { grid-column: span 2; }
.contrib-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 820px) {
.nav { display: none; }
.nav-toggle { display: block; }
.hero-grid { grid-template-columns: 1fr; }
.hero-figure { order: -1; }
.feature-panel { grid-template-columns: 1fr; }
.subscribe-card { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
body { font-size: 16px; }
.feature-tabs { flex-direction: column; }
.feature-tab { border-right: 0; border-bottom: 1px solid var(--rule-hair); flex-direction: row; align-items: baseline; gap: 0.8rem; }
.feature-tab::after { left: 0; right: auto; width: 3px; height: 100%; top: 0; transform: scaleY(0); transform-origin: top; }
.feature-tab.is-active::after { transform: scaleY(1); }
.issue-list li { grid-template-columns: 3.6rem 1fr; }
.issue-cat { grid-column: 2; }
}
@media (max-width: 540px) {
.story-grid { grid-template-columns: 1fr; }
.story-card--lede, .story-card--quote { grid-column: span 1; }
.contrib-row { grid-template-columns: 1fr; }
.masthead-left { display: none; }
.masthead-inner { grid-template-columns: 1fr; justify-items: center; min-height: 64px; }
.logo-word { font-size: 1.6rem; }
}
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; scroll-behavior: auto; }
[data-parallax] { transform: none !important; }
}(function () {
"use strict";
/* ---------- toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("is-visible");
window.clearTimeout(toastTimer);
toastTimer = window.setTimeout(function () {
toastEl.classList.remove("is-visible");
}, 3200);
}
/* ---------- mobile nav ---------- */
var navToggle = document.querySelector(".nav-toggle");
var mobileNav = document.getElementById("mobile-nav");
if (navToggle && mobileNav) {
navToggle.addEventListener("click", function () {
var open = navToggle.getAttribute("aria-expanded") === "true";
navToggle.setAttribute("aria-expanded", String(!open));
mobileNav.classList.toggle("is-open", !open);
});
mobileNav.addEventListener("click", function (e) {
if (e.target.tagName === "A") {
navToggle.setAttribute("aria-expanded", "false");
mobileNav.classList.remove("is-open");
}
});
}
/* ---------- featured-story switcher (tablist) ---------- */
var tabs = Array.prototype.slice.call(document.querySelectorAll(".feature-tab"));
var panels = Array.prototype.slice.call(document.querySelectorAll(".feature-panel"));
function activateTab(idx, focus) {
tabs.forEach(function (tab, i) {
var selected = i === idx;
tab.classList.toggle("is-active", selected);
tab.setAttribute("aria-selected", String(selected));
tab.tabIndex = selected ? 0 : -1;
if (selected && focus) tab.focus();
});
panels.forEach(function (panel, i) {
var show = i === idx;
panel.classList.toggle("is-active", show);
if (show) {
panel.hidden = false;
} else {
panel.hidden = true;
}
});
}
tabs.forEach(function (tab, i) {
tab.addEventListener("click", function () {
activateTab(i, false);
});
tab.addEventListener("keydown", function (e) {
var key = e.key;
var next = null;
if (key === "ArrowRight" || key === "ArrowDown") next = (i + 1) % tabs.length;
else if (key === "ArrowLeft" || key === "ArrowUp") next = (i - 1 + tabs.length) % tabs.length;
else if (key === "Home") next = 0;
else if (key === "End") next = tabs.length - 1;
if (next !== null) {
e.preventDefault();
activateTab(next, true);
}
});
});
/* auto-advance through featured stories, pause on interaction */
var autoIdx = 0;
var autoTimer = null;
var stage = document.querySelector(".feature-stage");
function startAuto() {
stopAuto();
autoTimer = window.setInterval(function () {
autoIdx = (currentTab() + 1) % tabs.length;
activateTab(autoIdx, false);
}, 6000);
}
function stopAuto() {
if (autoTimer) { window.clearInterval(autoTimer); autoTimer = null; }
}
function currentTab() {
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].classList.contains("is-active")) return i;
}
return 0;
}
var reduceMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (stage && tabs.length && !reduceMotion) {
startAuto();
stage.addEventListener("mouseenter", stopAuto);
stage.addEventListener("mouseleave", startAuto);
stage.addEventListener("focusin", stopAuto);
stage.addEventListener("click", function (e) {
if (e.target.closest(".feature-tab")) stopAuto();
});
}
/* ---------- gentle image parallax on scroll ---------- */
var parallaxEls = Array.prototype.slice.call(document.querySelectorAll("[data-parallax]"));
var ticking = false;
function applyParallax() {
var vh = window.innerHeight || document.documentElement.clientHeight;
parallaxEls.forEach(function (el) {
var rect = el.getBoundingClientRect();
if (rect.bottom < -200 || rect.top > vh + 200) return;
var speed = parseFloat(el.getAttribute("data-parallax")) || 0.1;
// progress: -1 (below) .. 1 (above), 0 when centered
var center = rect.top + rect.height / 2;
var progress = (center - vh / 2) / (vh / 2);
var shift = -progress * speed * 100;
var img = el.querySelector(".cover-image");
if (img) img.style.transform = "translate3d(0," + shift.toFixed(2) + "px,0) scale(1.06)";
});
ticking = false;
}
function onScroll() {
if (!ticking) {
window.requestAnimationFrame(applyParallax);
ticking = true;
}
}
if (parallaxEls.length && !reduceMotion) {
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll, { passive: true });
applyParallax();
}
/* ---------- read-more links ---------- */
document.querySelectorAll(".read-more, .story-headline, .feature-byline a, .story-byline a").forEach(function (el) {
el.addEventListener("click", function (e) {
if (el.getAttribute("href") === "#" || !el.getAttribute("href")) {
e.preventDefault();
toast("Full article available in the print edition.");
}
});
});
/* ---------- subscribe form ---------- */
var form = document.querySelector(".subscribe-form");
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var email = form.querySelector("#sub-email");
var plan = form.querySelector('input[name="plan"]:checked');
var value = email && email.value.trim();
if (!value || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
if (email) email.focus();
toast("Please enter a valid email address.");
return;
}
var planName = plan && plan.value === "print" ? "Print + Digital" : "Digital";
toast("Welcome to Maison — your " + planName + " subscription is ready.");
form.reset();
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>MAISON — The Lifestyle Issue</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=Playfair+Display:ital,wght@0,500;0,600;0,700;0,800;0,900;1,500;1,600&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header class="masthead" role="banner">
<div class="masthead-inner">
<div class="masthead-side masthead-left">
<span class="masthead-meta">Issue No. 47 — Summer</span>
</div>
<a class="logo" href="#" aria-label="Maison, home">
<span class="logo-word">MAISON</span>
</a>
<div class="masthead-side masthead-right">
<nav class="nav" aria-label="Primary">
<a href="#features">Features</a>
<a href="#issue">This Issue</a>
<a href="#contributors">People</a>
<a class="nav-cta" href="#subscribe">Subscribe</a>
</nav>
</div>
</div>
<button class="nav-toggle" aria-expanded="false" aria-controls="mobile-nav" aria-label="Open menu">
<span></span><span></span><span></span>
</button>
<nav class="mobile-nav" id="mobile-nav" aria-label="Mobile">
<a href="#features">Features</a>
<a href="#issue">This Issue</a>
<a href="#contributors">People</a>
<a href="#subscribe">Subscribe</a>
</nav>
</header>
<main id="main">
<!-- HERO -->
<section class="hero" aria-labelledby="hero-coverline">
<div class="hero-grid">
<div class="hero-copy">
<p class="kicker">The Lifestyle Issue · 2026</p>
<h1 class="hero-coverline" id="hero-coverline">
The Art of<br /><em>Slow</em> Living
</h1>
<p class="hero-dek">
Inside the quiet revolution reshaping how we cook, dress, and gather —
a season of considered pleasures, photographed at golden hour and savoured
without apology.
</p>
<div class="hero-actions">
<a class="btn btn-solid" href="#features">Read the issue</a>
<a class="btn btn-ghost" href="#subscribe">Subscribe from $9</a>
</div>
<ul class="hero-coverlines" aria-label="In this issue">
<li><span class="cl-tag">Style</span> Linen, and the case for the unironed shirt</li>
<li><span class="cl-tag">Table</span> Twelve dinners that begin in a garden</li>
<li><span class="cl-tag">Escape</span> A long weekend on the Amalfi backroads</li>
</ul>
</div>
<figure class="hero-figure" data-parallax="0.12">
<div class="cover-image cover-hero" role="img" aria-label="A woman in a flowing ivory dress photographed against a coral-washed studio backdrop"></div>
<figcaption>
<em>On the cover</em> — Ottoline wears Atelier Vey. Photographed by Noor Almasi.
</figcaption>
</figure>
</div>
</section>
<!-- FEATURED SWITCHER -->
<section class="features" id="features" aria-labelledby="features-title">
<header class="section-head">
<h2 class="section-title" id="features-title">Featured Stories</h2>
<p class="section-sub">Six pieces we couldn't stop thinking about.</p>
</header>
<div class="feature-stage">
<div class="feature-tabs" role="tablist" aria-label="Featured stories">
<button class="feature-tab is-active" role="tab" aria-selected="true" id="tab-1" aria-controls="panel-1" data-story="1">
<span class="tab-no">01</span>
<span class="tab-label">The Unironed Shirt</span>
</button>
<button class="feature-tab" role="tab" aria-selected="false" id="tab-2" aria-controls="panel-2" data-story="2" tabindex="-1">
<span class="tab-no">02</span>
<span class="tab-label">A Garden on the Table</span>
</button>
<button class="feature-tab" role="tab" aria-selected="false" id="tab-3" aria-controls="panel-3" data-story="3" tabindex="-1">
<span class="tab-no">03</span>
<span class="tab-label">Backroads of Amalfi</span>
</button>
</div>
<article class="feature-panel is-active" role="tabpanel" id="panel-1" aria-labelledby="tab-1" tabindex="0">
<figure class="feature-figure" data-parallax="0.08">
<div class="cover-image cover-1" role="img" aria-label="An ivory linen shirt softly creased on a sunlit chair"></div>
<figcaption><em>The case for crumpled</em> — Photograph by Lior Dahan.</figcaption>
</figure>
<div class="feature-text">
<p class="kicker kicker-accent">Style</p>
<h3 class="feature-headline">The Quiet Luxury of the Unironed Shirt</h3>
<p class="feature-byline">By <a href="#">Margaux Field</a> · 8 min read</p>
<p class="feature-lede">
We spent a decade chasing the perfect press. Then a generation of designers
decided the wrinkle was the point — proof of a body, a breeze, an afternoon
spent somewhere better than a meeting.
</p>
<a class="read-more" href="#">Read the feature <span aria-hidden="true">→</span></a>
</div>
</article>
<article class="feature-panel" role="tabpanel" id="panel-2" aria-labelledby="tab-2" tabindex="0" hidden>
<figure class="feature-figure" data-parallax="0.08">
<div class="cover-image cover-2" role="img" aria-label="A long table set among herbs and trailing vines at dusk"></div>
<figcaption><em>Dinner begins outside</em> — Photograph by Priya Sandoval.</figcaption>
</figure>
<div class="feature-text">
<p class="kicker kicker-accent">Table</p>
<h3 class="feature-headline">Twelve Dinners That Begin in a Garden</h3>
<p class="feature-byline">By <a href="#">Tomás Renner</a> · 11 min read</p>
<p class="feature-lede">
The most memorable meal of the summer started with a pair of scissors and
a walk to the far bed of basil. Here, a season of menus written by the soil
before the stove ever got involved.
</p>
<a class="read-more" href="#">Read the feature <span aria-hidden="true">→</span></a>
</div>
</article>
<article class="feature-panel" role="tabpanel" id="panel-3" aria-labelledby="tab-3" tabindex="0" hidden>
<figure class="feature-figure" data-parallax="0.08">
<div class="cover-image cover-3" role="img" aria-label="A coastal road curving between cliffs above a hazy sea"></div>
<figcaption><em>The long way down</em> — Photograph by Eli Marchetti.</figcaption>
</figure>
<div class="feature-text">
<p class="kicker kicker-accent">Escape</p>
<h3 class="feature-headline">A Long Weekend on the Amalfi Backroads</h3>
<p class="feature-byline">By <a href="#">Carla Beaumont</a> · 9 min read</p>
<p class="feature-lede">
Everyone takes the coast road. We took the one above it — past lemon
terraces and shuttered chapels, to a town with no harbour, no hotel, and
the best plate of pasta we ate all year.
</p>
<a class="read-more" href="#">Read the feature <span aria-hidden="true">→</span></a>
</div>
</article>
</div>
<!-- secondary grid -->
<div class="story-grid">
<article class="story-card story-card--lede">
<figure class="story-figure">
<div class="cover-image cover-4" role="img" aria-label="A ceramic studio washed in soft pink light"></div>
</figure>
<p class="kicker kicker-accent">Craft</p>
<h3 class="story-headline">The Potters Who Turned a Power Cut Into a Movement</h3>
<p class="story-lede">
<span class="dropcap">W</span>hen the kiln went cold for a week in the village
of Sant'Eria, three ceramicists started building by hand what the electricity
could no longer fire — and discovered, to their surprise, that the imperfect
pieces sold first. What began as a constraint became a quiet manifesto about
making things slowly, and on purpose.
</p>
<p class="story-byline">By <a href="#">Dana Whitlock</a></p>
</article>
<article class="story-card">
<figure class="story-figure">
<div class="cover-image cover-5" role="img" aria-label="A pair of woven leather sandals on warm stone"></div>
</figure>
<p class="kicker kicker-accent">Style</p>
<h3 class="story-headline">Ten Sandals Worth Walking Italy In</h3>
<p class="story-byline">By <a href="#">Iris Lund</a></p>
</article>
<article class="story-card">
<figure class="story-figure">
<div class="cover-image cover-6" role="img" aria-label="A coupe glass of pale aperitif against a coral wall"></div>
</figure>
<p class="kicker kicker-accent">Drinks</p>
<h3 class="story-headline">The Spritz Has a Quieter, Better Cousin</h3>
<p class="story-byline">By <a href="#">Olu Adeyemi</a></p>
</article>
<aside class="story-card story-card--quote">
<blockquote class="pull-quote">
<p>"Luxury stopped being about more. Now it is the audacity to want less, beautifully."</p>
<cite>— Margaux Field, on the new minimalism</cite>
</blockquote>
</aside>
</div>
</section>
<!-- THIS ISSUE STRIP -->
<section class="issue-strip" id="issue" aria-labelledby="issue-title">
<div class="issue-head">
<p class="kicker kicker-accent">In This Issue</p>
<h2 class="section-title" id="issue-title">Issue 47 at a Glance</h2>
</div>
<ol class="issue-list">
<li><span class="issue-no">P. 12</span><span class="issue-item">The Slow Living manifesto, in nine objects</span><span class="issue-cat">Essay</span></li>
<li><span class="issue-no">P. 28</span><span class="issue-item">Inside the linen mills of northern Portugal</span><span class="issue-cat">Style</span></li>
<li><span class="issue-no">P. 44</span><span class="issue-item">A chef's garden, mapped bed by bed</span><span class="issue-cat">Table</span></li>
<li><span class="issue-no">P. 61</span><span class="issue-item">Amalfi without the crowds — a backroad guide</span><span class="issue-cat">Escape</span></li>
<li><span class="issue-no">P. 78</span><span class="issue-item">The aperitivo hour, reconsidered</span><span class="issue-cat">Drinks</span></li>
<li><span class="issue-no">P. 90</span><span class="issue-item">Letters: readers on the year of doing less</span><span class="issue-cat">People</span></li>
</ol>
</section>
<!-- CONTRIBUTORS -->
<section class="contributors" id="contributors" aria-labelledby="contrib-title">
<header class="section-head section-head--center">
<p class="kicker kicker-accent">The People</p>
<h2 class="section-title" id="contrib-title">This Issue's Contributors</h2>
</header>
<ul class="contrib-row">
<li class="contrib">
<div class="contrib-portrait portrait-a" role="img" aria-label="Portrait of Margaux Field"></div>
<p class="contrib-name">Margaux Field</p>
<p class="contrib-role">Writer, Style</p>
<p class="contrib-bio">A former tailor turned essayist, writing on the quiet end of fashion from a farmhouse in Provence.</p>
</li>
<li class="contrib">
<div class="contrib-portrait portrait-b" role="img" aria-label="Portrait of Noor Almasi"></div>
<p class="contrib-name">Noor Almasi</p>
<p class="contrib-role">Photographer</p>
<p class="contrib-bio">Shot this issue's cover at first light in a Lisbon studio. Believes in natural light and very few rules.</p>
</li>
<li class="contrib">
<div class="contrib-portrait portrait-c" role="img" aria-label="Portrait of Tomás Renner"></div>
<p class="contrib-name">Tomás Renner</p>
<p class="contrib-role">Food Editor</p>
<p class="contrib-bio">Grows most of what he writes about. Spends summers documenting kitchen gardens across the Mediterranean.</p>
</li>
<li class="contrib">
<div class="contrib-portrait portrait-d" role="img" aria-label="Portrait of Carla Beaumont"></div>
<p class="contrib-name">Carla Beaumont</p>
<p class="contrib-role">Travel, At Large</p>
<p class="contrib-bio">Has a talent for finding the town just past the famous one. Reports from wherever the road runs out.</p>
</li>
</ul>
</section>
<!-- SUBSCRIBE -->
<section class="subscribe" id="subscribe" aria-labelledby="sub-title">
<div class="subscribe-card">
<div class="subscribe-copy">
<p class="kicker kicker-accent">Join Maison</p>
<h2 class="subscribe-title" id="sub-title">Twelve issues, delivered slowly.</h2>
<p class="subscribe-dek">
Print and digital, posted to your door each month. The first issue ships free,
and you can pause whenever the pace gets loud.
</p>
<ul class="subscribe-perks">
<li>Monthly print edition, beautifully bound</li>
<li>Full digital archive, back to Issue 1</li>
<li>Members-only field notes from our editors</li>
</ul>
</div>
<form class="subscribe-form" novalidate>
<label class="field">
<span class="field-label">Email address</span>
<input type="email" name="email" id="sub-email" required placeholder="[email protected]" autocomplete="email" />
</label>
<fieldset class="plan-group">
<legend class="field-label">Choose a plan</legend>
<label class="plan">
<input type="radio" name="plan" value="digital" checked />
<span class="plan-body"><span class="plan-name">Digital</span><span class="plan-price">$9<small>/mo</small></span></span>
</label>
<label class="plan">
<input type="radio" name="plan" value="print" />
<span class="plan-body"><span class="plan-name">Print + Digital</span><span class="plan-price">$15<small>/mo</small></span></span>
</label>
</fieldset>
<button class="btn btn-solid btn-block" type="submit">Start my subscription</button>
<p class="subscribe-fine">Cancel anytime. First issue on us.</p>
</form>
</div>
</section>
</main>
<footer class="footer" role="contentinfo">
<div class="footer-inner">
<span class="footer-logo">MAISON</span>
<p class="footer-tag">A magazine about living well, slowly.</p>
<nav class="footer-nav" aria-label="Footer">
<a href="#features">Features</a>
<a href="#issue">This Issue</a>
<a href="#contributors">People</a>
<a href="#subscribe">Subscribe</a>
</nav>
<p class="footer-fine">© 2026 Maison Editions — a fictional publication. All work shown is illustrative.</p>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Glossy Lifestyle Magazine Landing
A polished landing page for Maison, an invented monthly lifestyle title built around airy whitespace, a high-contrast Playfair Display serif, and a single hot-magenta accent used only for kickers, links, and active states. The sticky masthead centres a letter-spaced logo between issue meta and a primary nav that collapses to a hamburger on small screens. Below it, a two-column hero pairs the season’s coverline — The Art of Slow Living — with a large 4:5 cover “photograph” simulated entirely in layered CSS gradients, plus a stack of secondary coverlines.
The Featured Stories block is a real ARIA tablist: three tabs switch between full editorial panels with arrow-key navigation, and the carousel auto-advances every six seconds, pausing on hover or focus. A four-up story grid follows, leading with a wide feature that carries a serif drop cap and justified body text, alongside compact cards and a dark pull-quote panel. A “This Issue” contents strip lists page numbers and sections over hairline rules, a contributors row shows gradient portraits with bios, and a black subscribe card offers digital and print plans with an inline-validated email form.
Interactions are vanilla JS only: the tabbed featured-story switcher, a gentle scroll-driven image parallax (disabled under prefers-reduced-motion), placeholder article links that surface a toast, and a subscribe form that validates the email and confirms the chosen plan. Layout reflows from four columns to two to a single column down to roughly 360px wide.
Illustrative UI only — masthead, headlines, bylines, and articles are fictional; not a real news publication.