News — Standard Article
A self-contained editorial article page for the fictional Meridian Ledger, set in a warm newsprint palette with Playfair Display headlines and Inter meta. It pairs a red kicker, an oversized serif headline and italic deck with a byline row of author, dateline, read-time and share controls, a duotone captioned hero, justified multi-column body with a red drop cap, a floated related-coverage box, an oversized pull quote, and a three-card More in Climate row. Vanilla JS drives a reading-progress bar, share toasts and a text-size control.
MCP
Kod
:root {
--cream: #f4efe4;
--paper: #faf7f0;
--white: #ffffff;
--newsprint: #efe9da;
--ink: #16130f;
--ink-2: #2b2620;
--ink-3: #4a443b;
--muted: #7a7164;
--red: #b4291f;
--red-d: #8f1f17;
--red-50: #f3dcd9;
--rule: rgba(22, 19, 15, 0.16);
--rule-2: rgba(22, 19, 15, 0.3);
--rule-hair: rgba(22, 19, 15, 0.1);
--ok: #2f7d4f;
--warn: #b67a18;
--danger: #b4291f;
--r-sm: 4px;
--r-md: 8px;
--r-lg: 12px;
--serif: "Playfair Display", "Times New Roman", Georgia, serif;
--sans: "Inter", system-ui, -apple-system, sans-serif;
--read: 17px;
}
* {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
background: var(--cream);
color: var(--ink);
font-family: var(--sans);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
a {
color: inherit;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
/* Reading progress -------------------------------------------------------- */
.progress {
position: fixed;
inset: 0 0 auto 0;
height: 3px;
background: transparent;
z-index: 50;
}
.progress span {
display: block;
height: 100%;
width: 0%;
background: var(--red);
transition: width 0.08s linear;
}
/* Masthead ---------------------------------------------------------------- */
.masthead {
border-bottom: 2px solid var(--ink);
background: var(--paper);
}
.masthead__inner {
max-width: 1180px;
margin: 0 auto;
padding: 14px 24px 10px;
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
}
.masthead__date {
font-size: 11px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-3);
font-weight: 600;
}
.masthead__name {
font-family: var(--serif);
font-weight: 800;
font-size: clamp(28px, 5vw, 46px);
letter-spacing: 0.01em;
text-align: center;
text-decoration: none;
white-space: nowrap;
line-height: 1;
}
.masthead__tools {
text-align: right;
}
.masthead__price {
font-size: 11px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-3);
font-weight: 600;
}
.subnav {
border-top: 1px solid var(--rule-hair);
background: var(--paper);
}
.subnav ul {
max-width: 1180px;
margin: 0 auto;
padding: 0 24px;
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 22px;
justify-content: center;
}
.subnav a {
display: inline-block;
padding: 9px 0;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-2);
text-decoration: none;
border-bottom: 2px solid transparent;
}
.subnav a:hover {
color: var(--red);
}
.subnav a[aria-current="page"] {
border-bottom-color: var(--red);
color: var(--ink);
}
/* Layout ------------------------------------------------------------------ */
.wrap {
max-width: 820px;
margin: 0 auto;
padding: 0 24px 64px;
}
/* Article head ------------------------------------------------------------ */
.article__head {
padding: 38px 0 22px;
text-align: center;
}
.kicker {
font-size: 12px;
letter-spacing: 0.16em;
text-transform: uppercase;
font-weight: 700;
color: var(--ink-3);
margin: 0 0 16px;
display: inline-flex;
align-items: center;
gap: 10px;
}
.kicker__tag {
background: var(--red);
color: var(--paper);
padding: 3px 8px;
border-radius: var(--r-sm);
letter-spacing: 0.14em;
}
.headline {
font-family: var(--serif);
font-weight: 800;
font-size: clamp(32px, 6vw, 56px);
line-height: 1.04;
letter-spacing: -0.01em;
margin: 0 auto;
max-width: 16ch;
color: var(--ink);
}
.deck {
font-family: var(--serif);
font-style: italic;
font-size: clamp(17px, 2.6vw, 22px);
line-height: 1.42;
color: var(--ink-3);
max-width: 44ch;
margin: 18px auto 0;
}
/* Byline ------------------------------------------------------------------ */
.byline {
margin-top: 26px;
padding: 16px 0;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
text-align: left;
flex-wrap: wrap;
}
.byline__author {
display: flex;
align-items: center;
gap: 12px;
}
.byline__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: grid;
place-items: center;
font-weight: 700;
font-size: 14px;
color: var(--paper);
background: linear-gradient(135deg, var(--ink-2), var(--ink));
letter-spacing: 0.02em;
flex: none;
}
.byline__who {
display: flex;
flex-direction: column;
}
.byline__name {
font-weight: 700;
font-size: 14px;
letter-spacing: 0.02em;
}
.byline__dateline {
font-size: 12px;
color: var(--muted);
letter-spacing: 0.04em;
}
.share {
display: flex;
gap: 8px;
}
.share__btn {
display: inline-flex;
align-items: center;
gap: 7px;
font-family: var(--sans);
font-size: 12px;
font-weight: 600;
letter-spacing: 0.03em;
color: var(--ink-2);
background: var(--white);
border: 1px solid var(--rule);
border-radius: var(--r-sm);
padding: 7px 11px;
cursor: pointer;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.share__btn svg {
width: 15px;
height: 15px;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
.share__btn:hover {
border-color: var(--ink);
color: var(--ink);
}
.share__btn[data-share="x"],
.share__btn[data-share="mail"] {
padding: 7px 9px;
}
.share__btn:focus-visible,
.controls__btn:focus-visible,
.subnav a:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
/* Hero figure ------------------------------------------------------------- */
figure {
margin: 0;
}
.hero {
margin: 28px 0 8px;
}
.hero__img {
aspect-ratio: 16 / 9;
border-radius: var(--r-sm);
background: var(--newsprint);
}
.hero__img--dune {
background:
radial-gradient(120% 90% at 18% 8%, rgba(255, 238, 200, 0.85), transparent 46%),
radial-gradient(140% 120% at 88% 96%, rgba(22, 19, 15, 0.62), transparent 50%),
linear-gradient(176deg, #c9b58a 0%, #b39a6c 34%, #6f7c70 60%, #2f3a3a 100%);
}
figcaption {
margin-top: 9px;
font-size: 12.5px;
line-height: 1.4;
color: var(--muted);
padding-bottom: 4px;
}
.cap {
font-style: italic;
color: var(--ink-3);
}
.credit {
display: block;
margin-top: 3px;
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--muted);
}
/* Controls ---------------------------------------------------------------- */
.controls {
display: flex;
align-items: center;
gap: 8px;
margin: 22px 0 4px;
padding: 10px 0;
border-top: 1px solid var(--rule-hair);
border-bottom: 1px solid var(--rule-hair);
}
.controls__label {
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
font-weight: 600;
color: var(--muted);
margin-right: auto;
}
.controls__btn {
font-family: var(--sans);
font-size: 13px;
font-weight: 600;
color: var(--ink-2);
background: var(--white);
border: 1px solid var(--rule);
border-radius: var(--r-sm);
padding: 6px 12px;
cursor: pointer;
transition: background 0.15s, border-color 0.15s;
}
.controls__btn:hover {
border-color: var(--ink);
}
.controls__btn:active {
background: var(--newsprint);
}
/* Body -------------------------------------------------------------------- */
.body {
margin-top: 26px;
font-size: var(--read);
line-height: 1.72;
color: var(--ink-2);
}
.body p {
margin: 0 0 1.25em;
text-align: justify;
hyphens: auto;
}
.body p:last-child {
margin-bottom: 0;
}
.lead {
font-size: 1.06em;
}
.lead::first-letter {
font-family: var(--serif);
font-weight: 800;
float: left;
font-size: 4.4em;
line-height: 0.78;
padding: 0.04em 0.1em 0 0;
margin: 0.02em 0 0;
color: var(--red);
}
.body em {
font-style: italic;
}
/* Inline related box ------------------------------------------------------ */
.relatedbox {
float: right;
width: 268px;
max-width: 50%;
margin: 4px 0 18px 26px;
padding: 16px 18px;
background: var(--paper);
border-top: 3px solid var(--red);
border-bottom: 1px solid var(--rule);
}
.relatedbox__label {
margin: 0 0 10px;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
font-weight: 700;
color: var(--red);
}
.relatedbox ul {
margin: 0;
padding: 0;
list-style: none;
}
.relatedbox li {
border-top: 1px solid var(--rule-hair);
padding: 9px 0;
}
.relatedbox li:first-child {
border-top: 0;
padding-top: 0;
}
.relatedbox a {
font-family: var(--serif);
font-weight: 600;
font-size: 16px;
line-height: 1.3;
color: var(--ink);
text-decoration: none;
text-align: left;
display: block;
}
.relatedbox a:hover {
color: var(--red);
}
/* Pull quote -------------------------------------------------------------- */
.pull {
margin: 30px 0;
padding: 6px 0 6px 24px;
border-left: 3px solid var(--red);
clear: both;
}
.pull p {
font-family: var(--serif);
font-style: italic;
font-weight: 600;
font-size: clamp(22px, 4vw, 30px);
line-height: 1.22;
color: var(--ink);
margin: 0;
text-align: left;
hyphens: manual;
}
.pull cite {
display: block;
margin-top: 12px;
font-family: var(--sans);
font-style: normal;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
}
/* Inset figure ------------------------------------------------------------ */
.inset {
margin: 26px 0;
clear: both;
}
.inset__img {
aspect-ratio: 5 / 3;
border-radius: var(--r-sm);
background:
repeating-linear-gradient(90deg, rgba(22, 19, 15, 0.05) 0 1px, transparent 1px 38px),
radial-gradient(120% 140% at 0% 100%, rgba(180, 41, 31, 0.4), transparent 55%),
linear-gradient(180deg, #e6dcc4 0%, #cdbf9c 55%, #5d6a66 100%);
}
/* Article footer ---------------------------------------------------------- */
.article__foot {
margin-top: 32px;
padding-top: 18px;
border-top: 1px solid var(--rule);
}
.article__tags {
margin: 0;
font-size: 12px;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.article__tags span {
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--muted);
}
.article__tags a {
text-decoration: none;
color: var(--ink-2);
background: var(--white);
border: 1px solid var(--rule);
border-radius: 999px;
padding: 4px 11px;
font-weight: 600;
}
.article__tags a:hover {
border-color: var(--red);
color: var(--red);
}
/* Related cards ----------------------------------------------------------- */
.related {
margin-top: 56px;
padding-top: 18px;
border-top: 2px solid var(--ink);
}
.related__heading {
font-family: var(--serif);
font-weight: 700;
font-size: 22px;
margin: 0 0 22px;
letter-spacing: -0.01em;
}
.related__grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 26px;
}
.card {
text-decoration: none;
color: inherit;
display: block;
}
.card__img {
aspect-ratio: 4 / 3;
border-radius: var(--r-sm);
margin-bottom: 12px;
background: var(--newsprint);
}
.card:hover .card__img {
filter: brightness(0.94);
}
.card__img--forest {
background:
radial-gradient(120% 90% at 80% 6%, rgba(255, 210, 120, 0.7), transparent 50%),
linear-gradient(170deg, #8a6a3a 0%, #4f5a36 55%, #1d251a 100%);
}
.card__img--grid {
background:
repeating-linear-gradient(45deg, rgba(250, 247, 240, 0.18) 0 1px, transparent 1px 16px),
linear-gradient(160deg, #46566a 0%, #2a3340 60%, #b4291f 160%);
}
.card__img--river {
background:
radial-gradient(140% 100% at 20% 90%, rgba(180, 41, 31, 0.35), transparent 55%),
linear-gradient(165deg, #cdd6cf 0%, #7e9189 45%, #2c4742 100%);
}
.card__kicker {
margin: 0 0 6px;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
font-weight: 700;
color: var(--red);
}
.card__title {
font-family: var(--serif);
font-weight: 700;
font-size: 19px;
line-height: 1.22;
margin: 0 0 8px;
letter-spacing: -0.005em;
}
.card:hover .card__title {
text-decoration: underline;
text-decoration-color: var(--rule-2);
text-underline-offset: 2px;
}
.card__meta {
margin: 0;
font-size: 12px;
color: var(--muted);
letter-spacing: 0.02em;
}
/* Site footer ------------------------------------------------------------- */
.sitefoot {
border-top: 1px solid var(--rule);
background: var(--paper);
text-align: center;
padding: 26px 24px;
}
.sitefoot p {
margin: 0;
font-family: var(--serif);
font-weight: 600;
font-size: 15px;
color: var(--ink-2);
}
.sitefoot__fine {
margin-top: 6px !important;
font-family: var(--sans) !important;
font-weight: 400 !important;
font-size: 12px !important;
color: var(--muted) !important;
}
/* Toast ------------------------------------------------------------------- */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translate(-50%, 16px);
background: var(--ink);
color: var(--paper);
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
padding: 11px 18px;
border-radius: var(--r-md);
box-shadow: 0 6px 22px rgba(22, 19, 15, 0.28);
opacity: 0;
pointer-events: none;
transition: opacity 0.22s, transform 0.22s;
z-index: 60;
max-width: 90vw;
}
.toast.is-on {
opacity: 1;
transform: translate(-50%, 0);
}
/* Responsive -------------------------------------------------------------- */
@media (max-width: 720px) {
.masthead__inner {
grid-template-columns: 1fr;
text-align: center;
gap: 6px;
}
.masthead__tools {
text-align: center;
}
.subnav ul {
justify-content: flex-start;
gap: 16px;
overflow-x: auto;
flex-wrap: nowrap;
-webkit-overflow-scrolling: touch;
}
.relatedbox {
float: none;
width: auto;
max-width: none;
margin: 22px 0;
}
.related__grid {
grid-template-columns: 1fr;
gap: 28px;
}
.byline {
align-items: flex-start;
}
}
@media (max-width: 420px) {
.wrap {
padding: 0 18px 48px;
}
.controls__label {
display: none;
}
.share__btn[data-share="link"] span {
display: none;
}
.lead::first-letter {
font-size: 3.8em;
}
}
@media (prefers-reduced-motion: reduce) {
* {
transition: 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-on");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-on");
}, 2400);
}
/* -- Reading progress bar ------------------------------------------------ */
var bar = document.getElementById("progressBar");
var article = document.getElementById("article");
function updateProgress() {
if (!bar || !article) return;
var rect = article.getBoundingClientRect();
var viewport = window.innerHeight || document.documentElement.clientHeight;
var total = rect.height - viewport;
var scrolled = -rect.top;
var pct = total > 0 ? (scrolled / total) * 100 : 0;
if (pct < 0) pct = 0;
if (pct > 100) pct = 100;
bar.style.width = pct.toFixed(2) + "%";
}
var ticking = false;
function onScroll() {
if (ticking) return;
ticking = true;
requestAnimationFrame(function () {
updateProgress();
ticking = false;
});
}
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll);
updateProgress();
/* -- Share buttons ------------------------------------------------------- */
var shareButtons = document.querySelectorAll("[data-share]");
Array.prototype.forEach.call(shareButtons, function (btn) {
btn.addEventListener("click", function () {
var kind = btn.getAttribute("data-share");
if (kind === "link") {
var url = window.location.href;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(url).then(
function () {
toast("Link copied to clipboard");
},
function () {
toast("Couldn't copy — copy from the address bar");
}
);
} else {
toast("Link: " + url);
}
} else if (kind === "x") {
toast("Shared to X (demo)");
} else if (kind === "mail") {
toast("Email draft opened (demo)");
}
});
});
/* -- Font-size control --------------------------------------------------- */
var body = document.getElementById("articleBody");
var STEP = 1;
var MIN = 15;
var MAX = 22;
var DEFAULT = 17;
var size = DEFAULT;
function applySize() {
if (body) body.style.fontSize = size + "px";
}
function setSize(next) {
size = Math.max(MIN, Math.min(MAX, next));
applySize();
}
var up = document.getElementById("fontUp");
var down = document.getElementById("fontDown");
var reset = document.getElementById("fontReset");
if (up)
up.addEventListener("click", function () {
if (size >= MAX) {
toast("Largest text size");
return;
}
setSize(size + STEP);
toast("Text size: " + size + "px");
});
if (down)
down.addEventListener("click", function () {
if (size <= MIN) {
toast("Smallest text size");
return;
}
setSize(size - STEP);
toast("Text size: " + size + "px");
});
if (reset)
reset.addEventListener("click", function () {
setSize(DEFAULT);
toast("Text size reset");
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>The Meridian Ledger — Standard Article</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=Inter:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,500;0,600;0,700;0,800;0,900;1,500;1,600&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="progress" role="presentation" aria-hidden="true"><span id="progressBar"></span></div>
<header class="masthead">
<div class="masthead__inner">
<div class="masthead__date">Sunday, June 8, 2026 · Late City Edition</div>
<a class="masthead__name" href="#">The Meridian Ledger</a>
<div class="masthead__tools">
<span class="masthead__price">Vol. CXLII · No. 211</span>
</div>
</div>
<nav class="subnav" aria-label="Sections">
<ul>
<li><a href="#" aria-current="page">Climate</a></li>
<li><a href="#">Politics</a></li>
<li><a href="#">Business</a></li>
<li><a href="#">Culture</a></li>
<li><a href="#">Opinion</a></li>
<li><a href="#">Science</a></li>
</ul>
</nav>
</header>
<main class="wrap">
<article class="article" id="article">
<header class="article__head">
<p class="kicker"><span class="kicker__tag">Climate</span> The Coastline Project</p>
<h1 class="headline">After the Tide: How Marrow Bay Rebuilt a Harbor It Almost Lost</h1>
<p class="deck">
A decade after the floods of ’16 swallowed the old wharf, the town gambled on living
seawalls and a salt-marsh ledger. The bet is starting to pay — but the water is not done
rising.
</p>
<div class="byline" aria-label="Article metadata">
<div class="byline__author">
<span class="byline__avatar" aria-hidden="true">EH</span>
<span class="byline__who">
<span class="byline__name">By Elena Hartwell</span>
<span class="byline__dateline">Marrow Bay, Maine · 14 min read</span>
</span>
</div>
<div class="share" role="group" aria-label="Share this article">
<button class="share__btn" data-share="link" type="button" title="Copy link">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></svg>
<span>Copy link</span>
</button>
<button class="share__btn" data-share="x" type="button" title="Share on X">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 4l16 16M20 4L4 20"/></svg>
<span class="sr-only">Share on X</span>
</button>
<button class="share__btn" data-share="mail" type="button" title="Email this story">
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>
<span class="sr-only">Email this story</span>
</button>
</div>
</div>
</header>
<figure class="hero">
<div class="hero__img hero__img--dune" role="img" aria-label="A reconstructed living seawall fronts the harbor at low tide, marsh grass catching the early light."></div>
<figcaption>
<span class="cap">Salt marsh and basalt sill protect the new wharf at Marrow Bay, photographed at dawn from the breakwater.</span>
<span class="credit">Photograph by Theo Vance for The Meridian Ledger</span>
</figcaption>
</figure>
<div class="controls" role="group" aria-label="Reading controls">
<span class="controls__label">Text size</span>
<button class="controls__btn" id="fontDown" type="button" aria-label="Decrease text size">A−</button>
<button class="controls__btn" id="fontReset" type="button" aria-label="Reset text size">Reset</button>
<button class="controls__btn" id="fontUp" type="button" aria-label="Increase text size">A+</button>
</div>
<div class="body" id="articleBody">
<p class="lead">
The morning the harbor failed, Nora Pell was making coffee. She watched from her kitchen as
the tide came up the launch ramp, then the parking lot, then the door of the chandlery her
grandfather had built — water the color of weak tea, carrying lobster traps and a child’s
bicycle out into the bay. By noon the old wooden wharf was gone, and with it the only thing
most of Marrow Bay had ever agreed on: that the water knew its place.
</p>
<p>
That was the autumn of 2016. What followed was less a recovery than an argument — held in
church basements and at the bait shop, in two contested town meetings and one lawsuit — over
a single, deceptively simple question. Should the town rebuild the wall it had always
known, taller and harder this time, or should it try something almost nobody on the harbor
board had heard of?
</p>
<p>
The answer, eventually, was both. Marrow Bay poured a low basalt sill where the old bulkhead
had stood, then did the unthinkable in a working harbor: it gave the sea a little room. Where
there had been asphalt, planners laid down nearly four acres of restored salt marsh, terraced
so the tide could rise into it and spend its strength on the grass instead of the dock.
</p>
<aside class="relatedbox" aria-label="Related coverage">
<p class="relatedbox__label">Related coverage</p>
<ul>
<li><a href="#">The towns betting on “managed retreat” — and the ones refusing to</a></li>
<li><a href="#">A field guide to living seawalls, from oyster reefs to marsh terraces</a></li>
<li><a href="#">Why federal flood maps still lag a decade behind the water</a></li>
</ul>
</aside>
<p>
The engineering had a name that locals never used — a “nature-based hybrid defense” — and a
ledger that they used constantly. Every spring, volunteers from the harbor co-op count marsh
stems per square meter, log them in a shared spreadsheet, and compare the totals against the
erosion they would otherwise expect. The marsh, in other words, is audited like a business.
When it grows, the town’s flood insurance assumptions improve.
</p>
<blockquote class="pull">
<p>“We stopped trying to win against the water. We started trying to slow it down enough to
keep our footing.”</p>
<cite>— Nora Pell, harbormaster</cite>
</blockquote>
<p>
That shift in language matters more than it sounds. For three generations Marrow Bay had
treated the shoreline as a fixed line to be held, a border with the Atlantic. The marsh
ledger reframes it as something negotiable, even managed — an asset that appreciates if you
tend it and collapses if you pave it. Hartwell heard the same word, over and over, from
fishermen who once scorned the plan: <em>patience</em>.
</p>
<figure class="inset">
<div class="inset__img" role="img" aria-label="A duotone chart-like texture suggesting tide gauges and rising water lines."></div>
<figcaption>
<span class="cap">Tide-gauge records at the breakwater, 1998–2026. The trend line is the part nobody disputes anymore.</span>
<span class="credit">Source: Gulf of Maine Observing Cooperative</span>
</figcaption>
</figure>
<p>
None of this makes the town safe. The same gauges that justify the marsh also show the bay
rising faster than the engineers planned for — roughly an inch every four years now, with
the storms stacking on top. The basalt sill buys time; the marsh buys a little more. What it
cannot buy is permanence, and the people of Marrow Bay have, after a decade, stopped asking
for any.
</p>
<p>
On the morning Hartwell visited, Pell walked the new wharf at low tide, pointing out where the
grass had crept twenty feet seaward of last year’s stakes. A cormorant dried its wings on the
sill. Somewhere under the planking, oysters the co-op seeded in 2019 were quietly cementing
themselves into a reef nobody can see. “Ask me in another ten years,” she said. “The water
will. So I’d rather be ready with an answer.”
</p>
</div>
<footer class="article__foot">
<p class="article__tags">
<span>Filed under:</span>
<a href="#">Coastal resilience</a>
<a href="#">Sea-level rise</a>
<a href="#">Maine</a>
<a href="#">Infrastructure</a>
</p>
</footer>
</article>
<section class="related" aria-labelledby="moreHeading">
<h2 class="related__heading" id="moreHeading">More in Climate</h2>
<div class="related__grid">
<a class="card" href="#">
<div class="card__img card__img--forest" role="img" aria-label=""></div>
<p class="card__kicker">Wildfire</p>
<h3 class="card__title">The new fire season starts in February, and nobody is ready</h3>
<p class="card__meta">By Marcus Reyes · 9 min read</p>
</a>
<a class="card" href="#">
<div class="card__img card__img--grid" role="img" aria-label=""></div>
<p class="card__kicker">Energy</p>
<h3 class="card__title">A small town quietly built its own grid. Then the storms came.</h3>
<p class="card__meta">By Priya Anand · 12 min read</p>
</a>
<a class="card" href="#">
<div class="card__img card__img--river" role="img" aria-label=""></div>
<p class="card__kicker">Water</p>
<h3 class="card__title">The river that was straightened, and the city now bending it back</h3>
<p class="card__meta">By Dale Brennan · 7 min read</p>
</a>
</div>
</section>
</main>
<footer class="sitefoot">
<p>The Meridian Ledger · A fictional publication</p>
<p class="sitefoot__fine">All names, headlines and reporting on this page are invented for design purposes.</p>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Standard Article
A complete editorial reading view for The Meridian Ledger, a fictional broadsheet, art-directed in a warm newsprint palette with hairline rules and a single red accent. The masthead, uppercase section nav and dateline frame an oversized Playfair Display headline, an italic deck and a byline row carrying the author, dateline, read-time and three share controls. A duotone CSS hero stands in for a press photograph, complete with an italic caption and a credit line.
The body is set as justified, hyphenated columns with a red drop cap on the lead paragraph, a floated Related coverage box, an inset tide-gauge figure and an oversized serif pull quote. Below the article, a three-card More in Climate row continues the section, each card built from a gradient duotone image, a red kicker, a serif title and a byline.
Three vanilla-JS interactions ship with it: a top reading-progress bar tracks how far you are through the article, the share buttons copy the link (with a clipboard fallback) and raise a toast, and an A−/Reset/A+ control rescales the body text within sensible bounds. There are no frameworks, no build step and no network requests beyond the two Google Fonts.
Illustrative UI only — masthead, headlines, bylines, and articles are fictional; not a real news publication.